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 ; 7 8 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 obj, Translator tr) 21 { 22 if (! (obj instanceof Pair)) 23 return tr.syntaxError ("missing let arguments"); 24 Pair pair = (Pair) obj; 25 Object bindings = pair.car; 26 Object 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 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 } 45 Pair bind_pair = (Pair) bindings; 46 Object 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 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 ) && ! (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 (); 76 renamedAliases.push(alias); 77 renamedAliasesCount++; 78 } 79 80 Object 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 |