Пример #1
0
        public bool Apply(ICompositeState ancestor, ICompositeState descendant, TicNode ancestorNode,
                          TicNode descendantNode)
        {
            if (ancestor.GetType() != descendant.GetType())
            {
                return(false);
            }
            if (ancestor is StateArray ancArray)
            {
                var descArray = (StateArray)descendant;
                SolvingFunctions.PushConstraints(descArray.ElementNode, ancArray.ElementNode);
                return(true);
            }

            if (ancestor is StateFun ancFun)
            {
                var descFun = (StateFun)descendant;
                if (descFun.ArgsCount != ancFun.ArgsCount)
                {
                    return(false);
                }
                PushFunTypeArgumentsConstraints(descFun, ancFun);
                return(true);
            }
            if (ancestor is StateStruct ancStruct)
            {
                return(TryMergeStructFields(ancStruct, (StateStruct)descendant));
            }
            return(false);
        }
Пример #2
0
        private static void PushFunTypeArgumentsConstraints(StateFun descFun, StateFun ancFun)
        {
            for (int i = 0; i < descFun.ArgsCount; i++)
            {
                SolvingFunctions.PushConstraints(descFun.ArgNodes[i], ancFun.ArgNodes[i]);
            }

            SolvingFunctions.PushConstraints(descFun.RetNode, ancFun.RetNode);
        }
Пример #3
0
        public bool Apply(
            ICompositeState ancestor,
            ConstrainsState descendant,
            TicNode ancestorNode,
            TicNode descendantNode)
        {
            // if ancestor is composite type then descendant HAS to have same composite type
            // y:int[] = a:[..]  # 'a' has to be an array
            if (ancestor is StateArray ancArray)
            {
                var result = SolvingFunctions.TransformToArrayOrNull(descendantNode.Name, descendant);
                if (result == null)
                {
                    return(false);
                }
                if (result.ElementNode == ancArray.ElementNode)
                {
                    descendantNode.RemoveAncestor(ancestorNode);
                    return(true);
                }

                result.ElementNode.AddAncestor(ancArray.ElementNode);
                descendantNode.State = result;
                descendantNode.RemoveAncestor(ancestorNode);
                SolvingFunctions.PushConstraints(result.ElementNode, ancArray.ElementNode);
                return(true);
            }
            // y:f(x) = a:[..]  # 'a' has to be a functional variable
            if (ancestor is StateFun ancFun)
            {
                var descFun = SolvingFunctions.TransformToFunOrNull(descendantNode.Name, descendant, ancFun);
                if (descFun == null)
                {
                    return(false);
                }
                if (!descendantNode.State.Equals(descFun))
                {
                    descendantNode.State = descFun;
                    PushFunTypeArgumentsConstraints(descFun, ancFun);
                }

                return(true);
            }
            // y:user = a:[..]  # 'a' has to be a struct, that converts to type of 'user'
            if (ancestor is StateStruct ancStruct)
            {
                var descStruct = SolvingFunctions.TransformToStructOrNull(descendant, ancStruct);
                if (descStruct == null)
                {
                    return(false);
                }
                if (descendantNode.State.Equals(descStruct))
                {
                    descendantNode.RemoveAncestor(ancestorNode);
                    return(true);
                }
                descendantNode.State = descStruct;
                if (TryMergeStructFields(ancStruct, descStruct))
                {
                    descendantNode.RemoveAncestor(ancestorNode);
                    return(true);
                }
            }
            return(false);
        }