Ejemplo n.º 1
0
 def set_value(self, number, value):
     """number:int -> ...
     Stores a value in a register.
     """
     if number not in self.keys():
         return
     name = self._number_name[number]
     self.log.buffer("setting {:} to {:}".format(name, hex(value, 8)),
                     level.FINER)
     self._registers[number]['value']=value
Ejemplo n.º 2
0
    def _link(self, lines):
        """Transforms the program replacing branch identifiers with
        computed addresses that reference labels in the code.

        Description:
            [lines:str]:list -> [lines:str]:list
            Ensures all branch identifiers are valid (ie. corresponding
            labels were found in preprocessing) and replaces them with
            interim hexadecimal addresses. These hex addresses will be
            replaced during encoding with binary values.

        Purpose:
            preprocessing -> [linking] -> encoding

        Restrictions:
            N/A

        Exceptions:
            N/A

        Returns:
            A version of the program having all labels replaced with memory
            references.
         """

        # TODO: Linker needs to handle absolute addresses in multi-part
        # instructions. (2011-08-28)
        self.log.buffer("entering linker", level.FINER)

        # We will store the return data in output.
        output=[]
        for i in range(len(lines)):
            # First, check the instruction is valid. If we try to operate
            # with badly formed instructions at this point we will raise
            # an exception in the re module.
            instruction = lines[i].split()[0]
            if instruction in self._format_mappings:
                syntax     = self._instruction_syntax[instruction]
                expression = '^' + syntax['expression'] + '$'
            else:
                raise BadInstructionOrSyntax(
                    "{:} on line {:}:\n{:}"
                    .format(BAD, i+1, lines[i]))

            # We should have this data from the previous stage, or have
            # thrown an error.
            match = re.search(expression, lines[i])
            if match:
                key = re.match('\w+', lines[i]).group()
                if key in self._label_replacements:
                    group = self._label_replacements[key][1]
                    mode  = self._label_replacements[key][2]

                    pattern = self._instruction_syntax[key]['expression']
                    match = re.search(pattern, lines[i])
                    label = match.group(group)

                    # Calculate either absolute or relative addresses based on
                    # configuration file/API options.
                    try:
                        if mode == 'absolute':
                            base = self._text_offset
                            offset = self._jump_table[label]
                            offset = hex(base + (offset * self._word_spacing),
                                         self._isa_size/4)
                        elif mode == 'relative':
                            offset = str(self._jump_table[label] - i)
                    # Finally, we can replace the label.
                        lines[i] = lines[i].replace(label, offset)
                        self.log.buffer("replaced identifier `{:}'"
                                        "with {:}".format(
                                        label, offset), level.FINER)
                    except:
                        raise BadInstructionOrSyntax(
                            "{:} on line {:}: Label not found.\n{:}"
                            .format(BAD, i+1, lines[i]))
                output.append(lines[i])
            else:
                raise BadInstructionOrSyntax(
                    "{:} on line {:}:\n{:}"
                    .format(BAD, i+1, lines[i]))

        self._program = deepcopy(output)
        self.log.buffer("leaving linker", level.FINER)
        return output