diff --git a/src/main/scala/hb/dhbw/AST.scala b/src/main/scala/hb/dhbw/AST.scala index 08f35c8..36d2c72 100644 --- a/src/main/scala/hb/dhbw/AST.scala +++ b/src/main/scala/hb/dhbw/AST.scala @@ -1,7 +1,7 @@ package hb.dhbw -final case class Class(name: String, params: List[(Type,Type)], superType: RefType, fields: List[(Type,String)], methods: List[Method]) -final case class Method(retType: Type, name: String, params: List[(Type, String)], retExpr: Expr) +final case class Class(name: String, genericParams: List[(Type,Type)], superType: RefType, fields: List[(Type,String)], methods: List[Method]) +final case class Method(genericParams: List[Constraint], retType: Type, name: String, params: List[(Type, String)], retExpr: Expr) sealed trait Type final case class RefType(name: String, params: List[Type]) extends Type @@ -25,7 +25,7 @@ object ASTBuilder { val genericNames = c.params.map(_._1).map(_.name).toSet Class(c.name, c.params.map(p => (nTypeToType(p._1, genericNames), nTypeToType(p._2, genericNames))), nTypeToType(c.superType, genericNames).asInstanceOf[RefType], - c.fields.map(f => (nTypeToType(f._1, genericNames),f._2)), c.methods.map(m => Method(freshTPV(), m.name, m.params.map(p => (freshTPV(), p)), m.retExpr))) + c.fields.map(f => (nTypeToType(f._1, genericNames),f._2)), c.methods.map(m => Method(List(), freshTPV(), m.name, m.params.map(p => (freshTPV(), p)), m.retExpr))) }) private def freshTPV() = { diff --git a/src/main/scala/hb/dhbw/FJTypeinference.scala b/src/main/scala/hb/dhbw/FJTypeinference.scala index 39ef602..1220667 100644 --- a/src/main/scala/hb/dhbw/FJTypeinference.scala +++ b/src/main/scala/hb/dhbw/FJTypeinference.scala @@ -27,7 +27,7 @@ object FJTypeinference { private def generateFC(ast: List[Class]): FiniteClosure = new FiniteClosure( ast.map(c => (cToUnifyType(c), convertType(c.superType).asInstanceOf[UnifyRefType])).toSet) - private def cToUnifyType(c: Class) = UnifyRefType(c.name, c.params.map(it => convertType(it._1))) + private def cToUnifyType(c: Class) = UnifyRefType(c.name, c.genericParams.map(it => convertType(it._1))) def typeinference(str: String): Either[String, Set[Set[UnifyConstraint]]] = { val ast = Parser.parse(str).map(ASTBuilder.fromParseTree(_)) diff --git a/src/main/scala/hb/dhbw/InsertTypes.scala b/src/main/scala/hb/dhbw/InsertTypes.scala index 3e87a57..c2682e1 100644 --- a/src/main/scala/hb/dhbw/InsertTypes.scala +++ b/src/main/scala/hb/dhbw/InsertTypes.scala @@ -2,4 +2,22 @@ package hb.dhbw class InsertTypes { + def insert(unifyResult: Set[Set[UnifyConstraint]], into: Class): Class = { + val constraints = unifyResult.map(_.map(replaceTVWithGeneric(_))) + val newMethods = into.methods.flatMap(m => constraints.map(cons => insert(cons, m))) + Class(into.name, into.genericParams, into.superType, into.fields, newMethods) + } + + private def insert(constraints: Set[Constraint], into: Method): Method = { + Method(into.genericParams ++ constraints, into.retType, into.name, into.params, into.retExpr) + } + private def replaceTVWithGeneric(in: UnifyConstraint): Constraint= in match { + case UnifyLessDot(a,b) => LessDot(replaceTVWithGeneric(a), replaceTVWithGeneric(b)) + case UnifyEqualsDot(a, b) => EqualsDot(replaceTVWithGeneric(a), replaceTVWithGeneric(b)) + } + private def replaceTVWithGeneric(in: UnifyType) : Type = in match { + case UnifyRefType(name, params) => RefType(name, params.map(replaceTVWithGeneric(_))) + case UnifyTV(name) => GenericType(name) + } + } diff --git a/src/main/scala/hb/dhbw/TYPE.scala b/src/main/scala/hb/dhbw/TYPE.scala index 3cf23ef..aa437c7 100644 --- a/src/main/scala/hb/dhbw/TYPE.scala +++ b/src/main/scala/hb/dhbw/TYPE.scala @@ -67,7 +67,7 @@ object TYPE { val (rty, cons) = TYPEExpr(e, localVars, ast) val es = params.map(ex => TYPEExpr(ex, localVars, ast)) val methods = findMethods(name, es.size, ast) - val consM = methods.map(m => AndConstraint( + val consM = methods.map(m => AndConstraint(m._2.genericParams ++ List(EqualsDot(rty, cToType(m._1)), EqualsDot(a, m._2.retType)) ++ m._2.params.map(_._1).zip(es.map(_._1)).map(a => LessDot(a._2, a._1)) )) @@ -85,7 +85,7 @@ object TYPE { private def findFields(f: String, ast: List[Class]) = ast.flatMap(c => c.fields.filter(field => field._2.equals(f)).map(it => (c, it._1))) - private def cToType(c: Class) = RefType(c.name, c.params.map(it => it._1)) + private def cToType(c: Class) = RefType(c.name, c.genericParams.map(it => it._1)) } } diff --git a/src/main/scala/hb/dhbw/Unify.scala b/src/main/scala/hb/dhbw/Unify.scala index fa17797..de12a2a 100644 --- a/src/main/scala/hb/dhbw/Unify.scala +++ b/src/main/scala/hb/dhbw/Unify.scala @@ -9,6 +9,17 @@ sealed abstract class UnifyType final case class UnifyRefType(name: String, params: List[UnifyType]) extends UnifyType final case class UnifyTV(name: String) extends UnifyType +/* +sealed abstract class ResultType +final case class ResultTV(name: String) extends ResultType +final case class ResultRefType(name: String, params: List[ResultType]) extends ResultType +sealed abstract class UnifyResultConstraint +final case class AExtendsB(a: TypeVariable, b: TypeVariable) extends UnifyResultConstraint +final case class AExtendsN(a: TypeVariable, n: ResultRefType) extends UnifyResultConstraint +final case class AEqualsB(a: TypeVariable, b: TypeVariable) extends UnifyResultConstraint +final case class AEqualsN(a: TypeVariable, n: ResultRefType) extends UnifyResultConstraint +*/ + object Unify { def unifyIteratove(orCons: Set[Set[Set[UnifyConstraint]]], fc: FiniteClosure) : Set[Set[UnifyConstraint]] = {