コード例 #1
0
ファイル: TemplateParser.cs プロジェクト: deveel/dtplengine
        private Expression PrimaryExpression()
        {
            if (Current.Kind == TokenKind.StringStart)
                return ReadString();

            if (Current.Kind == TokenKind.ID) {
                Token id = Consume();

                Expression exp;

                // if ( follows ID, we have a function call
                if (Current.Kind == TokenKind.LParen) {
                    Consume(); // consume LParen
                    Expression[] args = ReadArguments();
                    Consume(TokenKind.RParen);

                    exp = new FunctionCallExpression(id.Line, id.Column, id.Text, args);
                } else // else, we just have id
                    exp = new IdExpression(id.Line, id.Column, id.Text);

                // while we have ".", keep chaining up field access or method call
                while (Current.Kind == TokenKind.Dot ||
                    Current.Kind == TokenKind.LBracket) {
                    if (Current.Kind == TokenKind.Dot) {
                        Consume(); // consume DOT
                        Token field = Consume(TokenKind.ID); // consume ID after dot

                        // if "(" after ID, then it's a method call
                        if (Current.Kind == TokenKind.LParen) {
                            Consume(); // consume "("
                            Expression[] args = ReadArguments();
                            Consume(TokenKind.RParen); // read ")"

                            exp = new MethodCallExpression(field.Line, field.Column, exp, field.Text, args);
                        } else
                            exp = new FieldAccessExpression(field.Line, field.Column, exp, field.Text);
                    } else { // must be LBracket
                        // array access
                        Token bracket = Current;
                        Consume(); // consume [
                        Expression indexExp = TopExpression();
                        Consume(TokenKind.RBracket);

                        exp = new ArrayAccessExpression(bracket.Line, bracket.Column, exp, indexExp);
                    }
                }

                return exp;

            }
            if (Current.Kind == TokenKind.Integer) {
                int value = Int32.Parse(Current.Text);
                IntegerLiteralExpression intLiteral = new IntegerLiteralExpression(Current.Line, Current.Column, value);
                Consume(); // consume int
                return intLiteral;
            }
            if (Current.Kind == TokenKind.Double) {
                double value = Double.Parse(Current.Text);
                DoubleLiteralExpression dLiteral = new DoubleLiteralExpression(Current.Line, Current.Column, value);
                Consume(); // consume int
                return dLiteral;
            }
            if (Current.Kind == TokenKind.BooleanTrue) {
                BooleanLiteralExpression bLiteral = new BooleanLiteralExpression(Current.Line, Current.Column, true);
                Consume();
                return bLiteral;
            }
            if (Current.Kind == TokenKind.BooleanFalse) {
                BooleanLiteralExpression bLiteral = new BooleanLiteralExpression(Current.Line, Current.Column, false);
                Consume();
                return bLiteral;
            }
            if (Current.Kind == TokenKind.LParen) {
                Consume(); // eat (
                Expression exp = TopExpression();
                Consume(TokenKind.RParen); // eat )

                return exp;
            }

            throw new ParseException("Invalid token in expression: " + Current.Kind + ". Was expecting ID or string.",
                                     Current.Line, Current.Column);
        }
コード例 #2
0
ファイル: TemplateContext.cs プロジェクト: deveel/dtplengine
        private object EvaluateArrayAccess(ArrayAccessExpression arrayAccess)
        {
            object obj = EvaluateExpression(arrayAccess.Expression);

            object index = EvaluateExpression(arrayAccess.Index);

            if (obj is Array) {
                Array array = (Array)obj;
                if (index is int)
                    return array.GetValue((int)index);

                throw new TemplateException("Index of array has to be integer", arrayAccess.Line, arrayAccess.Column);
            }

            return EvaluateMethodCall(obj, "get_Item", new object[] { index });
        }