public override IUnboundExpr Transform(LetExpr expr) { // a let expression desugars like this: // // let a b <- Foo then Bar else Bang // // becomes... // // def let__ <- Foo // if Some? let__ then // def a b <- 0 SomeValue let__ // Bar // else Bang var c = new CodeBuilder(mNameGenerator, expr.Position); var option = c.TempName(); return c.Block( c.Def(option, expr.Condition), c.If(c.Call("Some?", option), c.Block( c.Def(expr.Names, c.Call("SomeValue", option)), expr.ThenBody), expr.ElseBody)); }
public override IUnboundExpr Transform(LetExpr expr) { // a let expression desugars like this: // // let a b <- Foo then Bar else Bang // // becomes... // // def let__ <- Foo // if Some? let__ then // def a b <- 0 SomeValue let__ // Bar // else Bang var c = new CodeBuilder(mNameGenerator, expr.Position); var option = c.TempName(); return(c.Block( c.Def(option, expr.Condition), c.If(c.Call("Some?", option), c.Block( c.Def(expr.Names, c.Call("SomeValue", option)), expr.ThenBody), expr.ElseBody))); }
public override IUnboundExpr Transform(LoopExpr expr) { // a for expression is basically syntactic sugar for a while expression // and one or more iterators. for example, the following: // // for foo <- bar do // Print foo // end // // is equivalent to: // // def _fooIter <- Iterate bar // while MoveNext _fooIter do // def foo <- Current _fooIter // Print foo // end // // so, to bind a for expression, we just desugar it, then bind that. var c = new CodeBuilder(mNameGenerator, expr.Position); var topExprs = new List<IUnboundExpr>(); var conditionExpr = (IUnboundExpr)null; var whileExprs = new List<IUnboundExpr>(); // instantiate each clause foreach (var clause in expr.Clauses) { c.SetPosition(clause.Position); var condition = (IUnboundExpr)null; if (clause.IsWhile) { condition = clause.Expression; } else { var iterName = mNameGenerator.Generate(); topExprs.Add(c.Def(iterName, c.Call("Iterate", clause.Expression))); whileExprs.Add(c.Def(clause.Name, c.Call("Current", iterName))); condition = c.Call("MoveNext", iterName); } if (conditionExpr == null) { conditionExpr = condition; } else { // combine with previous condition(s) conditionExpr = c.Op(conditionExpr, "&", condition); } } // create the while loop c.SetPosition(expr.Position); whileExprs.Add(expr.Body); var whileExpr = c.While( conditionExpr, c.Block(whileExprs)); topExprs.Add(whileExpr); // build the whole block return c.Block(topExprs); }