def translateFile(self, filename): """ Translates a single .vm file to a .asm file """ parser = Parser(filename) self.codeWriter.setFileName(os.path.basename(filename).replace(".vm", "")) while parser.hasMoreCommands(): parser.advance() command = parser.commandType() if command == parser.C_ARITHMETIC: self.codeWriter.writeArithmetic(parser.arg1()) elif command == parser.C_PUSH or command == parser.C_POP: self.codeWriter.writePushPop(parser.command[0], parser.arg1(), parser.arg2()) elif command == parser.C_LABEL: self.codeWriter.writeLabel(parser.arg1()) elif command == parser.C_GOTO: self.codeWriter.writeGoTo(parser.arg1()) elif command == parser.C_IF: self.codeWriter.writeIf(parser.arg1()) elif command == parser.C_FUNCTION: self.codeWriter.writeFunction(parser.arg1(), parser.arg2()) elif command == parser.C_CALL: self.codeWriter.writeCall(parser.arg1(), parser.arg2()) elif command == parser.C_RETURN: self.codeWriter.writeReturn() parser.close()
def secondPass(self): """ Converts commands from Hack assembly to binary instructions """ parser = Parser(self.inFile) code = Code() address = 16 try: output = open(self.outFile, 'wb') except IOError: print "Unable to open output file" exit(-2) while parser.hasMoreCommands(): parser.advance() command = parser.commandType() if command is parser.A_COMMAND: # If the command is an A instruction, write the symbol's # binary number to the output file symbol = parser.symbol() toWrite = '0' # Get decimal number to write if symbol.isdigit(): symbol = bin(int(symbol))[2:] else: if not symbol in self.symbols: # If A instruction create temporary variable self.symbols[symbol] = address address = address + 1 symbol = bin(self.symbols[symbol])[2:] # Add 0s until the length is appropriate toWrite = toWrite + symbol toWrite = toWrite.zfill(16) # Write to output file output.write(toWrite+'\n') elif command is parser.C_COMMAND: # If the command is a C instruction, write # dest, comp and jump to the output file # Write first 3 bits output.write('111') # Write 'a' bit comp = parser.comp() if comp.find('M') is not -1: output.write('1') else: output.write('0') # Write 'comp', 'dest' and 'jump' bits output.write(code.comp(comp)) output.write(code.dest(parser.dest())) output.write(code.jump(parser.jump())) output.write('\n') parser.close()
def translateFile(self, filename): """ Translates a single .vm file to a .asm file """ parser = Parser(filename) self.codeWriter.setFileName(os.path.basename(filename).replace('.vm', "")) while parser.hasMoreCommands(): parser.advance() command = parser.commandType() if command == parser.C_ARITHMETIC: self.codeWriter.writeArithmetic(parser.arg1()) elif command == parser.C_PUSH or command == parser.C_POP: self.codeWriter.writePushPop(parser.command[0], parser.arg1(), parser.arg2()) parser.close()
def firstPass(self): """ Adds all user-defined symbols to symbols dictionary """ parser = Parser(self.inFile) commandLine = 0 while parser.hasMoreCommands(): parser.advance() command = parser.commandType() if command is parser.L_COMMAND: newSymbol = parser.symbol() if not newSymbol in self.symbols: self.symbols[newSymbol] = commandLine elif command is parser.C_COMMAND or command is parser.A_COMMAND: # If C instruction add 1 to the # of commands commandLine = commandLine + 1 parser.close()