/// <summary> /// Adds the expression and any dependent expressions to the supplied list of contained expressions. /// </summary> /// <param name="containedExpressions"></param> /// <param name="expr"></param> /// <param name="context"></param> private static void AddToContainedExpressions(List <IExpression> containedExpressions, IExpression expr, BasicTransformContext context) { containedExpressions.Add(expr); IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(expr); if (expr is IArrayIndexerExpression iaie) { foreach (var ind in iaie.Indices) { AddToContainedExpressions(containedExpressions, ind, context); } } if (baseVar == null) { return; } Containers containers = context.InputAttributes.Get <Containers>(baseVar); if (containers == null) { throw new Exception("Containers not found for: " + baseVar); } foreach (IStatement container in containers.inputs) { if (container is IForStatement ifs) { containedExpressions.Add(Builder.VarRefExpr(Recognizer.LoopVariable(ifs))); } } }
internal IVariableDeclaration DeriveArrayVariable(ICollection <IStatement> addTo, BasicTransformContext context, string name, IList <IExpression[]> arraySize, IList <IVariableDeclaration[]> newIndexVar, IList <IList <IExpression> > indices = null, IList <IList <IExpression> > wildcardVars = null, bool useLiteralIndices = false, bool copyInitializer = false) { List <IExpression[]> newSizes = new List <IExpression[]>(); List <IVariableDeclaration[]> newIndexVars = new List <IVariableDeclaration[]>(); Type innerType = varType; if (indices != null) { // add wildcard variables to newIndexVars for (int i = 0; i < indices.Count; i++) { List <IExpression> sizeBracket = new List <IExpression>(); List <IVariableDeclaration> indexVarsBracket = new List <IVariableDeclaration>(); for (int j = 0; j < indices[i].Count; j++) { IExpression index = indices[i][j]; if (Recognizer.IsStaticMethod(index, new Func <int>(GateAnalysisTransform.AnyIndex))) { int replaceCount = 0; sizeBracket.Add(ReplaceIndexVars(context, sizes[i][j], indices, wildcardVars, ref replaceCount)); IVariableDeclaration v = indexVars[i][j]; if (wildcardVars != null) { v = Recognizer.GetVariableDeclaration(wildcardVars[newIndexVars.Count][indexVarsBracket.Count]); } else if (Recognizer.GetLoopForVariable(context, v) != null) { // v is already used in a parent loop. must generate a new variable. v = GenerateLoopVar(context, "_a"); } indexVarsBracket.Add(v); } } if (sizeBracket.Count > 0) { newSizes.Add(sizeBracket.ToArray()); newIndexVars.Add(indexVarsBracket.ToArray()); } innerType = Util.GetElementType(innerType); } } int literalIndexingDepth = 0; if (arraySize != null) { newSizes.AddRange(arraySize); if (useLiteralIndices) { literalIndexingDepth = newSizes.Count; } newIndexVars.AddRange(newIndexVar); } // innerType may not be an array type, so we create the new array type here instead of descending further. Type arrayType = CodeBuilder.MakeJaggedArrayType(innerType, newSizes); int indexingDepth = (indices == null) ? 0 : indices.Count; List <IList <IExpression> > replacements = new List <IList <IExpression> >(); if (indices != null) { replacements.AddRange(indices); } for (int i = indexingDepth; i < sizes.Count; i++) { if (replacements.Count == 0) { newSizes.Add(sizes[i]); if (indexVars.Count > i) { newIndexVars.Add(indexVars[i]); } } else { // must substitute references to indexVars with indices IExpression[] sizeBracket = new IExpression[sizes[i].Length]; IVariableDeclaration[] indexVarBracket = new IVariableDeclaration[sizes[i].Length]; IList <IExpression> replacementBracket = Builder.ExprCollection(); for (int j = 0; j < sizeBracket.Length; j++) { int replaceCount = 0; sizeBracket[j] = ReplaceIndexVars(context, sizes[i][j], replacements, wildcardVars, ref replaceCount); if (replaceCount > 0) { indexVarBracket[j] = GenerateLoopVar(context, "_a"); } else if (indexVars.Count > i) { indexVarBracket[j] = indexVars[i][j]; } if (indexVarBracket[j] != null) { replacementBracket.Add(Builder.VarRefExpr(indexVarBracket[j])); } } newSizes.Add(sizeBracket); newIndexVars.Add(indexVarBracket); replacements.Add(replacementBracket); } } IVariableDeclaration arrayvd = Builder.VarDecl(CodeBuilder.MakeValid(name), arrayType); Builder.NewJaggedArray(addTo, arrayvd, newIndexVars, newSizes, literalIndexingDepth); context.InputAttributes.CopyObjectAttributesTo(declaration, context.OutputAttributes, arrayvd); // cannot copy the initializer since it will have a different size. context.OutputAttributes.Remove <InitialiseTo>(arrayvd); context.OutputAttributes.Remove <InitialiseBackwardTo>(arrayvd); context.OutputAttributes.Remove <InitialiseBackward>(arrayvd); context.OutputAttributes.Remove <VariableInformation>(arrayvd); context.OutputAttributes.Remove <SuppressVariableFactor>(arrayvd); context.OutputAttributes.Remove <LoopContext>(arrayvd); context.OutputAttributes.Remove <Containers>(arrayvd); context.OutputAttributes.Remove <ChannelInfo>(arrayvd); context.OutputAttributes.Remove <IsInferred>(arrayvd); context.OutputAttributes.Remove <QueryTypeCompilerAttribute>(arrayvd); context.OutputAttributes.Remove <DerivMessage>(arrayvd); context.OutputAttributes.Remove <PointEstimate>(arrayvd); context.OutputAttributes.Remove <DescriptionAttribute>(arrayvd); context.OutputAttributes.Remove <MarginalPrototype>(arrayvd); VariableInformation vi = VariableInformation.GetVariableInformation(context, arrayvd); vi.IsStochastic = IsStochastic; vi.sizes = newSizes; vi.indexVars = newIndexVars; if (useLiteralIndices) { vi.LiteralIndexingDepth = literalIndexingDepth; } if (marginalPrototypeExpression != null) { // substitute indices in the marginal prototype expression vi.marginalPrototypeExpression = GetMarginalPrototypeExpression(context, marginalPrototypeExpression, replacements, wildcardVars); } InitialiseTo it = context.InputAttributes.Get <InitialiseTo>(declaration); if (it != null && copyInitializer) { // if original array is indexed [i,j][k,l][m,n] and indices = [*,*][3,*] then // initExpr2 = new PlaceHolder[wildcard0,wildcard1] { new PlaceHolder[wildcard2] { new PlaceHolder[newIndexVar] { initExpr[wildcard0,wildcard1][3,wildcard2] } } } IExpression initExpr = it.initialMessagesExpression; // add indices to the initialiser expression int wildcardBracket = 0; for (int depth = 0; depth < indexingDepth; depth++) { IList <IExpression> indexCollection = Builder.ExprCollection(); int wildcardCount = 0; for (int i = 0; i < indices[depth].Count; i++) { if (Recognizer.IsStaticMethod(indices[depth][i], new Func <int>(GateAnalysisTransform.AnyIndex))) { indexCollection.Add(wildcardVars[wildcardBracket][wildcardCount]); wildcardCount++; } else { indexCollection.Add(indices[depth][i]); } } if (indexCollection.Count > 0) { if (wildcardCount > 0) { wildcardBracket++; } initExpr = Builder.ArrayIndex(initExpr, indexCollection); } } // add array creates to the initialiser expression if (newIndexVar != null) { initExpr = MakePlaceHolderArrayCreate(initExpr, newIndexVar); } if (wildcardBracket > 0) { while (wildcardBracket > 0) { wildcardBracket--; initExpr = MakePlaceHolderArrayCreate(initExpr, vi.indexVars[wildcardBracket]); } } context.OutputAttributes.Set(arrayvd, new InitialiseTo(initExpr)); } ChannelTransform.setAllGroupRoots(context, arrayvd, false); return(arrayvd); }