1 // Copyright (c) 1999, 2006, 2008 Per M.A. Bothner. 2 // This is free software; for terms and warranty disclaimer see ./COPYING. 3 4 package gnu.expr; 5 import gnu.bytecode.*; 6 import gnu.kawa.io.OutPort; 7 import gnu.mapping.CallContext; 8 9 /** 10 * Expression to exit a lexically surrounding block. 11 * @author Per Bothner 12 */ 13 14 public class ExitExp extends Expression 15 { 16 BlockExp block; 17 Expression result; 18 ExitExp(Expression result, BlockExp block)19 public ExitExp(Expression result, BlockExp block) 20 { 21 this.result = result; 22 this.block = block; 23 } 24 ExitExp(BlockExp block)25 public ExitExp(BlockExp block) 26 { 27 this.result = QuoteExp.voidExp; 28 this.block = block; 29 } 30 mustCompile()31 protected boolean mustCompile () { return false; } 32 33 @Override apply(CallContext ctx)34 public void apply (CallContext ctx) throws Throwable 35 { 36 throw new BlockExitException(this, result.eval(ctx)); 37 } 38 compile(Compilation comp, Target target)39 public void compile (Compilation comp, Target target) 40 { 41 CodeAttr code = comp.getCode(); 42 Expression res = result == null ? QuoteExp.voidExp : result; 43 res.compileWithPosition(comp, block.exitTarget); 44 block.exitableBlock.exit(); 45 } 46 deepCopy(gnu.kawa.util.IdentityHashTable mapper)47 protected Expression deepCopy (gnu.kawa.util.IdentityHashTable mapper) 48 { 49 Expression res = deepCopy(result, mapper); 50 if (res == null && result != null) 51 return null; 52 Object b = mapper.get(block); 53 ExitExp copy 54 = new ExitExp((Expression) res, b == null ? block : (BlockExp) b); 55 copy.flags = getFlags(); 56 return copy; 57 } 58 visit(ExpVisitor<R,D> visitor, D d)59 protected <R,D> R visit (ExpVisitor<R,D> visitor, D d) 60 { 61 return visitor.visitExitExp(this, d); 62 } 63 visitChildren(ExpVisitor<R,D> visitor, D d)64 protected <R,D> void visitChildren (ExpVisitor<R,D> visitor, D d) 65 { 66 result = visitor.visitAndUpdate(result, d); 67 } 68 print(OutPort out)69 public void print (OutPort out) 70 { 71 out.startLogicalBlock("(Exit", false, ")"); 72 out.writeSpaceFill(); 73 if (block != null) 74 { 75 out.print("Block#"); 76 out.print(block.id); 77 } 78 else if (block == null) 79 out.print("<unknown>"); 80 if (result != null) 81 { 82 out.writeSpaceLinear(); 83 result.print(out); 84 } 85 out.endLogicalBlock(")"); 86 } 87 calculateType()88 protected Type calculateType() 89 { 90 return Type.neverReturnsType; 91 } 92 } 93