Beispiel #1
0
        /// <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)));
                }
            }
        }
Beispiel #2
0
        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);
        }