private Object forLoop()

in src/main/java/org/apache/commons/jexl3/internal/Interpreter.java [697:769]


    private Object forLoop(final ASTForeachStatement node, final Object data) {
        Object result = null;
        int nc;
        final int form = node.getLoopForm();
        final LexicalFrame locals;
        /* first child node might be the loop variable */
        if ((form & 1) != 0) {
            nc = 1;
            final JexlNode init = node.jjtGetChild(0);
            ASTVar loopVariable = null;
            if (init instanceof ASTAssignment) {
                final JexlNode child = init.jjtGetChild(0);
                if (child instanceof ASTVar) {
                    loopVariable = (ASTVar) child;
                }
            } else if (init instanceof  ASTVar){
                loopVariable = (ASTVar) init;
            }
            if (loopVariable != null) {
                final boolean lexical = loopVariable.isLexical() || options.isLexical();
                locals = lexical ? new LexicalFrame(frame, block) : null;
                if (locals != null) {
                    block = locals;
                }
            } else {
                locals = null;
            }
            // initialize after eventual creation of local lexical frame
            init.jjtAccept(this, data);
            // other inits
            for (JexlNode moreAssignment = node.jjtGetChild(nc);
                 moreAssignment instanceof ASTAssignment;
                 moreAssignment = node.jjtGetChild(++nc)) {
                moreAssignment.jjtAccept(this, data);
            }
        } else {
            locals = null;
            nc = 0;
        }
        try {
            // the loop condition
            final JexlNode predicate = (form & 2) != 0? node.jjtGetChild(nc++) : null;
            // the loop step
            final JexlNode step = (form & 4) != 0? node.jjtGetChild(nc++) : null;
            // last child is body
            final JexlNode statement = (form & 8) != 0 ? node.jjtGetChild(nc) : null;
            // while(predicate())...
            while (predicate == null || testPredicate(predicate, predicate.jjtAccept(this, data))) {
                cancelCheck(node);
                // the body
                if (statement != null) {
                    try {
                        // execute statement
                        result = statement.jjtAccept(this, data);
                    } catch (final JexlException.Break stmtBreak) {
                        break;
                    } catch (final JexlException.Continue stmtContinue) {
                        //continue;
                    }
                }
                // the step
                if (step != null) {
                    step.jjtAccept(this, data);
                }
            }
        } finally {
            // restore lexical frame
            if (locals != null) {
                block = block.pop();
            }
        }
        return result;
    }