def main(filepath): out_filename, filenames = parseFilePath(filepath) if os.path.exists(out_filename): os.remove(out_filename) if os.path.isfile(filepath): with open(filepath, "r") as infile: data = infile.readlines() parser = Parser(data) code_writer = CodeWriter(out_filename, filenames[0]) writeFile(parser, code_writer) elif os.path.isdir(filepath): for filename in filenames: full_path = os.path.join(filepath, filename + ".vm") with open(full_path, "r") as infile: data = infile.readlines() parser = Parser(data) code_writer = CodeWriter(out_filename, filename) if filenames[0] == filename: code_writer.writeComment("call Sys.init 0") code_writer.writeInit() writeFile(parser, code_writer)
def main(): #put the files in the same folder as the code and put the names in the filenames array, pass codewriter the name you want to output or filename[x] if you want it to be the same name with .asm #filenames = ["BasicTest","PointerTest","SimpleAdd","StackTest","StaticTest"] filesnames = [] inputList = [] ##put the file directory here filesPath = "C:\\Users\\drumm\\OneDrive\\Documents\\Code\\nand2tetris\\projects\\08\\FunctionCalls\\StaticsTest\\" runInit = False inputList = glob.glob(filesPath + "*.vm") for x in range(0, len(inputList)): filesnames.append(inputList[x].split('\\')[-1].replace('.vm', '')) if len(inputList) > 1: runInit = True if runInit == True: codewriter = CodeWriter( filesPath + inputList[0].split('\\')[-2].replace('.vm', '') + ".asm") codewriter.writeInit() else: codewriter = CodeWriter(filesPath + filesnames[0] + ".asm") for x in range(0, len(inputList)): filename = inputList[x] parser = Parser(filename) while parser.hasMoreCommands(): parser.advance() if parser.arg1() == 'push' or parser.arg1() == 'pop': codewriter.WritePushPop( parser.arg1(), parser.arg2(), parser.arg3(), filename.split('\\')[-1].replace('.vm', '')) elif parser.commandType() == 'C_ARITHMETIC': codewriter.writeArithmetic(parser.currentCommand) elif parser.commandType() == 'C_LABEL': codewriter.writeLabel(parser.arg2()) elif parser.commandType() == 'C_GOTO': codewriter.writeGoto(parser.arg2()) elif parser.commandType() == 'C_IF': codewriter.writeIf(parser.arg2()) elif parser.commandType() == 'C_CALL': codewriter.writeCall(parser.arg2(), parser.arg3()) elif parser.commandType() == 'C_RETURN': codewriter.writeReturn() elif parser.commandType() == 'C_FUNCTION': codewriter.writeFunction(parser.arg2(), parser.arg3()) else: print("hitelse") parser.close() codewriter.Close()
def main(): inputFileName = getInputName() isDirectory = os.path.isdir(inputFileName) if isDirectory: files = os.listdir(inputFileName) vmFiles = filter(isVMFile, files) listOfFiles = list( map(lambda fileName: inputFileName + "/" + fileName, vmFiles)) outputFileName = trimFile(inputFileName) writer = CodeWriter(inputFileName + "/" + outputFileName) if len(listOfFiles) > 1: writer.bootstrap() else: listOfFiles = [inputFileName] outputFileName = trimFile(inputFileName) writer = CodeWriter(outputFileName) for currentFile in listOfFiles: print("File to be parsed: {}".format(currentFile)) writer.setNewInputFile(trimFile(currentFile)) parser = Parser(currentFile) while parser.hasMoreCommands(): parser.advance() command = parser.getCommand() if parser.isArithmetic(): writer.writeArithmetic(command) elif parser.isPush() or parser.isPop(): writer.writePushPop(command) elif parser.isLabel(): writer.writeLabel(command) elif parser.isGoto(): writer.writeGoto(command) elif parser.isIf(): writer.writeIf(command) elif parser.isFunction(): writer.writeFunction(command) elif parser.isCall(): writer.writeCall(command) elif parser.isReturn(): writer.writeReturn(command) elif parser.isComment() or parser.isBlankLine(): continue else: raise Exception("Command not supported") parser.close() writer.close() print("VMTranslator finished.")
def main(): input_file = parse_arguments() if validate(input_file): if Path(input_file).is_dir(): files = get_files_from_directory(input_file) code_writer = CodeWriter(input_file) for file in files: lines = read_file(f'{input_file}/{file}') for line in lines: handle_file_output(line, code_writer) else: lines = read_file(input_file) code_writer = CodeWriter(input_file) for line in lines: handle_file_output(line, code_writer)
def test_not(self): code_writer = CodeWriter() cmd = '@SP\nAM=M-1\n' cmd += 'D=!M\n' cmd += '@SP\nA=M\nM=D\n' cmd += '@SP\nM=M+1\n' self.assertEqual(code_writer.get_not(), cmd)
def test_pop_that_pointer_symbol(self): code_writer = CodeWriter() i = '1' segment = MemorySegmentType.POINTER cmd = '@SP\nAM=M-1\n' cmd += 'D=M\n@THAT\nM=D\n' self.assertEqual(code_writer.get_pop(segment, i), cmd)
def main(): filename = sys.argv[1] parser = Parser(filename) writer = CodeWriter(filename) writer.writeInit() while parser.hasMoreCommands(): parser.advance() lineType = parser.commandType() if lineType == 'C_ARITHMETIC': writer.writeArithmetic(parser.getCommand()) elif lineType == 'C_PUSH' or lineType == 'C_POP': writer.writePushPop(lineType, parser.arg1(), parser.arg2()) elif lineType == 'C_LABEL': writer.writeLabel(parser.arg1()) elif lineType == 'C_GOTO': writer.writeGoto(parser.arg1()) elif lineType == 'C_IF': writer.writeIf(parser.arg1()) elif lineType == 'C_CALL': writer.writeCall(parser.arg1(), parser.arg2()) elif lineType == 'C_RETURN': writer.writeReturn() elif lineType == 'C_FUNCTION': writer.writeFunction(parser.arg1(), parser.arg2())
def translate(self): print("Starting translation...") if (self._file_list is None) or (len(self._file_list) == 0): raise Exception("No valid files to translate.") with CodeWriter(self._out_filename) as writer: writer.write_init() for infile in self._file_list: print("Processing file '{}' ...".format(infile)) writer.set_filename(os.path.splitext(os.path.basename(infile))[0]) p = Parser(infile) while p.has_more_commands(): p.advance() if p.command_type == VmToken.ARITHMETIC: writer.write_arithmetic(p.arg1) elif p.command_type == VmToken.POP or p.command_type == VmToken.PUSH: writer.write_push_pop(p.command_type, p.arg1, p.arg2) elif p.command_type == VmToken.LABEL: writer.write_label(p.arg1) elif p.command_type == VmToken.IF: writer.write_if(p.arg1) elif p.command_type == VmToken.GOTO: writer.write_goto(p.arg1) elif p.command_type == VmToken.FUNCTION: writer.write_function(p.arg1, p.arg2) elif p.command_type == VmToken.CALL: writer.write_call(p.arg1, p.arg2) elif p.command_type == VmToken.RETURN: writer.write_return() else: raise Exception('Unknown command type "{}".'.format(p.command_type)) print("Translation complete.\nOutput is '{}'".format(self._out_filename))
def main(): args = [x for x in sys.argv] if len(args) < 2: raise Exception( "Error[7]: No file/dir name provided \"Usage: python VMTranslator.py file.vm\"" ) if not os.path.isfile(args[1]) and not os.path.isdir(args[1]): raise FileNotFoundError("Error[8]: \"" + args[1] + "\" does not exist") input_files = [os.path.abspath(args[1])] print(input_files) output_file_name = os.path.abspath(args[1]) is_input_dir = False if os.path.isdir(input_files[0]): is_input_dir = True input_files = [f for f in os.listdir(input_files[0])] input_files = [f for f in input_files if f.split(".")[-1] == "asm"] input_files = [os.path.join(output_file_name, f) for f in input_files] output_file_name = os.path.join(output_file_name, os.path.basename(output_file_name)) print(input_files) print(output_file_name) for file_name in input_files: parser = Parser(file_name) codeWriter = CodeWriter(file_name, parser.tokens, parser.symbol_table)
def __init__(self, tokenizer, file_path): self.tokenizer = tokenizer self.file_path = file_path self.symbol_table = SymbolTable() self.class_name = "" self.code_writer = CodeWriter(self) self.label_ind = 0
def test_push_this_pointer_symbol(self): code_writer = CodeWriter() i = '0' segment = MemorySegmentType.POINTER cmd = '@THIS\nD=M\n@SP\nA=M\nM=D\n' cmd += '@SP\nM=M+1\n' self.assertEqual(code_writer.get_push(segment, i), cmd)
def run_vm_translator(): file_path = str(argv[1]) vm_files = [] write_init = 0 code_writer = CodeWriter(file_path) if file_path.endswith(".vm"): vm_files.append(file_path) if file_path == "Sys.vm": write_init = 1 else: file_list = listdir(file_path) for file in file_list: if file.endswith(".vm"): vm_files.append(file_path + "/" + file) if file == "Sys.vm": write_init = 1 if write_init == 1: code_writer.write_init() for file in vm_files: current_parser = Parser(file) single_parser(current_parser, code_writer) code_writer.finish_code_writer()
def __init__(self, prodir, WriteInit=True): vmfiles = [] for vf in os.listdir(prodir): if vf[-3:] == ".vm": vmfiles.append(os.path.join(prodir, vf)) assert vmfiles self.parser = [Parser() for vmf in vmfiles] for vmf, parser in zip(vmfiles, self.parser): parser.coms = self.read_vm(vmf) parser.len_coms = len(parser.coms) parser.vmf = os.path.basename(vmf) directory = os.path.dirname(vmfiles[0]) asm_name = os.path.basename(directory) + '.asm' self.asmf = os.path.join(directory, asm_name) print '' print "direct: ", directory print "vmfiles:" for vmf in vmfiles: print "\t", vmf print "asmname: ", asm_name print "asmf: ", self.asmf print '' self.codewriter = CodeWriter(self.asmf) self.WI = WriteInit
def main(): args = [x for x in sys.argv] if len(args) < 2: raise Exception( "Error[7]: No file/dir name provided \"Usage: python VMTranslator.py file.vm\"" ) if not os.path.isfile(args[1]) and not os.path.isdir(args[1]): raise FileNotFoundError("Error[8]: \"" + args[1] + "\" does not exist") input_files = [args[1]] output_file_name = os.path.basename(os.path.abspath(args[1])).split(".") if len(output_file_name) > 1: output_file_name.pop() output_file_name = ".".join(output_file_name) if os.path.isdir(input_files[0]): input_files = [ f for f in os.listdir(input_files[0]) if os.path.isfile(os.path.join(input_files[0], f)) ] input_files = [f for f in input_files if f.split(".")[-1] == "vm"] input_files = [os.path.abspath(f) for f in input_files] print(input_files) print(output_file_name) code_writer = CodeWriter(output_file_name) for file_name in input_files: parser = Parser(file_name) code_writer.setFileName(file_name) while parser.hasMoreCommands(): parser.advance() arg1 = None arg2 = None if parser.commandType() != COMMAND_TYPES["C_RETURN"]: arg1 = parser.arg1() if parser.commandType() == COMMAND_TYPES["C_PUSH"] or \ parser.commandType() == COMMAND_TYPES["C_POP"] or \ parser.commandType() == COMMAND_TYPES["C_FUNCTION"] or \ parser.commandType() == COMMAND_TYPES["C_CALL"]: arg2 = parser.arg2() if parser.commandType( ) == COMMAND_TYPES["C_ARITHMETIC"] and arg1 is not None: code_writer.writeArithmetic(arg1) if (parser.commandType() == COMMAND_TYPES["C_PUSH"] or \ parser.commandType() == COMMAND_TYPES["C_POP"]) and \ arg1 is not None and arg2 is not None: code_writer.writePushPop(parser.commandType(), arg1, arg2) code_writer.close()
def __init__(self, vmfilename): """Constructs the Parser and CodeWriter objects to be used in translating the file and supplies them with the appropriate filenames. """ asmfilename = vmfilename.split('.')[0] + '.asm' self.parser = Parser(vmfilename) self.code_writer = CodeWriter(asmfilename)
def __init__(self, input: TextIOBase, output: TextIOBase): self.input = input self.output = output self.tokens = [] self.location = 0 self.writer = CodeWriter(output) self.generate_tokens() self.parse_file()
def compile_jack(jack_file_name): token_file_name = jack_file_name.replace('.jack', 'T.xml') token_file = open(token_file_name, 'w') jack_file = open(jack_file_name, 'r') tokenizer = Tokenizer(jack_file, token_file) vm_file = open(jack_file_name.replace('.jack', '') + '.vm', 'w') code_writer = CodeWriter(tokenizer, vm_file) code_writer.compile_class()
def test_pop_argument(self): code_writer = CodeWriter() i = '5' segment = MemorySegmentType.ARGUMENT segment_pointer = 'ARG' cmd = '@' + i + '\nD=A\n@' + segment_pointer + '\nD=D+M\n@addr\nM=D\n' cmd += '@SP\nAM=M-1\n' cmd += 'D=M\n@addr\nA=M\nM=D\n' self.assertEqual(code_writer.get_pop(segment, i), cmd)
def main(): #make sure they used the program right if len(sys.argv) != 2: print( "usage: python VMtranslator.py <some .vm file or a directory with .vm files in it>" ) return #holds the open file descriptors to pass to the Parser constructor fileHandles = [] inputPath = sys.argv[1] outputPath = "" #see if file or directory if inputPath.endswith(".vm"): #file vmFile = open(inputPath, 'r') fileHandles.append(vmFile) #set output path to be the vm file but with .asm extension outputPath = inputPath.replace(".vm", ".asm") elif os.path.isdir(inputPath): #make sure that the path doesn't end in a slash for a directory if inputPath.endswith("/"): inputPath = inputPath[:-1] #get .vm files and open them from directory for file in os.listdir(inputPath): if file.endswith(".vm"): vm = open(os.path.join(inputPath, file), 'r') fileHandles.append(vm) #outputpath is the path/directoryName.asm outputPath = inputPath + "/" + os.path.basename(inputPath) + ".asm" else: #error print( "You must enter a single .vm file or a directory with .vm files in it" ) #instantiate the codewriter with the correct output path writer = CodeWriter(outputPath) #run through all the .vm files we have for file in fileHandles: #make a new parser for each .vm file parser = Parser(file) #make sure to give the writer the current file name for static memory access stuff writer.setFileName(os.path.basename(file.name)) #write either arithmetic or memory access commands while (parser.hasMoreCommands()): if parser.commandType() == "C_ARITHMETIC": writer.writeArithmetic(parser.arg1()) elif parser.commandType() == "C_PUSH" or parser.commandType( ) == "C_POP": writer.writePushPop(parser.commandType(), parser.arg1(), parser.arg2()) parser.advance() #close the output file writer.close()
def test_push_local(self): code_writer = CodeWriter() i = '5' segment = MemorySegmentType.LOCAL segment_pointer = 'LCL' cmd = '@' + i + '\nD=A\n@' + segment_pointer + '\nA=M+D\nD=M\n' cmd += '@SP\nA=M\nM=D\n' cmd += '@SP\nM=M+1\n' self.assertEqual(code_writer.get_push(segment, i), cmd)
def __init__(self, path): self.path = path.replace('\\', '/') try: self.filename = self.path[len(self.path) - self.path[::-1].index('/'):-3] except ValueError: self.filename = self.path[:-3] self.cw = CodeWriter(self.filename) self.parser = Parser(path)
def test_pop_static(self): code_writer = CodeWriter() filename = 'filename1' code_writer.set_current_filename(filename) i = '5' segment = MemorySegmentType.STATIC cmd = '@SP\nAM=M-1\n' cmd += 'D=M\n@' + filename + '.' + i + '\nM=D\n' self.assertEqual(code_writer.get_pop(segment, i), cmd)
def test_pop_temp(self): code_writer = CodeWriter() i = '2' segment = MemorySegmentType.TEMP start_address = '5' cmd = '@' + start_address + '\nD=A\n@' + i + '\nD=D+A\n@addr\nM=D\n' cmd += '@SP\nAM=M-1\n' cmd += 'D=M\n@addr\nA=M\nM=D\n' self.assertEqual(code_writer.get_pop(segment, i), cmd)
def translate(self): '''Function responsible for orchestrating the translation''' #Following code for determining arguments and file/dir existence may need to be refactored out #However, not sure yet so will wait till further in development to make decision statusCode = None if (len(sys.argv) == 1): print("No file provided...") statusCode = 2 else: path = sys.argv[1] if not os.path.exists(path): print("Provided File/Folder does not exist") statusCode = 2 else: print(path) print(path.split("/")[-1]) print(self.__getFileName(path)) print(self.__getFileName(path).split('.')) print(self.__getFileName(path).split('.')[0]) asmFileLocation = "{0}.asm".format( self.__getFileName(path).split('.')[0]) print(asmFileLocation) with CodeWriter(asmFileLocation) as writer: paths = [] if os.path.isdir(path): paths = glob.glob("{0}/*.vm".format(path)) else: paths.append(path) for currentPath in paths: currentFileName = self.__getFileName( currentPath).split('.')[0] writer.setFileName(currentFileName) with Parser(currentPath) as parser: while (parser.hasMoreCommands()): parser.advance() commandType = parser.commandType() if commandType == CommandType.C_PUSH: writer.writePushPop( commandType, parser.arg1(), parser.arg2()) elif commandType == CommandType.C_POP: writer.writePushPop( commandType, parser.arg1(), parser.arg2()) elif commandType == CommandType.C_ARITHMETIC: writer.writeArithmetic(parser.arg1()) return statusCode
def run(): with ExitStack() as exit_stack: filename = filepath.split("/")[-1:][0].rstrip(".vm") input_file: IO = exit_stack.enter_context(open(filepath)) output_file: IO = exit_stack.enter_context( open(filepath.rstrip("vm") + "asm", "w")) code_writer = CodeWriter(filename, output_file) for command_type, arg1, arg2 in parse_commands(input_file): code_writer.write_command(command_type, arg1, arg2)
def __init__(self, path): self.cw = CodeWriter() self.files = [] if ".vm" in path: self.files.append(path) else: os.chdir(path) for filepath in os.listdir(): self.files.append(filepath) self.asmcode = ""
def test_return(self): code_writer = CodeWriter() cmd = '@LCL\nD=M\n@endFrame\nM=D\n@5\nA=D-A\nD=M\n@retAddr\nM=D\n' cmd += '@SP\nAM=M-1\nD=M\n@ARG\nA=M\nM=D\n' cmd += '@ARG\nD=M+1\n@SP\nM=D\n' cmd += '@endFrame\nD=M\n@1\nA=D-A\nD=M\n@THAT\nM=D\n' cmd += '@endFrame\nD=M\n@2\nA=D-A\nD=M\n@THIS\nM=D\n' cmd += '@endFrame\nD=M\n@3\nA=D-A\nD=M\n@ARG\nM=D\n' cmd += '@endFrame\nD=M\n@4\nA=D-A\nD=M\n@LCL\nM=D\n' cmd += '@retAddr\nA=M\n0;JMP\n' self.assertEqual(code_writer.get_return(), cmd)
def main(): foldername = str(sys.argv[-1]) code = CodeWriter() if foldername[-2:] == 'vm': translate(code,foldername) else: if '{0}Sys.vm'.format(foldername) in glob.glob(foldername+'*.vm'): code.write_init() for filename in glob.glob(foldername+'*.vm'): translate(code,filename) code.create_file(foldername) print("Done!")
def test_push_const(self): code_writer = CodeWriter() i = '5' segment = MemorySegmentType.CONSTANT cmd = '@' + i + '\n' cmd += 'D=A\n' cmd += '@SP\n' cmd += 'A=M\n' cmd += 'M=D\n' cmd += '@SP\n' cmd += 'M=M+1\n' self.assertEqual(code_writer.get_push(segment, i), cmd)
def __init__(self, path): is_directory = False if os.path.isfile(path): self.files = [path] elif os.path.isdir(path): self.files = [ os.path.join(path, file) for file in os.listdir(path) if file.endswith('.vm') ] is_directory = True self.parser = None self.writer = CodeWriter(path, is_directory)