Esempio n. 1
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
    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':
            cw.writeFunction(parser.arg1(), parser.arg2())
        elif parser.commandType() == 'C_RETURN':
Esempio n. 4
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()