// Ditto, but for LET*, which evaluates the bindings sequentially, // each visible to its successors. private static Datum ConstructLambdaFromLetStar(LetComps comps) { LetComps outer; outer.self = null; outer.bindings = new List<Pair>(); if (comps.bindings.Count == 0) { outer.body = comps.body; } else { Pair firstBinding = comps.bindings[0]; comps.bindings.RemoveAt(0); LetComps inner; inner.self = null; inner.bindings = comps.bindings; inner.body = comps.body; outer.bindings.Add(firstBinding); // A body is a *list* of expressions. outer.body = new Pair(ConstructLambdaFromLetStar(inner), null); } Datum transform = ConstructLambdaFromLet(outer); Shell.Trace("LET* transform produced ", transform); return transform; }
// Take a bag of LET components and write the equivalent LAMBDA // expression. Handles named LET. private static Datum ConstructLambdaFromLet(LetComps comps) { // Unzip! List<Datum> names = new List<Datum>(); List<Datum> vals = new List<Datum>(); foreach (Pair p in comps.bindings) { names.Add(p.First); vals.Add(p.Second); } Datum formals = Primitives.List(names); Datum bodyFunc = new Pair(new Symbol("lambda"), new Pair(formals, comps.body)); Datum transform; if (comps.self == null) { // Unnamed LET. transform = new Pair(bodyFunc, Primitives.List(vals)); } else { // Named LET. transform = new Pair(Datum.List(new Symbol("let"), Datum.List(Datum.List(comps.self, null)), Datum.List(new Symbol("set!"), comps.self, bodyFunc), comps.self), Primitives.List(vals)); } Shell.Trace("LET transform produced ", transform); return transform; }