summaryrefslogtreecommitdiff
path: root/src/continuations
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-04-14 19:50:21 +0200
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-04-14 22:49:02 +0200
commit28483739c365b1a3b748ebab50b03bd66a4db61d (patch)
treebb5e7f33fd3cb67781cef52a818b41d78d1fdacc /src/continuations
parent1a6e7129da15cf77beb26ab84bbfdb8ef356cc21 (diff)
downloadscala-28483739c365b1a3b748ebab50b03bd66a4db61d.tar.gz
scala-28483739c365b1a3b748ebab50b03bd66a4db61d.tar.bz2
scala-28483739c365b1a3b748ebab50b03bd66a4db61d.zip
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)
Diffstat (limited to 'src/continuations')
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala3
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala6
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala49
3 files changed, 28 insertions, 30 deletions
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)))
/*