コード例 #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 BeforeVisit(ForStatement node)
        {
            base.BeforeVisit(node);

            pushLoopContext();

            node.LoopBody.GetExtension<StatementBlockExtensions>().AnalyzeSymbolsExternally = true;
        }
コード例 #3
0
        static Expression getWhereEnumerator(ForStatement node, Expression enumerable, Expression whereExpression)
        {
            var methodInfo = typeof(RuntimeHelpers).GetMethod("GetWhereEnumerable");
            var arguments = new Expression[]
            {
                Expression.Convert(enumerable, typeof(IEnumerable)),
                Expression.Lambda(whereExpression, node.Where.GetExtension<ScopeExtension>().SymbolTable.GetParameterExpressions())
            };

            Expression retval = Expression.Call(methodInfo, arguments);
            return Expression.Call(retval, "GetEnumerator", new Type[] { });
        }
コード例 #4
0
ファイル: AstVisitorBase.cs プロジェクト: dlurton/Happy
 public virtual void BeforeVisit(ForStatement node)
 {
     this.BeforeVisitCatchAll(node);
 }
コード例 #5
0
ファイル: AstVisitorBase.cs プロジェクト: dlurton/Happy
 public virtual void AfterVisit(ForStatement node)
 {
     this.AfterVisitCatchAll(node);
 }
コード例 #6
0
ファイル: ScopedAstVisitorBase.cs プロジェクト: dlurton/Happy
 public override void BeforeVisit(ForStatement node)
 {
     base.BeforeVisit(node);
     _scopeStack.Push(node.LoopBody.GetExtension<ScopeExtension>().SymbolTable);
 }
コード例 #7
0
ファイル: ScopedAstVisitorBase.cs プロジェクト: dlurton/Happy
 public override void AfterVisit(ForStatement node)
 {
     _scopeStack.Pop();
     base.AfterVisit(node);
 }
コード例 #8
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);
 }