def main(): argparser = add_args() args = argparser.parse_args() file_name = args.source target_name = args.target verbose = args.verbose # build symbol table if verbose: print("Beginning symbol pass") with open(file_name, "r") as source: line = 0 for command in source: command = clear_trash(command) if parser.command_type(command) in ["A_COMMAND", "C_COMMAND"]: line += 1 elif parser.command_type(command) is "L_COMMAND": if verbose: print("Pseudocommand found at line {0}: {1}".format( line, command)) symbols[parser.symbol(clear_trash(command))] = str(line) print("Symbol {0} installed at line: {1}".format( parser.symbol(clear_trash(command)), line)) # assemble code if verbose: print("Beginning assembly pass") with open(file_name, "r") as source, open(target_name, "w") as target: for command in source: command = clear_trash(command) if len(command) is not 0: target.write(get_code(command))
def pass2(file_name): #first address for symbol memory with open(file_name, 'r') as asm_file: address = 16 command_list = [] for command in asm_file: current_command = parser.clean(command) #skip further processing if line made up of only spaces and/or comments if current_command: if parser.command_type(current_command) == 'C_Command': dest = parser.dest(current_command) comp = parser.comp(current_command) jump = parser.jump(current_command) binary_repr = code.binary_code(dest, comp, jump) command_list.append(binary_repr) elif parser.command_type(current_command) == 'A_Command': symbol = parser.symbol(current_command) #if symbol doesn't begin with a numeric value, check symbol table for #correct value. Add new symbol if necessary try: int_symbol = int(symbol) except ValueError: if not sym_table.contains(symbol): sym_table.add_entry(symbol, address) address += 1 symbol = sym_table.get_address(symbol) #convert decimal symbol to binary and add to command_list binary_symbol = "{0:016b}".format(int(symbol)) command_list.append(binary_symbol) return command_list
def get_code(command): command = clear_trash(command) output = "" if parser.command_type(command) == "A_COMMAND": output = "0" + address_of(parser.symbol(command)) + "\n" elif parser.command_type(command) == "L_COMMAND": pass elif parser.command_type(command) == "C_COMMAND": dest = code.dest(parser.dest(command)) jump = code.jump(parser.jump(command)) comp = code.comp(parser.comp(command)) output = "111" + comp + dest + jump + "\n" else: raise ValueError("Code not a valid command: {0}".format(command)) return output
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 pass1(file_name, sym_table): with open(file_name, 'r') as asm_file: program_counter = 0 #Go through file once, find the loops and store them in the symbol table for command in asm_file: current_command = parser.clean(command) #skip further processing if line made up of only spaces and/or comments if current_command: if parser.command_type(current_command) == 'L_Command': loop_symbol = parser.symbol(current_command) sym_table.add_entry(loop_symbol, program_counter) else: program_counter += 1
from code_writer import set_file_name, write_arithmetic, write_push_pop, close from parser import command_type, arg1, arg2, advance import sys vm_fn = sys.argv[1] vm_code = open(vm_fn, 'r').read().split('\n') set_file_name(vm_fn) complete = advance(vm_code) while not complete: C_type = command_type() if C_type == 'C_ARITHMETIC': write_arithmetic() elif C_type == 'C_PUSH' or C_type == 'C_POP': write_push_pop() complete = advance(vm_code) close()
from code_writer import set_file_name, write_arithmetic, write_push_pop, close from parser import command_type, arg1, arg2, advance import sys vm_fn = sys.argv[1] vm_code = open(vm_fn, 'r').read().split('\n') set_file_name(vm_fn) complete = advance(vm_code) while not complete : C_type = command_type() if C_type == 'C_ARITHMETIC' : write_arithmetic() elif C_type == 'C_PUSH' or C_type == 'C_POP' : write_push_pop() complete = advance(vm_code) close()