def CompileDoStatement(self, out):
     'compile doStatement'
     self.__print_nonterm_tag(out, 'doStatement') # <doStatement>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'do',1,1), True)
     self.CompileSubroutineCall(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,';',1,1), True)
     self.__print_nonterm_tag(out, 'doStatement', True) # </doStatement>
 def CompileTerm(self, out):
     'compile term'
     self.__print_nonterm_tag(out, 'term') # <term>
     token = self.__tokenizer.peek()
     if token.typ in (JackTokenizer.INTEGER, JackTokenizer.STRING) \
        or token.value in KEYWORDCONST:
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # intConst | strConst | keywordConstant
     elif token.value == '(':
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # (
         self.CompileExpression(out)
         self.__validate(out, Token(JackTokenizer.SYMBOL,')',1,1), True)
     elif token.value in UNARYOP:
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # unaryOp
         self.CompileTerm(out)
     else:
         token2 = self.__tokenizer.peek(1)
         if token2.value in ('(', '.'):
             self.CompileSubroutineCall(out)
         else:
             self.__validate(out, varName_token) # varName
             token = self.__tokenizer.peek()
             if token.value == '[':
                 _ = self.__tokenizer.next()
                 self.__print_term_tag(out, token) # [
                 self.CompileExpression(out)
                 self.__validate(out, Token(JackTokenizer.SYMBOL,']',1,1), True)
     self.__print_nonterm_tag(out, 'term', True) # </term>
 def CompileSubroutineBody(self, out):
     'compile subroutineBody'
     self.__print_nonterm_tag(out, 'subroutineBody') # <subroutineBody>
     self.__validate(out, Token(JackTokenizer.SYMBOL,'{',1,1), True)
     self.CompileVarDec(out)
     self.CompileStatements(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'}',1,1), True)
     self.__print_nonterm_tag(out, 'subroutineBody', True) # </subroutineBody>
 def CompileReturnStatement(self, out):
     'compile returnStatement'
     self.__print_nonterm_tag(out, 'returnStatement') # <returnStatement>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'return',1,1), True)
     token = self.__tokenizer.peek()
     if token.value != ';':
         self.CompileExpression(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,';',1,1), True)
     self.__print_nonterm_tag(out, 'returnStatement', True) # </returnStatement>
 def compileClass(self, out):
     'compile class'
     self.__print_nonterm_tag(out, 'class') # <class>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'class',1,1), True)
     self.__validate(out, varName_token)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'{',1,1), True)
     self.CompileClassVarDec(out)
     self.CompileSubroutineDec(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'}',1,1), True)
     self.__print_nonterm_tag(out, 'class', True) # </class>
 def CompileWhileStatement(self, out):
     'compile whileStatement'
     self.__print_nonterm_tag(out, 'whileStatement') # <whileStatement>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'while',1,1), True)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'(',1,1), True)
     self.CompileExpression(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,')',1,1), True)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'{',1,1), True)
     self.CompileStatements(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'}',1,1), True)
     self.__print_nonterm_tag(out, 'whileStatement', True) # </whileStatement>
 def CompileLetStatement(self, out):
     'compile letStatement'
     self.__print_nonterm_tag(out, 'letStatement') # <letStatement>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'let',1,1), True)
     self.__validate(out, varName_token)
     token = self.__tokenizer.peek()
     if token.value == '[':
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # [
         self.CompileExpression(out)
         self.__validate(out, Token(JackTokenizer.SYMBOL,']',1,1), True)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'=',1,1), True)
     self.CompileExpression(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,';',1,1), True)
     self.__print_nonterm_tag(out, 'letStatement', True) # </letStatement>
 def CompileSubroutineCall(self, out):
     'compile subroutineCall'
     self.__validate(out, varName_token) # varName
     token = self.__tokenizer.peek()
     if token.value == '.':
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # '.'
         self.__validate(out, varName_token) # varName
     self.__validate(out, Token(JackTokenizer.SYMBOL,'(',1,1), True)
     token = self.__tokenizer.peek()
     if token.value != ')':
         self.CompileExpressionList(out)
     else:
         self.__print_nonterm_tag(out, 'expressionList') # <expressionList>
         self.__print_nonterm_tag(out, 'expressionList', True) # </expressionList>
     self.__validate(out, Token(JackTokenizer.SYMBOL,')',1,1), True)
def _read_tokens(filename, start, end):
    with open(filename, 'r') as file:
        content = file.readlines()
    lines = content[start:end]
    tokens = []
    for line in lines:
        tokens.append(Token.load_xml(line.strip()))
    return tokens
 def CompileSubroutineDec(self, out):
     'compile subroutineDec'
     token = self.__tokenizer.peek()
     while token.value in SUBROUTINETYPE:
         self.__print_nonterm_tag(out, 'subroutineDec') # <subroutineDec>
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # 'constructor' | 'function' | 'method'
         token = self.__tokenizer.next()
         if token.value != 'void' and not self.__is_type(token):
             self.__error_msg(token, 'void|'+ '|'.join(TYPE_) +'|className')
         self.__print_term_tag(out, token) # 'void' | type
         self.__validate(out, varName_token)
         self.__validate(out, Token(JackTokenizer.SYMBOL,'(',1,1), True)
         self.CompileParameterList(out)
         self.__validate(out, Token(JackTokenizer.SYMBOL,')',1,1), True)
         self.CompileSubroutineBody(out)
         self.__print_nonterm_tag(out, 'subroutineDec', True) # </subroutineDec>
         token = self.__tokenizer.peek()
 def CompileClassVarDec(self, out):
     'compile classVarDec'
     token = self.__tokenizer.peek()
     while token.value in CLASSVARTYPE:
         self.__print_nonterm_tag(out, 'classVarDec') # <classVarDec>
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # 'static' | 'field'
         self.CompileType(out)
         self.__validate(out, varName_token)
         token = self.__tokenizer.peek()
         while token.value == ',':
             _ = self.__tokenizer.next()
             self.__print_term_tag(out, token) # ,
             self.__validate(out, varName_token)
             token = self.__tokenizer.peek()
         self.__validate(out, Token(JackTokenizer.SYMBOL,';',1,1), True)
         self.__print_nonterm_tag(out, 'classVarDec', True) # </classVarDec>
         token = self.__tokenizer.peek()
 def CompileVarDec(self, out):
     'compile varDec'
     token = self.__tokenizer.peek()
     while token.value == 'var':
         self.__print_nonterm_tag(out, 'varDec') # <varDec>
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # 'var'
         self.CompileType(out)
         self.__validate(out, varName_token)
         token = self.__tokenizer.peek()
         while token.value == ',':
             _ = self.__tokenizer.next()
             self.__print_term_tag(out, token) # ,
             self.__validate(out, varName_token)
             token = self.__tokenizer.peek()
         self.__validate(out, Token(JackTokenizer.SYMBOL,';',1,1), True)
         self.__print_nonterm_tag(out, 'varDec', True) # </varDec>
         token = self.__tokenizer.peek()
 def test_classVarDec(self):
     tokens = [
         Token(TOKEN_KEYWORD, 'field'),
         Token(TOKEN_KEYWORD, 'int'),
         Token(TOKEN_IDENTIFIER, 'x'),
         Token(TOKEN_SYMBOL, ','),
         Token(TOKEN_IDENTIFIER, 'y'),
         Token(TOKEN_SYMBOL, ';')
     ]
     compiler = CompilationEngine(None)
     compiler.tokens = tokens
     self.assertTrue(compiler.isClassVarDec(0, len(tokens) - 1))
     node = compiler.compileClassVarDec(0, len(tokens) - 1)
     self.assertEqual(len(node.children), 6)
 def CompileIfStatement(self, out):
     'compile ifStatement'
     self.__print_nonterm_tag(out, 'ifStatement') # <ifStatement>
     self.__validate(out, Token(JackTokenizer.KEYWORD,'if',1,1), True)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'(',1,1), True)
     self.CompileExpression(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,')',1,1), True)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'{',1,1), True)
     self.CompileStatements(out)
     self.__validate(out, Token(JackTokenizer.SYMBOL,'}',1,1), True)
     token = self.__tokenizer.peek()
     if token.value == 'else':
         _ = self.__tokenizer.next()
         self.__print_term_tag(out, token) # 'else'
         self.__validate(out, Token(JackTokenizer.SYMBOL,'{',1,1), True)
         self.CompileStatements(out)
         self.__validate(out, Token(JackTokenizer.SYMBOL,'}',1,1), True)
     self.__print_nonterm_tag(out, 'ifStatement', True) # </ifStatement>
**omitted
'''

import collections
from xml.sax.saxutils import escape
from JackTokenizer import JackTokenizer, Token

TABSIZE = 2
CLASSVARTYPE = ('static', 'field')
TYPE_ = ('int', 'char', 'boolean')
SUBROUTINETYPE = ('constructor', 'function', 'method')
STATEMENT = ('let', 'if', 'while', 'do', 'return')
OPERATOR = ('+', '-', '*', '/', '&', '|', '<', '>', '=')
KEYWORDCONST = ('true', 'false', 'null', 'this')
UNARYOP = ('-', '~')
varName_token = Token(JackTokenizer.IDENTIFIER,'varName',1,1)

class CompilationEngine(object):
    '''write tokens into file, only check the basic flow'''

    def __init__(self):
        self.__tokenizer = None
        self.__indent = 0

    def compile(self, tokenizer, outfile):
        'complie the source file'
        self.__tokenizer = tokenizer
        self.compileClass(outfile)

    def compileClass(self, out):
        'compile class'
Exemple #16
0
 def test_load_xml(self):
     string = '<integerConstant>30</integerConstant>'
     token = Token.load_xml(string)
     self.assertEqual(token.to_xml(), string)