Ejemplo n.º 1
0
        public void AddFunction(string functionName, IfsType functionType)
        {
            if (functionsTypes.ContainsKey(functionName))
            {
                throw new Exception($"Function {functionName} already exists in current scope");
            }

            functionsTypes.Add(functionName, functionType);
        }
Ejemplo n.º 2
0
        public void AddVar(string varName, IfsType varType)
        {
            if (varType.Name == "function")
            {
                if (functionsTypes.ContainsKey(varName))
                {
                    throw new Exception($"Function {varName} already exists in current scope");
                }

                functionsTypes.Add(varName, varType);
            }

            if (varsTypes.ContainsKey(varName))
            {
                throw new Exception($"Variable {varName} already exists in current scope");
            }

            varsTypes.Add(varName, varType);
        }
Ejemplo n.º 3
0
        public void ScopeVarOrFuncTypeChangedHandler(string oldTypeName, IfsType newType)
        {
            if (this.Text != "TYPE" || oldTypeName != NodeType.Name)
            {
                if (NodeType.Name == "function")
                {
                    fsType nodeTyped = NodeType as fsType;
                    for (int i = 0; i < nodeTyped.Types.Count; i++)
                    {
                        if (nodeTyped.Types[i].Name == oldTypeName)
                        {
                            nodeTyped.Types[i] = newType;
                        }
                    }
                }
                return;
            }

            NodeType = newType;
        }
Ejemplo n.º 4
0
        private void UnifyWrapper(ref IfsType t1, ref IfsType t2, fsScope scope)
        {
            bool isT1FromScope = false;
            bool isT2FromScope = false;
            string t1ScopeName = "";
            string t1NameBeforeUnification = t1.Name;
            string t2ScopeName = "";
            string t2NameBeforeUnification = t2.Name;

            if (t1 is fsTypeVar)
            {
                isT1FromScope = (t1 as fsTypeVar).IsFromScope;
                t1ScopeName = (t1 as fsTypeVar).ScopeVarName;
            }

            if (t2 is fsTypeVar)
            {
                isT2FromScope = (t2 as fsTypeVar).IsFromScope;
                t2ScopeName = (t2 as fsTypeVar).ScopeVarName;
            }

            Unify(ref t1, ref t2, scope);

            if (isT1FromScope)
            {
                scope.ChangeVarOrFuncType(t1ScopeName, t1NameBeforeUnification, t1);
            }

            if (isT2FromScope)
            {
                scope.ChangeVarOrFuncType(t2ScopeName, t2NameBeforeUnification, t2);
            }
        }
Ejemplo n.º 5
0
        private void Unify(ref IfsType t1, ref IfsType t2, fsScope scope)
        {
            if (t1.Name == "identity")
            {
                t1 = t2;
                return;
            }

            if (t2.Name == "identity")
            {
                t2 = t1;
                return;
            }

            IfsType t1Pruned = Prune(t1);
            IfsType t2Pruned = Prune(t2);

            if (t1Pruned.Name != "composite")
            {
                t1 = t1Pruned;
            }

            if (t2Pruned.Name != "composite")
            {
                t2 = t2Pruned;
            }

            if (t1 is fsTypeVar)
            {
                if (!t1.Equals(t2))
                {
                    if (OccursInType(t1, t2))
                    {
                        throw new Exception("Recursive unification");
                    }

                    if (t2.Name == "composite")
                    {
                        (t1 as fsTypeVar).Instance = t2;
                    }
                    else
                    {
                        t1 = t2;
                    }
                }
            }
            else if(t1 is fsType && t2 is fsTypeVar)
            {
                UnifyWrapper(ref t2, ref t1, scope);
            }
            else if (t1 is fsType && t2 is fsType)
            {
                fsType type1 = t1 as fsType;
                fsType type2 = t2 as fsType;

                if (type1.Name == "composite")
                {
                    if (type2.Name != "composite")
                    {
                        UnifyWrapper(ref t2, ref t1, scope);
                        return;
                    }

                    List<IfsType> commonTypes = new List<IfsType>();
                    for (int i = 0; i < type1.Types.Count; i++)
                    {
                        for (int j = 0; j < type2.Types.Count; j++)
                        {
                            if (type1.Types[i].Equals(type2.Types[j]))
                            {
                                commonTypes.Add(type1.Types[i]);
                            }
                        }
                    }

                    if (commonTypes.Count < 1)
                    {
                        throw new Exception($"Cannot unify types {type1.Name} and {type2.Name}");
                    }
                    else if (commonTypes.Count == 0)
                    {
                        t1 = t2 = commonTypes[0];
                    }
                    else
                    {
                        fsTypeVar commonType = new fsTypeVar();
                        commonType.Instance = fsType.GetCompositeType(commonTypes);
                        t1 = t2 = commonType;
                    }

                    return;
                }

                if (type2.Name == "composite")
                {
                    for (int i = 0; i < type2.Types.Count; i++)
                    {
                        if (type1.Equals(type2.Types[i]))
                        {
                            t1 = t2 = type1;
                            return;
                        }
                    }

                    throw new Exception($"Cannot unify types {type1.Name} and {type2.Name}");
                }

                if (!type1.Equals(type2))
                {
                    throw new Exception($"Cannot unify types {type1.Name} and {type2.Name}");
                }

                if (type1.Name == "function")
                {
                    if (type1.Types.Count == type2.Types.Count)
                    {
                        IfsType returningType = type2.Types[type2.Types.Count - 1];
                        for (int i = 0; i < type1.Types.Count - 1; i++)
                        {
                            IfsType t1Child = type1.Types[i];
                            IfsType t2Child = type2.Types[i];
                            string t2NameBeforeUnification = t2Child.Name;
                            //Changed !!!!!!!
                            UnifyWrapper(ref t2Child, ref t1Child, scope);
                            type1.Types[i] = t1Child;
                            type2.Types[i] = t2Child;

                            if (returningType.Name == t2NameBeforeUnification)
                            {
                                UnifyWrapper(ref returningType, ref t1Child, scope);
                                type1.Types[i] = returningType;
                                type2.Types[type2.Types.Count - 1] = t2Child;
                            }
                        }
                    }
                    else if (type1.Types.Count < type2.Types.Count)
                    {
                        int difference = type2.Types.Count - type1.Types.Count;

                        for (int i = 0; i < type1.Types.Count - 1; i++)
                        {
                            IfsType t1Child = type1.Types[i];
                            IfsType t2Child = type2.Types[i];
                            string t2NameBeforeUnification = t2Child.Name;
                            //Changed !!!!!!!
                            UnifyWrapper(ref t2Child, ref t1Child, scope);
                            type1.Types[i] = t1Child;
                            type2.Types[i] = t2Child;

                            for (int j = difference; j < type2.Types.Count; j++)
                            {
                                IfsType bufType = type2.Types[j];
                                if (bufType.Name == t2NameBeforeUnification)
                                {
                                    UnifyWrapper(ref t1Child, ref bufType, scope);
                                    type1.Types[i] = bufType;
                                    type2.Types[j] = t2Child;
                                }
                            }
                        }

                        List<IfsType> rest = type2.Types.GetRange(type1.Types.Count - 1, difference + 1);
                        type1.Types[type1.Types.Count - 1] = fsType.GetFunctionType(rest);
                        t1 = t2 = type1;
                    }
                    else
                    {
                        throw new Exception($"Cannot unify types {type1.Name} and {type2.Name}");
                    }
                }
            }
            else
            {
                throw new Exception($"Cannot unify types {t1.Name} and {t2.Name}");
            }
        }
Ejemplo n.º 6
0
        private IfsType Prune(IfsType type)
        {
            fsTypeVar a;
            if ((a = type as fsTypeVar)?.Instance != null)
            {
                a.Instance = Prune(a.Instance);
                return a.Instance;
            }

            return type;
        }
Ejemplo n.º 7
0
        private bool OccursInTypeArray(IfsType type, List<IfsType> types)
        {
            foreach (var t in types)
            {
                if (OccursInType(type, t))
                {
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 8
0
        private bool OccursInType(IfsType t1, IfsType t2)
        {
            t2 = Prune(t2);

            if (t2.Equals(t1))
            {
                return true;
            }
            else if (t2 is fsType)
            {
                return OccursInTypeArray(t1, (t2 as fsType).Types);
            }

            return false;
        }
Ejemplo n.º 9
0
        private IfsType InferBinaryOpType(ITree node, fsScope scope, IfsType availableType)
        {
            IfsType leftOperandType = Analyse(node.GetChild(0), scope);
            IfsType rightOperandType = Analyse(node.GetChild(1), scope);

            UnifyWrapper(ref leftOperandType, ref availableType, scope);
            UnifyWrapper(ref rightOperandType, ref availableType, scope);
            UnifyWrapper(ref leftOperandType, ref rightOperandType, scope);

            return leftOperandType;
        }
Ejemplo n.º 10
0
 public void ChangeVarOrFuncType(string varName, string oldTypeName, IfsType newType)
 {
     ScopeVarOrFuncTypeChanged(oldTypeName, newType);
 }
Ejemplo n.º 11
0
 public fsTreeNode(IfsType type)
     : base(new CommonToken(fsharp_ssParser.TYPE, type.Name))
 {
     this.Text = "TYPE";
     this.NodeType = type;
 }