示例#1
0
        //
        // letStatement: 'let' varName ('[' expression ']')? '=' expression ';'
        public void CompileLetStatement(int depth)
        {
            bool isLeftArray = false;

            // compile: 'let'
            var letToken = Eat("let");

            // compile: varName
            var varNameToken = EatIdentifier();
            var sbVarName    = SymbolTableManager.Find(varNameToken.Value);

            // compile: ('[' expression ']')?
            if (_tokenizer.CurrentToken.Value == "[")
            {
                isLeftArray = true;
                // compile: '['
                var leftBracketToken = Eat("[");

                // compile: expression
                CompileExpression(depth + 1, AssignmentType.LEFT);

                // write array
                _vmWriter.WritePush(sbVarName.KindDisplay, sbVarName.Number);
                _vmWriter.WriteOp(new Token {
                    Value = "+"
                });

                // compile: ']'
                var rightBracketToken = Eat("]");
            }

            // compile: '='
            var assignmentToken = Eat("=");

            // compile: expression
            CompileExpression(depth + 1, AssignmentType.RIGHT);

            // pop varAssigned
            if (isLeftArray)
            {
                _vmWriter.WritePop("temp", 0);
                _vmWriter.WritePop("pointer", 1);
                _vmWriter.WritePush("temp", 0);
                _vmWriter.WritePop("that", 0);
            }
            else
            {
                _vmWriter.WritePop(sbVarName.KindDisplay, sbVarName.Number);
            }

            // compile: ';'
            var semiColonToken = Eat(";");
        }
示例#2
0
        public void WriteExpr(CompilationUnit compUnit)
        {
            var compUnits = compUnit.CompUnits;

            if (compUnits.Count == 1)
            {
                Token token = compUnits[0];
                if (token.TokenType == TokenType.INT_CONST)
                {
                    _vmWriter.WritePush("constant", Convert.ToInt32(token.Value));
                }
                else if (token.TokenType == TokenType.IDENTIFIER)
                {
                    var sbUnit = SymbolTableManager.Find(token.Value);
                    _vmWriter.WritePush(sbUnit.Kind.ToString(), sbUnit.Number);
                }
            }
        }
示例#3
0
        //
        // subroutineCall: subroutineName '(' expressionList ')' | (className | varName) '.' subroutineName '(' expressionList '}'
        public void CompileSubroutineCall(int depth)
        {
            int    args      = 0;
            int    argadder  = 0;
            string sbSubName = string.Empty;
            var    nextToken = _tokenizer.Peek();

            // compile: subroutineName '(' expressionList ')'
            if (nextToken.Value == "(")
            {
                argadder = 1;
                // compile: subroutineName
                var subName = EatIdentifier();
                sbSubName = className + "." + subName.Value;

                // handle: push 'this' to stack -> push pointer 0
                _vmWriter.WritePush("pointer", 0);

                // compile: '('
                var leftParenToken = Eat("(");

                // compile: expressionList
                args = CompileExpressionList(depth) + argadder;

                // compile: ')'
                var rightParenToken = Eat(")");
            }
            else if (nextToken.Value == ".")
            {
                // compile: (className | varName)
                var nameToken = EatIdentifier();
                var sbClass   = SymbolTableManager.Find(nameToken.Value);
                if (sbClass == null)
                {   // handle: class.function(...)
                    sbSubName = nameToken.Value;
                }
                else
                {   // handle: obj.method(...)
                    argadder  = 1;
                    sbSubName = sbClass.Type;
                    var sbObj = SymbolTableManager.Find(nameToken.Value);
                    _vmWriter.WritePush(sbObj.KindDisplay, sbObj.Number);
                }

                // compile '.'
                var dotToken = Eat(".");
                sbSubName += dotToken.Value;

                // compile: subroutineName
                var subNameToken = EatIdentifier();
                sbSubName += subNameToken.Value;

                // compile: '('
                var leftParenToken = Eat("(");

                // compile: expression
                args = CompileExpressionList(depth) + argadder;

                // compile: ')'
                var rightParenToken = Eat(")");
            }

            // write call
            _vmWriter.WriteCall(sbSubName, args);
        }
示例#4
0
        //
        // term : integerConstant | stringConstant | keywordConstant | unaryOp term | '(' expression ')' | varName | varName '[' expression ']' | subroutineCall
        public void CompileTerm(int depth, AssignmentType assignType)
        {
            // compile: integerConstant
            if (_tokenizer.CurrentToken.TokenType == TokenType.INT_CONST)
            {
                _vmWriter.WritePush("constant", Convert.ToInt32(_tokenizer.CurrentToken.Value));
                _tokenizer.Advance();
            }
            // compile: stringConstant
            else if (_tokenizer.CurrentToken.TokenType == TokenType.STRING_CONST)
            {
                int strLen = _tokenizer.CurrentToken.Value.Length;
                _vmWriter.WritePush("constant", strLen);
                _vmWriter.WriteCall("String.new", 1);
                foreach (char strChar in _tokenizer.CurrentToken.Value)
                {
                    _vmWriter.WritePush("constant", (int)strChar);
                    _vmWriter.WriteCall("String.appendChar", 2);
                }
                _tokenizer.Advance();
            }
            // compile: keywordConstant
            else if (_tokenizer.CurrentToken.GetKeywordType() == Types.KeywordType.TRUE ||
                     _tokenizer.CurrentToken.GetKeywordType() == Types.KeywordType.FALSE ||
                     _tokenizer.CurrentToken.GetKeywordType() == Types.KeywordType.NULL ||
                     _tokenizer.CurrentToken.GetKeywordType() == Types.KeywordType.THIS)
            {
                if (_tokenizer.CurrentToken.GetKeywordType() == KeywordType.TRUE)
                {
                    _vmWriter.WritePush("constant", 0);
                    _vmWriter.WriteUnaryOp(new Token {
                        Value = "~"
                    });
                }
                if (_tokenizer.CurrentToken.GetKeywordType() == KeywordType.FALSE)
                {
                    _vmWriter.WritePush("constant", 0);
                }
                if (_tokenizer.CurrentToken.GetKeywordType() == KeywordType.THIS)
                {
                    _vmWriter.WritePush("pointer", 0);
                }
                if (_tokenizer.CurrentToken.GetKeywordType() == KeywordType.NULL)
                {
                    _vmWriter.WritePush("constant", 0);
                }
                _tokenizer.Advance();
            }
            // compile: unaryOp term
            else if (_tokenizer.CurrentToken.Value == "~" || _tokenizer.CurrentToken.Value == "-")
            {
                // compile: unaryOp
                var unaryOpToken = _tokenizer.CurrentToken;
                _tokenizer.Advance();

                // compile: term
                CompileTerm(depth + 1, assignType);

                // write op
                _vmWriter.WriteUnaryOp(unaryOpToken);
            }
            // compile: '(' expression ')'
            else if (_tokenizer.CurrentToken.Value == "(")
            {
                // compile '('
                var leftParenToken = Eat("(");

                // compile: expression
                CompileExpression(depth + 1, assignType);

                // compile: ')'
                var rightParenToken = Eat(")");
            }
            // compile: varName | varName '[' expression ']' | subroutineCall '(' expression ')'
            else if (_tokenizer.CurrentToken.TokenType == TokenType.IDENTIFIER)
            {
                var nextToken = _tokenizer.Peek();
                var sbVarName = SymbolTableManager.Find(_tokenizer.CurrentToken.Value);

                // compile: varName '[' expression ']'
                if (nextToken.Value == "[")
                {
                    // compile: varName
                    var varNameToken = EatIdentifier();

                    // compile: '['
                    var leftBracketToken = Eat("[");

                    // compile: expression
                    CompileExpression(depth + 1, assignType);
                    _vmWriter.WritePush(sbVarName.KindDisplay, sbVarName.Number);

                    _vmWriter.WriteOp(new Token {
                        Value = "+"
                    });
                    // add offset
                    _vmWriter.WritePop("pointer", 1);
                    _vmWriter.WritePush("that", 0);


                    // compile: ']'
                    var rightBracketToken = Eat("]");
                }
                // compile: subroutineCall
                else if (nextToken.Value == "(" || nextToken.Value == ".")
                {
                    CompileSubroutineCall(depth + 1);
                }
                // compile: varName
                else
                {
                    var varNameToken = EatIdentifier();
                    _vmWriter.WritePush(sbVarName.KindDisplay, sbVarName.Number);
                }
            }
        }