summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBurak Emir <emir@epfl.ch>2007-05-09 13:05:23 +0000
committerBurak Emir <emir@epfl.ch>2007-05-09 13:05:23 +0000
commitfbccd6a31839eb0e1f7f67e7c0cc35771226a6e5 (patch)
treee338ab13065387ba7af25ceec66ffff876f35bcc
parent86eaf4945b14b72b7b62430c73ceea69e0736a0e (diff)
downloadscala-fbccd6a31839eb0e1f7f67e7c0cc35771226a6e5.tar.gz
scala-fbccd6a31839eb0e1f7f67e7c0cc35771226a6e5.tar.bz2
scala-fbccd6a31839eb0e1f7f67e7c0cc35771226a6e5.zip
bug contributions fixed 460 461
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala165
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternMatchers.scala6
2 files changed, 97 insertions, 74 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 8af380d447..dc0c31c010 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -18,6 +18,7 @@ trait ParallelMatching {
import global._
//final def DEBUG(x:String) = {if (settings.debug.value) Console.println(x)}
+ //final def DEBUG(x:String) = {Console.println(x)}
// ---------------------------------- data
sealed trait RuleApplication
@@ -178,6 +179,7 @@ trait ParallelMatching {
}
def repToTree(rep:Rep, typed:Tree => Tree, handleOuter: Tree => Tree)(implicit theOwner: Symbol, failTree: Tree, bodies: collection.mutable.Map[Tree,(Tree,Tree, Symbol)]): Tree = {
+ //Console.println("repToTree")
rep.applyRule match {
case VariableRule(subst, EmptyTree, b) => bodies.get(b) match {
case Some(EmptyTree, b, theLabel) =>
@@ -277,46 +279,63 @@ trait ParallelMatching {
}
}
- def makeRep(temp:List[Symbol], row1:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]/*, exCh:List[Boolean]*/): Rep = {
- var i = -1
- val row = row1 flatMap {
- xx =>
- def isAlternative(p: Tree): Boolean = p match {
- case Bind(_,p) => isAlternative(p)
- case Alternative(ps) => true
- case _ => false
- }
- def getAlternativeBranches(p:Tree): List[Tree] = {
- def get_BIND(pctx:Tree => Tree, p:Tree):List[Tree] = p match {
- case b @ Bind(n,p) => get_BIND({ x:Tree => pctx(copy.Bind(b, n, x) setType x.tpe) }, p)
- case Alternative(ps) => ps map pctx
- }
- get_BIND({x=>x}, p)
- }
- val (pats,subst,g,b) = xx
- i = pats findIndexOf isAlternative
- if(i == -1)
- List((pats,subst,g,b))
- else {
- val prefix:List[Tree] = pats.take(i)
- val alts = getAlternativeBranches(pats(i))
- val suffix:List[Tree] = pats.drop(i+1)
- alts map { p => (prefix ::: p :: suffix, subst, g, b) }
- }
+object Rep {
+ type RepType = Product2[List[Symbol], List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]]
+ def unapply(x:Rep):Option[RepType] =
+ if(x.isInstanceOf[RepImpl]) Some(x.asInstanceOf[RepImpl]) else None
+
+ private
+ case class RepImpl(val temp:List[Symbol], val row:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]) extends Rep with RepType {
+ assert(row.forall { case (pats,subst,g,b) => temp.length == pats.length });
+ def _1 = temp
+ def _2 = row
+ }
+
+ /** the injection here handles alternatives */
+ def apply(temp:List[Symbol], row1:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]): Rep = {
+ var i = -1
+ val row = row1 flatMap {
+ xx =>
+ def isAlternative(p: Tree): Boolean = p match {
+ case Bind(_,p) => isAlternative(p)
+ case Alternative(ps) => true
+ case _ => false
+ }
+ def getAlternativeBranches(p:Tree): List[Tree] = {
+ def get_BIND(pctx:Tree => Tree, p:Tree):List[Tree] = p match {
+ case b @ Bind(n,p) => get_BIND({ x:Tree => pctx(copy.Bind(b, n, x) setType x.tpe) }, p)
+ case Alternative(ps) => ps map pctx
+ }
+ get_BIND({x=>x}, p)
}
+ val (pats,subst,g,b) = xx
+ i = pats findIndexOf isAlternative
if(i == -1)
- Rep(temp,row/*,ex*/)
- else
- makeRep(temp,row/*,ex*/)
+ List((pats,subst,g,b))
+ else {
+ val prefix:List[Tree] = pats.take(i)
+ val alts = getAlternativeBranches(pats(i))
+ val suffix:List[Tree] = pats.drop(i+1)
+ alts map { p => (prefix ::: p :: suffix, subst, g, b) }
+ }
}
+ if(i == -1)
+ RepImpl(temp,row).init
+ else
+ Rep(temp,row) // recursive call
+ }
+}
- case class Rep(val temp:List[Symbol], val row:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]/*, val exhaustivenessChecked:List[Boolean]*/) {
- assert(row.forall { case (pats,subst,g,b) => temp.length == pats.length })
+ abstract class Rep {
+ val temp:List[Symbol]
+ val row:List[(List[Tree], List[(Symbol,Symbol)], Tree, Tree)]
var sealedCols = List[Int]()
var sealedComb = List[Set[Symbol]]()
//Console.println(" the matrix "+this.toString)
- temp.zipWithIndex.foreach {
+
+ def init: this.type = {
+ temp.zipWithIndex.foreach {
case (sym,i) =>
//Console.println("sym! "+sym+" mutable? "+sym.hasFlag(symtab.Flags.MUTABLE)+" captured? "+sym.hasFlag(symtab.Flags.CAPTURED))
if (sym.hasFlag(symtab.Flags.MUTABLE) && // indicates that have not yet checked exhaustivity
@@ -340,48 +359,52 @@ trait ParallelMatching {
sealedComb = cases::sealedComb
}
}
- }
- // computes cartesian product, keeps indices available
- def combine(colcom: List[(Int,Set[Symbol])]): List[List[(Int,Symbol)]] = colcom match {
- case Nil => Nil
- case (i,syms)::Nil => syms.toList.map { sym => List((i,sym)) }
- case (i,syms)::cs => for (s <- syms.toList; rest <- combine(cs)) yield (i,s) :: rest
- }
+ }
- if(!sealedCols.isEmpty) {
- //DEBUG("cols"+sealedCols)
- //DEBUG("comb")
- //for (com <- sealedComb) DEBUG(com.toString)
-
- val allcomb = combine(sealedCols zip sealedComb)
- //Console.println("all comb!" + allcomb)
- /** returns true if pattern vector pats covers a type symbols "combination"
- * @param pats pattern vector
- * @param comb pairs of (column index, type symbol)
- */
- def covers(pats: List[Tree], comb:List[(Int,Symbol)]) = {
- comb forall { case (i,sym) => val p = pats(i); p.tpe.symbol == sym || sym.tpe <:< p.tpe }
+ // computes cartesian product, keeps indices available
+ def combine(colcom: List[(Int,Set[Symbol])]): List[List[(Int,Symbol)]] = colcom match {
+ case Nil => Nil
+ case (i,syms)::Nil => syms.toList.map { sym => List((i,sym)) }
+ case (i,syms)::cs => for (s <- syms.toList; rest <- combine(cs)) yield (i,s) :: rest
}
- val coversAll = allcomb forall { combination => row exists { r => covers(r._1, combination)}}
- //Console.println("all combinations covered? "+coversAll)
- if(!coversAll) {
- val sb = new StringBuilder()
- sb.append("match is not exhaustive!\n")
- for (open <- allcomb if !(row exists { r => covers(r._1, open)})) {
- sb.append("missing combination ")
- val NPAD = 15
- def pad(s:String) = { Iterator.range(1,NPAD - s.length).foreach { x => sb.append(" ") }; sb.append(s) }
- List.range(0, temp.length) foreach {
- i => open.find { case (j,sym) => j==i } match {
- case None => pad("*")
- case Some((_,sym)) => pad(sym.name.toString)
- }
+
+ if(!sealedCols.isEmpty) {
+ //DEBUG("cols"+sealedCols)
+ //DEBUG("comb")
+ //for (com <- sealedComb) DEBUG(com.toString)
+
+ val allcomb = combine(sealedCols zip sealedComb)
+ //Console.println("all comb!" + allcomb)
+ /** returns true if pattern vector pats covers a type symbols "combination"
+ * @param pats pattern vector
+ * @param comb pairs of (column index, type symbol)
+ */
+ def covers(pats: List[Tree], comb:List[(Int,Symbol)]) = {
+ comb forall { case (i,sym) => val p = pats(i); p.tpe.symbol == sym || sym.tpe <:< p.tpe }
+ }
+ val coversAll = allcomb forall { combination => row exists { r => covers(r._1, combination)}}
+ //Console.println("all combinations covered? "+coversAll)
+ if(!coversAll) {
+ val sb = new StringBuilder()
+ sb.append("match is not exhaustive!\n")
+ for (open <- allcomb if !(row exists { r => covers(r._1, open)})) {
+ sb.append("missing combination ")
+ val NPAD = 15
+ def pad(s:String) = { Iterator.range(1,NPAD - s.length).foreach { x => sb.append(" ") }; sb.append(s) }
+ List.range(0, temp.length) foreach {
+ i => open.find { case (j,sym) => j==i } match {
+ case None => pad("*")
+ case Some((_,sym)) => pad(sym.name.toString)
}
- sb.append('\n')
}
- cunit.warning(temp.head.pos, sb.toString)
+ sb.append('\n')
+ }
+ cunit.warning(temp.head.pos, sb.toString)
+ }
}
- }
+ return this
+ } // end init
+
// if this was the *fail* branch, the Rep preceding this Rep
var mixtureParent: MixtureRule = null
@@ -408,7 +431,7 @@ trait ParallelMatching {
val restTemp = temp.take(i) ::: temp.drop(i+1)
val restRows = row map { case (pats,subst,g,b) => (pats.take(i) ::: pats.drop(i+1),subst,g,b) }
//val restEx = exhaustivenessChecked.take(i) ::: exhaustivenessChecked.drop(i+1)
- MixtureRule(temp(i), column, makeRep(restTemp,restRows/*,restEx*/)) setParent this
+ MixtureRule(temp(i), column, Rep(restTemp,restRows/*,restEx*/)) setParent this
}
}
// a fancy toString method for debugging
@@ -434,7 +457,7 @@ trait ParallelMatching {
if(!checkExhaustive)
root.setFlag(symtab.Flags.CAPTURED)
val row = cases map { case CaseDef(pat,g,b) => (List(pat),List(),g,b) }
- makeRep(List(root), row)
+ Rep(List(root), row)
}
/** this tree node is used several times in the parallel algo and will never be needed for matching, so it is reused */
val Ident_WILDCARD = Ident(nme.WILDCARD) setType definitions.AnyClass.tpe
diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
index 409b939ad8..f2a7c15545 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala
@@ -166,9 +166,9 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes with P
if(i != -1) {
val CaseDef(_,_,b) = cases(i)
//DEBUG("*** damn, unreachable!")
- //for (b <- bodies) {
+ //Console.println("damn, unreachable!")
+ //for (b <- bodies)
// Console.println(b)
- //}
cunit.error(b.pos, "unreachable code")
}
@@ -245,7 +245,7 @@ trait PatternMatchers requires (transform.ExplicitOuter with PatternNodes with P
protected def updateBody(tree: Body, bound: Array[ValDef],
guard: Tree, body: Tree): Unit =
if (tree.guard(tree.guard.length - 1) == EmptyTree) {
- cunit.error(body.pos, "unreachable code")
+ cunit.error(body.pos, "B unreachable code")
} else {
val bd = new Array[Array[ValDef]](tree.bound.length + 1)
val ng = new Array[Tree](tree.guard.length + 1)