コード例 #1
0
 def assemble(self):
     # populate the symbol table w/ loop markers
     self.parse(self._firstPass)
     # aseemble the code
     self.parse(self._secPass)
     # write assembled code to .hack file
     fh.writeHackFile(self._filePath, self._codeList)
コード例 #2
0
ファイル: tokenizer.py プロジェクト: arshnooramin/Nand2Tetris
 def _firstParse(self):
     for line in self._f:
         # remove the newline char '\n'
         line = line.strip()
         # check if there is parseable code in line
         if not fh.isCommentOrEmpty(line):
             line = fh.removeInlineComments(line)
             # update the clean code string
             self._code += line
コード例 #3
0
 def _secPass(self, line):
     line = fh.removeInlineComments(line)
     # check if it's a instruction
     if fh.isAInst(line):
         # handle a-instruction
         self._handleAInst(line[1:])
     # else must be a c-instruction
     elif not fh.isLoopMarker(line):
         # handle c-instruction
         self._handleCInst(line)
コード例 #4
0
 def _handleAInst(self, aInst):
     address = ''
     # if a-inst is an int
     try:
         address = fh.dec2bin(int(aInst), 15)
     # else must be a symbol
     except:
         # decode the asm code
         decaddr = self._ht.symbolHandler(str(aInst))
         address = fh.dec2bin(decaddr, 15)
     # store it in the code list
     self._codeList.append('0' + address + '\n')
コード例 #5
0
 def parse(self, asmLogicFunc):
     for line in self._f:
         # remove the newline char '\n'
         line = line.strip()
         # remove whitespaces from lines
         line = fh.removeSpaces(line)
         # check if there is parseable code in line
         if not fh.isCommentOrEmpty(line):
             # apply assembly logic to it
             asmLogicFunc(line)
     # reset the file cursor to the start of file
     self._f.seek(0)
コード例 #6
0
 def parse(self):
     for line in self._f:
         # remove the newline char '\n'
         line = line.strip()
         # check if there is parseable code in line
         if not fh.isCommentOrEmpty(line):
             line = fh.removeInlineComments(line)
             # split commands from the line
             commands = line.split(" ")
             # get the type of command
             cmdtype = cf.commandType(commands[0])
             # if it's a push or pop command handle it
             if cmdtype == PUSH or cmdtype == POP:
                 self._handlePushPop(commands, cmdtype)
             # else if it's a arithmetic command handle it
             elif cmdtype == ARITHMETIC:
                 self._handleArithmetic(commands)
コード例 #7
0
 def _firstPass(self, line):
     # if line contain a loop marker
     if fh.isLoopMarker(line):
         loopMark = line[1:-1]
         # store it in the symbol hash table
         self._ht.addSymbol(loopMark, self._lineCount + 1)
     else:
         # count number of parseable code lines
         self._lineCount += 1
コード例 #8
0
 def parse(self):
     for line in self._f:
         # remove the newline char '\n'
         line = line.strip()
         # check if there is parseable code in line
         if not fh.isCommentOrEmpty(line):
             writeStr = ""
             # remove in-line comments from each line
             line = fh.removeInlineComments(line)
             # split commands from the line
             commands = line.split(" ")
             # get the type of command
             cmdtype = self._cf.commandType(commands[0])
             # if it's a push or pop command handle it
             if cmdtype == PUSH or cmdtype == POP:
                 writeStr = self._handlePushPop(commands, cmdtype)
             # else if it's a arithmetic command handle it
             elif cmdtype == ARITHMETIC:
                 writeStr = self._handleArithmetic(commands)
             # else if it's a label command handle it
             elif cmdtype == LABEL:
                 writeStr = self._cf.writeLabelAsm(commands[1])
             # else if it's a goto command handle it
             elif cmdtype == GOTO:
                 writeStr = self._cf.writeGotoAsm(commands[1])
             # else if it's a if-goto command handle it
             elif cmdtype == IF:
                 writeStr = self._cf.writeIfGotoAsm(commands[1])
             # else if it's a call command handle it
             elif cmdtype == CALL:
                 writeStr = self._cf.writeCallAsm(commands[1], int(commands[2]))
             # else if it's a return command handle it
             elif cmdtype == RETURN:
                 writeStr = self._cf.writeReturnAsm()
             # else if it's a function command handle it
             elif cmdtype == FUNCTION:
                 writeStr = self._cf.writeFunctionAsm(commands[1], int(commands[2]))
             # add it to the code list
             self._codeList.append(writeStr)
             print(line)
             print(self._codeList)
コード例 #9
0
 def _handlePushPop(self, commands, ptype):
     outStr = ""
     segment = commands[1]; index = int(commands[2])
     segtype = self._cf.pushPopType(segment)
     # if it's a group 1 command write asm code for it
     if segtype == GROUP_1:
         outStr = self._cf.writePushPopAsm1(ptype, segment, index)
     elif segtype == STATIC:
         outStr = self._cf.writeStaticPushPopAsm(fh.getVmFileName(self._filePath), ptype, index)
     # if it's a group 2 command write asm code for it
     elif segtype == GROUP_2:
         outStr = self._cf.writePushPopAsm2(ptype, segment, index)
     # if it's a constant command write asm code for it
     elif segtype == CONSTANT:
         outStr = self._cf.writeConstantPushPopAsm(index)
     return outStr
コード例 #10
0
        elif ';' in cInst:
            # must be a jump statement
            cList = cInst.split(';')
            comp, jump = cList[0], cList[1]
            cBin = self._getCInst(comp, 'null', jump)
        # store it in the code list
        self._codeList.append(cBin + '\n')

    # get and create a c-instruction with provided
    # asm codes
    def _getCInst(self, comp, dest, jump):
        return '111' + self._ht.compBin(comp) +\
               self._ht.destBin(dest) +\
               self._ht.jumpBin(jump)


# main/executable section of the code
if __name__ == '__main__':
    if len(sys.argv) != 2:
        sys.exit(".asm file path not provided")

    filePath = sys.argv[1]

    # check to see if valid asm was provided
    if (not fh.fileExists(filePath)) or \
       (not fh.isAsmFile(filePath)):
        sys.exit("Incorrect .asm file path")

    asm = Assembler(filePath)
    asm.assemble()
コード例 #11
0
 def translate(self):
     # aseemble the code
     self.parse()
     # write assembled code to .hack file
     fh.writeAsmFile(self._filePath, self._codeList)
コード例 #12
0
            outStr = self._cf.writeConstantPushPopAsm(index)
        return outStr

    # getter method for codelist attribute
    def getCodeList(self):
        return self._codeList

# main/executable section of the code
if __name__ == '__main__':
    if len(sys.argv) != 2:
        sys.exit(".vm file path not provided")
    
    fileDir = sys.argv[1]

    # check to see if the directory is valid
    if not fh.dirExists(fileDir):
        sys.exit("Incorrect file directory!")

    # get the file paths for all vm files in directory
    filePaths = fh.getVmFiles(fileDir)

    # the cformatter object
    cf = CFormatter()

    # intialize the code list for each file
    codeList = []
    # iterate over each file path
    for i, filePath in enumerate(filePaths):
        tr = Translator(filePath, cf)
        if i == 0:
            tr.handleInit()
コード例 #13
0
 def _error(self):
     fh.writeXMLFile(self._filePath, self._codeList)
     sys.exit(self._tk.token() + " " + types[self._tk.type()] + \
         " not a valid jack grammar")
コード例 #14
0
 def compile(self):
     # start by compiling class
     self._handleClass()
     # write assembled code to xml file
     fh.writeXMLFile(self._filePath, self._codeList)
コード例 #15
0
            self._writeXML()
            self._write("<expressionList>\n")
            self._level += 1
            while self._tk.token() != ')':
                if self._tk.token() == ',':
                    self._writeXML()
                else:
                    # handle param type or name
                    self._handleExpression()
            # write closing bracket
            self._level -= 1
            self._write("</expressionList>\n")
            self._writeXML()
        else:
            self._error()


# main/executable section of the code
if __name__ == '__main__':
    if len(sys.argv) != 2:
        sys.exit(".jack file path not provided")

    filePath = sys.argv[1]

    # check to see if valid jack file was provided
    if (not fh.fileExists(filePath)) or \
       (not fh.isJackFile(filePath)):
        sys.exit("Incorrect .jack file path")

    cp = Analyzer(filePath)
    cp.compile()