Exemple #1
0
        private bool ParseLiteralValue(ref ASTNode retn)
        {
            tokenStream.Save();

            // todo if we support bitwise not, add it here
            if (tokenStream.Current == ExpressionTokenType.Not && tokenStream.Next == ExpressionTokenType.Boolean)
            {
                bool value = bool.Parse(tokenStream.Next.value);
                retn = ASTNode.BooleanLiteralNode((!value).ToString()).WithLocation(tokenStream.Current);
                tokenStream.Advance(2);
                return(true);
            }

            if (tokenStream.Current == ExpressionTokenType.Minus && tokenStream.Next == ExpressionTokenType.Number && (tokenStream.Previous.IsOperator || !tokenStream.HasPrevious))
            {
                retn = ASTNode.NumericLiteralNode("-" + tokenStream.Next.value).WithLocation(tokenStream.Current);
                tokenStream.Advance(2);
                return(true);
            }

            if (tokenStream.Current == ExpressionTokenType.Plus && tokenStream.Next == ExpressionTokenType.Number && (tokenStream.Previous.IsOperator || !tokenStream.HasPrevious))
            {
                retn = ASTNode.NumericLiteralNode(tokenStream.Next.value).WithLocation(tokenStream.Current);
                tokenStream.Advance(2);
                return(true);
            }

            switch (tokenStream.Current.expressionTokenType)
            {
            case ExpressionTokenType.Null:
                retn = ASTNode.NullLiteralNode(tokenStream.Current.value).WithLocation(tokenStream.Current);
                break;

            case ExpressionTokenType.String:
                retn = ASTNode.StringLiteralNode(tokenStream.Current.value).WithLocation(tokenStream.Current);
                break;

            case ExpressionTokenType.Boolean:
                retn = ASTNode.BooleanLiteralNode(tokenStream.Current.value).WithLocation(tokenStream.Current);
                break;

            case ExpressionTokenType.Number:
                retn = ASTNode.NumericLiteralNode(tokenStream.Current.value).WithLocation(tokenStream.Current);
                break;

            case ExpressionTokenType.Default:
                // todo -- allow a type expression a-la default(List<float>);
                retn = ASTNode.DefaultLiteralNode(tokenStream.Current.value).WithLocation(tokenStream.Current);
                break;

            default:
                return(false);
            }

            tokenStream.Advance();
            return(true);
        }
Exemple #2
0
        private ASTNode ParseLoop()
        {
            while (tokenStream.HasMoreTokens)
            {
                ASTNode operand = default;
                if (ParseExpression(ref operand))
                {
                    if (tokenStream.Current == ExpressionTokenType.Increment)
                    {
                        tokenStream.Advance();
                        expressionStack.Push(ASTNode.UnaryExpressionNode(ASTNodeType.UnaryPostIncrement, operand));
                    }
                    else if (tokenStream.Current == ExpressionTokenType.Decrement)
                    {
                        tokenStream.Advance();
                        expressionStack.Push(ASTNode.UnaryExpressionNode(ASTNodeType.UnaryPostDecrement, operand));
                    }
                    else
                    {
                        expressionStack.Push(operand);
                    }

                    continue;
                }

                if (expressionStack.Count == 0)
                {
                    Abort();
                }

                if (tokenStream.Current == ExpressionTokenType.QuestionMark && !tokenStream.NextTokenIs(ExpressionTokenType.QuestionMark))
                {
                    while (operatorStack.Count != 0)
                    {
                        OperatorNode opNode = operatorStack.Pop();
                        opNode.right = expressionStack.Pop();
                        opNode.left  = expressionStack.Pop();
                        expressionStack.Push(opNode);
                    }

                    OperatorNode condition = ASTNode.OperatorNode(OperatorType.TernaryCondition);
                    OperatorNode selection = ASTNode.OperatorNode(OperatorType.TernarySelection);

                    condition.WithLocation(tokenStream.Previous);
                    tokenStream.Advance();
                    int idx = tokenStream.FindMatchingTernaryColon();

                    if (idx != -1)
                    {
                        TokenStream stream = tokenStream.AdvanceAndReturnSubStream(idx);

                        // parse the left side of the : operator
                        ExpressionParser parser   = new ExpressionParser(stream);
                        ASTNode          leftNode = parser.ParseLoop();
                        parser.Release();

                        tokenStream.Advance(); // step over colon

                        ExpressionParser parserRight = new ExpressionParser(tokenStream);
                        ASTNode          rightNode   = parserRight.ParseLoop();
                        tokenStream.Set(parserRight.tokenStream.CurrentIndex);
                        parserRight.Release(false);

                        selection.left  = leftNode;
                        selection.right = rightNode;

                        condition.left  = expressionStack.Pop();
                        condition.right = selection;

                        expressionStack.Push(condition);
                    }
                    else
                    {
                        // read to end use implicit default value for left hand side

                        ExpressionParser parserLeft = new ExpressionParser(tokenStream);
                        ASTNode          leftNode   = parserLeft.ParseLoop();
                        tokenStream.Set(parserLeft.tokenStream.CurrentIndex);
                        parserLeft.Release(false);

                        selection.left  = leftNode;
                        selection.right = ASTNode.DefaultLiteralNode("default");

                        condition.left  = expressionStack.Pop();
                        condition.right = selection;

                        expressionStack.Push(condition);
                    }

                    continue;
                }

                OperatorNode op;
                if (!ParseOperatorExpression(out op))
                {
                    Abort();
                    break;
                }

                while (operatorStack.Count != 0 && op.priority <= operatorStack.Peek().priority)
                {
                    OperatorNode opNode = operatorStack.Pop();
                    opNode.right = expressionStack.Pop();
                    opNode.left  = expressionStack.Pop();
                    expressionStack.Push(opNode);
                }

                operatorStack.Push(op);
            }

            while (operatorStack.Count != 0)
            {
                OperatorNode opNode = operatorStack.Pop();
                opNode.right = expressionStack.Pop();
                opNode.left  = expressionStack.Pop();
                expressionStack.Push(opNode);
            }

            if (expressionStack.Count != 1)
            {
                Abort();
            }

            return(expressionStack.Pop());
        }