Exemple #1
0
def main():

    output_list = []
    if len(sys.argv) == 2:
        file_name = str(os.path.splitext(sys.argv[1])[0])
        file_ext = os.path.splitext(sys.argv[1])[1]

    if len(sys.argv) != 2 or file_ext != ".vm":
        print("Usage: translator.py <inputFile>.vm")
        return

    try:
        parser = Parser(file_name, file_ext)
        writer = CodeWriter(file_name)
    except IOError as e:
        print(e)
        return
    else:
        while parser.hasMoreCommands():
            parser.advance()
            cmd = parser.command_type()
            if cmd != "C_RETURN":
                argument1 = parser.arg1()
            if cmd in ["C_POP", "C_PUSH", "C_FUNCTION", "C_CALL"]:
                argument2 = parser.arg2()
            if cmd == "C_ARITHMETIC":
                writer.write_arithmetic(argument1)
            if cmd in ["C_POP", "C_PUSH"]:
                writer.write_push_pop(cmd, argument1, argument2)
        writer.close()
Exemple #2
0
class VMTranslator():
    '''
    Manages the translation effort, bridging the gap between the Parser and Codewriter objects. 
    A new Parser is created for each file in the directory.
    '''
    def __init__(self, filename):
        if os.path.isdir(filename):
            self._files = [
                filename + '/' + x for x in os.listdir(filename)
                if x.endswith(".vm")
            ]
            self._isdir = True
            self._name = filename + '/' + filename.split('/')[-1] + '.asm'
        elif os.path.isfile(filename) and filename.endswith('.vm'):
            self._files = [filename]
            self._isdir = False
            self._name = filename.replace('.vm', '.asm')
        else:
            self._files = list()
            self._isdir = False
            return
        self._output = []
        self._code = CodeWriter(self._name)
        if self._isdir:
            self._code.write_init()
        for file in self._files:
            self._parser = Parser(file)
            self._code.filename(file.replace('.vm', '').split('/')[-1])
            self.translate()
        self._code.close()

    def translate(self):
        # using input from parser, translate and output
        while self._parser.has_more_commands():
            self._parser.advance()
            if self._parser.command_type() in ['C_ARITHMETIC', 'C_BOOLEAN']:
                self._code.write_arithmetic(self._parser.command())
            elif self._parser.command_type() in ['C_POP', 'C_PUSH']:
                self._code.write_pushpop(self._parser.command_type(),
                                         self._parser.arg1(),
                                         self._parser.arg2())
            elif self._parser.command_type() == 'C_LABEL':
                self._code.write_label(self._parser.arg1())
            elif self._parser.command_type() == 'C_GOTO':
                self._code.write_goto(self._parser.arg1())
            elif self._parser.command_type() == 'C_IF':
                self._code.write_if(self._parser.arg1())
            elif self._parser.command_type() == 'C_FUNCTION':
                self._code.write_function(self._parser.arg1(),
                                          self._parser.arg2())
            elif self._parser.command_type() == 'C_CALL':
                self._code.write_call(self._parser.arg1(), self._parser.arg2())
            elif self._parser.command_type() == 'C_RETURN':
                self._code.write_return()
Exemple #3
0
def translate_file(vm_file, asmfile):

    current_file_name = os.path.basename(vm_file)[:-3]
    # Initiate list of functions/files names and variables and append current file
    global_variables.function_list.append(current_file_name)

    with open(vm_file, 'r') as vmfile:
        # Create assembly file to receive translated code
        assembly_file = open(asmfile, 'a')

        parser = Parser()
        assembly_code = ""
        code_writer = CodeWriter(current_file_name)

        for line in vmfile:
            if is_blank_or_is_comment(line):
                pass
            else:
                command = parser.clean_line(line)
                command_type = parser.command_type(command)

                if command_type == "C_ARITHMETIC":
                    assembly_code = code_writer.write_arithmetic(command)

                elif command_type in ["C_LABEL", "C_GOTO", "C_IF"]:
                    command_args = parser.command_args(command)
                    assembly_code = code_writer.write_control_flow(
                        command_args)

                elif command_type in ["C_CALL", "C_RETURN", "C_FUNCTION"]:
                    command_args = parser.command_args(command)
                    assembly_code = code_writer.write_subroutines(command_args)

                else:
                    command_args = parser.command_args(command)
                    assembly_code = code_writer.write_push_pop(command_args)

                assembly_file.write(assembly_code)

        assembly_file.close()

    # Reset list of functions processed in the current file
    global_variables.function_list.clear()
def main():
    arg_len = len(sys.argv)
    file_list = []
    output_file = ""
    parsers = []

    if arg_len == 1:
        dir_name = os.getcwd()
        output_file = dir_name + '/' + dir_name.split('/')[-1] + ".asm"
        for f in os.listdir(dir_name):
            if f.endswith(".vm"):
                file_list.append(f)
        if not file_list:
            print("Error, no .vm files in current directory")
            return
    elif arg_len == 2:
        if os.path.isdir(sys.argv[1]):
            output_file = sys.argv[1] + sys.argv[1].split('/')[-2] + ".asm"
            for f in os.listdir(sys.argv[1]):
                if f.endswith(".vm"):
                    file_list.append(f)
            if not file_list:
                print("Error, no .vm files in given directory")
                return
            file_list = [sys.argv[1] + "/" + f for f in file_list]
        else:
            if os.path.splitext(sys.argv[1])[1] != ".vm":
                print("Error, .vm file not specified")
                return
            else:
                file_list.append(sys.argv[1])
                output_file = os.path.splitext(sys.argv[1])[0] + ".asm"
    try:
        writer = CodeWriter(output_file)
    except IOError as e:
        print("In codewriter: ")
        print(e)
        return
    else:
        try:
            parsers = [Parser(f) for f in file_list]
        except IOError as e:
            print("In parsers: ")
            print(e)
            return
        else:
            writer.write_init()
            for p in parsers:
                writer.set_file_name(p.static_name)
                while p.hasMoreCommands():
                    p.advance()
                    cmd = p.command_type()
                    if cmd != "C_RETURN":
                        argument1 = p.arg1()
                    if cmd in ["C_POP", "C_PUSH", "C_FUNCTION",
                               "C_CALL"]:
                        argument2 = p.arg2()
                    if cmd == "C_ARITHMETIC":
                        writer.write_arithmetic(argument1)
                    elif cmd in ["C_POP", "C_PUSH"]:
                        writer.write_push_pop(cmd, argument1,
                                              argument2)
                    elif cmd == "C_LABEL":
                        writer.write_label(argument1)
                    elif cmd == "C_GOTO":
                        writer.write_goto(argument1)
                    elif cmd == "C_IF":
                        writer.write_if(argument1)
                    elif cmd == "C_FUNCTION":
                        writer.write_function(argument1, int(argument2))
                    elif cmd == "C_CALL":
                        writer.write_call(argument1, argument2)
                    elif cmd == "C_RETURN":
                        writer.write_return()
        writer.close()