Search in sources :

Example 16 with ASTNode

use of org.mvel2.ast.ASTNode in project mvel by mikebrock.

the class MVELRuntime method execute.

/**
   * Main interpreter.
   *
   * @param debugger        Run in debug mode
   * @param expression      The compiled expression object
   * @param ctx             The root context object
   * @param variableFactory The variable factory to be injected
   * @return The resultant value
   * @see org.mvel2.MVEL
   */
public static Object execute(boolean debugger, final CompiledExpression expression, final Object ctx, VariableResolverFactory variableFactory) {
    Object v1, v2;
    ExecutionStack stk = new ExecutionStack();
    variableFactory.setTiltFlag(false);
    ASTNode tk = expression.getFirstNode();
    Integer operator;
    if (tk == null)
        return null;
    try {
        do {
            if (tk.fields == -1) {
                /**
           * This may seem silly and redundant, however, when an MVEL script recurses into a block
           * or substatement, a new runtime loop is entered.   Since the debugger state is not
           * passed through the AST, it is not possible to forward the state directly.  So when we
           * encounter a debugging symbol, we check the thread local to see if there is are registered
           * breakpoints.  If we find them, we assume that we are debugging.
           *
           * The consequence of this of course, is that it's not ideal to compileShared expressions with
           * debugging symbols which you plan to use in a production enviroment.
           */
                if (debugger || (debugger = hasDebuggerContext())) {
                    try {
                        debuggerContext.get().checkBreak((LineLabel) tk, variableFactory, expression);
                    } catch (NullPointerException e) {
                    // do nothing for now.  this isn't as calus as it seems.
                    }
                }
                continue;
            } else if (stk.isEmpty()) {
                stk.push(tk.getReducedValueAccelerated(ctx, ctx, variableFactory));
            }
            if (variableFactory.tiltFlag()) {
                return stk.pop();
            }
            switch(operator = tk.getOperator()) {
                case RETURN:
                    variableFactory.setTiltFlag(true);
                    return stk.pop();
                case NOOP:
                    continue;
                case TERNARY:
                    if (!stk.popBoolean()) {
                        //noinspection StatementWithEmptyBody
                        while (tk.nextASTNode != null && !(tk = tk.nextASTNode).isOperator(TERNARY_ELSE)) ;
                    }
                    stk.clear();
                    continue;
                case TERNARY_ELSE:
                    return stk.pop();
                case END_OF_STMT:
                    /**
             * If the program doesn't end here then we wipe anything off the stack that remains.
             * Althought it may seem like intuitive stack optimizations could be leveraged by
             * leaving hanging values on the stack,  trust me it's not a good idea.
             */
                    if (tk.nextASTNode != null) {
                        stk.clear();
                    }
                    continue;
            }
            stk.push(tk.nextASTNode.getReducedValueAccelerated(ctx, ctx, variableFactory), operator);
            try {
                while (stk.isReduceable()) {
                    if ((Integer) stk.peek() == CHOR) {
                        stk.pop();
                        v1 = stk.pop();
                        v2 = stk.pop();
                        if (!isEmpty(v2) || !isEmpty(v1)) {
                            stk.clear();
                            stk.push(!isEmpty(v2) ? v2 : v1);
                        } else
                            stk.push(null);
                    } else {
                        stk.op();
                    }
                }
            } catch (ClassCastException e) {
                throw new CompileException("syntax error or incomptable types", new char[0], 0, e);
            } catch (CompileException e) {
                throw e;
            } catch (Exception e) {
                throw new CompileException("failed to compileShared sub expression", new char[0], 0, e);
            }
        } while ((tk = tk.nextASTNode) != null);
        return stk.peek();
    } catch (NullPointerException e) {
        if (tk != null && tk.isOperator() && tk.nextASTNode != null) {
            throw new CompileException("incomplete statement: " + tk.getName() + " (possible use of reserved keyword as identifier: " + tk.getName() + ")", tk.getExpr(), tk.getStart());
        } else {
            throw e;
        }
    }
}
Also used : ExecutionStack(org.mvel2.util.ExecutionStack) ASTNode(org.mvel2.ast.ASTNode)

Example 17 with ASTNode

use of org.mvel2.ast.ASTNode in project mvel by mikebrock.

the class AbstractParser method _captureBlock.

private ASTNode _captureBlock(ASTNode node, final char[] expr, boolean cond, int type) {
    skipWhitespace();
    int startCond = 0;
    int endCond = 0;
    int blockStart;
    int blockEnd;
    String name;
    /**
     * Functions are a special case we handle differently from the rest of block parsing
     */
    switch(type) {
        case FUNCTION:
            {
                int st = cursor;
                captureToNextTokenJunction();
                if (cursor == end) {
                    throw new CompileException("unexpected end of statement", expr, st);
                }
                /**
         * Check to see if the name is legal.
         */
                if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                    throw new CompileException("illegal function name or use of reserved word", expr, cursor);
                if (pCtx == null)
                    pCtx = getParserContext();
                FunctionParser parser = new FunctionParser(name, cursor, end - cursor, expr, fields, pCtx, splitAccumulator);
                Function function = parser.parse();
                cursor = parser.getCursor();
                return lastNode = function;
            }
        case PROTO:
            if (ProtoParser.isUnresolvedWaiting()) {
                if (pCtx == null)
                    pCtx = getParserContext();
                ProtoParser.checkForPossibleUnresolvedViolations(expr, cursor, pCtx);
            }
            int st = cursor;
            captureToNextTokenJunction();
            if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                throw new CompileException("illegal prototype name or use of reserved word", expr, cursor);
            if (expr[cursor = nextNonBlank()] != '{') {
                throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
            }
            cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
            if (pCtx == null)
                pCtx = getParserContext();
            ProtoParser parser = new ProtoParser(expr, st, cursor, name, pCtx, fields, splitAccumulator);
            Proto proto = parser.parse();
            if (pCtx == null)
                pCtx = getParserContext();
            pCtx.addImport(proto);
            proto.setCursorPosition(st, cursor);
            cursor = parser.getCursor();
            ProtoParser.notifyForLateResolution(proto);
            return lastNode = proto;
        default:
            if (cond) {
                if (expr[cursor] != '(') {
                    throw new CompileException("expected '(' but encountered: " + expr[cursor], expr, cursor);
                }
                /**
           * This block is an: IF, FOREACH or WHILE node.
           */
                endCond = cursor = balancedCaptureWithLineAccounting(expr, startCond = cursor, end, '(', pCtx);
                startCond++;
                cursor++;
            }
    }
    skipWhitespace();
    if (cursor >= end) {
        throw new CompileException("unexpected end of statement", expr, end);
    } else if (expr[cursor] == '{') {
        blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
    } else {
        blockStart = cursor - 1;
        captureToEOSorEOL();
        blockEnd = cursor + 1;
    }
    if (type == ASTNode.BLOCK_IF) {
        IfNode ifNode = (IfNode) node;
        if (node != null) {
            if (!cond) {
                return ifNode.setElseBlock(expr, st = trimRight(blockStart + 1), trimLeft(blockEnd) - st, pCtx);
            } else {
                return ifNode.setElseIf((IfNode) createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type));
            }
        } else {
            return createBlockToken(startCond, endCond, blockStart + 1, blockEnd, type);
        }
    } else if (type == ASTNode.BLOCK_DO) {
        cursor++;
        skipWhitespace();
        st = cursor;
        captureToNextTokenJunction();
        if ("while".equals(name = new String(expr, st, cursor - st))) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
        } else if ("until".equals(name)) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), ASTNode.BLOCK_DO_UNTIL);
        } else {
            throw new CompileException("expected 'while' or 'until' but encountered: " + name, expr, cursor);
        }
    } else // DON"T REMOVE THIS COMMENT!
    // else if (isFlag(ASTNode.BLOCK_FOREACH) || isFlag(ASTNode.BLOCK_WITH)) {
    {
        return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
    }
}
Also used : FunctionParser(org.mvel2.util.FunctionParser) ProtoParser(org.mvel2.util.ProtoParser) CompileException(org.mvel2.CompileException)

Example 18 with ASTNode

use of org.mvel2.ast.ASTNode in project mvel by mikebrock.

the class CompiledExpression method toString.

public String toString() {
    StringBuilder appender = new StringBuilder();
    ASTNode node = firstNode;
    while (node != null) {
        appender.append(node.toString()).append(";\n");
        node = node.nextASTNode;
    }
    return appender.toString();
}
Also used : ASTNode(org.mvel2.ast.ASTNode)

Example 19 with ASTNode

use of org.mvel2.ast.ASTNode in project mvel by mikebrock.

the class MacroProcessorTest method testMacroSupportWithDebugging.

public void testMacroSupportWithDebugging() {
    Map<String, Object> vars = new HashMap<String, Object>();
    vars.put("foo", new Foo());
    Map<String, Interceptor> interceptors = new HashMap<String, Interceptor>();
    Map<String, Macro> macros = new HashMap<String, Macro>();
    interceptors.put("Modify", new Interceptor() {

        public int doBefore(ASTNode node, VariableResolverFactory factory) {
            ((WithNode) node).getNestedStatement().getValue(null, factory);
            factory.createVariable("mod", "FOOBAR!");
            return 0;
        }

        public int doAfter(Object val, ASTNode node, VariableResolverFactory factory) {
            return 0;
        }
    });
    macros.put("modify", new Macro() {

        public String doMacro() {
            return "@Modify with";
        }
    });
    ExpressionCompiler compiler = new ExpressionCompiler(parseMacros("System.out.println('hello');\n" + "System.out.println('bye');\n" + "modify (foo) { aValue = 'poo', \n" + " aValue = 'poo' };\n mod", macros));
    // compiler.setDebugSymbols(true);
    ParserContext ctx = new ParserContext(null, interceptors, null);
    ctx.setSourceFile("test.mv");
    ctx.setDebugSymbols(true);
    CompiledExpression compiled = compiler.compile(ctx);
    MVELRuntime.setThreadDebugger(new Debugger() {

        public int onBreak(Frame frame) {
            System.out.println(frame.getSourceName() + ":" + frame.getLineNumber());
            return Debugger.STEP;
        }
    });
    MVELRuntime.registerBreakpoint("test.mv", 3);
    System.out.println(DebugTools.decompile(compiled));
    Assert.assertEquals("FOOBAR!", MVEL.executeDebugger(compiled, null, new MapVariableResolverFactory(vars)));
}
Also used : Debugger(org.mvel2.debug.Debugger) Frame(org.mvel2.debug.Frame) HashMap(java.util.HashMap) Foo(org.mvel2.tests.core.res.Foo) WithNode(org.mvel2.ast.WithNode) CompiledExpression(org.mvel2.compiler.CompiledExpression) VariableResolverFactory(org.mvel2.integration.VariableResolverFactory) MapVariableResolverFactory(org.mvel2.integration.impl.MapVariableResolverFactory) ASTNode(org.mvel2.ast.ASTNode) MapVariableResolverFactory(org.mvel2.integration.impl.MapVariableResolverFactory) ExpressionCompiler(org.mvel2.compiler.ExpressionCompiler) Interceptor(org.mvel2.integration.Interceptor)

Example 20 with ASTNode

use of org.mvel2.ast.ASTNode in project mvel by mikebrock.

the class CoreConfidenceTests method testInterceptors.

public void testInterceptors() {
    Interceptor testInterceptor = new Interceptor() {

        public int doBefore(ASTNode node, VariableResolverFactory factory) {
            System.out.println("BEFORE Node: " + node.getName());
            return 0;
        }

        public int doAfter(Object val, ASTNode node, VariableResolverFactory factory) {
            System.out.println("AFTER Node: " + node.getName());
            return 0;
        }
    };
    Map<String, Interceptor> interceptors = new HashMap<String, Interceptor>();
    interceptors.put("test", testInterceptor);
    executeExpression(compileExpression("@test System.out.println('MIDDLE');", null, interceptors));
}
Also used : DefaultLocalVariableResolverFactory(org.mvel2.integration.impl.DefaultLocalVariableResolverFactory) VariableResolverFactory(org.mvel2.integration.VariableResolverFactory) MapVariableResolverFactory(org.mvel2.integration.impl.MapVariableResolverFactory) ASTNode(org.mvel2.ast.ASTNode) Interceptor(org.mvel2.integration.Interceptor)

Aggregations

ASTNode (org.mvel2.ast.ASTNode)11 AstNode (com.linkedin.pinot.pql.parsers.pql2.ast.AstNode)5 Interceptor (org.mvel2.integration.Interceptor)4 VariableResolverFactory (org.mvel2.integration.VariableResolverFactory)4 MapVariableResolverFactory (org.mvel2.integration.impl.MapVariableResolverFactory)4 FunctionCallAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.FunctionCallAstNode)3 IdentifierAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.IdentifierAstNode)3 HashMap (java.util.HashMap)3 CompileException (org.mvel2.CompileException)3 BetweenPredicateAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.BetweenPredicateAstNode)2 BinaryMathOpAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.BinaryMathOpAstNode)2 BooleanOperatorAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.BooleanOperatorAstNode)2 ComparisonPredicateAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.ComparisonPredicateAstNode)2 ExpressionParenthesisGroupAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.ExpressionParenthesisGroupAstNode)2 FloatingPointLiteralAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.FloatingPointLiteralAstNode)2 GroupByAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.GroupByAstNode)2 HavingAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.HavingAstNode)2 InPredicateAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.InPredicateAstNode)2 IntegerLiteralAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.IntegerLiteralAstNode)2 IsPredicateAstNode (com.linkedin.pinot.pql.parsers.pql2.ast.IsPredicateAstNode)2