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()
Exemple #3
0
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()
Exemple #5
0
 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()
Exemple #7
0
 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))
Exemple #8
0
 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)
Exemple #9
0
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)