Exemple #1
0
            static void ThrowIfStateHasRecursiveTypeDefeinitionReq(ITicNodeState state, int bypassNumber)
            {
                switch (state)
                {
                case StateRefTo refTo:
                    ThrowIfNodeHasRecursiveTypeDefenitionReq(refTo.Node, 1);
                    break;

                case ICompositeState composite:
                    foreach (var member in composite.Members)
                    {
                        ThrowIfNodeHasRecursiveTypeDefenitionReq(member, 1);
                    }
                    break;

                case ConstrainsState constrains:
                    if (constrains.HasDescendant)
                    {
                        ThrowIfStateHasRecursiveTypeDefeinitionReq(constrains.Descedant, 1);
                    }
                    if (constrains.HasAncestor)
                    {
                        ThrowIfStateHasRecursiveTypeDefeinitionReq(constrains.Ancestor, 1);
                    }
                    break;
                }
            }
 public IncompatibleAncestorSyntaxNodeException(int syntaxNodeId, ITicNodeState ancestor, ITicNodeState descendant)
     : base($"Incompatible ancestor {ancestor}=>{descendant} at node {syntaxNodeId}")
 {
     SyntaxNodeId = syntaxNodeId;
     Ancestor     = ancestor;
     Descendant   = descendant;
 }
Exemple #3
0
        public static void AssertGenericType(this ITicNodeState state, StatePrimitive desc, StatePrimitive anc,
                                             bool isComparable = false)
        {
            var generic = state as ConstrainsState;

            Assert.IsNotNull(generic);
            if (desc == null)
            {
                Assert.IsFalse(generic.HasDescendant);
            }
            else
            {
                Assert.AreEqual(desc, generic.Descedant, "Actual generic type is " + generic);
            }

            if (anc == null)
            {
                Assert.IsFalse(generic.HasAncestor);
            }
            else
            {
                Assert.AreEqual(anc, generic.Ancestor);
            }

            Assert.AreEqual(isComparable, generic.IsComparable, "IsComparable claim missed");
        }
Exemple #4
0
 private TicNode(object name, ITicNodeState state, TicNodeType type)
 {
     _uid  = Interlocked.Increment(ref _interlockedId);
     Name  = name;
     State = state;
     Type  = type;
 }
Exemple #5
0
        public static void SetCall(this GraphBuilder builder, StatePrimitive ofTheCall, params int[] argumentsThenResult)
        {
            var types = new ITicNodeState[argumentsThenResult.Length];

            for (int i = 0; i < types.Length; i++)
            {
                types[i] = ofTheCall;
            }
            builder.SetCall(types, argumentsThenResult);
        }
Exemple #6
0
 public static bool AreSame(ITicNodeState a, ITicNodeState b)
 {
     if (a is StateRefTo r1)
     {
         a = r1.Node.GetNonReference().State;
     }
     if (b is StateRefTo r2)
     {
         b = r2.Node.GetNonReference().State;
     }
     return(a.Equals(b));
 }
Exemple #7
0
 public static Exception CannotSetState(TicNode node, ITicNodeState b)
 {
     if (node.Type == TicNodeType.SyntaxNode)
     {
         return(new IncompatibleAncestorSyntaxNodeException((int)node.Name, node.State, b));
     }
     if (node.Type == TicNodeType.Named)
     {
         return(new IncompatibleAncestorNamedNodeException(node.Name.ToString(), node.State, b));
     }
     return(new TicNoDetailsException());
 }
Exemple #8
0
 public static StateArray Of(ITicNodeState state)
 {
     if (state is ITypeState type)
     {
         return(Of(type));
     }
     if (state is StateRefTo refTo)
     {
         return(Of(refTo.Node));
     }
     throw new InvalidOperationException();
 }
Exemple #9
0
 public static void AssertAreSame(ITicNodeState expected, ITicNodeState actual)
 {
     if (!AreSame(expected, actual))
     {
         if (expected is StateRefTo r1)
         {
             expected = r1.Node.GetNonReference().State;
         }
         if (actual is StateRefTo r2)
         {
             actual = r2.Node.GetNonReference().State;
         }
         Assert.Fail($"Expected: {expected} but was: {actual}");
     }
 }
Exemple #10
0
        private static bool AreStatesEqualByValue(ITicNodeState a, ITicNodeState b)
        {
            while (a is StateRefTo arefTo)
            {
                a = arefTo.Node.State;
            }
            while (b is StateRefTo brefTo)
            {
                b = brefTo.Node.State;
            }

            if (a.GetType() != b.GetType())
            {
                return(false);
            }

            if (a is StatePrimitive)
            {
                return(a.Equals(b));
            }
            if (a is ConstrainsState)
            {
                return(a.Equals(b));
            }
            if (a is ICompositeState aComposite && b is ICompositeState bComposite)
            {
                var aMembers = aComposite.Members.ToArray();
                var bMembers = bComposite.Members.ToArray();
                if (aMembers.Length != bMembers.Length)
                {
                    return(false);
                }
                for (int i = 0; i < aMembers.Length; i++)
                {
                    if (!AreStatesEqualByValue(aMembers[i].State, bMembers[i].State))
                    {
                        return(false);
                    }
                }
                return(true);
            }

            return(false);
        }
Exemple #11
0
 private static ITicNodeState GetNonReferencedState(ITicNodeState state)
 {
     if (state is StatePrimitive)
     {
         return(state);
     }
     if (state is ConstrainsState)
     {
         return(state);
     }
     if (state is StateRefTo refTo)
     {
         return(GetNonReferencedState(refTo.Node.State));
     }
     if (state is ICompositeState compositeState)
     {
         return(compositeState.GetNonReferenced());
     }
     throw new NotSupportedException();
 }
Exemple #12
0
        public static StateFun Of(ITicNodeState[] argTypes, ITicNodeState returnType)
        {
            TicNode[] argNodes = new TicNode[argTypes.Length];
            TicNode   retNode  = null;

            if (returnType is ITypeState rt)
            {
                retNode = TicNode.CreateTypeVariableNode(rt);
            }
            else if (returnType is StateRefTo retRef)
            {
                retNode = retRef.Node;
            }
            else
            {
                throw new InvalidOperationException();
            }

            for (int i = 0; i < argTypes.Length; i++)
            {
                if (argTypes[i] is ITypeState at)
                {
                    argNodes[i] = TicNode.CreateTypeVariableNode(at);
                }
                else if (argTypes[i] is StateRefTo aRef)
                {
                    argNodes[i] = aRef.Node;
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }


            return(new StateFun(argNodes, retNode));
        }
Exemple #13
0
 public static TicNode CreateTypeVariableNode(string name, ITicNodeState state, bool registrated = false)
 => new TicNode(name, state, TicNodeType.TypeVariable)
 {
     Registrated = registrated
 };
Exemple #14
0
 public static TicNode CreateNamedNode(object name, ITicNodeState state)
 => new TicNode(name, state, TicNodeType.Named)
 {
     Registrated = true
 };
Exemple #15
0
 public static TicNode CreateSyntaxNode(int id, ITicNodeState state, bool registrated = false)
 => new TicNode(id, state, TicNodeType.SyntaxNode)
 {
     Registrated = registrated
 };
Exemple #16
0
        public static ITicNodeState GetMergedStateOrNull(ITicNodeState stateA, ITicNodeState stateB)
        {
            if (stateB is ConstrainsState c && c.NoConstrains)
            {
                return(stateA);
            }

            if (stateA is ITypeState typeA && !typeA.IsMutable)
            {
                if (stateB is ITypeState typeB && !typeB.IsMutable)
                {
                    return(!typeB.Equals(typeA) ? null : typeA);
                }

                if (stateB is ConstrainsState constrainsB)
                {
                    return(!constrainsB.Fits(typeA) ? null : typeA);
                }
            }

            switch (stateA)
            {
            case StateArray arrayA when stateB is StateArray arrayB:
                MergeInplace(arrayA.ElementNode, arrayB.ElementNode);
                return(arrayA);

            case StateFun funA when stateB is StateFun funB:
            {
                if (funA.ArgsCount != funB.ArgsCount)
                {
                    return(null);
                }

                for (int i = 0; i < funA.ArgsCount; i++)
                {
                    MergeInplace(funA.ArgNodes[i], funB.ArgNodes[i]);
                }
                MergeInplace(funA.RetNode, funB.RetNode);
                return(funA);
            }

            case StateStruct strA when stateB is StateStruct strB:
            {
                var result = new Dictionary <string, TicNode>();
                foreach (var aField in strA.Fields)
                {
                    var bNode = strB.GetFieldOrNull(aField.Key);
                    if (bNode != null)
                    {
                        MergeInplace(aField.Value, bNode);
                    }
                    result.Add(aField.Key, aField.Value);
                }

                foreach (var bField in strB.Fields)
                {
                    if (!result.ContainsKey(bField.Key))
                    {
                        result.Add(bField.Key, bField.Value);
                    }
                }
                return(new StateStruct(result));
            }

            case ConstrainsState constrainsA when stateB is ConstrainsState constrainsB:
                return(constrainsB.MergeOrNull(constrainsA));

            case ConstrainsState _:
                return(GetMergedStateOrNull(stateB, stateA));

            case StateRefTo refA:
            {
                var state = GetMergedStateOrNull(refA.Node.State, stateB);
                if (state == null)
                {
                    return(null);
                }
                refA.Node.State = state;
                return(stateA);
            }
            }
            if (stateB is StateRefTo)
            {
                return(GetMergedStateOrNull(stateB, stateA));
            }

            return(null);
        }
Exemple #17
0
        public bool Visit(FunCallSyntaxNode node)
        {
            var signature = _dictionary.GetOrNull(node.Id, node.Args.Length);

            node.FunctionSignature = signature;
            //Apply visitor to child types
            for (int i = 0; i < node.Args.Length; i++)
            {
                if (signature != null)
                {
                    _parentFunctionArgType = signature.ArgTypes[i];
                }
                node.Args[i].Accept(this);
            }
            //Setup ids arrays
            var ids = new int[node.Args.Length + 1];

            for (int i = 0; i < node.Args.Length; i++)
            {
                ids[i] = node.Args[i].OrderNumber;
            }
            ids[ids.Length - 1] = node.OrderNumber;

            var userFunction = _resultsBuilder.GetUserFunctionSignature(node.Id, node.Args.Length);

            if (userFunction != null)
            {
                //Call user-function if it is being built at the same time as the current expression is being built
                //for example: recursive calls, or if function relates to global variables
#if DEBUG
                Trace(node, $"Call UF{node.Id}({string.Join(",", ids)})");
#endif
                _ticTypeGraph.SetCall(userFunction, ids);
                //in the case of generic user function  - we dont know generic arg types yet
                //we need to remember generic TIC signature to used it at the end of interpritation
                _resultsBuilder.RememberRecursiveCall(node.OrderNumber, userFunction);
                return(true);
            }

            if (signature == null)
            {
                //Functional variable
#if DEBUG
                Trace(node, $"Call hi order {node.Id}({string.Join(",", ids)})");
#endif
                _ticTypeGraph.SetCall(node.Id, ids);
                return(true);
            }
            //Normal function call
#if DEBUG
            Trace(node, $"Call {node.Id}({string.Join(",", ids)})");
#endif
            if (signature is PureGenericFunctionBase pure)
            {
                // Сase of (T,T):T signatures
                // This case is most common, so the call is optimized
                var genericType = InitializeGenericType(pure.Constrainses[0]);
                _resultsBuilder.RememberGenericCallArguments(node.OrderNumber, new[] { genericType });
                _ticTypeGraph.SetCall(genericType, ids);
                return(true);
            }
            StateRefTo[] genericTypes;
            if (signature is GenericFunctionBase t)
            {
                // Optimization
                // Remember generic arguments to use it again at the built time
                genericTypes = InitializeGenericTypes(t.Constrainses);
                // save refernces to generic types, for use at 'apply tic results' step
                _resultsBuilder.RememberGenericCallArguments(node.OrderNumber, genericTypes);
            }
            else
            {
                genericTypes = new StateRefTo[0];
            }

            var types = new ITicNodeState[signature.ArgTypes.Length + 1];
            for (int i = 0; i < signature.ArgTypes.Length; i++)
            {
                types[i] = signature.ArgTypes[i].ConvertToTiType(genericTypes);
            }
            types[types.Length - 1] = signature.ReturnType.ConvertToTiType(genericTypes);

            _ticTypeGraph.SetCall(types, ids);
            return(true);
        }
Exemple #18
0
 private static void AssertNodeStateEqualToState(ITypeState expected, ITicNodeState actual, object id) =>
 Assert.IsTrue(AreStatesEqualByValue(actual, expected),
               $"States are not equal for '{id}': \r\nExpected: {expected}\r\nActual: {actual}");
Exemple #19
0
 public static StateFun Of(ITicNodeState argType, ITicNodeState returnType)
 => Of(new[] { argType }, returnType);
Exemple #20
0
 public override FunnyType Convert(ITicNodeState type) =>
 type switch
 {
Exemple #21
0
 private static TicNode CreateNode(string name, ITicNodeState state = null)
 => TicNode.CreateNamedNode(name, state ?? new ConstrainsState());
Exemple #22
0
 public IncompatibleAncestorNamedNodeException(string nodeName, ITicNodeState ancestor, ITicNodeState descendant) : base($"Incompatible ancestor {ancestor}=>{descendant} at node {nodeName}")
 {
     NodeName   = nodeName;
     Ancestor   = ancestor;
     Descendant = descendant;
 }
Exemple #23
0
 public abstract FunnyType Convert(ITicNodeState type);
Exemple #24
0
 private BasicDescType ToBasicDescType(ITicNodeState state) => state switch
 {
Exemple #25
0
 void AssertGetMergedStateIsNull(ITicNodeState stateA, ITicNodeState stateB)
 {
     Assert.IsNull(SolvingFunctions.GetMergedStateOrNull(stateA, stateB));
     Assert.IsNull(SolvingFunctions.GetMergedStateOrNull(stateB, stateA));
 }
Exemple #26
0
            public override FunnyType Convert(ITicNodeState type)
            {
                switch (type)
                {
                case StateRefTo refTo:
                    return(Convert(refTo.Element));

                case StatePrimitive primitive:
                    return(ToConcrete(primitive.Name));

                case ConstrainsState constrains when constrains.Prefered != null:
                    return(ToConcrete(constrains.Prefered.Name));

                case ConstrainsState constrains when !constrains.HasAncestor:
                {
                    if (constrains.IsComparable)
                    {
                        return(FunnyType.Real);
                    }
                    return(FunnyType.Anything);
                }

                case ConstrainsState constrains:
                {
                    if (constrains.Ancestor.Name.HasFlag(PrimitiveTypeName._isAbstract))
                    {
                        switch (constrains.Ancestor.Name)
                        {
                        case PrimitiveTypeName.I96:
                        {
                            if (constrains.HasDescendant || constrains.Descedant.CanBeImplicitlyConvertedTo(StatePrimitive.I32))
                            {
                                return(FunnyType.Int32);
                            }
                            return(FunnyType.Int64);
                        }

                        case PrimitiveTypeName.I48:
                        {
                            if (constrains.HasDescendant || constrains.Descedant.CanBeImplicitlyConvertedTo(StatePrimitive.I32))
                            {
                                return(FunnyType.Int32);
                            }
                            return(FunnyType.UInt32);
                        }

                        case PrimitiveTypeName.U48: return(FunnyType.UInt32);

                        case PrimitiveTypeName.U24: return(FunnyType.UInt16);

                        case PrimitiveTypeName.U12: return(FunnyType.UInt8);

                        default: throw new NotSupportedException();
                        }
                    }
                    return(ToConcrete(constrains.Ancestor.Name));
                }

                case StateArray array:
                    return(FunnyType.ArrayOf(Convert(array.Element)));

                case StateFun fun:
                    return(FunnyType.Fun(Convert(fun.ReturnType), fun.ArgNodes.SelectToArray(a => Convert(a.State))));

                case StateStruct str:
                    return(FunnyType.StructOf(str.Fields.ToDictionary(f => f.Key, f => Convert(f.Value.State))));

                default:
                    throw new NotSupportedException();
                }
            }