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); }
public override void BeforeVisit(ForStatement node) { base.BeforeVisit(node); pushLoopContext(); node.LoopBody.GetExtension<StatementBlockExtensions>().AnalyzeSymbolsExternally = true; }
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[] { }); }
public virtual void BeforeVisit(ForStatement node) { this.BeforeVisitCatchAll(node); }
public virtual void AfterVisit(ForStatement node) { this.AfterVisitCatchAll(node); }
public override void BeforeVisit(ForStatement node) { base.BeforeVisit(node); _scopeStack.Push(node.LoopBody.GetExtension<ScopeExtension>().SymbolTable); }
public override void AfterVisit(ForStatement node) { _scopeStack.Pop(); base.AfterVisit(node); }
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); }