Exemplo n.º 1
0
class Translator:
    """ Translator combine Parser and CodeWriter classes to 
  translate .vm files to .asm files """

    def __init__(self, filename):
        """ Initiliaze with file/dirname and predefined symbols 
    Also, starts CodeWriter """
        self.filename = filename
        if filename.endswith(".vm"):
            outFile = filename.replace(".vm", ".asm")
        elif filename.endswith("/"):
            outFile = filename[: len(filename) - 1] + ".asm"
        else:
            outFile = filename + ".asm"
        self.codeWriter = CodeWriter(outFile)
        self.symbols = {"R12": 12, "R13": 13, "R14": 14, "R15": 15}

    def translate(self):
        """ Decides if it should translate a file or a directory """
        self.codeWriter.writeInit()
        if os.path.isfile(self.filename):
            self.translateFile(self.filename)
        else:
            self.translateDirectory(self.filename)

        self.codeWriter.close()

    def translateDirectory(self, directory):
        """ Translates all files in the provided directory """
        for file in glob.glob(os.path.join(directory, "*.vm")):
            self.translateFile(file)

    def translateFile(self, filename):
        """ Translates a single .vm file to a .asm file """
        parser = Parser(filename)
        self.codeWriter.setFileName(os.path.basename(filename).replace(".vm", ""))
        while parser.hasMoreCommands():
            parser.advance()
            command = parser.commandType()

            if command == parser.C_ARITHMETIC:
                self.codeWriter.writeArithmetic(parser.arg1())
            elif command == parser.C_PUSH or command == parser.C_POP:
                self.codeWriter.writePushPop(parser.command[0], parser.arg1(), parser.arg2())
            elif command == parser.C_LABEL:
                self.codeWriter.writeLabel(parser.arg1())
            elif command == parser.C_GOTO:
                self.codeWriter.writeGoTo(parser.arg1())
            elif command == parser.C_IF:
                self.codeWriter.writeIf(parser.arg1())
            elif command == parser.C_FUNCTION:
                self.codeWriter.writeFunction(parser.arg1(), parser.arg2())
            elif command == parser.C_CALL:
                self.codeWriter.writeCall(parser.arg1(), parser.arg2())
            elif command == parser.C_RETURN:
                self.codeWriter.writeReturn()

        parser.close()