def translate(self, file): """First pass - convert instructions to opcodes""" program = [] needsarg = False for line in file: for word in line.split(): word = word.upper() if word.startswith("#"): break elif needsarg: if program[-1] == opset.LIT: program.append(int(word)) else: program.append(word) needsarg = False elif word in opset.name2byte: byte = opset.name2byte[word] self.debug("%s -> %s", word, byte) if opset.unary(byte): needsarg = True program.append(byte) else: raise SyntaxError("Unrecognized instruction '%s'" % word) if needsarg: raise Exception("Missing argument for '%s'" % program[-1]) return program
def run(self, program): '''Execute list of instructions''' end = program[0] # First opcode is length self.memory = [0] * program[1] # Second opcode is memory size requirement self.pc = 2 while self.pc < end and program[self.pc] != opset.HALT: instruction = program[self.pc] self.pc += 1 if opset.nullary(instruction): self.debug("%02d %s", self.pc, opset.byte2name[instruction]) self.nullary[instruction]() elif opset.unary(instruction): argument = program[self.pc] self.pc += 1 self.debug("%02d %s %s", self.pc, opset.byte2name[instruction], argument) self.unary[instruction - opset.LIT](argument)
def relabel(self, program, symbols): """Replace symbols in program""" self.debug("Replacing symbols with labels and adresses") pc = 1 end = len(program) while pc < end: instruction = program[pc] pc += 1 if opset.unary(instruction): argument = program[pc] if opset.symbolarg(instruction): key = opset.LABEL if opset.labelarg(instruction) else opset.MEM if argument not in symbols[key]: raise Exception("Cannot use unknown symbol '%s'" % argument) value = symbols[key][argument] self.debug("Replace - %s %s -> %s", opset.byte2name[instruction], argument, value) program[pc] = value pc += 1 return program
def findsymbols(self, program): """Find labels and variables and build symboltable""" symbols = {opset.LABEL: {}, opset.MEM: {}} pc = addr = 0 end = len(program) newprogram = [0, 0] self.debug("Finding labels and variables") while pc < end: instruction = program[pc] pc += 1 if opset.nullary(instruction): newprogram.append(instruction) elif opset.unary(instruction): argument = program[pc] pc += 1 if instruction in (opset.LABEL, opset.MEM): if argument in symbols[instruction]: raise Exception( "Cannot declare symbol more than once: %s %s" % (opset.byte2name[instruction], argumet) ) if instruction == opset.LABEL: value = len(newprogram) else: value = addr addr += 1 self.debug("Symbol - %s %s -> %s", opset.byte2name[instruction], argument, value) symbols[instruction][argument] = value else: newprogram.append(instruction) newprogram.append(argument) # First instruction is length newprogram[0] = len(newprogram) # Second instruction is memory requirement newprogram[1] = addr return newprogram, symbols