def test_instruction_from_dict(self): """Simple smoke test: Can I make an instruction from a dict?""" d = { "opcode": "MUL", "predicate": "ALWAYS", "target": "r1", "src1": "r2", "src2": "r3", "offset": "-12" } instr = instr_format.instruction_from_dict(d) self.assertEqual(instr.op, OpCode.MUL) self.assertEqual(instr.cond, CondFlag.ALWAYS) self.assertEqual(instr.reg_target, 1) self.assertEqual(instr.reg_src1, 2) self.assertEqual(instr.reg_src2, 3) self.assertEqual(instr.offset, -12)
def assemble(lines: List[str]) -> List[int]: """ Simple one-pass assembly for now; must be extended to two passes to write convenient assembly code with labels; probably to three passes with expansion of control flow into standard assembly code. """ error_count = 0 instructions = [] for lnum in range(len(lines)): line = lines[lnum] log.debug("Processing line {}: {}".format(lnum, line)) try: fields = parse_line(line) #FIXME I added this print(fields) if fields["kind"] == AsmSrcKind.FULL: log.debug("Constructing instruction") fill_defaults(fields) instr = instruction_from_dict(fields) word = instr.encode() instructions.append(word) elif fields["kind"] == AsmSrcKind.DATA: word = value_parse(fields["value"]) instructions.append(word) else: log.debug("No instruction on line") except SyntaxError as e: error_count += 1 print("Syntax error in line {}: {}".format(lnum, line)) except KeyError as e: error_count += 1 print("Unknown word in line {}: {}".format(lnum, e)) except Exception as e: error_count += 1 print("Exception encountered in line {}: {}".format(lnum, e)) if error_count > ERROR_LIMIT: print("Too many errors; abandoning") sys.exit(1) return instructions