def main(): '''Main entry point for the script.''' # For each .vm file, create a parser object filetrue = os.path.isfile(sys.argv[1]) dirtrue = os.path.isdir(sys.argv[1]) vmfiles = [] # Rename directory as a ".asm" file for later use finame = os.path.basename(os.path.normpath(sys.argv[1])) + ".asm" # Get file path with .asm file appended dirname = os.path.join(sys.argv[1], finame) # Create list of files to convert and add to asm file if dirtrue: cw = CodeWriter(dirname) fi = os.listdir(sys.argv[1]) for names in fi: if names.endswith(".vm"): vmfiles.append(sys.argv[1] + names) elif filetrue: di = sys.argv[1] if di.endswith(".vm"): vmfiles.append(di) tr = vmfiles[0] trs = tr.replace("vm", "asm") cw = CodeWriter(trs) else: print "invalid filetype: only input .vm files" else: print "usage: 'python <file.vm> or <dirname/>'" out = cw.constructor() cw.writeInit(out) with out as outfile: for files in vmfiles: # Create new instance of class Parser() p = cw.setFileName(files) with p.constructor() as infile: for line in infile: if p.commandType(line) == "comments": pass elif p.commandType(line) == "C_ARITHMETIC": cw.writeArithmetic(outfile, p.args(line)[0]) elif p.commandType(line) == "C_IF": # Handle if-goto command cw.writeIf(outfile, p.args(line)[1]) elif p.commandType(line) == "C_GOTO": # Handle goto command cw.writeGoto(outfile, p.args(line)[1]) elif p.commandType(line) == "C_RETURN": # Return function result cw.writeReturn(outfile) elif p.commandType(line) == "C_LABEL": # Set label address cw.writeLabel(outfile, p.args(line)[1]) elif p.commandType(line) == "C_CALL": # Handle function calls cw.writeCall(outfile, p.args(line)[1], p.args(line)[2]) elif p.commandType(line) == "C_FUNCTION": cw.writeFunction(outfile, p.args(line)[1], p.args(line)[2]) elif p.commandType(line) == "C_PUSH" or "C_POP": cw.writePushPop(outfile, p.commandType(line), p.args(line)[1], p.args(line)[2])
def main(path): """Entry point for the vm translator.""" vm_files_paths = get_vm_files(path) if not os.path.exists(path): print("invalid file path") sys.exit(1) if os.path.isdir(path): dirname = os.path.dirname(path) name = os.path.basename(dirname) path = f"{dirname}/{name}" isdir = True else: path = os.path.splitext(path)[0] isdir = False # Create single code write module code_writer = CodeWriter(f"{path}.asm") if isdir: code_writer.writeInit() for vm_file_path in vm_files_paths: filestream = open(vm_file_path, "r") parser = Parser(filestream) filestream.close() # write to assembly file code_writer.setFileName(os.path.basename(vm_file_path)) while parser.hasMoreCommands(): parser.advance() command_type = parser.commandType() if (command_type == CommandType.C_PUSH or command_type == CommandType.C_POP): segment = parser.arg1() index = parser.arg2() code_writer.writePushPop( command_type, segment, int(index) ) elif command_type == CommandType.C_ARITHMETIC: command = parser.arg1() code_writer.writeArithmetic(command) elif command_type == CommandType.C_LABEL: label = parser.arg1() code_writer.writeLabel(label) elif command_type == CommandType.C_GOTO: label = parser.arg1() code_writer.writeGoto(label) elif command_type == CommandType.C_IF: label = parser.arg1() code_writer.writeIf(label) elif command_type == CommandType.C_FUNCTION: label = parser.arg1() number_of_locals = int(parser.arg2()) code_writer.writeFunction(label, number_of_locals) elif command_type == CommandType.C_RETURN: code_writer.writeReturn() elif command_type == CommandType.C_CALL: functioname = parser.arg1() number_of_args = int(parser.arg2()) code_writer.writeCall(functioname, number_of_args) print(code_writer.filestream.get_global_counter()) code_writer.close()