Expr IStatementVisitor <Expr> .Visit(Statement.ForIn statement)
{
var iterFuncVar = Expr.Variable(typeof(object));
var iterStateVar = Expr.Variable(typeof(object));
var iterableVar = Expr.Variable(typeof(object));
var iterVars = new[] { iterFuncVar, iterStateVar, iterableVar };
var valueExprs = statement.Values.Select(v => Expr.Convert(v.Visit(this), typeof(object)));
var assignIterVars = VarargsExpandAssignment(iterVars, valueExprs);
var parentScope = scope;
scope = Scope.CreateChild(scope);
var locals = statement.Identifiers.Select(id => scope.AddLocal(id)).ToList();
var invokeIterFunc = Expr.Dynamic(Context.DynamicCache.GetInvokeBinder(new CallInfo(2)),
typeof(object), iterFuncVar, iterStateVar, iterableVar);
var loop =
Expr.Loop(
Expr.Block(
locals,
VarargsExpandAssignment(
locals,
new[] { invokeIterFunc }),
Expr.IfThen(Expr.Equal(locals[0], Expr.Constant(null)), Expr.Break(scope.BreakLabel())),
Visit(statement.Body)),
scope.BreakLabel());
var expr = Expr.Block(iterVars, assignIterVars, loop);
scope = parentScope;
return(expr);
}