KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > expr > FluidLetExp


1 // Copyright (c) 1999, 2000 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 "fluid-let" for Scheme and "let" for Emacs.
10  * @author Per Bothner
11  */

12
13 public class FluidLetExp extends LetExp
14 {
15   public FluidLetExp (Expression[] i) { super(i); }
16
17   protected boolean mustCompile () { return true; }
18
19   public void compile (Compilation comp, Target target)
20   {
21     CodeAttr code = comp.getCode();
22     Type result_type = target instanceof IgnoreTarget ? null
23     : getType();
24     Target ttarg;
25     if (result_type == null)
26       ttarg = Target.Ignore;
27     else if (result_type == Type.pointer_type)
28       ttarg = Target.pushObject;
29     else
30       ttarg = new StackTarget(result_type);
31     Scope scope = getVarScope();
32     code.enterScope(scope);
33     Variable ctx = scope.addVariable(code, Compilation.typeCallContext, null);
34     comp.loadCallContext();
35     code.emitStore(ctx);
36     Variable[] save = new Variable[inits.length];
37     
38     Declaration decl = firstDecl();
39     doInits(decl, 0, save, comp, ctx);
40     code.emitTryStart(true, result_type);
41     body.compileWithPosition(comp, ttarg);
42     code.emitTryEnd();
43     code.emitFinallyStart();
44
45     
46     for (int i = 0; i < inits.length; i++, decl = decl.nextDecl())
47       {
48     decl.load(null, ReferenceExp.DONT_DEREFERENCE,
49           comp, Target.pushObject);
50     code.emitLoad(save[i]);
51         code.emitLoad(ctx);
52     code.emitInvokeVirtual(Compilation.typeLocation
53                    .getDeclaredMethod("setRestore", 2));
54     
55       }
56     code.emitTryCatchEnd();
57     popScope(code);
58     if (result_type != null)
59       target.compileFromStack(comp, result_type);
60   }
61
62   private void doInits (Declaration decl, int i, Variable[] save,
63             Compilation comp, Variable ctx)
64   {
65     if (i >= inits.length)
66       return;
67     CodeAttr code = comp.getCode();
68     save[i] = code.addLocal(Type.pointer_type);
69     decl.allocateVariable(code);
70     decl.base.load(null, ReferenceExp.DONT_DEREFERENCE,
71            comp, Target.pushObject);
72     code.emitDup();
73     code.emitStore(decl.getVariable());
74     inits[i].compile(comp, Target.pushObject);
75     doInits(decl.nextDecl(), i+1, save, comp, ctx);
76     code.emitLoad(ctx);
77     code.emitInvokeVirtual(Compilation.typeLocation
78                .getDeclaredMethod("setWithSave", 2));
79     code.emitStore(save[i]);
80   }
81
82   protected Expression walk (ExpWalker walker)
83   {
84     return walker.walkFluidLetExp(this);
85   }
86
87   public void print (OutPort out)
88   {
89     print(out, "(FluidLet", ")");
90   }
91 }
92
Popular Tags