Example #1
0
        private AstItem ReadExpression(TokenIterator tokens, List <TokenKind> terminators)
        {
            var expTokens = new List <Token>();

            if (terminators == null)
            {
                expTokens.AddRange(tokens.ToList());
            }
            else
            {
                var inArray = false;
                var tok     = tokens.Current();
                while (tok != null)
                {
                    if (!inArray && terminators.Contains(tok.Kind))
                    {
                        break;
                    }

                    if (tok.Kind == TokenKind.SquareBracketOpen)
                    {
                        inArray = true;
                    }

                    if (tok.Kind == TokenKind.SquareBracketClose)
                    {
                        inArray = false;
                    }

                    expTokens.Add(tok);
                    tokens.Step();
                    tok = tokens.Current();
                }
            }

            if (expTokens.Count == 0)
            {
                throw new Exception("Expected expression, found " + tokens.Current());
            }

            AstItem result    = null;
            var     tokenIter = new TokenIterator(expTokens);

            if (expTokens.Count == 1)
            {
                //Single immediate, vector or variable
                result = ReadSingleAstItem(tokenIter);
            }
            else
            {
                var token = tokenIter.Current();
                var next  = tokenIter.Next();
                if (token.Kind == TokenKind.New)
                {
                    result = ReadNewPointer(tokenIter);
                }
                else
                {
                    //Math Expression
                    var expItemsInfix = new List <AstItem>();
                    var expectOperand = true;
                    while (token != null)
                    {
                        switch (token.Kind)
                        {
                        case TokenKind.Word:
                        case TokenKind.Number:
                        case TokenKind.True:
                        case TokenKind.False:
                        case TokenKind.VectorConstructor:
                        case TokenKind.Char:
                        case TokenKind.String:
                        case TokenKind.SquareBracketOpen:
                            var operandItem = ReadSingleAstItem(tokenIter);
                            expItemsInfix.Add(operandItem);
                            expectOperand = false;     //Next we want an operator
                            break;

                        case TokenKind.RoundBracketOpen:
                        case TokenKind.RoundBracketClose:
                            expItemsInfix.Add(AstItem.AsOperator(ParseOperator(token.Value)));
                            break;

                        case TokenKind.ExpressionOperator:
                            if (expectOperand)
                            {
                                expItemsInfix.Add(AstItem.AsUnaryOperator(ParseUnaryOperator(token.Value)));
                            }
                            else
                            {
                                expItemsInfix.Add(AstItem.AsOperator(ParseOperator(token.Value)));
                                expectOperand = true;     //Next we want an operand
                            }
                            break;

                        default:
                            throw new Exception("Unexpected expression token: " + token);
                        }

                        tokenIter.Step();
                        token = tokenIter.Current();
                    }

                    //Convert to postfix
                    if (expItemsInfix.Count > 1)
                    {
                        result = InfixToPostfix(expItemsInfix);
                    }
                    else
                    {
                        result = expItemsInfix[0];
                    }
                }
            }

            return(result);
        }