protected override Expression OnGenerate() { var names = (CommonTree) Tree.Children[0]; var hasInitializers = Tree.Children.Count > 1; if (hasInitializers) { var scratch = Expression.Parameter(typeof (object)); var rValueList = new CompileTimeRValueList(Tree.Children[1], t => Gen<Exp>(t), scratch); var locals = new List<Expression>(); for (var i = 0; i < names.ChildCount; i++) { var name = names.Children[i].Text; var exp = rValueList.Next(); locals.Add(GenerateDefineLocal(name, exp)); } locals.Add(rValueList.EvalRestAndDiscard()); return Expression.Block( typeof (void), new[] { scratch }, locals); } else { var locals = new List<Expression>(); for (var i = 0; i < names.ChildCount; i++) { var name = names.Children[i].Text; locals.Add(GenerateDefineLocal(name, Expression.Constant(null, typeof (object)))); } return Expression.Block(typeof (void), locals); } }
protected override Expression OnGenerate() { Scope = Scope.NewForEachScope(); var f = Expression.Parameter(typeof (object)); var s = Expression.Parameter(typeof (object)); var seedVar = Expression.Parameter(typeof (object)); var topScratch = Expression.Parameter(typeof (object)); var rValues = new CompileTimeRValueList(Tree.Children[2], tree => Gen<Exp>(tree), topScratch); var assignF = Expression.Assign(f, rValues.Next()); var assignS = Expression.Assign(s, rValues.Next()); var initSeed = Expression.Assign(seedVar, rValues.Next()); var fResult = Expression.Parameter(typeof (object)); var invoke = Expression.Dynamic(InvokeBinder.New(StaticTables, new CallInfo(2)), typeof (object), f, s, seedVar); var assignFResult = Expression.Assign(fResult, invoke); var assignLocal = new List<Expression>(); var parameters = new List<ParameterExpression> {fResult}; var names = (CommonTree) Tree.Children[1]; for (var i = 0; i < names.Children.Count; i++) { var name = names.Children[i].Text; var rValue = i == 0 ? RValueList.EmitHandleFirst(fResult) : RValueList.EmitHandleRest(fResult, i); ParameterExpression varN; assignLocal.Add(GenerateDefineLocal(name, rValue, out varN)); parameters.Add(varN); } var checkNull = Expression.Dynamic( EqualityOperationBinder.New(StaticTables), typeof (object), parameters[1], Expression.Constant(null, typeof (object))); var checkCondition = Expression.IfThen(ToBool(checkNull), Expression.Goto(Scope.BreakTarget)); var assignSeed = Expression.Assign(seedVar, parameters[1]); var blockTree = Tree.Children[0]; var block = Gen<Block>(blockTree); var loopBody = Expression.Block( typeof (void), parameters, assignFResult, Expression.Block(typeof (void), assignLocal), checkCondition, assignSeed, block); var loop = Expression.Loop(loopBody, Scope.BreakTarget, Scope.ContinueTarget); var enclosingBlock = Expression.Block( typeof (void), new[] { f, s, seedVar, topScratch }, assignF, assignS, initSeed, loop); return enclosingBlock; }