class JackEngine():

    def __init__(self, tokens, outputFilePath, debugFlag):


        # Variables assigned from arguments
        self.tokenStream = deque(tokens)
        self.tokensForLookBack = deque(tokens)
        self.outputFilePath = outputFilePath

        # Check whether to print out each token as it's parsed
        if debugFlag == "0":
            self.debugMode = False
        else:
            self.debugMode = True

        # Variables relating to parsing tokens
        self.callingFunctionIsLet = False
        self.currentToken = ""
        self.symbolTable = SymbolTable.SymbolTable()
        self.identifier = Identifier(self.symbolTable)

        self.classVarDec = ["static", "field"]

        self.subroutineDec = ["constructor", "function", "method"]
        self.statements = ["let", "if", "else", "while", "do", "return"]
        self.callStatement = {
            "let" : self.compileLet,
            "if" : self.compileIf,
            "else" : self.compileWhile,
            "while" : self.compileWhile,
            "do" : self.compileDo,
            "return" : self.compileReturn
        }

        # Variables that hold the current xml element for a often used element
        self.doElement = None
        self.classVarDecElement = None
        self.elseElement = None
        self.expressionElement = None
        self.expressionElements = []
        self.ifElement = None
        self.letElement = None
        self.parameterListDecElement = None
        self.parentElement = None
        self.parentOfParentElement = None
        self.parentStatementsToIfOrWhile = None
        self.returnElement = None
        self.subroutineBodyElement = None
        self.subroutineDecElement = None
        self.statementsElement = None
        self.varDecElement = None
        self.whileElement = None

        # XML structure root
        self.root = ET.Element("class")

        # Used to keep track of values that are accessed in differently scoped functions
        self.current = Current()

        # Variables for turning xml structure into VM code
        self.VMWriter = VMWriter.VMWriter(outputFilePath)

    def advanceToken(self):
        if self.tokenStream:
            self.currentToken = self.tokenStream.popleft()
            if self.debugMode:
                self.debug("currentToken: ")
            return
        else:
            print "hit last token"

    def addCurrentTokenAsChildElement(self, parentElement):
        childTokenElement, childTokenValue = self.currentToken.items()[0]

        child = ET.SubElement(parentElement, childTokenElement)
        child.text = childTokenValue

        if childTokenElement == IDENTIFIER:
                self.compileIdentifier(child, parentElement)

        return

    def compileIdentifier(self, child, parent):

        # Determine if identifier is being declared or used
        self.identifier.identify(child, parent)
        beingDefined = child.get("beingDefined")
        identifierCategory = child.get("category")

       # print child.text + SPACE + beingDefined

        if beingDefined == "yes":
            self.addIdentifierToSymbolTable(child, identifierCategory)
            self.getIdentifierFromSymbolTable(child)

        else:
            self.compileIdentifierUse(child, parent, identifierCategory)

        return

    def compileIdentifierUse(self, child, parent, identifierCategory):

        if identifierCategory == SymbolTable.CLASS:
            return

        # If identifier is part of a do statement, it's a subroutine name
        elif parent.tag == "doStatement":
            self.identifier.setAttribute(child, "category", "subroutine")

        # If an identifier is part of a let statement, it can be a subroutine or a variable
        elif parent.tag == "letStatement":

            # If it's a variable, then it will be declared already, so try to find it
            kind = self.symbolTable.kindOf(child.text)

            # Check the class, too
            if kind == None:

                self.setClassAsCurrentScope()
                kind = self.symbolTable.kindOf(child.text)
                self.setMethodAsCurrentScope()

                if kind == None:
                    self.identifier.setAttribute(child, "category", "subroutine")

                else:
                    self.getIdentifierFromSymbolTable(child)

            else:
                self.getIdentifierFromSymbolTable(child)

        # Else, it's a subroutine
        else:
            self.getIdentifierFromSymbolTable(child)

        return

    def addIdentifierToSymbolTable(self, child, identifierCategory):

        # Then add identifier to symbol table
        if identifierCategory == SymbolTable.CLASS:
            self.symbolTable.startClass(child.text)

        elif identifierCategory == SymbolTable.SUB_ROUT_DEC:
            #print self.currentTokenValue()
            self.symbolTable.startSubroutine()

        elif identifierCategory in SymbolTable.VARS:
            self.symbolTable.define(child.text, child.get("type"), child.get("category"))

        return

    def getIdentifierFromSymbolTable(self, child):

        '''

        :param child: xml element (of identifier)
        :return: void

        Appends attributes the xml element representing the identifier by looking up the identifier in the symbol table
        '''

        attributes = self.identifier.getAttributes(child.text)
        self.identifier.setAttributes(child, attributes)

        return

    def isLastToken(self):
        if len(self.tokenStream) >= 1:
            return False
        return True

    def setClassAsCurrentScope(self):
        self.symbolTable.currentScopeIndex = self.symbolTable.classScopeIndex

    def setMethodAsCurrentScope(self):
        self.symbolTable.currentScopeIndex = self.symbolTable.methodScopeIndex

    def compile(self):

        self.compileClass()

        # Return parsed XML tree
        self.indentXML()
        #return self.root
        return

    def compileClass(self):
        '''
        Compiles a complete class
        '''

        self.advanceToken()

        if self.currentTokenValue() in self.classVarDec:

            # Current token is the first element of the new sub-element
            self.classVarDecElement = ET.SubElement(self.root, "classVarDec")
            self.addCurrentTokenAsChildElement(parentElement = self.classVarDecElement)

            self.compileClassVarDec()
            self.compileClass()

        elif self.currentTokenValue() in self.subroutineDec:

            # Current token is the first element of the new sub-element
            self.subroutineDecElement = ET.SubElement(self.root, "subroutineDec")
            self.addCurrentTokenAsChildElement(parentElement = self.subroutineDecElement)
            self.compileSubroutine()

            self.compileClass()

        # We're done
        elif self.currentTokenValue() == RIGHT_BRACE:

            self.addCurrentTokenAsChildElement(parentElement = self.root)
            return

        else:

            self.addCurrentTokenAsChildElement(parentElement = self.root)
            self.compileClass()

    def compileClassVarDec(self):
        '''
        Compiles a static declaration or a field declaration
        '''

        self.advanceToken()

        while self.currentTokenValue() is not SEMI_COLON:
            self.addCurrentTokenAsChildElement(parentElement = self.classVarDecElement)
            if self.currentTokenKey() == IDENTIFIER:
                self.current.numClassVars += 1

            self.advanceToken()

        return

    def compileSubroutine(self):
        '''
        Compiles a complete method, function, or constructor.  Starts on function owner
        '''

        self.current.subroutineType = self.currentTokenValue() # constructor, function or method

        # Append type
        self.advanceToken()
        self.addCurrentTokenAsChildElement(parentElement = self.subroutineDecElement)

        # Append name
        self.advanceToken()
        self.current.subroutineName = self.currentTokenValue()
        self.addCurrentTokenAsChildElement(parentElement = self.subroutineDecElement)

        # If it's a method call, this is argument 0
        if self.current.subroutineType == METHOD:
            self.symbolTable.kindCounter["arg"] += 1

        # Append param list symbol
        self.advanceToken()
        self.addCurrentTokenAsChildElement(parentElement = self.subroutineDecElement)

        # Compile the parameter list
        self.parameterListDecElement = ET.SubElement(self.subroutineDecElement, "parameterList")
        self.compileParameterList()

        # Append closing param list symbol
        self.addCurrentTokenAsChildElement(parentElement = self.subroutineDecElement)

        self.subroutineBodyElement = ET.SubElement(self.subroutineDecElement, "subroutineBody")
        self.compileSubroutineBody()

        # Reset if/while statement count
        self.VMWriter.resetStatementCount()
        return

    def compileParameterList(self):
        '''
        Compiles a (possibly empty) parameter list
        '''
        self.advanceToken()

        # If the parameter list is empty or we're done compiling it
        if self.currentTokenValue() == RIGHT_PARENTHESIS:
            return

        # Else
        self.addCurrentTokenAsChildElement(parentElement = self.parameterListDecElement)
        self.compileParameterList()

        return

    def compileSubroutineBody(self):
        '''
        Compiles either a varDec or statements
        '''

        self.advanceToken()

        # If beginning of body
        if self.currentTokenValue() == LEFT_BRACE:

            self.addCurrentTokenAsChildElement(parentElement = self.subroutineBodyElement)
            self.compileSubroutineBody()

        # If end of body
        elif self.currentTokenValue() == RIGHT_BRACE or self.currentTokenValue() == RIGHT_BRACE_WITH_SPACE:
            self.addCurrentTokenAsChildElement(parentElement = self.subroutineBodyElement)

            # Return to compile SR, which will return to compile class.
            return

        # If var dec
        elif self.currentTokenValue() == "var":

            self.varDecElement = ET.SubElement(self.subroutineBodyElement, "varDec")
            self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)
            self.compileVarDec()
            self.compileSubroutineBody()

        # If statement
        elif self.currentTokenValue() in self.statements:

            # Because we're into the subroutine's statements, all vars have been declared, so write subroutine dec
            self.VMWriter.writeFunction(name = self.current.subroutineName, nLocals = self.current.numLocals)

            # If we are constructing an object, we need to allocate space for it
            if self.current.subroutineType == CONSTRUCTOR:

                self.VMWriter.writePush(CONST, self.current.numClassVars)
                self.VMWriter.writeCall("Memory.alloc", 1)

                # Take the value returned from alloc and put it in "this"
                self.VMWriter.writePop(POINTER, 0)

            if self.current.subroutineType == METHOD:

                # Set the value of this
                self.VMWriter.writePush(ARG, 0)
                self.VMWriter.writePop(POINTER, 0)

            # Reset the subroutine dec info
            self.current.numClassVars = 0
            self.current.numLocals = 0
            self.current.subroutineName = ""
            self.current.subroutineType = ""

            self.statementsElement = ET.SubElement(self.subroutineBodyElement, "statements")
            self.parentElement = self.subroutineBodyElement
            self.compileStatements()
            self.addCurrentTokenAsChildElement(parentElement = self.subroutineBodyElement)

            # Return to subroutine dec
            return

        else:
            return

    def compileVarDec(self):
        '''
        Compiles a var declaration
        '''

        # Advance past var keyword
        self.advanceToken()

        # Compile type
        self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)
        self.advanceToken()

        # Compile name
        self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)
        self.current.numLocals += 1
        self.advanceToken()

        while self.currentTokenValue() == COMMA:

            # Compile the comma
            self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)
            self.advanceToken()

            # Compile the name
            self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)

            # Increment num locals for this subroutine
            self.current.numLocals += 1
            self.advanceToken()

        # Append the closing semi-colon
        self.addCurrentTokenAsChildElement(parentElement = self.varDecElement)

        return

    def compileStatements(self, parentStatement = None):
        '''
        Compiles a sequence of statements, not including the enclosing {}
        '''

        # If no more statements
        if self.currentTokenValue() == RIGHT_BRACE or self.currentTokenValue() == RIGHT_BRACE_WITH_SPACE:
            return

        else:

            # Call statement
            self.callStatement[self.currentTokenValue()]()
            self.compileStatements()

    def resetDoElements(self):

        self.current.numExpressions = 0
        self.current.subroutineName = ""

    def isVar(self, tokenValue):
        '''

        :return: bool

        Returns whether the current token is a method.  Determined by checking if current token is a variable.
        In the context of a do statement (which calls this func), a variable beginning the do statement means the subR call is a method call
        '''

        if self.symbolTable.kindOf(tokenValue) == None:
            return False
        return True

    def compileDo(self):
        '''
        Compiles a do statement:  -- do subroutineCall --
        '''

        # Initially set to false, reset to false at end
        methodCall = False
        self.current.numExpressions = 0

        # Compile do keyword (do)
        self.doElement = ET.SubElement(self.statementsElement, "doStatement")
        self.addCurrentTokenAsChildElement(parentElement = self.doElement)
        self.advanceToken()

        # 3 cases: (1) do method() (2) do var.method() (3) do class.function()
        tokenIsVar = self.isVar(self.currentTokenValue())

        # Case: do var.method()
        if tokenIsVar:

            # Subroutine to call will be the varType, not it's name (because it's a method)
            varName = self.currentTokenValue()
            varAttributes = self.identifier.getAttributes(varName)
            self.current.subroutineName = varAttributes["type"]

            # Append dot and subR name to var name
            self.advanceToken()
            while self.currentTokenValue() is not LEFT_PARENTHESIS:
                self.addCurrentTokenAsChildElement(parentElement = self.doElement)
                self.current.subroutineName = self.current.subroutineName + self.currentTokenValue()
                self.advanceToken()

        else:

            tokenValue = self.currentTokenValue()
            self.advanceToken()

            # Case: do method()
            if self.currentTokenValue() == LEFT_PARENTHESIS:

                self.addCurrentTokenAsChildElement(parentElement = self.doElement)
                self.current.subroutineName = self.VMWriter.className + DOT + tokenValue
                methodCall = True

                # Don't advance token, so that compiling the EL starts on left paren

            # Case: do class.function()
            else:

                self.current.subroutineName = tokenValue
                while self.currentTokenValue() is not LEFT_PARENTHESIS:
                    self.addCurrentTokenAsChildElement(parentElement = self.doElement)
                    self.current.subroutineName = self.current.subroutineName + self.currentTokenValue()
                    self.advanceToken()

        # Compile the expression list: (expression,*)
        self.addCurrentTokenAsChildElement(parentElement = self.doElement)
        self.advanceToken()

        # Set do element as parent to the expression list
        self.parentElement = self.doElement

        if tokenIsVar:

            # Set the base
            self.VMWriter.writePush(varAttributes["kind"], varAttributes["index"])

            # Method calls operate on k + 1 args
            self.current.numExpressions += 1

        # Method calls operate on k + 1 args
        if methodCall:

            # Push value of this for function being called
            self.VMWriter.writePush(POINTER, 0)
            self.current.numExpressions += 1

        # Save number of expressions compiled for VM code
        self.current.numExpressions = self.current.numExpressions + self.compileExpressionList()

        # Append closing paren to do element
        self.addCurrentTokenAsChildElement(parentElement = self.doElement)
        #print "closing paren: " + self.currentTokenValue()
        self.advanceToken()

        # Compile the semi-colon
        self.addCurrentTokenAsChildElement(parentElement = self.doElement)

        # Write the call
        self.VMWriter.writeCall(self.current.subroutineName, self.current.numExpressions)

        # Pop the return value
        self.VMWriter.writePop(TEMP, 0)

        # Advance to start of next non-terminal
        self.advanceToken()
        self.current.numExpressions = 0
        return

    def compileLet(self):
        '''
        Compiles a let statement
        '''

        compilingArray = False

        # Compile let keyword
        self.letElement = ET.SubElement(self.statementsElement, "letStatement")
        self.addCurrentTokenAsChildElement(parentElement = self.letElement)
        self.advanceToken()

        # Compile varName for use later in function
        varName = self.currentTokenValue()
        kind = self.symbolTable.kindOf(varName)
        index = self.symbolTable.indexOf(varName)

        self.addCurrentTokenAsChildElement(parentElement = self.letElement)
        self.advanceToken()

        # Next token is either the beginning of an expression (index into an array) or an equal sign.
        # If expression, compile it and advance to the equal sign following it.
        if self.currentTokenValue() == BRACKET_EXPRESSION:

            compilingArray = True

            # Compile opening bracket
            self.addCurrentTokenAsChildElement(parentElement = self.letElement)
            self.advanceToken()

            # Compile expression
            self.parentElement = self.letElement
            self.compileExpression()

            # Push var onto the stack
            self.VMWriter.writePush(kind, index)

            # Add the result of the expression to the base of the variable
            self.VMWriter.writeArithmetic(ADD, BINARY)

            # Compile closing bracket
            self.addCurrentTokenAsChildElement(parentElement = self.letElement)
            self.advanceToken()

            # If nested brackets
            if self.currentTokenValue() == "]":
                self.advanceToken() # Compiled expression doesn't know about closing brace

        # Compile the equal sign and advance
        self.addCurrentTokenAsChildElement(parentElement = self.letElement)
        self.advanceToken()

        # Compile expression
        self.parentElement = self.letElement
        self.compileExpression() # Expression will be pushed to top of stack


        if compilingArray:

            # Pop the result of the expression into temp
            self.VMWriter.writePop(TEMP, 0)

            # Pop the address of the array into that
            self.VMWriter.writePop(POINTER, 1)

            # Push the expression result in temp onto the stack
            self.VMWriter.writePush(TEMP, 0)

            # Store the result in address that is pointing to
            self.VMWriter.writePop(THAT, 0)

        else:
            # Pop result of the expression into LHS of let statement
            self.VMWriter.writePop(kind, index)

        # Next token is either a semi-colon, right bracket or a right paren.
        # If right bracket or paren, we need an extra advance
        if self.currentTokenValue() in EXPRESSION_ENDER:

            self.addCurrentTokenAsChildElement(parentElement = self.letElement)
            self.advanceToken()

        # Compile semi-colon and advance out of the let statement
        self.addCurrentTokenAsChildElement(parentElement = self.letElement)
        self.advanceToken()
        return

    def compileWhile(self):
        '''
        Compiles a while statement
        '''

        # Append while element
        self.whileElement = ET.SubElement(self.statementsElement, "whileStatement")


        # Determine what number while statement this is (in the current subroutine)
        self.VMWriter.statementCount[WHILE] += 1
        parentWhileNumber = str(self.VMWriter.statementCount[WHILE])

        # Save value of parent statement element and value of while element (for the case where a while statement has while statements as statements)
        parentWhile = self.whileElement
        parentToWhile = self.statementsElement

        # Append while keyword
        self.addCurrentTokenAsChildElement(parentElement = self.whileElement)

        self.VMWriter.writeLabel(WHILE, EXP, parentWhileNumber)

        # Advance and append the left paren that marks the beginning of an expression
        self.advanceToken()
        self.addCurrentTokenAsChildElement(parentElement = self.whileElement)

        # Compile the expression, which will advance token(s)
        self.advanceToken()
        self.parentElement = self.whileElement
        self.compileExpression()

        # Not the result of the expression
        self.VMWriter.writeArithmetic(NOT, UNARY)

        # With the computed expression on the top of the stack, test if-goto
        self.VMWriter.writeIf(WHILE + "_" + END + parentWhileNumber)

        # Append the right paren that marks the end of the expression
        self.addCurrentTokenAsChildElement(parentElement = self.whileElement)

        # Advance to the left brace and append it
        self.advanceToken()
        self.addCurrentTokenAsChildElement(parentElement = self.whileElement)

        # Advance to the first keyword of the first statement
        self.advanceToken()
        self.statementsElement = ET.SubElement(self.whileElement, "statements")
        self.compileStatements()

        # After writing statements, go to the beginning of while statement (and then test the expression again)
        self.VMWriter.writeGoto(WHILE + "_" + EXP + parentWhileNumber)

        # Add closing brace
        self.addCurrentTokenAsChildElement(parentElement = parentWhile)
        self.advanceToken()

        # Label denoting end of while statement
        self.VMWriter.writeLabel(WHILE, END, parentWhileNumber)

        # Reset the statement element
        self.statementsElement = parentToWhile

        return

    def compileReturn(self):
        '''

        :return:
        Compile a return statement.  Two cases: return; | return expression;
        '''

        # Append return keyword
        self.returnElement = ET.SubElement(self.statementsElement, "returnStatement")
        self.addCurrentTokenAsChildElement(parentElement = self.returnElement)
        self.advanceToken()

        # Case: return;
        if self.currentTokenValue() == SEMI_COLON:

            self.addCurrentTokenAsChildElement(parentElement = self.returnElement)
            self.parentElement = self.returnElement
            self.advanceToken()

            self.VMWriter.writePush(CONST, 0)
            self.VMWriter.writeReturn()

            return

        # Case: return expression
        else:

            self.parentElement = self.returnElement
            self.compileExpression()

            # Append semi-colon and prepare for next statement (or end of statements)
            self.addCurrentTokenAsChildElement(parentElement = self.returnElement)
            self.advanceToken()

            self.VMWriter.writeReturn()

            return

    def compileIf(self):
        '''
        Compiles an if statement, possibly with a trailing else clause
        '''

        # Append if keyword
        self.ifElement = ET.SubElement(self.statementsElement, "ifStatement")

        # Determine what number if statement this is (in the current subroutine)
        self.VMWriter.statementCount[IF] += 1
        parentIfCount = str(self.VMWriter.statementCount[IF])

        # Save value of parent statement element and value of if element (for the case where a if statement has if statements as statements)
        parentIF = self.ifElement
        parentToIf = self.statementsElement

        self.addCurrentTokenAsChildElement(parentElement = self.ifElement)
        self.advanceToken()

        # Append paren as if symbol, then compile the expression
        self.addCurrentTokenAsChildElement(parentElement = self.ifElement)
        self.parentElement = self.ifElement
        self.advanceToken()
        self.compileExpression()

        # Not the result of the expression
        self.VMWriter.writeArithmetic(NOT, UNARY)

        # Determine which label to jump to
        self.VMWriter.writeIf(IF + "_" + FALSE + parentIfCount)
        self.VMWriter.writeGoto(IF + "_" + TRUE + parentIfCount)

        # Append closing paren
        self.addCurrentTokenAsChildElement(parentElement = self.ifElement)

        # Append opening brace as if symbol
        self.advanceToken()
        self.addCurrentTokenAsChildElement(parentElement = self.ifElement)

        # Write TRUE label
        self.VMWriter.writeLabel(IF, TRUE, parentIfCount)

        # Compile statements after if expression
        self.advanceToken()
        self.statementsElement = ET.SubElement(self.ifElement, "statements")
        self.compileStatements()

        self.VMWriter.writeGoto(IF + "_" + END + parentIfCount)
        # If expression was true, statements executed.  Now, jump to end of if statement
        #self.VMWriter.writeGoto(IF + "_" + FALSE + parentIfCount)

        self.statementsElement = parentToIf

        # Add closing brace to if
        self.addCurrentTokenAsChildElement(parentElement = parentIF)

        self.VMWriter.writeLabel(IF, FALSE, parentIfCount)

        # Check for a trailing else
        self.advanceToken()
        if self.currentTokenValue() == "else":

            self.addCurrentTokenAsChildElement(parentElement = parentIF)

            # Append the opening else brace to xml structure
            self.advanceToken()
            self.addCurrentTokenAsChildElement(parentElement = parentIF)

            # Compile statements in the else block
            self.advanceToken()
            self.compileStatements()

            # Append closing else brace
            self.addCurrentTokenAsChildElement(parentElement = parentIF)
            self.advanceToken()

        self.VMWriter.writeLabel(IF, END, parentIfCount)

        return

    def compileExpression(self):
        '''
        Compiles an expression.
        '''

        self.expressionElement = ET.SubElement(self.parentElement, "expression")
        self.parentElement = self.expressionElement

        # Compile the first term
        self.compileTerm()

        # Compile the op and second term
        while self.currentTokenValue() in OPS:
            operator = self.currentTokenValue()
            self.advanceToken()
            self.compileTerm()
            self.compileOp(operator)

        return

    def compileOp(self, operator):

        # XML tree
        child = ET.SubElement(self.parentElement, "symbol")
        child.text = operator

        self.VMWriter.writeArithmetic(operator, BINARY)

        return

    def compileTerm(self):
        '''
        Compiles a term.  This routine is faced with slight difficulty when trying to decide between alternate parsing roles
        If current token is an identifier, the routine must distinguish between a variable, an array entry, and a subroutine call.
        A single look ahead token, may may be one of "[", "(" or "." suffices to distinguish between the three possibilities
        Any other token is not part of this term and should not be advanced over.
        '''

        self.termElement = ET.SubElement(self.parentElement, "term")
        self.parentElement = self.termElement

        # If term is a unary op
        if self.currentTokenValue() in UNARY_OPS:

            # Add unary op to tree
            self.addCurrentTokenAsChildElement(self.parentElement)
            operator = self.currentTokenValue()

            # Compile the term the op applies to
            self.advanceToken()
            self.compileTerm()

            # Write vm code
            self.VMWriter.writeArithmetic(operator, UNARY)
            return

        # If term is an expression
        elif self.currentTokenValue() == LEFT_PARENTHESIS:

            # Opening paren goes to term
            self.addCurrentTokenAsChildElement(parentElement = self.termElement)

            # Save hierarchy of the expression
            savedExpressionElement = self.expressionElement
            savedTermElement = self.termElement

            self.advanceToken()
            self.compileExpression()

            # Append closing paren to term
            self.addCurrentTokenAsChildElement(parentElement = savedTermElement)
            self.parentElement = savedExpressionElement
            self.advanceToken()

            return

        else:

            # Append to XML structure
            self.addCurrentTokenAsChildElement(parentElement = self.parentElement)

            # Process look ahead token if identifier
            if self.currentTokenKey() == IDENTIFIER:

                # Lookup identifier in symbolTable
                name = self.currentTokenValue()
                kind = self.symbolTable.kindOf(name)
                index = self.symbolTable.indexOf(name)


                # Look ahead to determine if identifier is beginning of an expression
                self.advanceToken()

                # If subroutine call with a class
                if self.currentTokenValue() == DOT:

                    subroutineArgs = 0
                    subroutineName = name

                    # Check if subroutine call is from a var
                    tokenIsVar = self.isVar(name)
                    if tokenIsVar:

                        # Subroutine name is var's class type
                        varAttributes = self.identifier.getAttributes(name)
                        subroutineName = varAttributes["type"]

                        # Push var as arg 0
                        self.VMWriter.writePush(varAttributes["kind"], varAttributes["index"])
                        subroutineArgs =+ 1

                    # Add dot and advance
                    subroutineName = subroutineName + DOT
                    self.addCurrentTokenAsChildElement(parentElement = self.parentElement)
                    self.advanceToken()

                    # Add subroutine name and advance
                    subroutineName = subroutineName + self.currentTokenValue()
                    self.addCurrentTokenAsChildElement(parentElement = self.parentElement)
                    self.advanceToken()

                    # Add opening paren and advance
                    self.addCurrentTokenAsChildElement(self.termElement)
                    self.advanceToken()

                    savedTermElement = self.termElement
                    self.parentElement = self.termElement

                    # Compile expression list, returning number of expressions compiled (which equals num of args passed in)
                    subroutineArgs = subroutineArgs + self.compileExpressionList()
                    self.addCurrentTokenAsChildElement(parentElement = savedTermElement)

                    # Write subroutine call
                    self.VMWriter.writeCall(subroutineName, subroutineArgs)
                    self.advanceToken()
                    return

                # varName[expression]
                elif self.currentTokenValue() == BRACKET_EXPRESSION:

                    savedTermElement = self.termElement
                    self.addCurrentTokenAsChildElement(parentElement = self.termElement)
                    self.parentElement = self.termElement

                    # Advance to first term in expression and then compile the expression
                    self.advanceToken()
                    self.compileExpression()

                    # Push varName
                    self.VMWriter.writePush(kind, index)

                    # Add the result of the expression to the base of the variable
                    self.VMWriter.writeArithmetic(ADD, BINARY)

                    # Pop sum into "that" pointer
                    self.VMWriter.writePop(POINTER, 1)

                    # Push value of address that is pointing to
                    self.VMWriter.writePush("that", 0)

                    # Append closing bracket
                    self.addCurrentTokenAsChildElement(parentElement = savedTermElement)
                    self.advanceToken()
                    return

                # If a subroutine call
                elif self.currentTokenValue() == LEFT_PARENTHESIS:

                    # Parens symbol goes with the term
                    self.compileExpressionList()
                    return

                # Else, look ahead token is not part of greater identifier, so compile it as separate term or op
                else:

                    if self.currentTokenValue() == "]":
                        self.VMWriter.writePush(kind, index)
                        return

                    else:

                        # Push the token before the look ahead token
                        self.VMWriter.writePush(segment=kind, index=index)
                        self.parentElement = self.expressionElement
                        return

            # If current token is not an identifier or op, then it's a keyword, constant (string or int)
            else:

                if self.currentTokenKey() == KEYWORD:

                    keyword = self.currentTokenValue()
                    self.VMWriter.writeKeywordConstant(keyword)
                    self.advanceToken()

                elif self.currentTokenKey() == STRING:

                    # Create new string
                    string = self.currentTokenValue()
                    stringLen = len(string)
                    self.VMWriter.writePush(CONST, stringLen)
                    self.VMWriter.writeCall("String.new", 1)

                    # Append each character to string
                    for char in string:
                        self.VMWriter.writePush(CONST, ord(char))
                        self.VMWriter.writeCall("String.appendChar", 2)

                    self.advanceToken()

                # Otherwise, it's an int
                else:

                    self.VMWriter.writePush(CONST, self.currentTokenValue())
                    self.advanceToken()

            return

    def compileExpressionList(self):
        '''
        Compiles a (possibly empty) comma-separated list of expressions
        '''
        numExpressions = 0

        self.expressionListElement = ET.SubElement(self.parentElement, "expressionList")
        self.parentElement = self.expressionListElement


        # Return if expression list is empty
        if self.currentTokenValue() == RIGHT_PARENTHESIS:
            return numExpressions

        else:

            numExpressions += 1
            self.compileExpression()

            while self.currentTokenValue() == COMMA:

                numExpressions += 1

                self.addCurrentTokenAsChildElement(parentElement = self.expressionListElement)
                self.advanceToken()

                # Reset expression list as the parent element
                self.parentElement = self.expressionListElement
                self.compileExpression()


            return numExpressions

    def currentTokenKey(self):
        return self.currentToken.keys()[0]

    def currentTokenValue(self):
        return self.currentToken.values()[0]

    def debug(self, optionalString=""):
        print optionalString + self.currentTokenValue() + " " + self.outputFilePath

    def indent(self, elem, level=0):
        i = "\n" + level*"  "
        if len(elem):
            if not elem.text or not elem.text.strip():
                elem.text = i + "  "
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
            for elem in elem:
                self.indent(elem, level+1)
            if not elem.tail or not elem.tail.strip():
                elem.tail = i
        else:
            if level and (not elem.tail or not elem.tail.strip()):
                elem.tail = i

    def indentXML(self):
        self.indent(self.root)
        return