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;
}