Search in sources :

Example 1 with CaseStmtToken

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());
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) CaseStmtToken(org.develnext.jphp.core.tokenizer.token.stmt.CaseStmtToken) LocalVariable(org.develnext.jphp.core.compiler.jvm.misc.LocalVariable) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LineNumberNode(org.objectweb.asm.tree.LineNumberNode)

Aggregations

LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)1 CaseStmtToken (org.develnext.jphp.core.tokenizer.token.stmt.CaseStmtToken)1 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)1 LabelNode (org.objectweb.asm.tree.LabelNode)1 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)1