KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > kawa > standard > let


1 package kawa.standard;
2 import kawa.lang.*;
3 import gnu.lists.*;
4 import gnu.mapping.*;
5 import gnu.expr.*;
6 import java.util.Stack JavaDoc;
7
8 /**
9  * The Syntax transformer that re-writes the Scheme "let" primitive.
10  * This only handles standard "unnamed" let.
11  * The let macro in ../lib/let.scm handles named let as well.
12  * @author Per Bothner
13  */

14
15 public class let extends Syntax
16 {
17   public static final let let = new let();
18   static { let.setName("let"); }
19
20   public Expression rewrite (Object JavaDoc obj, Translator tr)
21   {
22     if (! (obj instanceof Pair))
23       return tr.syntaxError ("missing let arguments");
24     Pair pair = (Pair) obj;
25     Object JavaDoc bindings = pair.car;
26     Object JavaDoc body = pair.cdr;
27     int decl_count = Translator.listLength(bindings);
28     if (decl_count < 0)
29       return tr.syntaxError("bindings not a proper list");
30       
31     Expression[] inits = new Expression[decl_count];
32     LetExp let = new LetExp (inits);
33     Stack JavaDoc renamedAliases = null;
34     int renamedAliasesCount = 0;
35     SyntaxForm syntaxRest = null;
36     for (int i = 0; i < decl_count; i++)
37       {
38     while (bindings instanceof SyntaxForm)
39       {
40         syntaxRest = (SyntaxForm) bindings;
41         bindings = syntaxRest.form;
42         // The SyntaxForm "surrounds" both the current binding (the car),
43
// as well as the cdr - i.e. the remaining bindings.
44
}
45     Pair bind_pair = (Pair) bindings;
46     Object JavaDoc bind_pair_car = bind_pair.car;
47     SyntaxForm syntax = syntaxRest;
48     if (bind_pair_car instanceof SyntaxForm)
49       {
50         syntax = (SyntaxForm) bind_pair_car;
51         bind_pair_car = syntax.form;
52       }
53     if (! (bind_pair_car instanceof Pair))
54       return tr.syntaxError ("let binding is not a pair:"+bind_pair_car);
55     Pair binding = (Pair) bind_pair_car;
56     Object JavaDoc name = binding.car;
57     TemplateScope templateScope;
58     if (name instanceof SyntaxForm)
59       {
60         SyntaxForm sf = (SyntaxForm) name;
61         name = sf.form;
62         templateScope = sf.scope;
63       }
64     else
65       templateScope = syntax == null ? null : syntax.scope;
66     if (! (name instanceof String JavaDoc) && ! (name instanceof Symbol))
67       return tr.syntaxError("variable "+name+" in let binding is not a symbol: "+obj);
68
69     Declaration decl = let.addDeclaration(name);
70
71     if (templateScope != null)
72       {
73         Declaration alias = tr.makeRenamedAlias(decl, templateScope);
74         if (renamedAliases == null)
75           renamedAliases = new Stack JavaDoc();
76         renamedAliases.push(alias);
77         renamedAliasesCount++;
78       }
79
80     Object JavaDoc binding_cdr = binding.cdr;
81     while (binding_cdr instanceof SyntaxForm)
82       {
83         syntax = (SyntaxForm) binding_cdr;
84         binding_cdr = syntax.form;
85       }
86     if (! (binding_cdr instanceof Pair))
87       return tr.syntaxError("let has no value for '"+name+"'");
88     binding = (Pair) binding_cdr;
89     binding_cdr = binding.cdr;
90     Pair init;
91     while (binding_cdr instanceof SyntaxForm)
92       {
93         syntax = (SyntaxForm) binding_cdr;
94         binding_cdr = syntax.form;
95       }
96     if (tr.matches(binding.car, "::"))
97       {
98         if (! (binding_cdr instanceof Pair)
99         || (binding = (Pair) binding_cdr).cdr == LList.Empty)
100           return tr.syntaxError("missing type after '::' in let");
101         binding_cdr = binding.cdr;
102         while (binding_cdr instanceof SyntaxForm)
103           {
104         syntax = (SyntaxForm) binding_cdr;
105         binding_cdr = syntax.form;
106           }
107       }
108     if (binding_cdr == LList.Empty)
109       {
110         init = binding;
111       }
112     else if (binding_cdr instanceof Pair)
113       {
114         decl.setType(tr.exp2Type(binding));
115         decl.setFlag(Declaration.TYPE_SPECIFIED);
116         init = (Pair) binding_cdr;
117       }
118     else
119       return tr.syntaxError("let binding for '"+name+"' is improper list");
120     inits[i] = tr.rewrite_car (init, syntax);
121     if (init.cdr != LList.Empty)
122       return tr.syntaxError("junk after declaration of "+name);
123     decl.noteValue (inits[i]);
124     bindings = bind_pair.cdr;
125       }
126
127     for (int i = renamedAliasesCount; --i >= 0; )
128       tr.pushRenamedAlias((Declaration) renamedAliases.pop());
129
130     tr.push(let);
131     let.body = tr.rewrite_body(body);
132     tr.pop(let);
133     tr.popRenamedAlias(renamedAliasesCount);
134
135     return let;
136   }
137 }
138
Popular Tags