/// <summary> /// Creates a loop context, given the current transform context. /// </summary> internal LoopContext(List <IForStatement> loops) { this.loops = loops; foreach (IForStatement loop in loops) { loopVariables.Add(Recognizer.LoopVariable(loop)); } }
/// <summary> /// The containers of the current transform context. /// </summary> /// <param name="context"></param> /// <param name="loopVarsHaveOneContainer"></param> internal Containers(BasicTransformContext context, bool loopVarsHaveOneContainer = true) // : this(FindContainers(context)) { if (loopVarsHaveOneContainer) { int ancIndex2 = Recognizer.GetAncestorIndexOfLoopBeingInitialized(context); if (ancIndex2 != -1) { // For a loop variable, the loop is the only container. // This is needed to allow re-ordering nested loops. Otherwise, the inner loop variable would always require the outer loop around it. // It is also useful for ignoring conditioned loops. TransformInfo ti = context.InputStack[ancIndex2]; IForStatement ifs = (IForStatement)ti.inputElement; IStatement container = CreateContainer(ifs); inputs.Add(container); #if ignoreOutput outputs.Add(container); #else outputs.Add((IStatement)ti.PrimaryOutput); #endif var loopVar = Recognizer.LoopVariable(ifs); bool mustRemove = false; if (!context.InputAttributes.Has <Containers>(loopVar)) { context.InputAttributes.Set(loopVar, this); mustRemove = true; } var initExpr = ((IExpressionStatement)ifs.Initializer).Expression; this.AddContainersNeededForExpression(context, initExpr); this.AddContainersNeededForExpression(context, ifs.Condition); if (mustRemove) { context.InputAttributes.Remove <Containers>(loopVar); } return; } } // exclude the current statement. int ancIndex = context.FindAncestorIndex <IStatement>(); for (int i = 0; i < ancIndex; i++) { TransformInfo ti = context.InputStack[i]; IStatement inputElement = ti.inputElement as IStatement; if (IsContainer(inputElement) && !context.InputAttributes.Has <ConvergenceLoop>(inputElement)) { inputs.Add(CreateContainer(inputElement)); outputs.Add((IStatement)ti.PrimaryOutput); } } }
/// <summary> /// Check that the replacements are safe. /// </summary> /// <param name="context"></param> /// <param name="expr"></param> /// <param name="replacedIndexVars"></param> private static void CheckReplacements(BasicTransformContext context, IExpression expr, Dictionary <IVariableDeclaration, IExpression> replacedIndexVars) { foreach (var v in Recognizer.GetVariables(expr)) { Containers containers = context.InputAttributes.Get <Containers>(v); if (containers != null && !replacedIndexVars.ContainsKey(v)) { foreach (IStatement container in containers.inputs) { if (container is IForStatement ifs) { IVariableDeclaration loopVar = Recognizer.LoopVariable(ifs); if (replacedIndexVars.TryGetValue(loopVar, out IExpression actualIndex)) { context.Error($"Cannot index {expr} by {loopVar.Name}={actualIndex} since {v.Name} has an implicit dependency on {loopVar.Name}. Try making the dependency explicit by putting {v.Name} into an array indexed by {loopVar.Name}"); } } } } } }