Skip to content
Snippets Groups Projects
Commit 916be314 authored by Nicolas Voirol's avatar Nicolas Voirol
Browse files

Fix for first-class functions returning more functions

parent ccdbaa76
No related branches found
No related tags found
No related merge requests found
......@@ -148,6 +148,14 @@ object Types {
case t => Some(Nil, _ => t)
}
}
object FirstOrderFunctionType {
def unapply(tpe: TypeTree): Option[(Seq[TypeTree], TypeTree)] = tpe match {
case FunctionType(from, to) =>
unapply(to).map(p => (from ++ p._1) -> p._2) orElse Some(from -> to)
case _ => None
}
}
def optionToType(tp: Option[TypeTree]) = tp getOrElse Untyped
......
......@@ -256,7 +256,7 @@ class LambdaManager[T](encoder: TemplateEncoder[T]) extends DatatypeManager(enco
(Seq(encoder.mkImplies(blocker, typeBlocker)), Map.empty, Map.empty)
case None =>
val App(caller, tpe @ FunctionType(_, to), args, value) = app
val App(caller, tpe @ FirstOrderFunctionType(_, to), args, value) = app
val typeBlocker = encoder.encodeId(FreshIdentifier("t", BooleanType))
typeBlockers += value -> typeBlocker
implies(blocker, typeBlocker)
......
......@@ -117,6 +117,15 @@ object Template {
}
}
private def mkApplication(caller: Expr, args: Seq[Expr]): Expr = caller.getType match {
case FunctionType(from, to) =>
val (curr, next) = args.splitAt(from.size)
mkApplication(Application(caller, curr), next)
case _ =>
assert(args.isEmpty, s"Non-function typed $caller applied to ${args.mkString(",")}")
caller
}
private def invocationMatcher[T](encodeExpr: Expr => T)(tfd: TypedFunDef, args: Seq[Expr]): Matcher[T] = {
assert(tfd.returnType.isInstanceOf[FunctionType], "invocationMatcher() is only defined on function-typed defs")
......@@ -186,7 +195,7 @@ object Template {
val optIdCall = optCall.map(tfd => TemplateCallInfo[T](tfd, arguments.map(p => Left(p._2))))
val optIdApp = optApp.map { case (idT, tpe) =>
val id = FreshIdentifier("x", tpe, true)
val encoded = encoder.encodeExpr(Map(id -> idT) ++ arguments)(Application(Variable(id), arguments.map(_._1.toVariable)))
val encoded = encoder.encodeExpr(Map(id -> idT) ++ arguments)(mkApplication(Variable(id), arguments.map(_._1.toVariable)))
App(idT, bestRealType(tpe).asInstanceOf[FunctionType], arguments.map(p => Left(p._2)), encoded)
}
......@@ -229,7 +238,7 @@ object Template {
funInfos ++= firstOrderCallsOf(e).map(p => TemplateCallInfo(p._1, p._2.map(encodeArg)))
appInfos ++= firstOrderAppsOf(e).map { case (c, args) =>
val tpe = bestRealType(c.getType).asInstanceOf[FunctionType]
App(encodeExpr(c), tpe, args.map(encodeArg), encodeExpr(Application(c, args)))
App(encodeExpr(c), tpe, args.map(encodeArg), encodeExpr(mkApplication(c, args)))
}
matchInfos ++= exprToMatcher.values
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment