/// <summary> /// Two array types are compatible if: /// 1. Their element types are compatible. /// 2. If both have constant size, that size is the same. /// /// Note: /// arrays of unknown bound is compatible with any array of compatible element type. /// arrays of variable length is compatible with any array of compatible element type. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { if (other.IsArray) { TArr a = other as TArr; if (element.Compatible(a.element)) { // They points to compatible type. // Check if other is VLA. if (a is TVArr) { return(true); } if (IsComplete && a.IsComplete) { return(n == (a as TCArr).n); } else { return(true); } } else { return(false); } } else { return(false); } }
/// <summary> /// Arrays with variable length is compatible with any array of compatible element type. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { if (other.IsArray) { TArr a = other as TArr; return(element.Compatible(a.element)); } else { return(false); } }
/// <summary> /// For two function types to be compatible, both shall specify compatible returns types. /// Moreover, the parameter type lists, if both are present, shall agree in the number of parameters /// and in use of the ellipsis terminator. /// TODO: Support old style function type. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { if (other.IsFunc) { TFunc f = other as TFunc; if (ret.Compatible(f.ret) && isEllipis == f.isEllipis && parameters.Count() == f.parameters.Count()) { return(parameters.Zip(f.parameters, (p, q) => p.Compatible(q)).Aggregate(true, (x, y) => x && y)); } } return(false); }
/// <summary> /// Two array types are compatible if: /// 1. Their element types are compatible. /// 2. If both have constant size, that size is the same. /// /// Note: /// arrays of unknown bound is compatible with any array of compatible element type. /// arrays of variable length is compatible with any array of compatible element type. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { if (other.IsArray) { TArr a = other as TArr; if (element.Compatible(a.element)) { // They points to compatible type. // Check if other is VLA. return(true); } } return(false); }
public override TArithmetic UsualArithConversion(TUnqualified other) { if (!other.IsArithmetic) { throw new ArgumentException(string.Format("Usual arithmetic conversion should be performed on arithmetic types, not {0}!", other)); } TArithmetic x = other as TArithmetic; // First determine a common real type. TReal crt = CommonRealType(x); // Check if both type domain are real. if (TypeDomain() == TDomain.REAL && other.TypeDomain() == TDomain.REAL) { return(crt); } else { // Convert the complex domain. return(crt.Complex); } }
public override TUnqualified Composite(TUnqualified other) { throw new NotImplementedException(); }
/// <summary> /// For two pointers to be compatible, both shall be identically qualified /// and both shall be pointers to compatible types. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { return(other.IsPtr && element.Compatible((other as TPtr).element)); }
public T(TUnqualified nake, TQualifiers qualifiers) { this.nake = nake; this.qualifiers = qualifiers; }
/// <summary> /// Perform usual arithmetic conversion. /// Only call this on arithmetic types. /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual TArithmetic UsualArithConversion(TUnqualified other) { throw new InvalidOperationException("Can't do usual arithmetic conversions on non-arithmetic type!"); }
/// <summary> /// Return a composite type of this and other. /// </summary> /// <param name="other"></param> /// <returns></returns> public abstract TUnqualified Composite(TUnqualified other);
/// <summary> /// Whether two types are compatible. /// /// From C99 6.2.7: /// Two types have compatible type if their types are the same. /// /// Additional rules for enum, type qualifiers, /// </summary> /// <param name="other"></param> /// <returns></returns> public virtual bool Compatible(TUnqualified other) { return(Equals(other)); }
/// <summary> /// Notice that enum is represented as int, therefore int and enum are /// compatible types. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { return(Equals(other) || other.IsEnum); }
/// <summary> /// Each enumerated type shall be compatible with char, a signed integer type, /// or an unsigned integer type. The choice of type is implementation-defined, /// but shall be capable of representing the values of all the members of the /// enumeration. /// /// Here the enumerated type is represented as int, thus enum should be compatible /// with int. /// Notice that enum and int are NOT the same type, thus Equals should return false. /// </summary> /// <param name="other"></param> /// <returns></returns> public override bool Compatible(TUnqualified other) { return(Equals(other) || other is TInt); }