private bool VisitNodeInCycle(TicNode node) { node.VisitMark = NotVisited; _cycle.Push(node); if (_cycleInitiator != node) { //continue to collect cycle route return(false); } // Ref and/or ancestor cycle found // That means all elements in cycle have to be merged // (a<= b <= c = a) => (a = b = c) var merged = SolvingFunctions.MergeGroup(_cycle.Reverse()); // Cycle is merged _cycle = null; _cycleInitiator = null; // continue toposort algorithm return(Visit(merged)); // Whole cycle is not found yet // step back }
public void SetCall(IState[] argThenReturnTypes, int[] argThenReturnIds) { if (argThenReturnTypes.Length != argThenReturnIds.Length) { throw new ArgumentException("Sizes of type and id array have to be equal"); } for (int i = 0; i < argThenReturnIds.Length - 1; i++) { var type = argThenReturnTypes[i]; var argId = argThenReturnIds[i]; switch (type) { case Primitive primitive: { var node = GetOrCreateNode(argId); if (!node.TrySetAncestor(primitive)) { throw new InvalidOperationException(); } break; } case Array array: { //var node = GetOrCreateNode(argId); //var ancestor = CreateVarType(array); //ancestor.BecomeAncestorFor(node); //todo Upcast support GetOrCreateArrayNode(argId, array.ElementNode); break; } case Fun fun: { var node = GetOrCreateNode(argId); var ancestor = CreateVarType(fun); ancestor.BecomeAncestorFor(node); break; } case RefTo refTo: { var node = GetOrCreateNode(argId); refTo.Node.BecomeAncestorFor(node); break; } default: throw new InvalidOperationException(); } } var returnId = argThenReturnIds[argThenReturnIds.Length - 1]; var returnType = argThenReturnTypes[argThenReturnIds.Length - 1]; var returnNode = GetOrCreateNode(returnId); returnNode.State = SolvingFunctions.GetMergedState(returnNode.State, returnType); }
public FinalizationResults Solve() { PrintTrace(); Console.WriteLine(); var sorted = Toposort(); Console.WriteLine("Decycled:"); PrintTrace(); Console.WriteLine(); Console.WriteLine("Set up"); SolvingFunctions.SetUpwardsLimits(sorted); PrintTrace(); Console.WriteLine(); Console.WriteLine("Set down"); SolvingFunctions.SetDownwardsLimits(sorted); PrintTrace(); SolvingFunctions.Destruction(sorted); Console.WriteLine(); Console.WriteLine("Destruct Down"); PrintTrace(); Console.WriteLine("Finalize"); var results = SolvingFunctions.FinalizeUp(sorted, _outputNodes.ToArray()); Console.WriteLine($"Type variables: {results.TypeVariables.Length}"); foreach (var typeVariable in results.TypeVariables) { Console.WriteLine(" " + typeVariable); } Console.WriteLine($"Syntax node types: "); foreach (var syntaxNode in results.SyntaxNodes.Where(s => s != null)) { Console.WriteLine(" " + syntaxNode); } Console.WriteLine($"Named node types: "); foreach (var namedNode in results.NamedNodes) { Console.WriteLine(" " + namedNode); } return(results); }
public SolvingNode[] Toposort() { int iteration = 0; while (true) { var allNodes = _syntaxNodes.Concat(_variables.Values).Concat(_typeVariables).ToArray(); if (iteration > allNodes.Length * allNodes.Length) { throw new InvalidOperationException("Infinite cycle detected. Types cannot be solved"); } iteration++; var result = NodeToposortFunctions.Toposort(allNodes); switch (result.Status) { case SortStatus.MemebershipCycle: throw new InvalidOperationException("Reqursive type defenition"); case SortStatus.AncestorCycle: { var cycle = result.Order; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine($"Found cycle: "); Console.ResetColor(); Console.WriteLine(string.Join("->", cycle.Select(r => r.Name))); //main node. every other node has to reference on it SolvingFunctions.MergeGroup(cycle); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"Cycle normalization results: "); Console.ResetColor(); foreach (var solvingNode in cycle) { solvingNode.PrintToConsole(); } break; } case SortStatus.Sorted: Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine($"Toposort results: "); Console.ResetColor(); Console.WriteLine(string.Join("->", result.Order.Select(r => r.Name))); Console.WriteLine("Refs:" + string.Join(",", result.Refs.Select(r => r.Name))); return(result.Order.Union(result.Refs).ToArray()); } } }
private SolvingNode GetOrCreateArrayNode(int id, SolvingNode elementType) { while (_syntaxNodes.Count <= id) { _syntaxNodes.Add(null); } var alreadyExists = _syntaxNodes[id]; if (alreadyExists != null) { alreadyExists.State = SolvingFunctions.GetMergedState(new Array(elementType), alreadyExists.State); return(alreadyExists); } var res = new SolvingNode(id.ToString(), new Array(elementType), SolvingNodeType.SyntaxNode); _syntaxNodes[id] = res; return(res); }
private void SetOrCreateLambda(int lambdaId, SolvingNode[] args, SolvingNode ret) { var fun = Fun.Of(args, ret); while (_syntaxNodes.Count <= lambdaId) { _syntaxNodes.Add(null); } var alreadyExists = _syntaxNodes[lambdaId]; if (alreadyExists != null) { alreadyExists.State = SolvingFunctions.GetMergedState(fun, alreadyExists.State); } else { var res = new SolvingNode(lambdaId.ToString(), fun, SolvingNodeType.SyntaxNode); _syntaxNodes[lambdaId] = res; } }