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
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