01: package gnu.expr;
02:
03: import gnu.bytecode.*;
04: import gnu.mapping.*;
05:
06: /**
07: * A simplified IfExp that makes use of the Branchable interface
08: */
09:
10: public class SimpleIfExp extends IfExp {
11:
12: public SimpleIfExp(Expression i, Expression t, Expression e) {
13: super (i, t, e);
14: }
15:
16: public static Expression make(Expression i, Expression t,
17: Expression e) {
18: if (i == QuoteExp.trueExp)
19: return t;
20: if (i == QuoteExp.falseExp)
21: return e;
22:
23: return new SimpleIfExp(i, t, e);
24: }
25:
26: public void compile(Compilation comp, Target target) {
27: compile(test, then_clause,
28: else_clause == null ? QuoteExp.voidExp : else_clause,
29: comp, target);
30: }
31:
32: public static void compile(Expression test, Expression then_clause,
33: Expression else_clause, Compilation comp, Target target) {
34: gnu.bytecode.CodeAttr code = comp.getCode();
35: Label elseLabel;
36: elseLabel = new Label(code);
37: Branchable branchOp = test.getBranchable();
38: if (branchOp != null) {
39: branchOp.compileJumpNot(comp, ((ApplyExp) test).getArgs(),
40: elseLabel);
41: } else {
42: Target stack = new StackTarget(Type.boolean_type);
43: test.compile(comp, stack);
44: code.emitGotoIfIntEqZero(elseLabel);
45: }
46: code.emitIfThen();
47: then_clause.compileWithPosition(comp, target);
48: if (else_clause instanceof QuoteExp
49: && ((QuoteExp) else_clause).getValue() == Values.empty) {
50: code.setUnreachable();
51: elseLabel.define(code);
52: } else {
53: code.emitElse();
54: elseLabel.define(code);
55: else_clause.compileWithPosition(comp, target);
56: }
57: code.emitFi();
58: }
59:
60: }
|