Пример #1
0
        public override void AfterVisit(ForStatement node)
        {
            Expression whereCondition = null, between = null;
            var currentLoopContext = _loopContextStack.Pop();

            if (node.Where != null)
                whereCondition = _expressionStack.Pop();

            if (node.Between != null)
                between = _expressionStack.Pop();

            var loopBody = _expressionStack.Pop();
            Expression enumerable = _expressionStack.Pop();

            ParameterExpression loopVariable = node.GetExtension<ForExtension>().LoopVariableSymbol.GetGetExpression() as ParameterExpression;
            Expression getEnumerator = whereCondition == null
                                           ? Expression.Call(Expression.Convert(enumerable, typeof(IEnumerable)), typeof(IEnumerable).GetMethod("GetEnumerator"))
                                           : getWhereEnumerator(node, enumerable, whereCondition);

            ParameterExpression enumerator = Expression.Parameter(typeof(IEnumerator), EnumeratorParameterExpressionName);
            List<Expression> loop = new List<Expression> { Expression.Assign(enumerator, getEnumerator) };

            //The loop "wrapper", which wraps the actual loop body
            //It's purpose is to assign the loopVariable after each iteration and
            //to write the between clause to the current output
            var iteratorAdvancerAndLoopExiter =
                Expression.IfThenElse(
                    Expression.Call(enumerator, typeof(IEnumerator).GetMethod("MoveNext")),
                    between == null ? Expression.Empty() : SafeWriteToTopWriter(between),
                    Expression.Goto(currentLoopContext.BreakLabel));
            BlockExpression loopWrapper = Expression.Block(
                // ReSharper disable AssignNullToNotNullAttribute
                Expression.Assign(loopVariable, Expression.Property(enumerator, typeof(IEnumerator).GetProperty("Current"))),
                // ReSharper restore AssignNullToNotNullAttribute
                loopBody,
                Expression.Label(currentLoopContext.ContinueLabel),
                iteratorAdvancerAndLoopExiter);

            //Primes the loop
            ConditionalExpression outerIf = Expression.IfThen(
                Expression.Call(enumerator, typeof(IEnumerator).GetMethod("MoveNext")),
                Expression.Loop(loopWrapper, currentLoopContext.BreakLabel));
            loop.Add(outerIf);

            var parameters = node.LoopBody.GetExtension<ScopeExtension>().SymbolTable.GetParameterExpressions().Union(new[] { enumerator }).ToArray();
            _expressionStack.Push(node, MaybeBlock(parameters, loop));
            base.AfterVisit(node);
        }
Пример #2
0
 public override void AfterVisit(ForStatement node)
 {
     base.AfterVisit(node);
     if(node.LoopBody.GetExtension<ScopeExtension>().SymbolTable.FindInCurrentScope(node.LoopVariable.Text) != null)
         _errorCollector.VariableOfSameNameDefinedInForLoopScope(node.LoopVariable);
     else
         node.GetExtension<ForExtension>().LoopVariableSymbol = node.LoopBody.GetExtension<ScopeExtension>().SymbolTable.Add(node.LoopVariable.Text);
 }