Beispiel #1
0
        public int CompareInternal(DataType x, DataType y, int count)
        {
            if (count > 20)
            {
                throw new ApplicationException("Way too deep");     //$BUG: discover why datatypes recurse so deep.
            }
            int prioX = x.Accept(this);
            int prioY = y.Accept(this);
            int dPrio = prioX - prioY;

            if (dPrio != 0)
            {
                return(dPrio);
            }

            if (x is VoidType)
            {
                return(0);
            }

            if (x is UnknownType && y is UnknownType)
            {
                return(0);
            }
            if (x is UnknownType)
            {
                return(-1);
            }
            if (y is UnknownType)
            {
                return(1);
            }

            PrimitiveType ix = x as PrimitiveType;
            PrimitiveType iy = y as PrimitiveType;

            if (ix != null && iy != null)
            {
                return(ix.Compare(iy));
            }
            if (ix != null)
            {
                return(-1);
            }
            if (iy != null)
            {
                return(1);
            }

            if (x is EnumType || y is EnumType)
            {
                throw new NotImplementedException();
            }

            CodeType cx = x as CodeType;
            CodeType cy = y as CodeType;

            if (cx != null && cy != null)
            {
                return(0);
            }
            if (cx != null)
            {
                return(-1);
            }
            if (cy != null)
            {
                return(1);
            }

            TypeVariable tx = x as TypeVariable;
            TypeVariable ty = y as TypeVariable;

            if (tx != null && ty != null)
            {
                return(tx.Number - ty.Number);
            }

            TypeReference tr_x = x as TypeReference;
            TypeReference tr_y = y as TypeReference;

            if (tr_x != null && tr_y != null)
            {
                return(StringComparer.InvariantCulture.Compare(tr_x.Name, tr_y.Name));
            }

            EquivalenceClass ex = x as EquivalenceClass;
            EquivalenceClass ey = y as EquivalenceClass;

            if (ex != null && ey != null)
            {
                return(ex.Number - ey.Number);
            }

            Pointer ptrX = x as Pointer;
            Pointer ptrY = y as Pointer;

            if (ptrX != null && ptrY != null)
            {
                return(Compare(ptrX.Pointee, ptrY.Pointee, ++count));
            }

            MemberPointer mX = x as MemberPointer;
            MemberPointer mY = y as MemberPointer;

            if (mX != null && mY != null)
            {
                int d = Compare(mX.BasePointer, mY.BasePointer, ++count);
                if (d != 0)
                {
                    return(d);
                }
                return(Compare(mX.Pointee, mY.Pointee, ++count));
            }

            ReferenceTo rX = x as ReferenceTo;
            ReferenceTo rY = y as ReferenceTo;

            if (rX != null && rY != null)
            {
                return(Compare(rX.Referent, rY.Referent, ++count));
            }

            StructureType sX = x as StructureType;
            StructureType sY = y as StructureType;

            if (sX != null && sY != null)
            {
                return(Compare(sX, sY, ++count));
            }

            UnionType ux = x as UnionType;
            UnionType uy = y as UnionType;

            if (ux != null && uy != null)
            {
                return(Compare(ux, uy, ++count));
            }
            ArrayType ax = x as ArrayType;
            ArrayType ay = y as ArrayType;

            if (ax != null && ay != null)
            {
                return(Compare(ax, ay, ++count));
            }

            StringType strX = x as StringType;
            StringType strY = y as StringType;

            if (strX != null && strY != null)
            {
                return(Compare(strX, strY, ++count));
            }

            FunctionType fnX = x as FunctionType;
            FunctionType fnY = y as FunctionType;

            if (fnX != null && fnY != null)
            {
                return(Compare(fnX, fnY, ++count));
            }
            throw new NotImplementedException(string.Format("NYI: comparison between {0} and {1}", x.GetType(), y.GetType()));
        }
Beispiel #2
0
 public int VisitArray(ArrayType at)
 {
     return(Array);
 }
Beispiel #3
0
        public bool AreCompatible(DataType a, DataType b)
        {
            if (a == null || b == null)
            {
                return(false);
            }

            PrimitiveType pa = a as PrimitiveType;
            PrimitiveType pb = b as PrimitiveType;

            if (pa != null && pb != null)
            {
                if (pa.Size != pb.Size)
                {
                    return(false);
                }
                return((pa.Domain & pb.Domain) != 0);
            }

            TypeReference tra = a as TypeReference;
            TypeReference trb = b as TypeReference;

            if (tra != null && trb != null)
            {
                return(tra == trb);
            }
            if (tra != null)
            {
                return(AreCompatible(tra.Referent, b));
            }
            if (trb != null)
            {
                return(AreCompatible(a, trb.Referent));
            }

            TypeVariable tva = a as TypeVariable;
            TypeVariable tvb = b as TypeVariable;

            if (tva != null && tvb != null)
            {
                return(tva.Number == tvb.Number);
            }

            EquivalenceClass eqA = a as EquivalenceClass;
            EquivalenceClass eqB = b as EquivalenceClass;

            if (eqA != null && eqB != null)
            {
                return(eqA.Number == eqB.Number);
            }

            Pointer ptrA = a as Pointer;
            Pointer ptrB = b as Pointer;

            if (ptrA != null)
            {
                return(IsCompatibleWithPointer(ptrA, b));
            }
            if (ptrB != null)
            {
                return(IsCompatibleWithPointer(ptrB, a));
            }

            MemberPointer mpA = a as MemberPointer;
            MemberPointer mpB = b as MemberPointer;

            if (mpA != null)
            {
                return(IsCompatibleWithMemberPointer(mpA, b));
            }
            if (mpB != null)
            {
                return(IsCompatibleWithMemberPointer(mpB, a));
            }

            StructureType sa = a as StructureType;
            StructureType sb = b as StructureType;

            if (sa != null && sb != null)
            {
                return(AreCompatible(sa, sb));
            }

            ArrayType aa = a as ArrayType;
            ArrayType ab = b as ArrayType;

            if (aa != null && ab != null)
            {
                return(AreCompatible(aa.ElementType, ab.ElementType));
            }

            UnionType ua = a as UnionType;
            UnionType ub = b as UnionType;

            if (ua != null && ub != null)
            {
                return(true);
            }

            FunctionType fa = a as FunctionType;
            FunctionType fb = b as FunctionType;

            if (fa != null && fb != null)
            {
                return(fa.Parameters.Length == fb.Parameters.Length);
            }

            CodeType ca = a as CodeType;
            CodeType cb = a as CodeType;

            if (ca != null && cb != null)
            {
                return(true);
            }
            return(a is UnknownType || b is UnknownType);
        }
Beispiel #4
0
        private DataType UnifyInternal(DataType a, DataType b)
        {
            if (a == null)
            {
                return(b);
            }
            if (b == null)
            {
                return(a);
            }

            if (a == b)
            {
                return(a);
            }

            if (a is UnknownType)
            {
                return(b);
            }
            if (b is UnknownType)
            {
                return(a);
            }

            if (a is VoidType)
            {
                return(b);
            }
            if (b is VoidType)
            {
                return(a);
            }

            UnionType ua = a as UnionType;
            UnionType ub = b as UnionType;

            if (ua != null && ub != null)
            {
                UnionType u2 = UnifyUnions(ua, ub);
                return(u2.Simplify());
            }
            if (ua != null)
            {
                UnifyIntoUnion(ua, b);
                return(ua.Simplify());
            }
            if (ub != null)
            {
                UnifyIntoUnion(ub, a);
                return(ub.Simplify());
            }

            PrimitiveType pa = a as PrimitiveType;
            PrimitiveType pb = b as PrimitiveType;

            if (pa != null && pb != null)
            {
                if (pa == pb)
                {
                    return(pa);
                }

                return(UnifyPrimitives(pa, pb));
            }

            TypeVariable tA = a as TypeVariable;
            TypeVariable tB = b as TypeVariable;

            if (tA != null && tB != null)
            {
                return(UnifyTypeVariables(tA, tB));
            }

            TypeReference trA = a as TypeReference;
            TypeReference trB = b as TypeReference;

            if (trA != null && trB != null)
            {
                if (trA == trB)
                {
                    return(trA);
                }
                else
                {
                    return(MakeUnion(a, b));
                }
            }
            if (trA != null)
            {
                if (AreCompatible(trA.Referent, b))
                {
                    return(new TypeReference(trA.Name, UnifyInternal(trA.Referent, b)));
                }
            }
            if (trB != null)
            {
                if (AreCompatible(a, trB.Referent))
                {
                    return(new TypeReference(trB.Name, UnifyInternal(trB.Referent, a)));
                }
            }

            EquivalenceClass eqA = a as EquivalenceClass;
            EquivalenceClass eqB = b as EquivalenceClass;

            if (eqA != null && eqB != null)
            {
                if (eqA.Number == eqB.Number)
                {
                    return(eqA);
                }
                else
                {
                    return(MakeUnion(eqA, eqB));
                }
            }

            Pointer ptrA = a as Pointer;
            Pointer ptrB = b as Pointer;

            if (ptrA != null && ptrB != null)
            {
                DataType dt = UnifyInternal(ptrA.Pointee, ptrB.Pointee);
                return(new Pointer(dt, Math.Max(ptrA.BitSize, ptrB.BitSize)));
            }
            if (ptrA != null)
            {
                var dt = UnifyPointer(ptrA, b);
                if (dt != null)
                {
                    return(dt);
                }
            }
            if (ptrB != null)
            {
                var dt = UnifyPointer(ptrB, a);
                if (dt != null)
                {
                    return(dt);
                }
            }

            MemberPointer mpA = a as MemberPointer;
            MemberPointer mpB = b as MemberPointer;

            if (mpA != null && mpB != null)
            {
                DataType baseType = UnifyInternal(mpA.BasePointer, mpB.BasePointer);
                DataType pointee  = UnifyInternal(mpA.Pointee, mpB.Pointee);
                return(new MemberPointer(baseType, pointee, mpB.Size));
            }
            if (mpA != null)
            {
                var dt = UnifyMemberPointer(mpA, b);
                if (dt != null)
                {
                    return(dt);
                }
            }
            if (mpB != null)
            {
                var dt = UnifyMemberPointer(mpB, a);
                if (dt != null)
                {
                    return(dt);
                }
            }

            FunctionType funA = a as FunctionType;
            FunctionType funB = b as FunctionType;

            if (funA != null && funB != null)
            {
                return(UnifyFunctions(funA, funB));
            }
            if (funA != null && b is CodeType)
            {
                return(funA);
            }
            if (funB != null && a is CodeType)
            {
                return(funB);
            }

            ArrayType arrA = a as ArrayType;
            ArrayType arrB = b as ArrayType;

            if (arrA != null && arrB != null)
            {
                return(UnifyArrays(arrA, arrB));
            }
            if (arrA != null && arrA.ElementType.Size >= b.Size)
            {
                arrA.ElementType = Unify(arrA.ElementType, b);
                return(arrA);
            }
            if (arrB != null && arrB.ElementType.Size >= a.Size)
            {
                arrB.ElementType = Unify(arrB.ElementType, a);
                return(arrB);
            }

            StructureType strA = a as StructureType;
            StructureType strB = b as StructureType;

            if (strA != null && strB != null)
            {
                return(UnifyStructures(strA, strB));
            }
            if (strA != null && (strA.Size == 0 || strA.Size >= b.Size))
            {
                MergeIntoStructure(b, strA);
                return(strA);
            }
            if (strB != null && (strB.Size == 0 || strB.Size >= a.Size))
            {
                MergeIntoStructure(a, strB);
                return(strB);
            }
            if (strA != null || strB != null)
            {
                return(MakeUnion(a, b));
            }
            CodeType ca = a as CodeType;
            CodeType cb = b as CodeType;

            if (ca != null && cb != null)
            {
                return(ca);
            }
            if (tA != null)
            {
                return(UnifyTypeVariable(tA, b));
            }
            if (tB != null)
            {
                return(UnifyTypeVariable(tB, a));
            }
            return(MakeUnion(a, b));
        }
Beispiel #5
0
        private bool DoAreCompatible(DataType a, DataType b, int depth)
        {
            if (a == null || b == null)
            {
                return(false);
            }

            if (depth > 20)
            {
                throw new StackOverflowException("Way too deep");                     //$BUG: discover why datatypes recurse so deep.
            }
            PrimitiveType pa = a as PrimitiveType;
            PrimitiveType pb = b as PrimitiveType;

            if (pa != null && pb != null)
            {
                if (pa.Size != pb.Size)
                {
                    return(false);
                }
                return((pa.Domain & pb.Domain) != 0);
            }

            TypeReference tra = a as TypeReference;
            TypeReference trb = b as TypeReference;

            if (tra != null && trb != null)
            {
                return(tra == trb);
            }
            if (tra != null)
            {
                return(AreCompatible(tra.Referent, b, ++depth));
            }
            if (trb != null)
            {
                return(AreCompatible(a, trb.Referent, ++depth));
            }

            TypeVariable tva = a as TypeVariable;
            TypeVariable tvb = b as TypeVariable;

            if (tva != null && tvb != null)
            {
                return(tva.Number == tvb.Number);
            }

            EquivalenceClass eqA = a as EquivalenceClass;
            EquivalenceClass eqB = b as EquivalenceClass;

            if (eqA != null && eqB != null)
            {
                return(eqA.Number == eqB.Number);
            }

            Pointer ptrA = a as Pointer;
            Pointer ptrB = b as Pointer;

            if (ptrA != null)
            {
                return(IsCompatibleWithPointer(ptrA, b, ++depth));
            }
            if (ptrB != null)
            {
                return(IsCompatibleWithPointer(ptrB, a, ++depth));
            }

            MemberPointer mpA = a as MemberPointer;
            MemberPointer mpB = b as MemberPointer;

            if (mpA != null)
            {
                return(IsCompatibleWithMemberPointer(mpA, b, ++depth));
            }
            if (mpB != null)
            {
                return(IsCompatibleWithMemberPointer(mpB, a, ++depth));
            }

            StructureType sa = a as StructureType;
            StructureType sb = b as StructureType;

            if (sa != null && sb != null)
            {
                return(AreCompatible(sa, sb));
            }

            ArrayType aa = a as ArrayType;
            ArrayType ab = b as ArrayType;

            if (aa != null && ab != null)
            {
                return(AreCompatible(aa.ElementType, ab.ElementType, ++depth));
            }

            UnionType ua = a as UnionType;
            UnionType ub = b as UnionType;

            if (ua != null && ub != null)
            {
                return(true);
            }

            FunctionType fa = a as FunctionType;
            FunctionType fb = b as FunctionType;

            if (fa != null && fb != null)
            {
                return(fa.Parameters.Length == fb.Parameters.Length);
            }

            CodeType ca = a as CodeType;
            CodeType cb = a as CodeType;

            if (ca != null && cb != null)
            {
                return(true);
            }
            if (a is UnknownType unkA)
            {
                if (unkA.Size == 0 || a.Size == b.Size)
                {
                    return(true);
                }
            }
            if (b is UnknownType unkB)
            {
                if (unkB.Size == 0 || a.Size == b.Size)
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #6
0
 public DataType VisitArray(ArrayType at)
 {
     at.ElementType = at.ElementType.Accept(this);
     return(at);
 }