예제 #1
0
def main():
    readPaths: List[Path]
    writePath: Path
    inputPath = Path(sys.argv[1])

    if inputPath.is_dir():
        readPaths = [p for p in inputPath.iterdir() if p.suffix == ".vm"]
        writePath = (inputPath / inputPath.stem).with_suffix(".asm")
    else:
        assert inputPath.suffix == ".vm", "Invalid input file: must have .vm extension"
        readPaths = [inputPath]
        writePath = inputPath.with_suffix(".asm")

    with open(writePath, "w+") as writeFile:
        writer = VMCodeWriter(writeFile)
        writer.writeInit()
        for p in readPaths:
            parser = VMParser(p, writer)  # sets up the VMParser
            while parser.hasMoreCommands():
                parser.writeNextCommand()
예제 #2
0
class VMTranslator:
    def __init__(self):
        self.parser = VMParser()
        self.coder = CodeWriter()
        self.myPath = Path(sys.argv[1])
        self.initParameters()

    def initParameters(self):
        self.filelists = list()
        if self.myPath.is_file():
            self.filelists = [self.myPath]
            self.outputFile = str(self.myPath.with_suffix('.asm'))
        elif self.myPath.is_dir():
            self.filelists = [
                file for file in self.myPath.iterdir()
                if str(file).endswith('.vm')
            ]
            self.outputFile = str(
                self.myPath) + ('/' + str(self.myPath.stem) + '.asm')
        self.outputFileHandle = open(self.outputFile, 'w')

    def run(self):
        self.outputFileHandle.write(
            self.coder.translateCode(['bootstrap'], 'Call Sys.init 0'))

        for file in self.filelists:
            fileHandle = open(str(file))
            filename = file.stem  #extract filename without the extendion e.g foo.vm => foo

            self.coder.setFilename(filename)

            for line in fileHandle:
                sanitizedLine = self.sanitizeInput(line)
                if len(sanitizedLine) == 0: continue
                parsedInstruction = self.parser.parse(sanitizedLine)
                codeString = self.coder.translateCode(parsedInstruction,
                                                      sanitizedLine)
                self.outputFileHandle.write(codeString)
            fileHandle.close()

        print('Translated VM code to assembly successfully.')
        # noinspection PyUnboundLocalVariable
        self.outputFileHandle.close()

    # remove whitespace and comments from input[line]
    def sanitizeInput(self, line):
        if len(line) == 0 or line.startswith('//'):
            return ''
        line = line.strip()
        commentIndex = line.find('//')
        if commentIndex > -1:
            line = line[:commentIndex]
        return line
예제 #3
0
 def __init__(self):
     self.parser = VMParser()
     self.coder = CodeWriter()
     self.myPath = Path(sys.argv[1])
     self.initParameters()
    filenames = [args.source]
    output_filename = split(args.source)[0] + ".asm"

if args.stdout:
    output_file = sys.stdout
else:
    output_file = open(output_filename, "w")

cw = CodeWriter(output_file, args.stamp)

if args.bootstrap:
    cw.writeInit()

for filename in filenames:
    cw.setFileName(filename)
    p = VMParser(filename)
    while p.hasMoreCommands():
        t = p.commandType()
        if t in ["C_PUSH", "C_POP"]:
            cw.WritePushPop(t, p.arg1(), p.arg2())
        elif t == "C_ARITHMETIC":
            cw.writeArithmetic(p.arg1())
        elif t == "C_LABEL":
            cw.writeLabel(p.arg1())
        elif t == "C_GOTO":
            cw.writeGoto(p.arg1())
        elif t == "C_IF":
            cw.writeIf(p.arg1())
        elif t == "C_FUNCTION":
            cw.writeFunction(p.arg1(), p.arg2())
        elif t == "C_RETURN":
예제 #5
0
    def runSingleFile(self, isWrite=True):
        parser = VMParser(self.content)
        codeWriter = VMCodeWriter(self.className)
        asmCmds = self.asmCmds
        while(parser.hasMoreCommands()):
            parser.advance()
            commandType = parser.commandType()

            if commandType in ['C_PUSH','C_POP']: 
                segment,index = parser.arg1(),parser.arg2()
                asmCmds += codeWriter.writePushPop(commandType, segment, index)

            elif commandType == 'C_ARITHMETIC':
                cmd = parser.arg1()
                asmCmds += codeWriter.writeArithmetic(cmd)

            elif commandType == 'C_LABEL':
                cmd = parser.arg1()
                asmCmds += codeWriter.writeLabel(cmd)

            elif commandType == 'C_GOTO':
                cmd = parser.arg1()
                asmCmds += codeWriter.writeGoto(cmd)

            elif commandType == 'C_IF':
                cmd = parser.arg1()
                asmCmds += codeWriter.writeIf(cmd)

            elif commandType == 'C_FUNCTION':
                functionName,numVars = parser.arg1(),parser.arg2()
                asmCmds += codeWriter.writeFunction(functionName, numVars)

            elif commandType == 'C_CALL':
                functionName,numArgs = parser.arg1(),parser.arg2()
                asmCmds += codeWriter.writeCall(functionName, numArgs)

            elif commandType == 'C_RETURN':
                asmCmds += codeWriter.writeReturn()
            
        if isWrite:
            with open(self.outputPath, 'w') as f:
                f.write(''.join(asmCmds))