package org.develnext.jphp.core.compiler.jvm.statement.expr; import java.util.Iterator; import org.develnext.jphp.core.compiler.jvm.misc.LocalVariable; import org.develnext.jphp.core.compiler.jvm.statement.ExpressionStmtCompiler; import org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken; import org.develnext.jphp.core.tokenizer.token.stmt.BodyStmtToken; import org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken; import org.develnext.jphp.core.tokenizer.token.stmt.ForStmtToken; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.LineNumberNode; import static org.objectweb.asm.Opcodes.GOTO; import static org.objectweb.asm.Opcodes.IFEQ; public class ForCompiler extends BaseStatementCompiler<ForStmtToken> { public ForCompiler(ExpressionStmtCompiler exprCompiler) { super(exprCompiler); } @Override public void write(ForStmtToken token) { expr.writeDefineVariables(token.getInitLocal()); for(ExprStmtToken expr : token.getInitExpr()){ this.expr.writeExpression(expr, false, false); } expr.writeUndefineVariables(token.getInitLocal()); expr.writeDefineVariables(token.getLocal()); for(VariableExprToken variable : token.getIterationLocal()){ // TODO optimize this for Dynamic Values of variables LocalVariable local = method.getLocalVariable(variable.getName()); local.setValue(null); } LabelNode start = expr.writeLabel(node, token.getMeta().getStartLine()); LabelNode iter = new LabelNode(); LabelNode end = new LabelNode(); for (Iterator<ExprStmtToken> i = token.getConditionExpr().iterator(); i.hasNext();) { ExprStmtToken expr = i.next(); if (i.hasNext()) { this.expr.writeExpression(expr, false, false); } else { this.expr.writeExpression(expr, true, false); this.expr.writePopBoolean(); add(new JumpInsnNode(IFEQ, end)); this.expr.stackPop(); } } method.pushJump(end, iter); expr.write(BodyStmtToken.class, token.getBody()); method.popJump(); add(iter); for(ExprStmtToken expr : token.getIterationExpr()){ this.expr.writeExpression(expr, false, false); } add(new JumpInsnNode(GOTO, start)); add(end); add(new LineNumberNode(token.getMeta().getEndLine(), end)); expr.writeUndefineVariables(token.getLocal()); } }