1 package kawa.standard; 2 import kawa.lang.*; 3 import gnu.mapping.*; 4 import gnu.expr.*; 5 import gnu.lists.*; 6 7 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 18 boolean star; 19 20 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 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 bindings, Object 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 savePos = tr.pushPositionOf(bind_pair); 52 try 53 { 54 Expression value; 55 Pair binding; 56 Object name = bind_pair.car; 57 if (name instanceof String || name instanceof Symbol) 58 { 59 value = defaultInit; 60 } 61 else if (name instanceof Pair 62 && ((binding = (Pair) name).car instanceof String 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 |