def main(path): """ Creates parser object and code writer object, transfers the relevant commands to the relevant methods. :param path: file path :return: void """ directory = [] if os.path.isdir(path): code_writer = cw.CodeWriter(os.path.join(path, os.path.basename(path))+".asm") directory = glob.iglob(os.path.join(path, "*.vm")) else: file_name = path[:-3] code_writer = cw.CodeWriter(file_name + ".asm") directory.append(path) for file in directory: # removing the file extension and send it to the setFileName f = os.path.basename(file)[:-3] code_writer.setFileName(f) # creating a relevant parser object parser = ps.Parser(file) while parser.hasMoreCommands(): cmd = parser.commandType() if cmd == gc.C_PUSH or cmd == gc.C_POP: code_writer.writePushPop(cmd, parser.arg1(), parser.arg2()) if cmd == gc.C_ARITHMETIC: code_writer.writeArithmetic(parser.arg1()) parser.advance() code_writer.close()
def test_function_command(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_function_command('Foo.test', 2) expected = [ '// function Foo.test 2', '(Foo.test)', # Push 2 local vars '// C_PUSH constant 0', # local 0 '@0', # D = i 'D=A', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1', '// C_PUSH constant 0', # local 1 '@0', # D = i 'D=A', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1', ] cw.close() self.assertEqual(result, expected)
def translate_files(self, inputfiles, outputfile): code_writer = CodeWriter.CodeWriter(outputfile) # TODO: initialize code writer in chapter 8 if inputfiles: # list of inputfiles is not empty for file in inputfiles: self.translate(file, code_writer) code_writer.close()
def translate_all(self, infiles, outfile): if infiles != []: code_writer = CodeWriter.CodeWriter(outfile) code_writer.write_init() for infile in infiles: self._translate(infile, code_writer) code_writer.close_file()
def main(): filepath = sys.argv[1] if not os.path.isfile(filepath): print("File path {} does not exist. Exiting...".format(filepath)) sys.exit() asm_filepath = os.path.splitext(filepath)[0] + ".asm" print('Loading file: ' + filepath) parser = Parser.Parser(filepath) code_writer = CodeWriter.CodeWriter(asm_filepath) print('Running through all commands in VM code') while parser.has_more_commands(): parser.advance() if parser.command_type == Constants.C_ARITHMETIC: code_writer.write_arithmetic(parser.arg1) elif parser.command_type in [Constants.C_PUSH, Constants.C_POP]: code_writer.write_push_pop(parser.command_type, parser.arg1, parser.arg2) print('Closing file: ' + filepath) code_writer.close()
def handle_files(files_list, full_file_path): """ Main func go over the lines of the files :param files_list: list of files in the dir :param full_file_path : path to save to """ if full_file_path is None: return code_writer = CodeWriter.CodeWriter(full_file_path) code_writer.write_init() for file_name in files_list: parser = Parser.Parser( os.path.join(os.path.split(full_file_path)[0], file_name)) code_writer.set_file_name(file_name.replace(VM, "")) while parser.has_more_commands(): parser.advance() command = parser.command_type() if command == Parser.C_POP or command == Parser.C_PUSH: code_writer.write_push_pop(command, parser.arg1(), parser.arg2()) elif command == Parser.C_GOTO: code_writer.write_goto(parser.arg1()) elif command == Parser.C_IF: code_writer.write_if(parser.arg1()) elif command == Parser.C_CALL: code_writer.write_call(parser.arg1(), parser.arg2()) elif command == Parser.C_RETURN: code_writer.write_return() elif command == Parser.C_FUNCTION: code_writer.write_function(parser.arg1(), parser.arg2()) elif command == Parser.C_LABEL: code_writer.write_label(parser.arg1()) else: code_writer.write_arithmetic(parser.arg1()) code_writer.close()
def parse_files(path): """ this function will parse given files in path (even if single file) by using parse_single_file :param path: :return: """ if VM_SUFFIX in path: files = [os.path.basename(path)] else: files = [vm for vm in glob.glob(osjoin(path, '*' + VM_SUFFIX))] if os.path.isdir(path): output_file_path = path + "/" + path.rsplit('/', 1)[1] else: output_file_path = path.rsplit('.', 1)[0] output_file_path = output_file_path + ".asm" is_init = False for file in files: with open(file, mode='r') as curr_file: for line in curr_file.readlines(): if 'Sys.init' in line: is_init = True curr_file.close() writer = CodeWriter(output_file_path, files[0], len(files)) if is_init: writer.writeInit() for file in files: writer.setFileName(file) parse_single_file(file, writer) writer.close()
def createWriterFromDir(input): # removing last slash if exists input = removeSlash(input) fileName = os.path.basename(input) outputFileName = input + os.sep + fileName + ASM_EXTENTION return CodeWriter.CodeWriter(outputFileName)
def translate(self, input_files, output_file): writer = CodeWriter.CodeWriter(output_file) writer.writeInit() for input_file in input_files: self._translate(input_file, writer) writer.close()
def __init__(self): """constructor: holds an instance of CodeWriter ( which consist the main translaring methods), and the VMTextLines- the list containing the original VM lines before translation""" self.codeWriter = CodeWriter() self.__translated_text = [ ] #the asm lines after translation by the CodeWriter self.VMTextLines = [] #the original VM lines to be translated self.first = True
def Translate(self, path): #open files in a folder if os.path.isdir(path): fileName = ntpath.basename(path) new_file_name = path + "/" + fileName + ".asm" self.codeWriter = C.CodeWriter(new_file_name) files_in_dir = os.listdir(path) for file_in_dir in files_in_dir: if file_in_dir.endswith("vm"): self.translateFile(path + "/" + file_in_dir) #open one file elif path.endswith("vm"): new_file_name = path[:-2] + "asm" self.codeWriter = C.CodeWriter(new_file_name) self.translateFile(path) self.codeWriter.close()
def main(argv): userInput = sys.argv[1] if os.path.isdir(userInput): if userInput.endswith("/"): userInput = userInput[0:-1] dirname = os.path.basename(userInput) outputFile = userInput + "/" + dirname + ".asm" code = CodeWriter.CodeWriter(outputFile) for file in os.listdir(userInput): if ".vm" in file.lower(): code.setFileName(file) translateFile(userInput + "/" + file, code) else: outputFile = userInput.split('.')[0] + ".asm" code = CodeWriter.CodeWriter(outputFile) code.setFileName(userInput) translateFile(userInput, code)
def test_label(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_label_command('TEST_LABEL') expected = [ '// label TEST_LABEL', '(TEST_LABEL)', ] cw.close() self.assertEqual(result, expected)
def translate_all(self): ''' Translates all the .vm files in file_list to assembly language and save the output to file_out. ''' code_writer = CodeWriter.CodeWriter(self.file_out) for file_in in self.files_in: self.translate(file_in, code_writer) code_writer.close()
def test_goto(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_goto_command('TEST_LABEL') expected = [ '// goto TEST_LABEL', '@TEST_LABEL', '0;JMP', ] cw.close() self.assertEqual(result, expected)
def __init__(self): self.parser = argparse.ArgumentParser( description='Transrate VM file or directory to single asm file.') self.parser.add_argument('path', type=str, help='vm file or directory') args = self.parser.parse_args() path = args.path if os.path.isfile(path): if path.endswith('.vm'): self.code_writer = CodeWriter.CodeWriter( "{}.asm".format(path[:-3])) self.files = [path] else: raise Exception("path: file name should end with \".vm\".") elif os.path.isdir(path): if path.endswith('/'): path = path[:-1] self.code_writer = CodeWriter.CodeWriter("{}.asm".format(path)) self.files = glob.glob(f"{path}/*.vm") else: raise Exception("Unsupport File Type.")
def doAll(name): """ runs the translator for a specific ".vm" file, or, if given a directory name, runs the translator for all ".vm" files in directory :param name: file/directory name """ if ".vm" in name: outputName = name.strip(VMConsts.SOURCE_SUFFIX) + VMConsts.OUT_SUFFIX codeWriter = CodeWriter.CodeWriter(outputName) codeWriter.writeInit() parseFile(name, codeWriter) else: outputName = name.split("/")[-1] outputName = name + "//" + outputName + VMConsts.OUT_SUFFIX codeWriter = CodeWriter.CodeWriter(outputName) codeWriter.writeInit() for fileName in os.listdir(name): if ".vm" in fileName: codeWriter.setCurrentFile(fileName.strip(".vm")) parseFile(name + "//" + fileName, codeWriter) codeWriter.close()
def convert_all_files(self, input_files, output_file): """ For each input file, commands contained in it are converted to assembly and written into one output file. """ if input_files != []: code_writer = CodeWriter.CodeWriter(output_file) code_writer.write_init() for input_file in input_files: self.convert(input_file, code_writer) code_writer.close()
def main(): filename = sys.argv[1] outfile = os.path.splitext(filename)[0] + '.asm' with ps.Parser(filename) as p: c = cw.CodeWriter(outfile) while p.hasMoreCommands(): p.advance() if p.commandType() == ps.C_PUSH: c.writePushPop(ps.C_PUSH, p.arg1(), p.arg2()) elif p.commandType() == ps.C_POP: c.writePushPop(ps.C_POP, p.arg1(), p.arg2()) elif p.commandType() == ps.C_ARITHMETIC: c.writeArithmetic(p.command)
def main(): path = sys.argv[1] if os.path.isfile(path): file_list = [sys.argv[1]] output_file = os.path.splitext(path)[0] + '.asm' else: if path[-1] != '/': path = path + '/' file_list = glob.glob(path + '*.vm') output_file = path + path.split('/')[-2] + '.asm' ## Sys.vm を file_list の先頭に index_of_sys = file_list.index(path + 'Sys.vm') file_list[0], file_list[index_of_sys] = \ file_list[index_of_sys], file_list[0] c = cw.CodeWriter(output_file) iter_counter = 0 for file in file_list: c.setFileName(file) if iter_counter == 0: ## 初回だけ writeInit() を呼ぶ c.writeInit() iter_counter += 1 with ps.Parser(file) as p: while p.hasMoreCommands(): p.advance() c.f.write('\n') if p.commandType() == ps.C_ARITHMETIC: c.writeArithmetic(p.command) elif p.commandType() == ps.C_PUSH: c.writePushPop(ps.C_PUSH, p.arg1(), p.arg2()) elif p.commandType() == ps.C_POP: c.writePushPop(ps.C_POP, p.arg1(), p.arg2()) elif p.commandType() == ps.C_LABEL: c.writeLabel(p.arg1()) elif p.commandType() == ps.C_GOTO: c.writeGoto(p.arg1()) elif p.commandType() == ps.C_IF: c.writeIf(p.arg1()) elif p.commandType() == ps.C_CALL: c.writeCall(p.arg1(), p.arg2()) elif p.commandType() == ps.C_RETURN: c.writeReturn() elif p.commandType() == ps.C_FUNCTION: c.writeFunction(p.arg1(), p.arg2()) c.close()
def __init__(self): parser = Parser.Parser(infile) codewriter = CodeWriter.CodeWriter() codewriter.setFileName(infile) while parser.hasMoreCommands(): parser.advance() cmd = parser.command_type() if cmd == parser.C_ARITHMETIC: codewriter.writeArithmetic(parser.arg1()) elif cmd == parser.C_PUSH or cmd == parser.C_POP: codewriter.writePushPop(parser.command_type(), parser.arg1(), parser.arg2()) else: print ("other") codewriter.close()
def translate(self, path): if os.path.isdir(path): output_path = path + '/' + os.path.basename(path) + '.asm' else: output_path = path.replace('.vm', '.asm') self._codeWriter = CodeWriter.CodeWriter(output_path) if os.path.isdir(path): vmFiles = [file for file in os.listdir(path) if file.endswith('.vm')] for vmFile in vmFiles: self._translateVMfile(path + '/' + vmFile) else: self._translateVMfile(path)
def test_push_constant(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_push_command('push', 'constant', 10) expected = [ '// push constant 10', '@10', # D = i 'D=A', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1' ] cw.close() self.assertEqual(result, expected)
def test_push_pointer_0(self): cw = CodeWriter.CodeWriter('test1.test') result = cw.convert_push_command('push', 'pointer', 0) expected = [ '// push pointer 0', '@THIS', # D = THIS 'D=M', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1' ] cw.close() self.assertEqual(result, expected)
def test_pop_pointer_0(self): cw = CodeWriter.CodeWriter('test1.test') result = cw.convert_pop_command('pop', 'pointer', 0) expected = [ '// pop pointer 0', '@SP', # SP-- 'M=M-1', '@SP', # D = *SP 'A=M', 'D=M', '@THIS', # THIS = D 'M=D' ] cw.close() self.assertEqual(result, expected)
def test_pop_pointer_1(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_pop_command('pop', 'pointer', 1) expected = [ '// pop pointer 1', '@SP', # SP-- 'M=M-1', '@SP', # D = *SP 'A=M', 'D=M', '@THAT', # THAT = D 'M=D' ] cw.close() self.assertEqual(result, expected)
def test_pop_static(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_pop_command('pop', 'static', 5) expected = [ '// pop static 5', '@SP', # SP-- 'M=M-1', '@SP', # D = *SP 'A=M', 'D=M', '@Test.5', # var = D 'M=D' ] cw.close() self.assertEqual(result, expected)
def test_push_pointer_1(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_push_command('push', 'pointer', 1) expected = [ '// push pointer 1', '@THAT', # D = THAT 'D=M', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1' ] cw.close() self.assertEqual(result, expected)
def test_push_static(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_push_command('push', 'static', 5) expected = [ '// push static 5', '@Test.5', # D = var 'D=M', '@SP', # *SP = D 'A=M', 'M=D', '@SP', # SP++ 'M=M+1' ] cw.close() self.assertEqual(result, expected)
def test_if_goto(self): cw = CodeWriter.CodeWriter('Test.vm') result = cw.convert_if_goto_command('TEST_LABEL') expected = [ '// if-goto TEST_LABEL', '@SP', # SP-- 'M=M-1', '@SP', # D = *SP 'A=M', 'D=M', '@TEST_LABEL', # if cond jump 'D;JNE', # if-goto just looking for any non-zero value # in order to be true ] cw.close() self.assertEqual(result, expected)