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.º 2
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()
Exemplo n.º 3
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)
    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':
            cw.writeGoto(parser.arg1())
        elif parser.commandType() == 'C_CALL':
            cw.writeCall(parser.arg1(), parser.arg2())
        elif parser.commandType() == 'C_FUNCTION':