diff options
Diffstat (limited to 'src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala')
-rw-r--r-- | src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala | 117 |
1 files changed, 54 insertions, 63 deletions
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala index d1a35df04b..5cb06d42db 100644 --- a/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala +++ b/src/continuations/plugin/scala/tools/selectivecps/CPSUtils.scala @@ -13,96 +13,90 @@ trait CPSUtils { val verbose: Boolean = System.getProperty("cpsVerbose", "false") == "true" def vprintln(x: =>Any): Unit = if (verbose) println(x) - lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym") - lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam") - lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth") - - lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus") + lazy val MarkerCPSSym = definitions.getClass("scala.util.continuations.cpsSym") + lazy val MarkerCPSTypes = definitions.getClass("scala.util.continuations.cpsParam") + lazy val MarkerCPSSynth = definitions.getClass("scala.util.continuations.cpsSynth") + lazy val MarkerCPSAdaptPlus = definitions.getClass("scala.util.continuations.cpsPlus") lazy val MarkerCPSAdaptMinus = definitions.getClass("scala.util.continuations.cpsMinus") - lazy val Context = definitions.getClass("scala.util.continuations.ControlContext") - lazy val ModCPS = definitions.getModule("scala.util.continuations") - lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit") - lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR") - lazy val MethShift = definitions.getMember(ModCPS, "shift") - lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR") - lazy val MethReify = definitions.getMember(ModCPS, "reify") - lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR") + lazy val MethShiftUnit = definitions.getMember(ModCPS, "shiftUnit") + lazy val MethShiftUnitR = definitions.getMember(ModCPS, "shiftUnitR") + lazy val MethShift = definitions.getMember(ModCPS, "shift") + lazy val MethShiftR = definitions.getMember(ModCPS, "shiftR") + lazy val MethReify = definitions.getMember(ModCPS, "reify") + lazy val MethReifyR = definitions.getMember(ModCPS, "reifyR") lazy val allCPSAnnotations = List(MarkerCPSSym, MarkerCPSTypes, MarkerCPSSynth, MarkerCPSAdaptPlus, MarkerCPSAdaptMinus) + // TODO - needed? Can these all use the same annotation info? + protected def newSynthMarker() = newMarker(MarkerCPSSynth) + protected def newPlusMarker() = newMarker(MarkerCPSAdaptPlus) + protected def newMinusMarker() = newMarker(MarkerCPSAdaptMinus) + protected def newMarker(tpe: Type): AnnotationInfo = AnnotationInfo marker tpe + protected def newMarker(sym: Symbol): AnnotationInfo = AnnotationInfo marker sym.tpe + + protected def newCpsParamsMarker(tp1: Type, tp2: Type) = + newMarker(appliedType(MarkerCPSTypes.tpe, List(tp1, tp2))) + // annotation checker + protected def annTypes(ann: AnnotationInfo): (Type, Type) = { + val tp0 :: tp1 :: Nil = ann.atp.normalize.typeArgs + ((tp0, tp1)) + } + protected def hasMinusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptMinus + protected def hasPlusMarker(tpe: Type) = tpe hasAnnotation MarkerCPSAdaptPlus + protected def hasSynthMarker(tpe: Type) = tpe hasAnnotation MarkerCPSSynth + protected def hasCpsParamTypes(tpe: Type) = tpe hasAnnotation MarkerCPSTypes + protected def cpsParamTypes(tpe: Type) = tpe getAnnotation MarkerCPSTypes map annTypes + def filterAttribs(tpe:Type, cls:Symbol) = - tpe.annotations.filter(_.atp.typeSymbol == cls) + tpe.annotations filter (_ matches cls) - def removeAttribs(tpe:Type, cls:Symbol*) = - tpe.withoutAnnotations.withAnnotations(tpe.annotations.filterNot(cls contains _.atp.typeSymbol)) + def removeAttribs(tpe: Type, classes: Symbol*) = + tpe filterAnnotations (ann => !(classes exists (ann matches _))) def removeAllCPSAnnotations(tpe: Type) = removeAttribs(tpe, allCPSAnnotations:_*) + def cpsParamAnnotation(tpe: Type) = filterAttribs(tpe, MarkerCPSTypes) + def linearize(ann: List[AnnotationInfo]): AnnotationInfo = { - ann.reduceLeft { (a, b) => - val atp0::atp1::Nil = a.atp.normalize.typeArgs - val btp0::btp1::Nil = b.atp.normalize.typeArgs - val (u0,v0) = (atp0, atp1) - val (u1,v1) = (btp0, btp1) -/* - val (u0,v0) = (a.atp.typeArgs(0), a.atp.typeArgs(1)) - val (u1,v1) = (b.atp.typeArgs(0), b.atp.typeArgs(1)) - vprintln("check lin " + a + " andThen " + b) -*/ - vprintln("check lin " + a + " andThen " + b) - if (!(v1 <:< u0)) + ann reduceLeft { (a, b) => + val (u0,v0) = annTypes(a) + val (u1,v1) = annTypes(b) + // vprintln("check lin " + a + " andThen " + b) + + if (v1 <:< u0) + newCpsParamsMarker(u1, v0) + else throw new TypeError("illegal answer type modification: " + a + " andThen " + b) - // TODO: improve error message (but it is not very common) - AnnotationInfo(appliedType(MarkerCPSTypes.tpe, List(u1,v0)),Nil,Nil) } } // anf transform def getExternalAnswerTypeAnn(tp: Type) = { - tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match { - case Some(AnnotationInfo(atp, _, _)) => - val atp0::atp1::Nil = atp.normalize.typeArgs - Some((atp0, atp1)) - case None => - if (tp.hasAnnotation(MarkerCPSAdaptPlus)) - global.warning("trying to instantiate type " + tp + " to unknown cps type") - None - } - } - - def getAnswerTypeAnn(tp: Type) = { - tp.annotations.find(a => a.atp.typeSymbol == MarkerCPSTypes) match { - case Some(AnnotationInfo(atp, _, _)) => - if (!tp.hasAnnotation(MarkerCPSAdaptPlus)) {//&& !tp.hasAnnotation(MarkerCPSAdaptMinus)) - val atp0::atp1::Nil = atp.normalize.typeArgs - Some((atp0, atp1)) - } else - None - case None => None + cpsParamTypes(tp) orElse { + if (hasPlusMarker(tp)) + global.warning("trying to instantiate type " + tp + " to unknown cps type") + None } } - def hasAnswerTypeAnn(tp: Type) = { - tp.hasAnnotation(MarkerCPSTypes) && !tp.hasAnnotation(MarkerCPSAdaptPlus) /*&& - !tp.hasAnnotation(MarkerCPSAdaptMinus)*/ - } + def getAnswerTypeAnn(tp: Type): Option[(Type, Type)] = + cpsParamTypes(tp) filterNot (_ => hasPlusMarker(tp)) - def hasSynthAnn(tp: Type) = { - tp.annotations.exists(a => a.atp.typeSymbol == MarkerCPSSynth) - } + def hasAnswerTypeAnn(tp: Type) = + hasCpsParamTypes(tp) && !hasPlusMarker(tp) def updateSynthFlag(tree: Tree) = { // remove annotations if *we* added them (@synth present) - if (hasSynthAnn(tree.tpe)) { + if (hasSynthMarker(tree.tpe)) { log("removing annotation from " + tree) - tree.setType(removeAllCPSAnnotations(tree.tpe)) + tree modifyType removeAllCPSAnnotations } else tree } @@ -124,7 +118,4 @@ trait CPSUtils { case _ => None } } - - // cps transform - -}
\ No newline at end of file +} |