/* zweic -- a compiler for zwei
*
* Stephane Micheloud & LAMP
*
* $Id$
*/
package zweic;
// Internal type
abstract class Type {
def intersection[a](c1: List[a], c2: List[a]):List[a] = {
c1.filter(x => c2.contains(x))
}
override def toString(): String = this match {
case IClassType(c) => "ClassType(" + c.toString()+")";
case IIntType => "IntType"
case INullType => "NullType"
case IBadType => "<Bad>"
}
def isSubtype(that: Type): Boolean = Pair(this, that) match {
case Pair(INullType, x) => true
case Pair(x, INullType) => false
case Pair(IIntType, IIntType) => true
case Pair(IClassType(c1), IClassType(c2)) => c1.superclasses.contains(c2)
case _ => false
}
def isSametype(that: Type): Boolean = Pair(this, that) match {
case Pair(IIntType, IIntType) => true
case Pair(INullType, INullType) => true
case Pair(IClassType(c1), IClassType(c2)) => c1 == c2
case _ => false
}
def lub(that: Type): Option[Type] = Pair(this, that) match {
case Pair(IIntType, IIntType) => Some(IIntType)
case Pair(INullType, INullType) => Some(INullType)
case Pair(IIntType, INullType) => Some(IIntType)
case Pair(INullType, IIntType) => Some(IIntType)
case Pair(c@IClassType(x), INullType) => Some(c)
case Pair(INullType, c@IClassType(x)) => Some(c)
case Pair(IClassType(c1), IClassType(c2)) =>
intersection(c1.superclasses, c2.superclasses) match {
case t :: ts => Some(IClassType(t))
case List() => None
}
case _ => None
}
}
// Class type
case class IClassType(c: ClassSymbol) extends Type;
// Integer type
case object IIntType extends Type;
// Null type
case object INullType extends Type;
// Bad type
case object IBadType extends Type;