Advertisement
VladNitu

TypeCheckerResit20-21Nistor

May 25th, 2023
446
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 7.69 KB | None | 0 0
  1. import Library._
  2.  
  3. object TypeCheck {
  4.  
  5.   def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
  6.     case NumExt(n) => NumT()
  7.     case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  8.       case (NumT(), NumT()) => NumT()
  9.       case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
  10.     }
  11.     case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  12.       case (NumT(), NumT()) => NumT()
  13.       case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
  14.     }
  15.     case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  16.       case (NumT(), NumT()) => NumT()
  17.       case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
  18.     }
  19.     case TrueExt() => BoolT()
  20.     case FalseExt() => BoolT()
  21.     case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  22.       case (NumT(), NumT()) => BoolT()
  23.       case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
  24.     }
  25.     case IfExt(c, t, e) => typeOf(c, tnv) match {
  26.       case BoolT() => if (typeOf(t, tnv) == typeOf(e, tnv)) typeOf(t, tnv) else throw TypeException("Branches IF diff types")
  27.       case _ => throw TypeException(s"$c not a Boolean")
  28.     }
  29.     case AppExt(f, arg) => typeOf(f, tnv) match {
  30.       case FunT(paramTy, retTy) => if (typeOf(arg, tnv) == paramTy) retTy else throw TypeException("AppC: paramTy and arg diff types")
  31.       case _ => throw TypeException(s"$f does not eval. to FunT")
  32.      
  33.     }
  34.     case IdExt(x) => tnv.find(bnd => bnd.x == x) match {
  35.       case Some(TBind(_, ty)) => ty
  36.       case _ => throw TypeException(s"$x not found in lookup $tnv")
  37.     }
  38.     case FunctionsExt(funs, cont) =>
  39.      val funsBinds = funs.map(fun => TBind(fun.f, FunT(fun.paramTy , fun.retTy)))
  40.      // Check if each function's body types
  41.      funs.find(fun => typeOf(fun.body, TBind(fun.param, fun.paramTy) :: funsBinds ::: tnv) != fun.retTy) match {
  42.        case Some(_) => throw TypeException("body does not bind")
  43.        case _ => {}
  44.      }
  45.      
  46.      typeOf(cont, funsBinds ::: tnv)
  47. }
  48. }
  49.  
  50. // import Library._
  51. //
  52. // object TypeCheck {
  53. //
  54. //   def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
  55. //     case NumExt(n) => NumT()
  56. //     case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  57. //       case (NumT(), NumT()) => NumT()
  58. //       case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
  59. //     }
  60. //     case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  61. //       case (NumT(), NumT()) => NumT()
  62. //       case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
  63. //     }
  64. //     case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  65. //       case (NumT(), NumT()) => NumT()
  66. //       case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
  67. //     }
  68. //     case TrueExt() => BoolT()
  69. //     case FalseExt() => BoolT()
  70. //     case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  71. //       case (NumT(), NumT()) => BoolT()
  72. //       case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
  73. //     }
  74. //    
  75. //     case IfExt(c, t, e) => typeOf(c, tnv) match {
  76. //       case BoolT() => if (typeOf(t, tnv) == typeOf(e, tnv)) typeOf(t, tnv) else throw TypeException("Branches don't match IF")
  77. //       case _ => throw TypeException("s$c does not evaluate to Boolean")
  78. //     }
  79. //     case AppExt(f, arg) => typeOf(f, tnv) match {
  80. //       case FunT(paramTy, retTy) => if (typeOf(arg, tnv) == paramTy) retTy else throw TypeException("s$paramTy and $arg type missmatch")
  81. //       case _ => throw TypeException("s$f does not evaluate to FunT")
  82. //     }
  83. //      
  84. //     case IdExt(x) => tnv.find(tbind => tbind.x == x) match {
  85. //       case Some(TBind(_, ty)) => ty
  86. //       case _ => throw TypeException(s"$x ID not found in nv")
  87. //     }
  88. //     case FunctionsExt(funs, cont) =>
  89. //       val functionBinds = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy)))
  90. //       val paramBinds = funs.map(fun => TBind(fun.param, fun.paramTy))
  91. //  
  92. //       funs.find(fun => typeOf(fun.body, TBind(fun.param, fun.paramTy) :: functionBinds ::: tnv) != fun.retTy) match {
  93. //         case Some(_) => throw TypeException("missmatch of types")
  94. //         case None => {}
  95. //       }
  96. //      
  97. //       typeOf(cont, functionBinds ::: tnv)
  98. //      
  99. //    
  100. //   }
  101. //  
  102. // }
  103. //
  104. // // import Library._
  105. // //
  106. // // object TypeCheck {
  107. // //
  108. // //   def lookup(x: String, tnv: List[TBind]): Type = tnv match {
  109. // //     case TBind(y, t) :: tail => if (x == y) t else lookup(x, tail)
  110. // //     case _ => throw new TypeException(s"$x is not bounded in environment $tnv")
  111. // //   }
  112. // //  
  113. // //   def checkFunsTypes(funs: List[FuncExt], tnv: List[TBind]): Unit = funs match {
  114. // //    
  115. // //     case fun :: t => if (typeOf(fun.body, tnv) == fun.retTy) checkFunsTypes(t, tnv) else throw TypeException("Body-param does not match")
  116. // //     case Nil => {}
  117. // //    
  118. // //   }
  119. // //  
  120. // //   def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
  121. // //     case NumExt(n) => NumT()
  122. // //     case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  123. // //       case (NumT(), NumT()) => NumT()
  124. // //       case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
  125. // //     }
  126. // //     case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  127. // //       case (NumT(), NumT()) => NumT()
  128. // //       case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
  129. // //     }
  130. // //     case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  131. // //       case (NumT(), NumT()) => NumT()
  132. // //       case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
  133. // //     }
  134. // //     case TrueExt() => BoolT()
  135. // //     case FalseExt() => BoolT()
  136. // //     case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
  137. // //       case (NumT(), NumT()) => BoolT()
  138. // //       case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
  139. // //     }
  140. // //    
  141. // //     case IfExt(c, t, e) => typeOf(c, tnv) match {
  142. // //       case BoolT() =>
  143. // //       val t1 = typeOf(t, tnv)
  144. // //       val t2 = typeOf(e, tnv)
  145. // //       if (t1 == t2) t1 else throw new TypeException("Branches have diff. types")
  146. // //       case _ => throw new TypeException("Conditional should be boolean")
  147. // //     }
  148. // //      
  149. // //     case AppExt(f, args) => typeOf(f, tnv) match {
  150. // //       case FunT(paramTy, retTy) => {
  151. // //         if (typeOf(args, tnv) == paramTy)
  152. // //           retTy
  153. // //         else  throw new TypeException(s"$args do not match $paramTy")
  154. // //       }
  155. // //       case _ => throw new TypeException(s"$f is not a FunT")
  156. // //     }
  157. // //      
  158. // //      
  159. // //    
  160. // //     case IdExt(x) => lookup(x, tnv)
  161. // //     case FunctionsExt(funs, cont) =>  {
  162. // //    
  163. // //     val bindsF = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy)))
  164. // //     val bindsParams = funs.map(fun => TBind(fun.param, fun.paramTy))
  165. // //     checkFunsTypes(funs, bindsParams ::: bindsF ::: tnv)
  166. // //     val newTnv = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy))) ::: tnv
  167. // //
  168. // //     typeOf(cont, newTnv)
  169. // //     }
  170. // //   }
  171. // //  
  172. // // }
  173. // //
  174. // // //FunT(fun.paramTy,
  175. // //     //if (typeOf(fun.body, tnv) ==
  176.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement