Пример #1
0
        static object solverAliasImpl(CallExpr ce, Generator.Ctx ctx)
        {
            var alias = OPs.TryAsName(ce.args[0], ctx);

            if (alias == null)
            {
                throw new SolverException(string.Format(ce.funcName + "(alias ...): alias must be constant or name instead of [{0}]", ce.args[0]));
            }
            var target = (ce.args.Count > 1) ? OPs.TryAsName(ce.args[1], ctx) : string.Empty;

            if (target == null)
            {
                throw new SolverException(string.Format(ce.funcName + "(..., target ...): target must be constant or name instead of [{0}]", ce.args[0]));
            }
            int priority = (ce.args.Count > 2) ? Convert.ToInt32(ctx.GetConstant(ce.args[2])) : 255;
            int i        = ctx.GetOrCreateIndexOf(optionSolverAliases);
            var aliases  = ctx[i] as SolverAliases;

            if (aliases == null)
            {
                aliases = new SolverAliases();
                ctx[i]  = aliases;
            }
            switch (ce.funcName)
            {
            case nameof(solverAlias):
                return(aliases.Set(alias, target, priority));

            case nameof(solverAliasPush):
                return(aliases.Push(alias, target));

            case nameof(solverAliasPop):
                return(aliases.Pop(alias));

            default:
                throw new NotImplementedException(ce.funcName);
            }
        }
Пример #2
0
            public static Dictionary <string, Dictionary <string, int> > Find(IEnumerable <FuncInfo> availableFunctions,
                                                                              SolverAliases aliases,
                                                                              int maxDistance          = int.MaxValue,
                                                                              string[] sourceValues    = null,
                                                                              string[] dependentValues = null)
            {
                var dependence = new Dictionary <string, Dictionary <string, int> >(StringComparer.OrdinalIgnoreCase);

                // dependencies with "distance" = 1
                foreach (var fi in availableFunctions)
                {
                    foreach (var value in fi.pureOuts)
                    {
                        var valueDeps = aliases.AtKey(dependence, value, null);
                        if (valueDeps == null)
                        {
                            valueDeps         = new Dictionary <string, int>(StringComparer.OrdinalIgnoreCase);
                            dependence[value] = valueDeps;
                        }
                        foreach (var src in fi.inputs)
                        {
                            valueDeps[src] = 1;
                        }
                    }
                }

                if (maxDistance > 1)
                {
                    // dependencies with "distance" > 1
                    int prevDistance = 1;

                    if (sourceValues != null)
                    {
                        var emptyDeps = new Dictionary <string, int>(0);
                        foreach (var value in sourceValues)
                        {
                            var valueDeps = aliases.AtKey(dependence, value, null);
                            if (valueDeps == null)
                            {
                                dependence[value] = emptyDeps;
                            }
                            else
                            {
                                valueDeps.Clear();
                            }
                        }
                    }


                    var nextq = new Dictionary <string, bool>(dependence.Count, StringComparer.OrdinalIgnoreCase);
                    foreach (var value in (dependentValues != null) ? dependentValues.Distinct() : dependence.Keys)
                    {
                        nextq[value] = true;
                    }

                    var queue = new Dictionary <string, bool>(dependence.Count, StringComparer.OrdinalIgnoreCase);

                    while (prevDistance < maxDistance)
                    {
                        {
                            var tmp = nextq;
                            nextq = queue;
                            queue = tmp;
                        }
                        foreach (var valueName in queue.Keys)
                        {
                            if (valueName.Length == 0)
                            {
                                break;
                            }
                            var valueDeps = aliases.AtKey(dependence, valueName, null);
                            if (valueDeps == null)
                            {
                                continue;
                            }
                            var  prevLvlDeps = valueDeps.Where(dep => dep.Value == prevDistance).ToArray();
                            bool newDepAdded = false;
                            foreach (var dep in prevLvlDeps)
                            {
                                var srcDeps = aliases.AtKey(dependence, dep.Key, null);
                                if (srcDeps != null)
                                {
                                    foreach (var srcDep in srcDeps)
                                    {
                                        int dist = aliases.AtKey(valueDeps, srcDep.Key, 0);
                                        if (dist == 0)
                                        {
                                            valueDeps[srcDep.Key] = prevDistance + 1;
                                            nextq[srcDep.Key]     = true;
                                            newDepAdded           = true;
                                        }
                                    }
                                }
                            }
                            if (newDepAdded)
                            {
                                nextq[valueName] = true;
                            }
                        }
                        queue.Clear();
                        if (nextq.Count == 0)
                        {
                            break;
                        }
                        prevDistance++;
                    }
                }
                return(dependence);
            }
Пример #3
0
 public static IEnumerable <FuncInfo> GetFuncInfos(IEnumerable <FuncDef> funcDefs, SolverAliases aliasOf, Func <FuncInfo, bool> funcFilter = null)
 {
     if (funcFilter == null)
     {
         funcFilter = x => true;
     }
     return(funcDefs.Select(fd => FuncInfo.Create(fd, aliasOf)).Where(fi => fi != null && funcFilter(fi)));
 }