Example #1
0
        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);
            }
        }
Example #2
0
        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;
        }