Advertisement
Guest User

Untitled

a guest
Jul 1st, 2019
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 4.36 KB | None | 0 0
  1. object TypeCheck {
  2.  
  3.   def typeOf(e: ExprExt, nv: List[TBind], tnv: List[TVBind]): Type = {
  4.   //println("e: " + e + " nv: " + nv + " tnv: " + tnv)
  5.     e match {
  6.       case NumExt(n) => NumT()
  7.       case PlusExt(e1, e2) =>
  8.         (normalizeType(typeOf(e1, nv, tnv),tnv), normalizeType(typeOf(e2, nv, tnv),tnv)) match {
  9.           case (NumT(), NumT()) =>
  10.             NumT()
  11.           case r =>
  12.             throw TypeException("expected both branches of plus expression to be num typed, but got: " + r)
  13.         }
  14.       case MultExt(e1, e2) =>
  15.         (normalizeType(typeOf(e1, nv, tnv),tnv), normalizeType(typeOf(e2, nv, tnv),tnv)) match {
  16.           case (NumT(), NumT()) =>
  17.             NumT()
  18.           case r =>
  19.             throw TypeException("expected both branches of mult expression to be num typed, but got: " + r)
  20.         }
  21.       case FdExt(x, t, e) => {
  22.         val nv2 = TBind(x,normalizeType(t,tnv))::nv
  23.         FunT(normalizeType(t,tnv), normalizeType(typeOf(e,nv2,tnv),tnv))
  24.       }
  25.       case AppExt(f, a) => normalizeType(typeOf(f,nv,tnv),tnv) match {
  26.         case FunT(in,out) => if(normalizeType(typeOf(a,nv,tnv),tnv)==normalizeType(in,tnv)) out else throw TypeException("wrong input for function app")
  27.         case _ => throw TypeException("no function in app")
  28.       }
  29.       case IdExt(x) => normalizeType(lookup(x, nv),tnv) match {
  30.         case VarT(a) => normalizeType(VarT(a),tnv)
  31.         case b => normalizeType(b,tnv)
  32.       }
  33.       case ConsExt(hd, tl) => {
  34.         val t = normalizeType(typeOf(hd,nv,tnv),tnv)
  35.         if(t==normalizeType(typeOf(tl,nv,tnv),tnv)) ListT(normalizeType(t,tnv))
  36.         else if (ListT(t)==normalizeType(typeOf(tl,nv,tnv),tnv)) ListT(normalizeType(t,tnv))
  37.         else {
  38.           println("cons: " + t + " " + typeOf(tl,nv,tnv))
  39.           throw TypeException("not same types in list")
  40.         }
  41.       }
  42.       case NilExt(t) => ListT(normalizeType(t,tnv))
  43.       case HeadExt(e) => normalizeType(typeOf(e,nv,tnv),tnv) match {
  44.        case ListT(x) => normalizeType(x,tnv)
  45.        case _ => throw TypeException("head not a list")
  46.       }
  47.       case TailExt(e) => normalizeType(typeOf(e,nv,tnv),tnv) match {
  48.        case ListT(x) => ListT(x)
  49.        case _ => throw TypeException("head not a list")
  50.       }
  51.       case LetType(x, t, e) => {
  52.        val tnv2 = TVBind(x,normalizeType(t,tnv))::tnv
  53.        normalizeType(typeOf(e,nv,tnv2),tnv2)
  54.       }
  55.     }
  56.   }
  57.  
  58.   def lookup(x: String, nv: List[TBind]): Type = nv match {
  59.     case Nil => throw TypeException("lookup: empty list")
  60.     case TBind(str,t) :: tail => if(str == x) t else lookup(x, tail)
  61.     case _ => throw TypeException("no tbind in nv")
  62.   }
  63.    
  64.  
  65.   def tlookup(x: String, tnv: List[TVBind]): Type = tnv match {
  66.     case Nil => throw TypeException("tlookup: empty list")
  67.     case TVBind(str,t) :: tail => if(str == x) normalizeType(t,tnv) else tlookup(x, tail)
  68.     case _ => throw TypeException("no tvbind in tnv")
  69.   }
  70.  
  71.   def normalizeType(t: Type, tnv: List[TVBind]): Type = t match {
  72.     case VarT(a) => tlookup(a,tnv)
  73.     case FunT(in, out) => FunT(normalizeType(in,tnv), normalizeType(out,tnv))
  74.     case NumT() => NumT()
  75.     case ListT(a) => ListT(normalizeType(a,tnv))
  76.     case _ => {
  77.       println("nt: " + t)
  78.       throw TypeException("another thing than var?")
  79.     }
  80.   }
  81.    
  82.  
  83. }
  84.  
  85. sealed abstract class ExprExt
  86.  
  87. case class NumExt(n: Int)                          extends ExprExt
  88. case class PlusExt(e1: ExprExt, e2: ExprExt)       extends ExprExt
  89. case class MultExt(e1: ExprExt, e2: ExprExt)       extends ExprExt
  90. case class FdExt(x: String, t: Type, e: ExprExt)   extends ExprExt
  91. case class AppExt(f: ExprExt, a: ExprExt)          extends ExprExt
  92. case class IdExt(x: String)                        extends ExprExt
  93. case class ConsExt(hd: ExprExt, tl: ExprExt)       extends ExprExt
  94. case class NilExt(t: Type)                         extends ExprExt
  95. case class HeadExt(e: ExprExt)                     extends ExprExt
  96. case class TailExt(e: ExprExt)                     extends ExprExt
  97. case class LetType(x: String, t: Type, e: ExprExt) extends ExprExt
  98.  
  99. sealed abstract class Type
  100.  
  101. case class NumT()                 extends Type
  102. case class ListT(t: Type)         extends Type
  103. case class FunT(a: Type, r: Type) extends Type
  104. case class VarT(x: String)        extends Type
  105.  
  106. case class TBind(x: String, t: Type)
  107.  
  108. case class TVBind(x: String, t: Type)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement