class TestAssembler(unittest.TestCase): # instructions = ["@2", "A_const", "L", "C_DP1", "C_APDM", "D0", "0JNE"] def setUp(self): self.fakeParser = fakeparser() self.fakeSymbolTable = fakesymboltable() self.assembler = Assembler() self.assembler.setParser(self.fakeParser) self.assembler.setSymbolTable(self.fakeSymbolTable) def test_assemble_A_const(self): binary_instruction = self.assembler.assembleInstruction("@2") self.assertEqual("0b0000000000000010", binary_instruction) def test_assemble_A_sym(self): self.fakeSymbolTable.addEntry("loop", 110) binary_instruction = self.assembler.assembleInstruction("@loop") self.assertEqual("0b0000000001101110", binary_instruction) def test_jumpInstruction(self): binary_instruction = self.assembler.assembleInstruction("0;JNE") self.assertEqual("0b1110101010000101", binary_instruction) def test_D_eq_DplusOne(self): binary_instruction = self.assembler.assembleInstruction("D=D+1") self.assertEqual("0b1110011111010000", binary_instruction) def test_A_eq_DPlusM(self): binary_instruction = self.assembler.assembleInstruction("A=D+M") self.assertEqual("0b1111000010100000", binary_instruction) def testRemoveWhiteSpaceOnLine(self): r = self.assembler.removeWhiteSpaceOnLine(" A = D + 1 //a comment") self.assertEqual("A=D+1//acomment", r) def testRemoveCommentsOnLine(self): r = self.assembler.removeCommentsOnLine(" A = D + 1 //a comment") self.assertEqual(" A = D + 1 ", r) def testAssemble(self): instructions = ["@2", "0;JNE", "D=D+1", "A=D+M"] assembledInstructions = self.assembler.assemble(instructions) self.assertEqual(["0b0000000000000010", "0b1110101010000101", "0b1110011111010000", "0b1111000010100000"], assembledInstructions) def testAssembleWithSymbolicA(self): # symbol table already initialized in setUp() to return 110 for any symbol instructions = ["@2", "0;JNE", "@myVariable", "D=D+1", "A=D+M"] assembledInstructions = self.assembler.assemble(instructions) self.assertEqual(["0b0000000000000010", "0b1110101010000101", "0b0000000001101110", "0b1110011111010000", "0b1111000010100000"], assembledInstructions) def testFirstPass(self): instructions = ["@2", "0;JNE", "@userSymbol", "D=D+1", "A=D+M"] self.assertEqual(5, self.assembler.firstPass(instructions))
class TestAssemblerFinal(unittest.TestCase): def setUp(self): self.assembler = Assembler() parser = Parser() self.symbolTable = SymbolTable() self.assembler.setSymbolTable(self.symbolTable) self.assembler.setParser(parser) def testFirstPassSimpleLoop(self): instructions = ["(loop)", "@loop", "0;JNE"] self.assembler.firstPass(instructions) self.assertTrue(self.symbolTable.contains("loop")) self.assertEqual(self.symbolTable.getAddress("loop"), 0) def testFirstPassComplexLoops(self): instructions = ["(loop)", "@loop", "0;JNE", "(bob)", "D=D+1", "(tim)", "M=A+D"] self.assembler.firstPass(instructions) self.assertTrue(self.symbolTable.contains("loop")) self.assertTrue(self.symbolTable.contains("bob")) self.assertTrue(self.symbolTable.contains("tim")) self.assertEqual(self.symbolTable.getAddress("loop"), 0) self.assertEqual(self.symbolTable.getAddress("bob"), 2) self.assertEqual(self.symbolTable.getAddress("tim"), 3) def testFirstPassMaxAsm(self): instructions = ["@R0", "D=M", "@R1", "D=D-M", "@OUTPUT_FIRST", "D;JGT", "@R1", "D=M", "@OUTPUT_D", "0;JMP", "(OUTPUT_FIRST)", "@R0", "D=M", "(OUTPUT_D)", "@R2", "M=D", "(INFINITE_LOOP)", "@INFINITE_LOOP", "0;JMP"] self.assembler.firstPass(instructions) self.assertTrue(self.assembler.symbolTable.contains("OUTPUT_FIRST")) self.assertEqual(self.assembler.symbolTable.getAddress("OUTPUT_FIRST"), 10) def testFirstPassMaxAsmInfiniteLoopAddress(self): instructions = ["@R0", "D=M", "@R1", "D=D-M", "@OUTPUT_FIRST", "D;JGT", "@R1", "D=M", "@OUTPUT_D", "0;JMP", "(OUTPUT_FIRST)", "@R0", "D=M", "(OUTPUT_D)", "@R2", "M=D", "(INFINITE_LOOP)", "@INFINITE_LOOP", "0;JMP"] self.assembler.firstPass(instructions) self.assertTrue(self.assembler.symbolTable.contains("INFINITE_LOOP")) self.assertEqual(self.assembler.symbolTable.getAddress("INFINITE_LOOP"), 14) def testSecondPassMaxAsmInfiniteLoopAddress(self): instructions = ["@R0", "D=M", "@R1", "D=D-M", "@OUTPUT_FIRST", "D;JGT", "@R1", "D=M", "@OUTPUT_D", "0;JMP", "(OUTPUT_FIRST)", "@R0", "D=M", "(OUTPUT_D)", "@R2", "M=D", "(INFINITE_LOOP)", "@INFINITE_LOOP", "0;JMP"] self.assembler.firstPass(instructions) self.assembler.secondPass(instructions) self.assertTrue(self.assembler.symbolTable.contains("INFINITE_LOOP")) self.assertEqual(self.assembler.symbolTable.getAddress("INFINITE_LOOP"), 14) def testSecondPassSimple(self): instructions = ["(loop)", "@myVar", "M=5", "@loop", "0;JNE"] self.assembler.firstPass(instructions) self.assembler.secondPass(instructions) self.assertTrue(self.symbolTable.contains("loop")) self.assertTrue(self.symbolTable.contains("myVar")) self.assertEqual(self.symbolTable.getAddress("myVar"), 16) self.assertEqual(self.symbolTable.getAddress("loop"), 0) def testAssembleInstructions(self): instructions = ["(loop)", "@loop", "0;JEQ"] self.assembler.firstPass(instructions) self.assembler.secondPass(instructions) self.assertEqual(["0b0000000000000000", "0b1110101010000010"], self.assembler.assemble(instructions))
from Assembler import Assembler from Parser import Parser from SymbolTable import SymbolTable import sys # initialize assembler assembler = Assembler() parser = Parser() symbolTable = SymbolTable() assembler.setParser(parser) assembler.setSymbolTable(symbolTable) # open source file filename = sys.argv[1].split(".")[0] asmFile = open(sys.argv[1]) # get instructions for assembler from source # and remove whitespace and comments as well instructions = [] for line in asmFile: line = assembler.removeCommentsOnLine(line) line = assembler.removeWhiteSpaceOnLine(line) if line != "" and line != "\n": instructions.append(line) asmFile.close()