public override DLR.Expression GenerateExpressionTree(GenScope scope)
        {
            var loop = scope.CreateLoop();

            var condition = Utils.Convert(Condition.GenerateExpressionTree(scope), typeof(bool));
            var block     = Block.GenerateExpressionTree(loop);

            return(Utils.While(condition, block, DLR.Expression.Empty(), loop.BreakTarget, loop.ContinueTarget));
        }
Exemple #2
0
        public override DLR.Expression GenerateExpressionTree(GenScope scope)
        {
            var loopScope = scope.CreateLoop();

            var bindVar = DLR.Expression.Variable(typeof(object), VariableName);
            var inExpr  = InExpression.GenerateExpressionTree(scope);

            loopScope.Definitions[VariableName] = bindVar;

            var block = Block.GenerateExpressionTree(loopScope);

            var enumeratorVar = DLR.Expression.Variable(typeof(object), "$enumeratorVar");

            var getEnumeratorCall = DLR.Expression.Dynamic(
                scope.Runtime.GetInvokeMemberBinder(new Tuple <string, CallInfo>("GetEnumerator", new CallInfo(0))),
                typeof(object),
                inExpr);

            var enumeratorAssign  = DLR.Expression.Assign(enumeratorVar, getEnumeratorCall);
            var enumeratorDispose = DLR.Expression.Dynamic(scope.Runtime.GetInvokeMemberBinder(new Tuple <string, CallInfo>("Dispose", new CallInfo(0))),
                                                           typeof(void),
                                                           enumeratorVar);

            var moveNextCall = DLR.Expression.Dynamic(scope.Runtime.GetInvokeMemberBinder(new Tuple <string, CallInfo>("MoveNext", new CallInfo(0))),
                                                      typeof(object),
                                                      enumeratorVar);

            var loop =
                DLR.Expression.Loop(
                    DLR.Expression.IfThenElse(
                        DLR.Expression.Convert(
                            DLR.Expression.Dynamic(scope.Runtime.GetBinaryOperationBinder(ExpressionType.Equal), typeof(object), moveNextCall, DLR.Expression.Constant(true)),
                            typeof(bool)),
                        DLR.Expression.Block(
                            new[] { bindVar },
                            DLR.Expression.Assign(bindVar, DLR.Expression.Dynamic(scope.Runtime.GetGetMemberBinder("Current"), typeof(object), enumeratorVar)),
                            block),
                        DLR.Expression.Break(loopScope.BreakTarget)),
                    loopScope.BreakTarget,
                    loopScope.ContinueTarget);

            var tryFinally =
                DLR.Expression.TryFinally(
                    loop,
                    DLR.Expression.IfThen( //Arrays do not implement IDisposable, so we need to check
                        DLR.Expression.TypeIs(enumeratorVar, typeof(IDisposable)), enumeratorDispose));

            var body =
                DLR.Expression.Block(
                    new[] { enumeratorVar },
                    enumeratorAssign,
                    tryFinally);

            return(body);
        }