01: // Copyright (c) 1999, 2006 Per M.A. Bothner.
02: // This is free software; for terms and warranty disclaimer see ./COPYING.
03:
04: package gnu.expr;
05:
06: import gnu.bytecode.*;
07: import gnu.mapping.*;
08:
09: /**
10: * Expression to exit a lexically surrounding block.
11: * @author Per Bothner
12: */
13:
14: public class ExitExp extends Expression {
15: BlockExp block;
16: Expression result;
17:
18: public ExitExp(Expression result, BlockExp block) {
19: this .result = result;
20: this .block = block;
21: }
22:
23: public ExitExp(BlockExp block) {
24: this .result = QuoteExp.voidExp;
25: this .block = block;
26: }
27:
28: protected boolean mustCompile() {
29: return false;
30: }
31:
32: public void apply(CallContext ctx) throws Throwable {
33: throw new BlockExitException(this , result.eval(ctx));
34: }
35:
36: public void compile(Compilation comp, Target target) {
37: CodeAttr code = comp.getCode();
38: Expression res = result == null ? QuoteExp.voidExp : result;
39: res.compileWithPosition(comp, block.subTarget);
40: code.doPendingFinalizers(block.oldTryState);
41: code.emitGoto(block.exitLabel);
42: }
43:
44: protected Expression walk(ExpWalker walker) {
45: return walker.walkExitExp(this );
46: }
47:
48: protected void walkChildren(ExpWalker walker) {
49: result = walker.walk(result);
50: }
51:
52: public void print(OutPort out) {
53: out.startLogicalBlock("(Exit", false, ")");
54: out.writeSpaceFill();
55: if (block == null || block.label == null)
56: out.print("<unknown>");
57: else
58: out.print(block.label.getName());
59: if (result != null) {
60: out.writeSpaceLinear();
61: result.print(out);
62: }
63: out.endLogicalBlock(")");
64: }
65:
66: public Type getType() {
67: return Type.neverReturnsType;
68: }
69: }
|