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); } }
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); }
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))); }