jetbrick.template.parser.ast.AstDirectiveFor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jetbrick-template Show documentation
Show all versions of jetbrick-template Show documentation
Next generation template engine for Java
/**
* Copyright 2013-2016 Guoqiang Chen, Shanghai, China. All rights reserved.
*
* Author: Guoqiang Chen
* Email: [email protected]
* WebURL: https://github.com/subchen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrick.template.parser.ast;
import jetbrick.template.Errors;
import jetbrick.template.parser.Symbols;
import jetbrick.template.runtime.*;
public final class AstDirectiveFor extends AstDirective {
private final String identifier;
private final AstExpression expression;
private final AstStatementList statements;
private final AstStatementList elseStatements;
public AstDirectiveFor(String identifier, AstExpression expression, AstStatementList statements, AstStatementList elseStatements, Position position) {
super(position);
this.identifier = identifier;
this.expression = expression;
this.statements = statements;
this.elseStatements = elseStatements;
}
@Override
public void execute(InterpretContext ctx) throws InterpretException {
Object result = expression.execute(ctx);
JetForIterator it = new JetForIterator(result);
if (it.getSize() > 0) {
ValueStack valueStack = ctx.getValueStack();
// save outside variable which will be reset in #for
it.setOuter((JetForIterator) valueStack.getValue(Symbols.FOR));
Object outsideIdentifier = valueStack.getValue(identifier);
// set this.for
valueStack.setLocal(Symbols.FOR, it);
while (it.hasNext()) {
Object item = it.next();
try {
valueStack.setLocal(identifier, item);
} catch (IllegalStateException e) {
throw new InterpretException(Errors.FOR_ITERATOR_ERROR, it.getIndex()).cause(e).set(expression.getPosition());
}
statements.execute(ctx);
// 处理 break, continue, return, stop 语句
int signal = ctx.getSignal();
if (signal != InterpretContext.SIGNAL_NONE) {
if (signal == InterpretContext.SIGNAL_BREAK) {
ctx.setSignal(InterpretContext.SIGNAL_NONE); // clear signal
break;
} else if (signal == InterpretContext.SIGNAL_CONTINUE) {
ctx.setSignal(InterpretContext.SIGNAL_NONE); // clear signal
continue;
} else {
return;
}
}
}
// reset outside variable
valueStack.setLocal(identifier, outsideIdentifier);
valueStack.setLocal(Symbols.FOR, it.getOuter());
} else if (elseStatements != null) {
elseStatements.execute(ctx);
}
}
}