def main(argv): """ Main flow of program dealing with extracting files for reading and initializing files to translate into """ if not check_args(argv): return # extracting asm file to be processed vm_files_path = argv[1] # creating a .asm file to contain vm files translation to hack machine language if os.path.isdir(vm_files_path): dir_name = os.path.basename(vm_files_path) asm_file_name = "{0}/{1}.asm".format(vm_files_path, dir_name) code_writer = CodeWriter(asm_file_name) code_writer.write_init() for file in os.listdir(vm_files_path): if file.endswith(".vm"): code_writer.set_file_name(file) vm_parser = VMParser('{0}/{1}'.format(vm_files_path, file)) translate_vm_file(code_writer, vm_parser) else: asm_file_name = "{0}.asm".format(os.path.splitext(vm_files_path)[0]) code_writer = CodeWriter(asm_file_name) code_writer.write_init() code_writer.set_file_name(vm_files_path) vm_parser = VMParser(vm_files_path) translate_vm_file(code_writer, vm_parser)
def create_assembly_file_from_directory(self): self.current_file = self.current_directory + '\\Sys.vm' file_exists = os.path.exists(self.current_file) if not file_exists: print(f"Main file {self.current_file} was not found!") return assembly_name = os.path.basename(self.current_directory) + '.asm' assembly_full_path = self.current_directory + '\\' + assembly_name assembly_writer = VMCodeWriter(assembly_full_path) self.current_writer = assembly_writer self.current_writer.write_init() for filename in os.listdir(self.current_user_command): if filename.endswith('.vm'): self.current_file = filename filepath = self.current_directory + "\\" + filename self.current_writer.set_file_name(filename) vm_parser = VMParser(filepath) self.read_write_vm_file(vm_parser) self.current_writer.write_output_to_file() print( 'Requested directory has been translated successfully. Quiting program.' ) sys.exit()
def main(): if len(sys.argv) != 2: print('<VMTranslator>: Execute script with ' 'one argument only (The path of an existing "vm" file)\n') exit() vm_file = sys.argv[1] parser = VMParser(vm_file) asm_file = vm_file.replace('.vm', '.asm') code_writer = CodeWriter(asm_file) while parser.has_more_commands(): code_writer.write_command(parser.command) parser.advance() code_writer.write_end() print '<VMTranslator>: Successfully created "{}"\n'.format(asm_file)
def create_assembly_file_from_file(self): assembly_file_name = self.current_user_command.replace(".vm", ".asm") assembly_writer = VMCodeWriter(assembly_file_name) self.current_writer = assembly_writer vm_parser = VMParser(self.current_user_command) self.read_write_vm_file(vm_parser) assembly_writer.write_output_to_file() print( 'Requested file has been translated successfully. Quiting program.' ) sys.exit()
def execute(self): for f in self.read_files: file = VMParser(f) while file.has_more_commands: file.advance() command_type = file.command_type() print(command_type) if command_type == "arithmetic": self.w.write_arithmetic(file.operation()) elif command_type == "comparison": self.w.write_comparison(file.operation()) elif command_type == "pop" or command_type == "push": self.w.write_push_pop(file.operation(), file.segment(), file.index(),file.file_name) elif command_type == "goto": self.w.write_goto(file.segment()) elif command_type == "if-goto": self.w.write_if(file.segment()) elif command_type == "call": self.w.write_call(file.segment(), file.index()) elif command_type == "return": self.w.write_return() elif command_type == "function": self.w.write_function(file.segment(), file.index()) elif command_type == "label": self.w.write_label(file.segment()) file.close()
def create_assembly_file(self): assembly_file_name = self.current_user_command.replace(".vm", ".asm") vm_parser = VMParser(self.current_user_command) assembly_writer = VMCodeWriter(assembly_file_name) try: vm_parser.read_file_lines_into_a_list() except FileNotFoundError: print('The referenced file could not be found. Check filename and path for typing errors.') return vm_parser.remove_whitespaces_and_newlines() while vm_parser.has_more_commands(): vm_command_type = vm_parser.command_type() if vm_command_type == 'C_ARITHMETIC': assembly_writer.write_arithmetic(vm_parser.arg1()) if vm_command_type == 'C_PUSH': assembly_writer.write_push_pop(vm_parser.command_type(), vm_parser.arg1(), vm_parser.arg2()) if vm_command_type == 'C_POP': assembly_writer.write_push_pop(vm_parser.command_type(), vm_parser.arg1(), vm_parser.arg2()) vm_parser.advance() assembly_writer.write_output_to_file() print('Requested file has been translated successfully. Quiting program.') sys.exit()
def create_parser_objects(self): files = self.get_files_to_be_translated() if files == None: print("Error file type not supported") self.read_files.append(VMParser(files))
def setUp(self): file_name = path.join(environ['HOME'], 'tmp', 'tmp.asm') f = open(file_name, 'w') f.close() self.parser = VMParser(file_name) remove(file_name)
class TestVMParser(TestCase): def setUp(self): file_name = path.join(environ['HOME'], 'tmp', 'tmp.asm') f = open(file_name, 'w') f.close() self.parser = VMParser(file_name) remove(file_name) def test_constructor(self): # for existing file self.assertTrue(isinstance(self.parser, VMParser)) def test_constructor_file_not_there(self): # for no longer existing file file_name = path.join(environ['HOME'], 'tmp', 'tmp.asm') with self.assertRaises(SystemExit) as cm: self.parser.__init__(file_name) self.assertEqual(cm.exception.code, 1) def test_push(self): """ test recognizing push commands """ command = 'push constant 7' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_PUSH') command = 'PUSH CONSTANT 7' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_PUSH') command = 'POP CONSTANT 7' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertNotEqual(self.parser.command.ctype, 'C_PUSH', self.parser.command) def test_pop(self): """ test recognizing pop commands """ command = 'pop argument 7' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_POP') command = 'pOp arguemnt 8' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_POP') command = 'push CONSTANT 7' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertNotEqual(self.parser.command.ctype, 'C_POP') def test_add_arithmetic(self): """ test recognizing add commands """ command = 'add' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_ARITHMETIC') command = 'notadd' self.parser.command = VMCommand(command) with self.assertRaises(SystemExit) as cm: self.parser.command.set_ctype() self.assertEqual(cm.exception.code, 1) command = 'pop this' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertNotEqual(self.parser.command.ctype, 'C_ARITHMETIC') def test_sub_arithmetic(self): """ test recognizing sub commands """ command = 'sub' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertEqual(self.parser.command.ctype, 'C_ARITHMETIC') command = 'push that' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.assertNotEqual(self.parser.command.ctype, 'C_ARITHMETIC', self.parser.command) def test_invalid_command(self): """ test for invalid command """ command = 'subbie' self.parser.command = VMCommand(command) with self.assertRaises(SystemExit) as cm: self.parser.command.set_ctype() self.assertEqual(cm.exception.code, 1) def test_arg1(self): """ test parse out arg1 """ command = 'push constant 21' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.parser.command.set_arg1() self.assertEqual('constant', self.parser.command.arg1), self.parser.command command = 'pop pointer 1' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.parser.command.set_arg1() self.assertEqual('pointer', self.parser.command.arg1, self.parser.command) command = 'add' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.parser.command.set_arg1() self.assertEqual('add', self.parser.command.arg1) def test_arg1_bad_command_type(self): """ test parse out arg1 """ command = 'return sum' self.parser.command = VMCommand(command) self.parser.command.set_ctype() with self.assertRaises(SystemExit) as cm: self.parser.command.set_arg1() self.assertEqual(cm.exception.code, 1) def test_arg2(self): """ test parse out arg2 """ command = 'push constant 21' self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.parser.command.set_arg1() self.parser.command.set_arg2() self.assertEqual('21', self.parser.command.arg2) self.assertEqual('constant', self.parser.command.arg1) def test_arg2_bad_command_type(self): """ test parse out arg2 with bad command type """ command = 'add' self.command = command self.parser.command = VMCommand(command) self.parser.command.set_ctype() self.parser.command.set_arg1() with self.assertRaises(SystemExit) as cm: self.parser.command.set_arg2() self.assertEqual(cm.exception.code, 1)