improve cps handling of if-then-else. no review.
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26092 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
2a34d20013
commit
90f4ba32a2
|
|
@ -173,40 +173,44 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
|
|||
|
||||
(Nil, tree1, cpsA)
|
||||
|
||||
case If(cond, thenp, elsep) =>
|
||||
|
||||
val (condStats, condVal, spc) = transInlineValue(cond, cpsA)
|
||||
case If(cond, thenp, elsep) =>
|
||||
/* possible situations:
|
||||
cps before (cpsA)
|
||||
cps in condition (spc) <-- synth flag set if *only* here!
|
||||
cps in (one or both) branches */
|
||||
val (condStats, condVal, spc) = transInlineValue(cond, cpsA)
|
||||
val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
|
||||
(spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
|
||||
(None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly
|
||||
val thenVal = transExpr(thenp, cpsA2, cpsR2)
|
||||
val elseVal = transExpr(elsep, cpsA2, cpsR2)
|
||||
|
||||
val (cpsA2, cpsR2) = (spc, linearize(spc, getAnswerTypeAnn(tree.tpe)))
|
||||
// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
|
||||
val thenVal = transExpr(thenp, cpsA2, cpsR2)
|
||||
val elseVal = transExpr(elsep, cpsA2, cpsR2)
|
||||
|
||||
// check that then and else parts agree (not necessary any more, but left as sanity check)
|
||||
if (cpsR.isDefined) {
|
||||
if (elsep == EmptyTree)
|
||||
unit.error(tree.pos, "always need else part in cps code")
|
||||
}
|
||||
if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) {
|
||||
unit.error(tree.pos, "then and else parts must both be cps code or neither of them")
|
||||
}
|
||||
// check that then and else parts agree (not necessary any more, but left as sanity check)
|
||||
if (cpsR.isDefined) {
|
||||
if (elsep == EmptyTree)
|
||||
unit.error(tree.pos, "always need else part in cps code")
|
||||
}
|
||||
if (hasAnswerTypeAnn(thenVal.tpe) != hasAnswerTypeAnn(elseVal.tpe)) {
|
||||
unit.error(tree.pos, "then and else parts must both be cps code or neither of them")
|
||||
}
|
||||
|
||||
(condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc)
|
||||
(condStats, updateSynthFlag(treeCopy.If(tree, condVal, thenVal, elseVal)), spc)
|
||||
|
||||
case Match(selector, cases) =>
|
||||
|
||||
val (selStats, selVal, spc) = transInlineValue(selector, cpsA)
|
||||
val (cpsA2, cpsR2) = (spc, linearize(spc, getAnswerTypeAnn(tree.tpe)))
|
||||
// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
|
||||
case Match(selector, cases) =>
|
||||
|
||||
val caseVals = for {
|
||||
cd @ CaseDef(pat, guard, body) <- cases
|
||||
bodyVal = transExpr(body, cpsA2, cpsR2)
|
||||
} yield {
|
||||
treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
|
||||
}
|
||||
|
||||
(selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc)
|
||||
val (selStats, selVal, spc) = transInlineValue(selector, cpsA)
|
||||
val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
|
||||
(spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
|
||||
(None, getAnswerTypeAnn(tree.tpe))
|
||||
|
||||
val caseVals = for {
|
||||
cd @ CaseDef(pat, guard, body) <- cases
|
||||
bodyVal = transExpr(body, cpsA2, cpsR2)
|
||||
} yield {
|
||||
treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
|
||||
}
|
||||
|
||||
(selStats, updateSynthFlag(treeCopy.Match(tree, selVal, caseVals)), spc)
|
||||
|
||||
|
||||
case ldef @ LabelDef(name, params, rhs) =>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
10
|
||||
10
|
||||
10
|
||||
10
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import scala.util.continuations._
|
||||
|
||||
object Test {
|
||||
def sh(x1:Int) = shift( (k: Int => Int) => k(k(k(x1))))
|
||||
|
||||
def testA(x1: Int): Int @cps[Int] = {
|
||||
sh(x1)
|
||||
if (x1==42) x1 else sh(x1)
|
||||
}
|
||||
|
||||
def testB(x1: Int): Int @cps[Int] = {
|
||||
if (sh(x1)==43) x1 else x1
|
||||
}
|
||||
|
||||
def testC(x1: Int): Int @cps[Int] = {
|
||||
sh(x1)
|
||||
if (sh(x1)==44) x1 else x1
|
||||
}
|
||||
|
||||
def testD(x1: Int): Int @cps[Int] = {
|
||||
sh(x1)
|
||||
if (sh(x1)==45) x1 else sh(x1)
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Any = {
|
||||
println(reset(1 + testA(7)))
|
||||
println(reset(1 + testB(9)))
|
||||
println(reset(1 + testC(9)))
|
||||
println(reset(1 + testD(7)))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
10
|
||||
11
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import scala.util.continuations._
|
||||
|
||||
object Test {
|
||||
def sh(x1:Int) = shift( (k: Int => Int) => k(k(k(x1))))
|
||||
|
||||
def test(x1: Int) = {
|
||||
val o7 = {
|
||||
val o6 = {
|
||||
val o3 =
|
||||
if (7 == x1) Some(x1)
|
||||
else None
|
||||
|
||||
if (o3.isEmpty) None
|
||||
else Some(sh(x1))
|
||||
}
|
||||
if (o6.isEmpty) {
|
||||
val o5 =
|
||||
if (8 == x1) Some(x1)
|
||||
else None
|
||||
|
||||
if (o5.isEmpty) None
|
||||
else Some(sh(x1))
|
||||
} else o6
|
||||
}
|
||||
o7.get
|
||||
}
|
||||
|
||||
def main(args: Array[String]): Any = {
|
||||
println(reset(1 + test(7)))
|
||||
println(reset(1 + test(8)))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue