Exemplo n.º 1
0
def translate(input_file_path, output_file):
    parser = Parser(input_file_path)
    command = parser.next_command()
    current_function = "no_function"
    while command:
        command_type = get_command_type(command)
        parts = command.split()
        if command_type == MEMORY_ACCESS:
            output_file.write(
                memory_access.translate_command(
                    parts[0], parts[1], parts[2],
                    get_file_name(input_file_path)))
        elif command_type == ARITHMETIC:
            output_file.write(arithmetic.translate_command(command))
        elif command_type == PROGRAM_FLOW:
            output_file.write(
                program_flow.translate_command(parts[0], parts[1],
                                               current_function))
        elif command_type == FUNCTION:
            if parts[0] == FUNCTION_DECLARATION:
                current_function = parts[1]
            if len(parts) == 3:
                output_file.write(
                    function.translate_command(parts[0], parts[1], parts[2]))
            else:
                output_file.write(function.translate_command(parts[0], "", ""))
        command = parser.next_command()
        output_file.write("\n\n")
Exemplo n.º 2
0
def translate(input_file_path, output_file):
    parser = Parser(input_file_path)
    command = parser.next_command()
    while command:
        command_type = get_command_type(command)
        if command_type == MEMORY_ACCESS:
            parts = command.split()
            output_file.write(
                memory_access.translate_command(
                    parts[0], parts[1], parts[2],
                    get_file_name(input_file_path)))
        elif command_type == ARITHMETIC:
            output_file.write(arithmetic.translate_command(command))
        command = parser.next_command()
        output_file.write("\n\n")
 def test_parser(self):
     expected = [
         "push constant 17", "push constant 17", "eq", "push constant 17",
         "push constant 16", "eq", "push constant 16", "push constant 17",
         "eq", "push constant 892", "push constant 891", "lt",
         "push constant 891", "push constant 892", "lt",
         "push constant 891", "push constant 891", "lt",
         "push constant 32767", "push constant 32766", "gt",
         "push constant 32766", "push constant 32767", "gt",
         "push constant 32766", "push constant 32766", "gt",
         "push constant 57", "push constant 31", "push constant 53", "add",
         "push constant 112", "sub", "neg", "and", "push constant 82", "or",
         "not"
     ]
     vm_parser = Parser("StackArithmetic/StackTest/StackTest.vm")
     list = []
     command = vm_parser.next_command()
     while command:
         list.append(command)
         command = vm_parser.next_command()
     self.assertListEqual(expected, list)
Exemplo n.º 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()
def read_file(input_file, code_writer):
    """ Reads and translates to assembly code a single file """

    # Creates a new parser to parse the file.
    parser = Parser(input_file)

    # Set the current file name to be input file
    code_writer.set_file_name(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)
        # If the command type is C_LABEL parses it to get the label and passes it to the code writer to add to the output file
        elif command_type == "C_LABEL":
            label = parser.arg1()
            code_writer.write_label(label)
        # If the command type is C_GOTO parses it to get the label and passes it to the code writer to add to the output file
        elif command_type == "C_GOTO":
            label = parser.arg1()
            code_writer.write_goto(label)
        # If the command type is C_IF parses it to get the label and passes it to the code writer to add to the output file
        elif command_type == "C_IF":
            label = parser.arg1()
            code_writer.write_if(label)
        elif command_type == "C_CALL":
            function_name = parser.arg1()
            num_args = parser.arg2()
            code_writer.write_call(function_name, num_args)
        # If the command type is C_RETURN passes it to the code writer to add it to the output file.
        elif command_type == "C_RETURN":
            code_writer.write_return()
        # If the command type is C_FUNCTION parses it to get the function name and number of local variables and passes it to the code writer to add to the output file
        elif command_type == "C_FUNCTION":
            function_name = parser.arg1()
            num_locals = parser.arg2()
            code_writer.write_function(function_name, num_locals)

    del parser
Exemplo n.º 6
0
    else:
        vmfiles = [
            inpath + '/' + f for f in os.listdir(inpath) if f.endswith('.vm')
        ]
        outdir = vmfiles[0].rsplit('/', 1)[0]
        outfilename = outdir.rsplit('/', 1)[-1]

    outpath = outdir + '/' + outfilename + '.asm'

    translator = Translator()

    if len(sys.argv) == 3 and sys.argv[2] == '--init':
        translator.write_init()

    for file in vmfiles:
        filename = file.rsplit('.vm', 1)[0].rsplit('/', 1)[-1]
        translator.set_filename(filename)
        with open(file, 'r') as infile:
            lines = infile.readlines()
            parser = Parser(lines)

        while parser.has_more_commands():
            cmd = parser.advance()
            cmd_type = parser.get_cmd_type()
            translator.translate(cmd_type, cmd)

    translator.close()

    with open(outpath, 'w') as outfile:
        outfile.write(translator.translation)
            if '.vm' in file:
                dirs.append(os.path.join(r, file))
#Si es un archivo .vm lo tomo solito
else:
    dirs = sys.argv
    del dirs[0]
    outname = dirs[0].split('.vm')[0]
#Creo el codewriter con el nombre del archivo en el cual voy a escribir
cw = code_writer(outname)
#Si es un directorio escribo el llamado a Sys.init
if len(dirs) > 1:
    cw.writeInit()
#Itero sobre cada file
for file_path in dirs:
    #Creo parser y  pongo el codewriter con el file que estoy analizando
    parser = Parser(file_path)
    cw.setFileName(file_path)
    # Itero por cada linea
    while parser.hasMoreCommands():
        parser.advance()
        if parser.commandType() == 'C_PUSH':
            cw.writePushPop('C_PUSH', parser.arg1(), parser.arg2())
        elif parser.commandType() == 'C_POP':
            cw.writePushPop('C_POP', parser.arg1(), parser.arg2())
        elif parser.commandType() == 'C_ARITHMETIC':
            cw.writeArithmetic(parser.arg1())
        elif parser.commandType() == 'C_LABEL':
            cw.writeLabel(parser.arg1())
        elif parser.commandType() == 'C_IF':
            cw.writeIf(parser.arg1())
        elif parser.commandType() == 'C_GOTO':
Exemplo n.º 8
0
from vm_parser import Parser, VMCommandType
from vm_code_writer import CodeWriter

import sys
from pathlib import Path

if __name__ == '__main__':
    if len(sys.argv) > 1:
        program_path = sys.argv[1]
        parser = Parser(program_path)
        file_name = Path(program_path).with_suffix('.asm')
        writer = CodeWriter(file_name)
        while parser.has_more_commands():
            parser.advance()
            c_type = parser.command_type()
            if c_type == VMCommandType.C_POP or c_type == VMCommandType.C_PUSH:
                writer.write_push_pop(c_type, parser.arg1, parser.arg2)
            elif c_type == VMCommandType.C_ARITHMETIC:
                writer.write_arithmetic(parser.arg1)
        writer.close()

    else:
        raise TypeError("1 argument is required: program path, 0 arguments entered")
Exemplo n.º 9
0
 def compile_single(self, vm):
     pure_vm = Preprocessor().process(vm.read_text())
     parsed_vm = Parser().parse(pure_vm)
     return CodeGenerator(vm.stem).generate(parsed_vm)
Exemplo n.º 10
0
        program_path = sys.argv[1]
        if isfile(program_path):
            files = [program_path]
            output_path = Path(program_path).parent
        elif isdir(program_path):
            files = glob.glob(join(program_path, '*.vm'))
            output_path = program_path
        else:
            raise FileNotFoundError("[Errno 2] No such file or directory: ", program_path)

        output_file_name = PurePath(program_path).name.split('.')[0] + '.asm'
        output_file = Path(output_path, output_file_name)
        writer = CodeWriter(output_file)

        for i, vm_file in enumerate(files):
            parser = Parser(vm_file)
            file_name = PurePath(program_path).name
            writer.set_file_name(file_name)
            while parser.has_more_commands():
                parser.advance()
                c_type = parser.command_type()
                if c_type == VMCommandType.C_POP or c_type == VMCommandType.C_PUSH:
                    writer.write_push_pop(c_type, parser.arg1, parser.arg2)
                elif c_type == VMCommandType.C_ARITHMETIC:
                    writer.write_arithmetic(parser.arg1)
                elif c_type == VMCommandType.C_LABEL:
                    writer.write_label(parser.arg1)
                elif c_type == VMCommandType.C_GOTO:
                    writer.write_goto(parser.arg1)
                elif c_type == VMCommandType.C_IF:
                    writer.write_if(parser.arg1)
Exemplo n.º 11
0
import sys
from vm_parser import Parser
from vm_code_writer import code_writer
#Obtengo el nombre del file
file_path = sys.argv[1]
#Creo parser y code writer
parser = Parser(file_path)
cw = code_writer(file_path)
#Itero por cada linea
while parser.hasMoreCommands():
    parser.advance()
    if parser.commandType() == 'C_PUSH':
        cw.writePushPop('C_PUSH', parser.arg1(), parser.arg2())
    elif parser.commandType() == 'C_POP':
        cw.writePushPop('C_POP', parser.arg1(), parser.arg2())
    elif parser.commandType() == 'C_ARITHMETIC':
        cw.writeArithmetic(parser.arg1())
cw.close()