Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Library._
- object TypeCheck {
- def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
- case NumExt(n) => NumT()
- case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- case (NumT(), NumT()) => NumT()
- case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
- }
- case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- case (NumT(), NumT()) => NumT()
- case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
- }
- case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- case (NumT(), NumT()) => NumT()
- case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
- }
- case TrueExt() => BoolT()
- case FalseExt() => BoolT()
- case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- case (NumT(), NumT()) => BoolT()
- case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
- }
- case IfExt(c, t, e) => typeOf(c, tnv) match {
- case BoolT() => if (typeOf(t, tnv) == typeOf(e, tnv)) typeOf(t, tnv) else throw TypeException("Branches IF diff types")
- case _ => throw TypeException(s"$c not a Boolean")
- }
- case AppExt(f, arg) => typeOf(f, tnv) match {
- case FunT(paramTy, retTy) => if (typeOf(arg, tnv) == paramTy) retTy else throw TypeException("AppC: paramTy and arg diff types")
- case _ => throw TypeException(s"$f does not eval. to FunT")
- }
- case IdExt(x) => tnv.find(bnd => bnd.x == x) match {
- case Some(TBind(_, ty)) => ty
- case _ => throw TypeException(s"$x not found in lookup $tnv")
- }
- case FunctionsExt(funs, cont) =>
- val funsBinds = funs.map(fun => TBind(fun.f, FunT(fun.paramTy , fun.retTy)))
- // Check if each function's body types
- funs.find(fun => typeOf(fun.body, TBind(fun.param, fun.paramTy) :: funsBinds ::: tnv) != fun.retTy) match {
- case Some(_) => throw TypeException("body does not bind")
- case _ => {}
- }
- typeOf(cont, funsBinds ::: tnv)
- }
- }
- // import Library._
- //
- // object TypeCheck {
- //
- // def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
- // case NumExt(n) => NumT()
- // case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // case (NumT(), NumT()) => NumT()
- // case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
- // }
- // case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // case (NumT(), NumT()) => NumT()
- // case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
- // }
- // case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // case (NumT(), NumT()) => NumT()
- // case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
- // }
- // case TrueExt() => BoolT()
- // case FalseExt() => BoolT()
- // case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // case (NumT(), NumT()) => BoolT()
- // case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
- // }
- //
- // case IfExt(c, t, e) => typeOf(c, tnv) match {
- // case BoolT() => if (typeOf(t, tnv) == typeOf(e, tnv)) typeOf(t, tnv) else throw TypeException("Branches don't match IF")
- // case _ => throw TypeException("s$c does not evaluate to Boolean")
- // }
- // case AppExt(f, arg) => typeOf(f, tnv) match {
- // case FunT(paramTy, retTy) => if (typeOf(arg, tnv) == paramTy) retTy else throw TypeException("s$paramTy and $arg type missmatch")
- // case _ => throw TypeException("s$f does not evaluate to FunT")
- // }
- //
- // case IdExt(x) => tnv.find(tbind => tbind.x == x) match {
- // case Some(TBind(_, ty)) => ty
- // case _ => throw TypeException(s"$x ID not found in nv")
- // }
- // case FunctionsExt(funs, cont) =>
- // val functionBinds = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy)))
- // val paramBinds = funs.map(fun => TBind(fun.param, fun.paramTy))
- //
- // funs.find(fun => typeOf(fun.body, TBind(fun.param, fun.paramTy) :: functionBinds ::: tnv) != fun.retTy) match {
- // case Some(_) => throw TypeException("missmatch of types")
- // case None => {}
- // }
- //
- // typeOf(cont, functionBinds ::: tnv)
- //
- //
- // }
- //
- // }
- //
- // // import Library._
- // //
- // // object TypeCheck {
- // //
- // // def lookup(x: String, tnv: List[TBind]): Type = tnv match {
- // // case TBind(y, t) :: tail => if (x == y) t else lookup(x, tail)
- // // case _ => throw new TypeException(s"$x is not bounded in environment $tnv")
- // // }
- // //
- // // def checkFunsTypes(funs: List[FuncExt], tnv: List[TBind]): Unit = funs match {
- // //
- // // case fun :: t => if (typeOf(fun.body, tnv) == fun.retTy) checkFunsTypes(t, tnv) else throw TypeException("Body-param does not match")
- // // case Nil => {}
- // //
- // // }
- // //
- // // def typeOf(e: ExprExt, tnv: List[TBind]): Type = e match {
- // // case NumExt(n) => NumT()
- // // case PlusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // // case (NumT(), NumT()) => NumT()
- // // case p => throw TypeException("Bad addition. Expected expressions to be number typed, but got: " + p)
- // // }
- // // case MultExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // // case (NumT(), NumT()) => NumT()
- // // case p => throw TypeException("Bad multiplication. Expected expressions to be number typed, but got: " + p)
- // // }
- // // case MinusExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // // case (NumT(), NumT()) => NumT()
- // // case p => throw TypeException("Bad subtraction. Expected expressions to be number typed, but got: " + p)
- // // }
- // // case TrueExt() => BoolT()
- // // case FalseExt() => BoolT()
- // // case EqNumExt(l, r) => (typeOf(l, tnv), typeOf(r, tnv)) match {
- // // case (NumT(), NumT()) => BoolT()
- // // case p => throw TypeException("Bad number equality comparison. Expected expressions to be number typed, but got: " + p)
- // // }
- // //
- // // case IfExt(c, t, e) => typeOf(c, tnv) match {
- // // case BoolT() =>
- // // val t1 = typeOf(t, tnv)
- // // val t2 = typeOf(e, tnv)
- // // if (t1 == t2) t1 else throw new TypeException("Branches have diff. types")
- // // case _ => throw new TypeException("Conditional should be boolean")
- // // }
- // //
- // // case AppExt(f, args) => typeOf(f, tnv) match {
- // // case FunT(paramTy, retTy) => {
- // // if (typeOf(args, tnv) == paramTy)
- // // retTy
- // // else throw new TypeException(s"$args do not match $paramTy")
- // // }
- // // case _ => throw new TypeException(s"$f is not a FunT")
- // // }
- // //
- // //
- // //
- // // case IdExt(x) => lookup(x, tnv)
- // // case FunctionsExt(funs, cont) => {
- // //
- // // val bindsF = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy)))
- // // val bindsParams = funs.map(fun => TBind(fun.param, fun.paramTy))
- // // checkFunsTypes(funs, bindsParams ::: bindsF ::: tnv)
- // // val newTnv = funs.map(fun => TBind(fun.f, FunT(fun.paramTy, fun.retTy))) ::: tnv
- // //
- // // typeOf(cont, newTnv)
- // // }
- // // }
- // //
- // // }
- // //
- // // //FunT(fun.paramTy,
- // // //if (typeOf(fun.body, tnv) ==
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement