KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > BlockExp


1 // Copyright (c) 1999, 2006 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.mapping.*;
7
8 /**
9  * Class used to implement a block that can be exited.
10  * @author Per Bothner
11  */

12
13 public class BlockExp extends Expression
14 {
15   Declaration label;
16   Expression body;
17
18   /** If non-null, evaluate this, but only if non-normal exit. */
19   Expression exitBody;
20
21   public void setBody(Expression body)
22   {
23     this.body = body;
24   }
25
26   public void setBody(Expression body, Expression exitBody)
27   {
28     this.body = body;
29     this.exitBody = exitBody;
30   }
31
32   /* Target used to evaluate body. Temporary only used during compilation. */
33   Target subTarget;
34   /* Label to exit to. Temporary only used during compilation. */
35   Label exitLabel;
36   /* Current TryState when we start compiling the. Temporary. */
37   TryState oldTryState;
38
39   protected boolean mustCompile () { return false; }
40
41   public void apply (CallContext ctx) throws Throwable JavaDoc
42   {
43     Object JavaDoc result;
44     try
45       {
46         result = body.eval(ctx);
47       }
48     catch (BlockExitException ex)
49       {
50         if (ex.exit.block != this)
51           throw ex;
52         result = ex.exit.result;
53         if (exitBody != null)
54           result = exitBody.eval(ctx);
55       }
56     ctx.writeValue(result);
57   }
58
59   public void compile (Compilation comp, Target target)
60   {
61     Target subTarget;
62     if (target instanceof IgnoreTarget
63     || target == Target.pushObject)
64       subTarget = target;
65     else
66       {
67     // We can probably do better - and this is probably
68
// wrong for TailTargets. FIXME.
69
subTarget = new StackTarget(getType());
70       }
71     gnu.bytecode.CodeAttr code = comp.getCode();
72     oldTryState = code.getCurrentTry();
73     exitLabel = new Label(code);
74     this.subTarget = exitBody == null ? subTarget : Target.Ignore;
75     body.compileWithPosition(comp, subTarget);
76     if (exitBody != null)
77       {
78         Label doneLabel = new Label(code);
79         code.emitGoto(doneLabel);
80         exitLabel.define(code);
81         exitBody.compileWithPosition(comp, subTarget);
82         doneLabel.define(code);
83       }
84     else
85       exitLabel.define(code);
86     if (subTarget != target)
87       target.compileFromStack(comp, subTarget.getType());
88     oldTryState = null;
89   }
90
91   protected Expression walk (ExpWalker walker)
92   {
93     return walker.walkBlockExp(this);
94   }
95
96   protected void walkChildren (ExpWalker walker)
97   {
98     body = walker.walk(body);
99     if (walker.exitValue == null && exitBody != null)
100       exitBody = walker.walk(exitBody);
101   }
102
103   public void print (OutPort out)
104   {
105     out.startLogicalBlock("(Block", ")", 2);
106     if (label != null)
107      out.print(label.getName());
108     out.writeSpaceLinear();
109     body.print(out);
110     if (exitBody != null)
111       {
112     out.writeSpaceLinear();
113         out.print("else ");
114         exitBody.print(out);
115       }
116     out.endLogicalBlock(")");
117   }
118 }
119
120 class BlockExitException extends RuntimeException JavaDoc
121 {
122   ExitExp exit;
123   Object JavaDoc result;
124   public BlockExitException (ExitExp exit, Object JavaDoc result)
125   {
126     this.exit = exit;
127     this.result = result;
128   }
129 }
130
Popular Tags