KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > standard > fluid_let


1 package kawa.standard;
2 import kawa.lang.*;
3 import gnu.mapping.*;
4 import gnu.expr.*;
5 import gnu.lists.*;
6
7 /**
8  * The Syntax transformer that re-writes the Scheme "fluid-let" primitive.
9  * @author Per Bothner
10  */

11
12 public class fluid_let extends Syntax
13 {
14   public static final fluid_let fluid_let = new fluid_let();
15   static { fluid_let.setName("fluid-set"); }
16
17   /** True if bindings should be evaluated sequentionally, as in ELisp let*. */
18   boolean star;
19
20   /** Value to use if an initial value is not specified.
21    * Null means use the existing binding. */

22   Expression defaultInit;
23
24   public fluid_let(boolean star, Expression defaultInit)
25   {
26     this.star = star;
27     this.defaultInit = defaultInit;
28   }
29
30   public fluid_let()
31   {
32     this.star = false;
33   }
34
35   public Expression rewrite (Object JavaDoc obj, Translator tr)
36   {
37     if (! (obj instanceof Pair))
38       return tr.syntaxError ("missing let arguments");
39     Pair pair = (Pair) obj;
40     return rewrite(pair.car, pair.cdr, tr);
41   }
42
43   public Expression rewrite (Object JavaDoc bindings, Object JavaDoc body, Translator tr)
44   {
45     int decl_count = star ? 1 : LList.length (bindings);
46     Expression[] inits = new Expression[decl_count];
47     FluidLetExp let = new FluidLetExp (inits);
48     for (int i = 0; i < decl_count; i++)
49       {
50     Pair bind_pair = (Pair) bindings;
51         Object JavaDoc savePos = tr.pushPositionOf(bind_pair);
52         try
53           {
54             Expression value;
55             Pair binding;
56             Object JavaDoc name = bind_pair.car;
57             if (name instanceof String JavaDoc || name instanceof Symbol)
58               {
59                 value = defaultInit;
60               }
61             else if (name instanceof Pair
62                      && ((binding = (Pair) name).car instanceof String JavaDoc
63                          || binding.car instanceof Symbol
64                          || binding.car instanceof SyntaxForm))
65               {
66                 name = binding.car;
67                 if (name instanceof SyntaxForm)
68                   name = ((SyntaxForm)name).form;
69
70                 if (binding.cdr == LList.Empty)
71                   value = defaultInit;
72                 else if (! (binding.cdr instanceof Pair)
73                          || (binding = (Pair) binding.cdr).cdr != LList.Empty)
74                   return tr.syntaxError("bad syntax for value of " + name
75                                         + " in " + getName());
76                 else
77                   value = tr.rewrite(binding.car);
78               }
79             else
80               return tr.syntaxError("invalid " + getName() + " syntax");
81             Declaration decl = let.addDeclaration(name);
82             Declaration found = tr.lexical.lookup(name, false);
83             if (found != null)
84               {
85                 if (found.isLexical())
86                   found.setIndirectBinding(true);
87                 decl.base = found;
88               }
89             decl.setFluid(true);
90             decl.setIndirectBinding(true);
91             if (value == null)
92               value = new ReferenceExp(name);
93             inits[i] = value;
94             decl.noteValue(null);
95             bindings = bind_pair.cdr;
96           }
97         finally
98           {
99             tr.popPositionOf(savePos);
100           }
101       }
102     tr.push(let);
103     if (star && bindings != LList.Empty)
104       let.body = rewrite (bindings, body, tr);
105     else
106       let.body = tr.rewrite_body(body);
107     tr.pop(let);
108     return let;
109   }
110 }
111
Popular Tags