From 28483739c365b1a3b748ebab50b03bd66a4db61d Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Sat, 14 Apr 2012 19:50:21 +0200 Subject: restore typedMatchAnonFun in all its glory detect partialfunction in cpsannotationchecker emit apply/isDefinedAt if PF has @cps targs (applyOrElse can't be typed) further hacky improvements to selective anf better try/catch support in selective cps using freshly minted anonfun match make virtpatmat resilient to scaladoc (after uncurry, don't translate matches TODO: factor out translation all together so presentation compiler/scaladoc can skip it) --- .../tools/selectivecps/CPSAnnotationChecker.scala | 3 +- .../tools/selectivecps/SelectiveANFTransform.scala | 6 ++- .../tools/selectivecps/SelectiveCPSTransform.scala | 49 ++++++++++------------ 3 files changed, 28 insertions(+), 30 deletions(-) (limited to 'src/continuations') diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala index af0d768607..bed8e93d1b 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala @@ -94,8 +94,7 @@ abstract class CPSAnnotationChecker extends CPSUtils { if (!cpsEnabled) return bounds val anyAtCPS = newCpsParamsMarker(NothingClass.tpe, AnyClass.tpe) - - if (isFunctionType(tparams.head.owner.tpe) || tparams.head.owner == PartialFunctionClass) { + if (isFunctionType(tparams.head.owner.tpe) || isPartialFunctionType(tparams.head.owner.tpe)) { vprintln("function bound: " + tparams.head.owner.tpe + "/"+bounds+"/"+targs) if (hasCpsParamTypes(targs.last)) bounds.reverse match { diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala index 0975f16c6e..e1d699debc 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala @@ -457,11 +457,13 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with val (anfStats, anfExpr) = rec(stms, cpsA, List()) // println("\nanf-block:\n"+ ((stms :+ expr) mkString ("{", "\n", "}")) +"\nBECAME\n"+ ((anfStats :+ anfExpr) mkString ("{", "\n", "}"))) - if (anfStats.nonEmpty && (anfStats forall gen.hasSynthCaseSymbol)) { + // SUPER UGLY HACK: handle virtpatmat-style matches, whose labels have already been turned into DefDefs + if (anfStats.nonEmpty && (anfStats forall (t => !t.isDef || gen.hasSynthCaseSymbol(t)))) { val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case // val (defs, calls) = rest partition (_.isInstanceOf[DefDef]) if (rest nonEmpty){ - val stats = prologue ++ rest.reverse // ++ calls + // the filter drops the ()'s emitted when transValue encountered a LabelDef + val stats = prologue ++ (rest filter (_.isInstanceOf[DefDef])).reverse // ++ calls // println("REVERSED "+ (stats mkString ("{", "\n", "}"))) (stats, localTyper.typed{Apply(Ident(rest.head.symbol), List())}) // call first label to kick-start the match } else (anfStats, anfExpr) diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala index 2db4054ef5..a78de8e6c8 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala @@ -190,32 +190,29 @@ abstract class SelectiveCPSTransform extends PluginComponent with val targettp = transformCPSType(tree.tpe) -// val expr2 = if (catches.nonEmpty) { - val pos = catches.head.pos - val argSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) - val rhs = Match(Ident(argSym), catches1) - val fun = Function(List(ValDef(argSym)), rhs) - val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp))) - val funDef = localTyper.typed(atPos(pos) { ValDef(funSym, fun) }) - val expr2 = localTyper.typed(atPos(pos) { Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) }) - - argSym.owner = fun.symbol - rhs.changeOwner(currentOwner -> fun.symbol) - - val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) - - import CODE._ - // generate a case that is supported directly by the back-end - val catchIfDefined = CaseDef( - Bind(exSym, Ident(nme.WILDCARD)), - EmptyTree, - IF ((REF(funSym) DOT nme.isDefinedAt)(REF(exSym))) THEN (REF(funSym) APPLY (REF(exSym))) ELSE Throw(REF(exSym)) - ) - - val catch2 = localTyper.typedCases(List(catchIfDefined), ThrowableClass.tpe, targettp) - //typedCases(tree, catches, ThrowableClass.tpe, pt) - - localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1))) + val pos = catches.head.pos + val funSym = currentOwner.newValueParameter(cpsNames.catches, pos).setInfo(appliedType(PartialFunctionClass.tpe, List(ThrowableClass.tpe, targettp))) + val funDef = localTyper.typed(atPos(pos) { + ValDef(funSym, Match(EmptyTree, catches1)) + }) + val expr2 = localTyper.typed(atPos(pos) { + Apply(Select(expr1, expr1.tpe.member(cpsNames.flatMapCatch)), List(Ident(funSym))) + }) + + val exSym = currentOwner.newValueParameter(cpsNames.ex, pos).setInfo(ThrowableClass.tpe) + + import CODE._ + // generate a case that is supported directly by the back-end + val catchIfDefined = CaseDef( + Bind(exSym, Ident(nme.WILDCARD)), + EmptyTree, + IF ((REF(funSym) DOT nme.isDefinedAt)(REF(exSym))) THEN (REF(funSym) APPLY (REF(exSym))) ELSE Throw(REF(exSym)) + ) + + val catch2 = localTyper.typedCases(List(catchIfDefined), ThrowableClass.tpe, targettp) + //typedCases(tree, catches, ThrowableClass.tpe, pt) + + localTyper.typed(Block(List(funDef), treeCopy.Try(tree, treeCopy.Block(block1, stms, expr2), catch2, finalizer1))) /* -- cgit v1.2.3