Beispiel #1
0
class VMTranslator:
    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 translate(self):
        """Translates the given VM file, writing the corresponding assembly
        code to the output file.
        """
        self.parser.advance()
        while self.parser.has_more_commands():
            self.translate_current_command()
            self.parser.advance()
        
        self.code_writer.close_outfile()
    
    def translate_current_command(self):
        """Translates the current command of the Parser, using the CodeWriter
        to write the corresponding assembly code to the output file.
        """
        command_type = self.parser.command_type()
        arg1 = self.parser.arg1()
        arg2 = self.parser.arg2()
        
        if command_type == 'ARITHMETIC':
            self.code_writer.write_arithmetic(arg1)
        elif command_type in ('PUSH', 'POP'):
            self.code_writer.write_push_pop(command_type, arg1, int(arg2))
        else:
            raise ValueError('Incorrect command type.')
Beispiel #2
0
class VMTranslator:
    def __init__(self, input_name):
        """Constructs the Parser and CodeWriter objects to be used in
        translating the file and supplies them with the appropriate filenames.
        """
        if input_name.endswith('.vm'):
            vmfilename = input_name
            self.vmfilenames = [vmfilename]
            self.asmfilename = vmfilename[:-3] + '.asm'
            write_init = False
        else:
            directory = input_name
            self.vmfilenames = self.get_vmfilenames(directory)
            self.asmfilename = '{}\{}'.format(directory,
                                              directory.split('\\')[-1] + '.asm')
            write_init = True
            
        self.code_writer = CodeWriter(self.asmfilename)
        
        if write_init:
            self.code_writer.write_init()
    
    def get_vmfilenames(self, directory):
        """Takes the path of a directory, starting from the current directory,
        and returns a list of all the VM filenames in that directory,
        including their paths from the current directory.
        """
        filenames = os.listdir(os.getcwd() + '\\' + directory)
        return [directory + '\\' + filename for filename in filenames if
                filename.endswith('.vm')]
    
    def translate(self):
        """Translates all the given VM files"""
        for vmfilename in self.vmfilenames:
            self.translate_file(vmfilename)
        
        self.code_writer.close_outfile()
    
    def translate_file(self, vmfilename):
        """Translates the given VM file, creating a parser for the file, and 
        writing the corresponding assembly code to the output file.
        """
        self.parser = Parser(vmfilename)
        self.code_writer.set_filename(vmfilename.split('\\')[-1][:-3])
        
        self.parser.advance()
        while self.parser.has_more_commands():
            self.translate_current_command()
            self.parser.advance()
    
    def translate_current_command(self):
        """Translates the current command of the Parser, using the CodeWriter
        to write the corresponding assembly code to the output file.
        """
        command_type = self.parser.command_type()
        arg1 = self.parser.arg1()
        arg2 = self.parser.arg2()
        
        if command_type == 'ARITHMETIC':
            self.code_writer.write_arithmetic(arg1)
        elif command_type in ('PUSH', 'POP'):
            self.code_writer.write_push_pop(command_type, arg1, int(arg2))
        elif command_type == 'LABEL':
            self.code_writer.write_label(arg1)
        elif command_type == 'GOTO':
            self.code_writer.write_goto(arg1)
        elif command_type == 'IF':
            self.code_writer.write_if(arg1)
        elif command_type == 'FUNCTION':
            self.code_writer.set_function_name(arg1)            
            self.code_writer.write_function(arg1, int(arg2))
        elif command_type == 'CALL':
            self.code_writer.write_call(arg1, int(arg2))
        elif command_type == 'RETURN':
            self.code_writer.write_return()
        else:
            raise ValueError('Incorrect command type.')