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