Example #1
0
def main(input_file):
    if len(input_file.split('.')) == 1:
        if input_file[-1] == '/':
            input_file = input_file[:-1]
        output_file = join(input_file, input_file.split('/')[-1])
        input_files = [
            join(input_file, f) for f in listdir(input_file)
            if f.split('.')[1] == 'vm' and f != 'Sys.vm'
            and isfile(join(input_file, f))
        ]
        input_files.insert(0, join(input_file, 'Sys.vm'))
        print('Input files: {}'.format(input_files))
    else:
        input_files = [input_file]
        directory = '/'.join(input_file.split('/')[:-1])
        output_file = join(directory, input_file.split('/')[-1].split('.')[0])

    code_writer = CodeWriter(output_file)
    code_writer.write_init()

    for input_file in input_files:
        parser = Parser(input_file)
        code_writer.set_filename(input_file)
        n = 0
        while parser.advance():
            com_type = parser.command_type()
            print('LINE {}'.format(n))
            print('\tcom type: {}'.format(com_type))
            print('\tcommand: {}'.format(parser.command))
            if com_type != parser.c_return:
                arg1 = parser.arg1()
                if com_type in [
                        parser.c_push, parser.c_pop, parser.c_function,
                        parser.c_call
                ]:
                    arg2 = parser.arg2()

            if com_type == parser.c_arithmetic:
                code_writer.write_arithmetic(arg1)
            elif com_type in [parser.c_pop, parser.c_push]:
                code_writer.write_push_pop(com_type, arg1, int(arg2))
            elif com_type == parser.c_label:
                code_writer.write_label(arg1)
            elif com_type == parser.c_goto:
                code_writer.write_goto(arg1)
            elif com_type == parser.c_if:
                code_writer.write_if(arg1)
            elif com_type == parser.c_function:
                code_writer.write_function(arg1, arg2)
            elif com_type == parser.c_return:
                code_writer.write_return()
            elif com_type == parser.c_call:
                code_writer.write_call(arg1, arg2)
            n += 1
    code_writer.close()
Example #2
0
def main():
	filename = sys.argv[1].split('.')[0]
	parser = Parser(filename)
	code = CodeWriter(filename)
	while(parser.has_more_commands()):
		parser.advance()

		command_type = parser.command_type()

		if command_type == 'C_ARITHMETIC':
			code.write_arithmetic(parser.arg1())

		elif command_type == 'C_PUSH' or command_type == 'C_POP':
			code.write_push_pop(parser.command(), parser.arg1(), parser.arg2())

		# print(parser.current_command)
	parser.close()
	code.close()
Example #3
0
def main():
    vm_filename = sys.argv[1]
    asm_filename = vm_filename.replace('.vm', '.asm')
    vm_file = open(vm_filename, 'r')
    asm_file = open(asm_filename, 'a')

    parser = Parser(vm_file)
    code_writer = CodeWriter(asm_file)

    while parser.has_more_commands():
        parser.advance()
        if parser.command_type() == C_ARITHMETIC:
            code_writer.write_arithmetic(parser.arg1())
        elif parser.command_type() == C_PUSH:
            code_writer.write_push_pop(C_PUSH, parser.arg1(), parser.arg2())
        elif parser.command_type() == C_POP:
            code_writer.write_push_pop(C_POP, parser.arg1(), parser.arg2())

    vm_file.close()
    code_writer.close()
Example #4
0
def main():

    # If there is an invalid number of arguments the program stops.
    if len(sys.argv) != 2:
        print("ERROR: Invalid number of arguments. Expected: file_name.vm ")
        exit(1)
    # the VM translator only accepts vm files to be translated into assembly files.
    elif sys.argv[1][-3:] != ".vm":
        print("ERROR: Invalid file type. Expected: vm file")
        exit(1)

    # Get the name of the file to be parsed from the arguments.
    input_file = sys.argv[1]

    # Creates a new parser to parse the file.
    parser = Parser(input_file)
    # Creates the code writer with the input file excluding the .vm part
    code_writer = CodeWriter(input_file[0:-3])

    # Reads the whole file.
    while parser.has_more_commands():
        parser.advance()
        # Gets the command type from the current command.
        command_type = parser.command_type()
        # If the command type is C_ARITHMETIC parses it to get the command and passes it to the code writer to add it to the output file
        if command_type == "C_ARITHMETIC":
            command = parser.arg1()
            code_writer.write_arithmetic(command)
        # If the command type is C_PUSH or C_POP parses it to get the segment and the index and passes it to the code writer to add it to the output file
        elif command_type == "C_PUSH" or command_type == "C_POP":
            segment = parser.arg1()
            index = parser.arg2()
            code_writer.write_push_pop(command_type, segment, index)

    del parser
    code_writer.close()
Example #5
0
    c.write_init()
    for filename in [files[sys_init]] + rest: #  order matters
        # only parse .vm files
        if filename.find('.vm') != -1:
            c.set_filename(filename)
            p = Parser(BASE + filename)
            while p.has_more_lines():
                p.advance()
                command = p.command_type()
                arg_1 = p.arg_1()
                arg_2 = p.arg_2()
                if command in ['C_PUSH', 'C_POP']:
                    c.write_push_pop(command, arg_1, arg_2)

                if command == 'C_ARITHMETIC':
                    c.write_arithmetic(arg_1)

                if command == 'C_GOTO':
                    c.write_goto(arg_1)

                if command == 'C_IF':
                    c.write_if(arg_1)

                if command == 'C_LABEL':
                    c.write_label(arg_1)

                if command == 'C_FUNCTION':
                    c.write_function(arg_1, arg_2)

                if command == 'C_RETURN':
                    c.write_return()
Example #6
0
class VMTranslator:
    def __init__(self, src: str):
        self.asm_file, self.vm_files = self._parse_files(src)
        print("Translate to %s." % self.asm_file)
        self.code_writer = CodeWriter(self.asm_file)

    def translates(self):
        for vm_file in self.vm_files:
            self._translate(vm_file)

    def _parse_files(self, file_path: str) -> (str, list):
        if not os.path.exists(file_path):
            raise IOError("No such file or directory.")

        if os.path.isfile(file_path) and file_path.endswith(VM_EXT):
            asm_file = file_path.replace(VM_EXT, ASM_EXT)
            vm_files = [file_path]

        elif os.path.isdir(file_path):
            dir_path = file_path[:-1] if file_path[-1] == "/" else file_path
            asm_file = dir_path + "/" + os.path.basename(dir_path) + ASM_EXT
            vm_files = self._find_all_files_with_ext(dir_path, "vm")
        else:
            raise IOError("No such file or directory.")

        return asm_file, vm_files

    def _find_all_files_with_ext(self, dir_path: str, ext: str) -> list:
        ext_files = []
        suffix = os.extsep + ext.lower()
        for cur_dir, _, files in os.walk(dir_path):
            for file in files:
                if file.lower().endswith(suffix):
                    ext_files.append(os.path.join(cur_dir, file))
        return ext_files

    def _translate(self, vm_file: str):
        parser = Parser(vm_file)
        self.code_writer.set_filename(vm_file)
        self.code_writer.write("// ----------  %s ----------" %
                               self.code_writer.current_vm_file)

        while parser.next_line():
            self.code_writer.write("// " + parser.command_line())

            if parser.command_type() == "C_ARITHMETIC":
                self.code_writer.write_arithmetic(parser.argn(0))
            elif parser.command_type() == "C_PUSH":
                self.code_writer.write_push(parser.argn(1), parser.argn(2))
            elif parser.command_type() == "C_POP":
                self.code_writer.write_pop(parser.argn(1), parser.argn(2))
            elif parser.command_type() == "C_LABEL":
                self.code_writer.write_label(parser.argn(1))
            elif parser.command_type() == "C_GOTO":
                self.code_writer.write_goto(parser.argn(1))
            elif parser.command_type() == "C_IF_GOTO":
                self.code_writer.write_if_goto(parser.argn(1))
            elif parser.command_type() == "C_FUNCTION":
                self.code_writer.write_function(parser.argn(1),
                                                int(parser.argn(2)))
            elif parser.command_type() == "C_CALL":
                self.code_writer.write_call(parser.argn(1),
                                            int(parser.argn(2)))
            elif parser.command_type() == "C_RETURN":
                self.code_writer.write_return()

            self.code_writer.write("")  # empty line
        self.code_writer.write("// ------------------------------\n")
Example #7
0
if __name__ == "__main__":

    if len(sys.argv) != 2:
        print(f"Usage: {sys.argv[0]} <{sys.argv[1]}>")

    files = []
    if sys.argv[1].endswith('.vm'):
        files.append(sys.argv[1])
    elif os.path.isdir(sys.argv[1]):
        files.extend(glob.glob("*.vm"))

    cw = CodeWriter(sys.argv[1].strip(".vm") + ".asm")

    print(f"Creating {sys.argv[1].strip('.vm') + '.asm'} ...")

    for f in files:
        p = Parser(f)
        cw.file_name = f
        while p.advance():
            if p.command_type == CommandType.C_ARITHMETIC:
                cw.write_arithmetic(p.arg1())
            elif p.command_type == CommandType.C_PUSH:
                cw.write_push_pop(CommandType.C_PUSH, segment_map[p.arg1()],
                                  p.arg2())
            elif p.command_type == CommandType.C_POP:
                cw.write_push_pop(CommandType.C_POP, segment_map[p.arg1()],
                                  p.arg2())

    print("Success.")