use of org.develnext.jphp.core.tokenizer.token.stmt.CaseStmtToken in project jphp by jphp-compiler.
the class SwitchCompiler method write.
@Override
public void write(SwitchStmtToken token) {
expr.writeDefineVariables(token.getLocal());
LabelNode l = new LabelNode();
LabelNode end = new LabelNode();
add(l);
LocalVariable switchValue = method.addLocalVariable("~switch~" + method.nextStatementIndex(Memory.class), l, Memory.class);
switchValue.setEndLabel(end);
LabelNode[][] jumps = new LabelNode[token.getCases().size() + 1][2];
int i = 0;
for (CaseStmtToken one : token.getCases()) {
// checkLabel, bodyLabel
jumps[i] = new LabelNode[] { new LabelNode(), new LabelNode() };
if (i == jumps.length - 1)
jumps[i] = new LabelNode[] { end, end };
i++;
}
jumps[jumps.length - 1] = new LabelNode[] { end, end };
method.pushJump(end, end);
expr.writeExpression(token.getValue(), true, false);
expr.writePopBoxing();
expr.writeVarStore(switchValue, false, false);
i = 0;
for (CaseStmtToken one : token.getCases()) {
// conditional
add(jumps[i][0]);
if (one.getConditional() != null) {
expr.writeVarLoad(switchValue);
expr.writeExpression(one.getConditional(), true, false);
expr.writeSysDynamicCall(Memory.class, "equal", Boolean.TYPE, expr.stackPeek().type.toClass());
add(new JumpInsnNode(IFEQ, jumps[i + 1][0]));
expr.stackPop();
}
// if is done...
add(new JumpInsnNode(GOTO, jumps[i][1]));
i++;
}
i = 0;
for (CaseStmtToken one : token.getCases()) {
add(jumps[i][1]);
expr.writeDefineVariables(one.getLocals());
expr.write(BodyStmtToken.class, one.getBody());
i++;
expr.writeUndefineVariables(one.getLocals());
}
method.popJump();
add(end);
add(new LineNumberNode(token.getMeta().getEndLine(), end));
method.prevStatementIndex(Memory.class);
expr.writeUndefineVariables(token.getLocal());
}
Aggregations