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)); }
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); }