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())); }
public int VisitArray(ArrayType at) { return(Array); }
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); }
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)); }
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); }
public DataType VisitArray(ArrayType at) { at.ElementType = at.ElementType.Accept(this); return(at); }