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 __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 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 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 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 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_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 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 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 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_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 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 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 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 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 __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 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 get_mdp_body( self, transitions, state_var, rand_var): c, eos, eq = self.get_common_vars() condition_writer = CodeWriter( self.config ) i = 0 for cdf, state, prob in transitions: cond = rand_var + " < " + str(cdf) assign_state = state_var + eq + state + eos condition_writer.write_comment("Probability of transition: " + str(prob * 100) + "%", 0 ) if i == 0: condition_writer.write_cond( 0, cond, assign_state ) else: condition_writer.write_else_if( 0, cond, assign_state ) i += 1 return condition_writer.code
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 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 __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 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_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_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_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_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_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_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_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)
def main(): """ runs the assembler on the given argument (Assembler.py <file_name>) """ file_name = sys.argv[1] if os.path.isfile(file_name): CodeWriter.set_asm_file(file_name[:-len(VM_SUFF)] + ASM_SUFF) parse_vm_file(file_name) elif os.path.isdir(file_name): if file_name.endswith('/'): file_name = file_name[:-1] dir_name = file_name.split("/")[-1] CodeWriter.set_asm_file(os.path.abspath(file_name) + "/" + dir_name + ASM_SUFF) os.chdir(file_name) CodeWriter.writeInit() for f in os.listdir(): if f.endswith(VM_SUFF): parse_vm_file(f) os.chdir('..') CodeWriter.write_asm()
#!/usr/bin/python import sys,os import Parser import CodeWriter filename = sys.argv[1] rfile = open(filename,'r') wfile = CodeWriter.setFileName(filename) wfile.write('@256\nD=A\n@SP\nM=D\n') line = Parser.advance(rfile) flag = Parser.hasMoreCommands(line) while flag: while line == '\n' or line.startswith('//'): line = rfile.readline() ctype = Parser.commandType(line) if ctype == 'C_ARITHMATIC': attribute1 = Parser.arg1(line).strip() CodeWriter.writeArithmatic(wfile,attribute1) elif ctype in ('C_PUSH','C_POP'): attribute1 = Parser.arg1(line).strip() attribute2 = Parser.arg2(line).strip() CodeWriter.WritePushPop(wfile,ctype,attribute1,attribute2,filename) line = Parser.advance(rfile) flag = Parser.hasMoreCommands(line) rfile.close() CodeWriter.Close(wfile)
from Parser import * from CodeWriter import * from sys import argv import os directory = argv[1] if directory.endswith('/'): directory = directory[:-1] outname = directory.split('/')[-1] os.chdir(directory) files = [f for f in os.listdir('.') if f.endswith('.vm')] codewriter = CodeWriter(outname) for f in files: parser = Parser(f) codewriter.setFileName(f[:-3]) while parser.hasMoreCommands(): parser.advance() Ctype = parser.commandType() if Ctype == 'C_ARITHMETIC': codewriter.writeArithmetic(parser.currentcommand) elif Ctype in ('C_PUSH','C_POP'): if 'pop' in parser.currentcommand: command = 'pop' else: command = 'push' segment = parser.arg1() index = parser.arg2() codewriter.writePushPop(command,segment,index) elif Ctype == 'C_LABEL':
def Main(rfile,wfile,filename): line=Parser.advance(rfile) flag=Parser.hasMoreCommands(line) while flag: while line == '\n' or line.startswith('//'): line=rfile.readline() if '//' in line: line=line[:line.find('//')] ctype=Parser.commandType(line) if ctype == 'C_ARITHMATIC': attribute1=Parser.arg1(line).strip() CodeWriter.writeArithmatic(wfile,attribute1) elif ctype in ('C_PUSH','C_POP'): attribute1=Parser.arg1(line).strip() attribute2=Parser.arg2(line).strip() CodeWriter.writePushPop(wfile,ctype,attribute1,attribute2,filename) elif ctype =='C_LABEL': attribute1=Parser.arg1(line).strip() CodeWriter.writeLabel(wfile,attribute1) elif ctype =='C_GOTO': attribute1=Parser.arg1(line).strip() CodeWriter.writeGoto(wfile,attribute1) elif ctype =='C_IF': attribute1=Parser.arg1(line).strip() CodeWriter.writeIf(wfile,attribute1) elif ctype =='C_FUNCTION': attribute1=Parser.arg1(line).strip() attribute2=Parser.arg2(line).strip() CodeWriter.writeFunction(wfile,attribute1,attribute2) elif ctype =='C_RETURN': CodeWriter.writeReturn(wfile) elif ctype =='C_CALL': attribute1=Parser.arg1(line).strip() attribute2=Parser.arg2(line).strip() CodeWriter.writeCall(wfile,attribute1,attribute2) line=Parser.advance(rfile) flag=Parser.hasMoreCommands(line)
print('this is a file') dotIndex=inputFile.find('.') slashIndex=inputFile.rfind('/') filename = inputFile[:dotIndex] if slashIndex>=0: curdir = os.getcwd()+'/'+inputFile[:slashIndex] os.chdir(curdir) print(os.getcwd()) inputFile = inputFile[slashIndex+1:] outputFile=inputFile[slashIndex+1:dotIndex]+'.asm' else: outputFile=inputFile[:dotIndex]+'.asm' fpread=open(inputFile,'r') fpwrite=open(outputFile,'w') fpwrite.write('@256\nD=A\n@SP\nM=D\n') fpwrite.write(CodeWriter.transInit()) # first time reading, delete all comments and build up symbol table line=fpread.readline() while(line): line = Parser.analyzeLine(line) if line!='': line_list.append(line) line=fpread.readline() # second time reading, parse all instructions for line in line_list: asmCode = CodeWriter.transToAsm(line) fpwrite.write(asmCode) fpread.close() fpwrite.close()
elif ctype =='C_CALL': attribute1=Parser.arg1(line).strip() attribute2=Parser.arg2(line).strip() CodeWriter.writeCall(wfile,attribute1,attribute2) line=Parser.advance(rfile) flag=Parser.hasMoreCommands(line) filename=sys.argv[1] #if filename exists in the dir, open the file directly if os.path.isfile(filename): rfile = open(filename,'r') wfile = CodeWriter.setFileName(filename) wfile.write('@256\nD=A\n@SP\nM=D\n') Main(rfile,wfile,filename) #if filename doesn't exist, find all the .vm files elif os.path.isfile('Sys.vm'): wfile = CodeWriter.setFileName(filename) wfile.write('@256\nD=A\n@SP\nM=D\n') wfile.write('@return_address0\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\ \n@LCL\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n@ARG\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\ \n@THIS\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n@THAT\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\ \n@0\nD=A\n@5\nD=D+A\n@SP\nD=M-D\n@ARG\nM=D\n@SP\nD=M\n@LCL\nM=D\ \[email protected]\n0;JMP\n(return_address0)\n') #check all the files in the dir for i in os.walk(os.getcwd()): filelist=i[2] for j in range(0,len(filelist)):
def make_code(self): c, eos, eq = self.get_common_vars() writer = CodeWriter( c ) # Write out the headers self.write_headers( writer ) # Create the state variables state_var, prev_state_var, time_var = self.write_state_vars( writer ) # Begin optional sections indent_level = self.create_optional_sections( writer ) prev_var_decl = c["prev_var_type"] + prev_state_var + eq + state_var writer.write( prev_var_decl + eos, indent_level) # Handle state action logic self.create_actions( writer, indent_level, state_var ) # Create the transtion logic if self.is_hlsm(): self.create_hlsm_transitions( writer, indent_level, state_var ) elif self.is_mdp(): self.create_mdp_transitions( writer, indent_level, state_var ) # Write any extra functions at the end of the state loop if "run_at_end" in c: for l in c["run_at_end"]: writer.write( l, indent_level ) # Set transition time transition_body = c["time_var"] + eq + c["time_function"] + c["end_var"] if on_trans in c: transition_body = [ transition_body, c[on_trans ] ] writer.write_cond( indent_level, prev_state_var + "!=" + state_var, transition_body) # End optional sections # End infinite loop if inf_loop in c: writer.write( c["after_func"], indent_level - 1 ) # End wrapper function if wrapper_function in c: writer.write( c["after_func"], 1 ) self.create_function_stubs( writer ) self.create_footer( writer ) return writer.dump()
def main(): """Drives the VM-to-Hack translation procces""" file_name = sys.argv[1] parsers = [] abs_path = os.path.abspath(file_name) if ".vm" in file_name and file_name[-3:] == ".vm": parser = Parser(abs_path) parsers.append(parser) output_path = os.path.splitext(abs_path)[0] + ".asm" else: path_split = abs_path.rsplit("/") output_path = abs_path + "/" + path_split[-1] + ".asm" for walk_obj in os.walk(abs_path): for vm_file in walk_obj[2]: if ".vm" in vm_file and vm_file[-3:] == ".vm": parser = Parser(abs_path + "/" + vm_file) parsers.append(parser) cw = CodeWriter(output_path) cw.write_init() for parser in parsers: a_path = parser.get_file_name() fname = os.path.split(a_path)[1][:-3] cw.set_file_name(fname) while parser.has_more_commands(): parser.advance() command_type = parser.command_type() if command_type == "C_ARITHMETIC": cw.write_arithmetic(parser.get_command()) elif command_type == "C_PUSH" or command_type == "C_POP": command = command_type segment = parser.arg1() index = parser.arg2() cw.write_push_pop(command, segment, index) elif command_type == "C_LABEL": label = parser.arg1() cw.write_label(label) elif command_type == "C_GOTO": label = parser.arg1() cw.write_goto(label) elif command_type == "C_IF": label = parser.arg1() cw.write_if(label) elif command_type == "C_CALL": function_name = parser.arg1() num_args = parser.arg2() cw.write_call(function_name, num_args) elif command_type == "C_RETURN": cw.write_return() elif command_type == "C_FUNCTION": function_name = parser.arg1() num_locals = parser.arg2() cw.write_function(function_name, num_locals)
def parse_vm_file(file_name): """ Gets the commands list using the parser and scans it twice first time searching for labels, second time uses the code to translate the A and C commands to machine code. Adds the machine code to a new .asm file Input: file_name - the .vm file needed to be translated Output: the translated file_name.asm file """ clean_file_name = file_name.split('/')[-1] func_name = '' delim = '' Parser.parse(file_name) CodeWriter.set_vm_file(file_name) for command in Parser.get_commands(): if command.type == Parser.CommandType.C_ARITHMETIC: CodeWriter.write_arithmetic(command.content[0]) elif command.type == Parser.CommandType.C_PUSH or \ command.type == Parser.CommandType.C_POP: CodeWriter.write_push_pop(command.type, command.content[1], command.content[2]) elif command.type == Parser.CommandType.C_LABEL: CodeWriter.writeLabel(func_name + delim + command.content[1]) elif command.type == Parser.CommandType.C_GOTO: CodeWriter.writeGoto(func_name + delim + command.content[1]) elif command.type == Parser.CommandType.C_IF: CodeWriter.writeIf(func_name + delim + command.content[1]) elif command.type == Parser.CommandType.C_CALL: CodeWriter.writeCall(command.content[1], command.content[2]) elif command.type == Parser.CommandType.C_RETURN: CodeWriter.writeReturn() elif command.type == Parser.CommandType.C_FUNCTION: func_name = command.content[1] delim = ':' CodeWriter.writeFunction(func_name, command.content[2])
#!/usr/bin/python import sys,os import Parser import CodeWriter filename=sys.argv[1] rfile = open(filename,'r') wfile = CodeWriter.setFileName(filename) wfile.write('@256\nD=A\n@SP\nM=D\n') line=Parser.advance(rfile) flag=Parser.hasMoreCommands(line) while flag: while line == '\n' or line.startswith('//'): line=rfile.readline() ctype=Parser.commandType(line) if ctype == 'C_ARITHMATIC': attribute1=Parser.arg1(line).strip() CodeWriter.writeArithmatic(wfile,attribute1) elif ctype in ('C_PUSH','C_POP'): attribute1=Parser.arg1(line).strip() attribute2=Parser.arg2(line).strip() CodeWriter.writePushPop(wfile,ctype,attribute1,attribute2) line=Parser.advance(rfile) flag=Parser.hasMoreCommands(line) rfile.close() CodeWriter.Close(wfile)
#!/usr/bin/python from CodeWriter import * cw = CodeWriter("test.asm") cw.writePushPop("PUSH", "CONSTANT", 3) cw.close()
if directory.endswith(".vm"): outputname = directory.split("/")[-1][:-3] length = -(len(outputname) + 4) directory = directory[:length] else: outputname = directory.split("/")[-1] os.chdir(directory) for f in os.listdir("."): if f.endswith(".vm"): files.append(f) codewriter = CodeWriter(outputname) for file in files: print (file) parser = Parser.Parser(file) codewriter.setFileName(file[:-3]) while parser.hasMoreCommands(): parser.advance() command = parser.commandType() if command == Parser.C_ARITHMETIC: codewriter.writeArithmetic(parser.arg1()) elif command == Parser.C_POP or command == Parser.C_PUSH: if command == Parser.C_POP: com = "pop"