Пример #1
0
        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
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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());
                }
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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;
            }
        }