def decode(singlefile): print(singlefile) with open(singlefile, 'r') as f: name = os.path.basename(singlefile).split('.')[0] asmname = os.path.join(os.path.dirname(singlefile), "%s.asm" % name) asm = open(asmname, 'w') print(asmname) print() n = 0 while True: line = f.readline() if line == '': break line = parser.removeun(line) if line == '': continue n += 1 line = parser.removeun(line) command = line.split()[0] ctype = parser.commandType(command) a1 = parser.arg1(line, ctype) if ctype == 'C_ARITHMETIC': code = writeArithmetic(command) if command in ['eq', 'gt', 'lt']: code = code % (n, n, n, n, n, n, n) elif ctype == 'C_PUSH' or ctype == "C_POP": a2 = parser.arg2(line) code = writepushpop(name, command, a1, a2) asm.write("%s\n" % code) asm.close()
def getASM(self, parser, code_writer): CT = parser.commandType() if CT == parser.C_ARITHMETIC: # print(parser.arg1()) code_writer.writeArithmetic(parser.arg1()) elif CT == parser.C_PUSH or CT == parser.C_POP: # print (parser.arg1(), parser.arg2()) code_writer.writePushPop(CT, parser.arg1(), parser.arg2()) elif CT == parser.C_LABEL: # print(parser.arg1()) code_writer.writeLabel(parser.arg1()) elif CT == parser.C_GOTO: # print(parser.arg1()) code_writer.writeGoTo(parser.arg1()) elif CT == parser.C_IF: # print(parser.arg1()) code_writer.writeIf(parser.arg1()) elif CT == parser.C_RETURN: # print("return") code_writer.writeReturn() elif CT == parser.C_FUNCTION: # print(parser.arg1(), parser.arg2()) code_writer.writeFunction(parser.arg1(), parser.arg2()) elif CT == parser.C_CALL: # print(parser.arg1(), parser.arg2()) code_writer.writeCall(parser.arg1(), parser.arg2())
def write_push_pop(): base = arg1() if base == 'static': f.write('@16' + '\n') f.write('D=A' + '\n') elif base == 'local': f.write('@LCL' + '\n') f.write('D=M' + '\n') elif base == 'argument': f.write('@ARG' + '\n') f.write('D=M' + '\n') elif base == 'this': f.write('@THIS' + '\n') f.write('D=M' + '\n') elif base == 'that': f.write('@THAT' + '\n') f.write('D=M' + '\n') elif base == 'constant': f.write('@SP' + '\n') f.write('D=A' + '\n') elif base == 'temp': f.write('@5' + '\n') f.write('D=A' + '\n') f.write('@R13' + '\n') f.write('M=D' + '\n') index = arg2() f.write('@' + index + '\n') f.write('D=A' + '\n') f.write('@R13' + '\n') f.write('M=M+D' + '\n') command = command_type() if command == 'C_PUSH': f.write('D=M' + '\n') if base != 'constant': f.write('A=D' + '\n') f.write('D=M' + '\n') f.write('@SP' + '\n') f.write('M=M+1' + '\n') f.write('A=M-1' + '\n') f.write('M=D' + '\n') else: # (if command == 'C_POP') f.write('@SP' + '\n') f.write('M=M-1' + '\n') f.write('A=M+1' + '\n') f.write('D=M' + '\n') f.write('@R13' + '\n') f.write('A=M' + '\n') f.write('M=D' + '\n')
def write_push_pop () : base = arg1() if base == 'static' : f.write('@16' + '\n') f.write('D=A' + '\n') elif base == 'local' : f.write('@LCL' + '\n') f.write('D=M' + '\n') elif base == 'argument' : f.write('@ARG' + '\n') f.write('D=M' + '\n') elif base == 'this' : f.write('@THIS' + '\n') f.write('D=M' + '\n') elif base == 'that' : f.write('@THAT' + '\n') f.write('D=M' + '\n') elif base == 'constant' : f.write('@SP' + '\n') f.write('D=A' + '\n') elif base == 'temp' : f.write('@5' + '\n') f.write('D=A' + '\n') f.write('@R13' + '\n') f.write('M=D' + '\n') index = arg2() f.write('@' + index + '\n') f.write('D=A' + '\n') f.write('@R13' + '\n') f.write('M=M+D' + '\n') command = command_type() if command == 'C_PUSH' : f.write('D=M' + '\n') if base != 'constant' : f.write('A=D' + '\n') f.write('D=M' + '\n') f.write('@SP' + '\n') f.write('M=M+1' + '\n') f.write('A=M-1' + '\n') f.write('M=D' + '\n') else : # (if command == 'C_POP') f.write('@SP' + '\n') f.write('M=M-1' + '\n') f.write('A=M+1' + '\n') f.write('D=M' + '\n') f.write('@R13' + '\n') f.write('A=M' + '\n') f.write('M=D' + '\n')
def write_arithmetic(): command = arg1() # (if command operates on single value) if command == 'not' or command == 'neg': f.write('@SP' + '\n') f.write('A=M' + '\n') if command == 'not': f.write('M=!M' + '\n') else: f.write('M=-M' + '\n') else: # (if command operates on two values) f.write('@SP' + '\n') f.write('M=M-1' + '\n') f.write('A=M+1' + '\n') f.write('D=M' + '\n') f.write('A=A-1' + '\n') if command == 'add': f.write('M=M+D' + '\n') elif command == 'sub': f.write('M=M-D' + '\n') elif command == 'and': f.write('M=M&D' + '\n') elif command == 'or': f.write('M=M|D' + '\n') else: # (if operation is comparative) f.write('D=M-D' + '\n') global set_true_count, continue_count f.write('@SET_TRUE.' + str(set_true_count) + '\n') if command == 'eq': f.write('D;JEQ' + '\n') if command == 'gt': f.write('D;JGT' + '\n') if command == 'lt': f.write('D;JLT' + '\n') f.write('@SP' + '\n') f.write('A=M' + '\n') f.write('M=0' + '\n') f.write('@CONTINUE.' + str(continue_count) + '\n') f.write('0;JMP' + '\n') f.write('(SET_TRUE.' + str(set_true_count) + ')' + '\n') f.write('@SP' + '\n') f.write('A=M' + '\n') f.write('M=1' + '\n') f.write('(CONTINUE.' + str(continue_count) + ')' + '\n') set_true_count += 1 continue_count += 1
def write_arithmetic () : command = arg1() # (if command operates on single value) if command == 'not' or command == 'neg' : f.write('@SP' + '\n') f.write('A=M' + '\n') if command =='not' : f.write('M=!M' + '\n') else : f.write('M=-M' + '\n') else : # (if command operates on two values) f.write('@SP' + '\n') f.write('M=M-1' + '\n') f.write('A=M+1' + '\n') f.write('D=M' + '\n') f.write('A=A-1' + '\n') if command == 'add' : f.write('M=M+D' + '\n') elif command == 'sub' : f.write('M=M-D' + '\n') elif command == 'and' : f.write('M=M&D' + '\n') elif command == 'or' : f.write('M=M|D' + '\n') else : # (if operation is comparative) f.write('D=M-D' + '\n') global set_true_count, continue_count f.write('@SET_TRUE.' + str(set_true_count) + '\n') if command == 'eq' : f.write('D;JEQ' + '\n') if command == 'gt' : f.write('D;JGT' + '\n') if command == 'lt' : f.write('D;JLT' + '\n') f.write('@SP' + '\n') f.write('A=M' + '\n') f.write('M=0' + '\n') f.write('@CONTINUE.' + str(continue_count) + '\n') f.write('0;JMP' + '\n') f.write('(SET_TRUE.' + str(set_true_count) + ')' + '\n') f.write('@SP' + '\n') f.write('A=M' + '\n') f.write('M=1' + '\n') f.write('(CONTINUE.' + str(continue_count) + ')' + '\n') set_true_count += 1 continue_count += 1