summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/matching/ParallelMatching.scala')
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala105
1 files changed, 41 insertions, 64 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 1b0265ce5d..f41c37080a 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -39,15 +39,16 @@ trait ParallelMatching extends ast.TreeDSL
def data: MatrixContext#MatrixInit
- lazy val MatrixInit(roots, cases, failTree) = data
- lazy val ExpandedMatrix(rows, targets) = expand(roots, cases)
- lazy val expansion: Rep = make(roots, rows)
+ lazy val MatrixInit(roots, cases, failTree) = data
+ lazy val (rows, targets) = expand(roots, cases).unzip
+ lazy val expansion: Rep = make(roots, rows)
- val shortCuts = new ListBuffer[Symbol]()
+ private val shortCuts = mutable.HashMap[Int, Symbol]()
- final def shortCut(theLabel: Symbol): Int = {
- shortCuts += theLabel
- -shortCuts.length
+ final def createShortCut(theLabel: Symbol): Int = {
+ val key = shortCuts.size + 1
+ shortCuts(key) = theLabel
+ -key
}
/** first time bx is requested, a LabelDef is returned. next time, a jump.
@@ -55,18 +56,25 @@ trait ParallelMatching extends ast.TreeDSL
*/
final def requestBody(bx: Int, subst: Bindings): Tree = {
// shortcut
- if (bx < 0) Apply(ID(shortCuts(-bx-1)), Nil)
+ if (bx < 0) Apply(ID(shortCuts(-bx)), Nil)
else targets(bx) labelBody subst
}
- /** the injection here handles alternatives and unapply type tests */
- final def make(tvars: PatternVarGroup, row1: List[Row]): Rep = {
- // TRACE("make(%s%s)", pp(tvars.pvs, 1, true), pp(row1, 1, true))
- def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify tvars(j)
+ /** This is the recursively focal point for translating the current
+ * list of pattern variables and a list of pattern match rows into
+ * a tree suitable for entering erasure.
+ *
+ * The first time it is called, the variables are (copies of) the
+ * original pattern matcher roots, and the rows correspond to the
+ * original casedefs.
+ */
+ final def make(roots1: PatternVarGroup, rows1: List[Row]): Rep = {
+ traceCategory("New Match", "%sx%s (%s)", roots1.size, rows1.size, roots1.syms.mkString(", "))
+ def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify roots1(j)
- val rows = row1 flatMap (_ expandAlternatives classifyPat)
- if (rows.length != row1.length) make(tvars, rows) // recursive call if any change
- else Rep(tvars, rows).checkExhaustive
+ val newRows = rows1 flatMap (_ expandAlternatives classifyPat)
+ if (rows1.length != newRows.length) make(roots1, newRows) // recursive call if any change
+ else Rep(roots1, newRows).checkExhaustive
}
override def toString() = "MatchMatrix(%s) { %s }".format(matchResultType, indentAll(targets))
@@ -182,17 +190,11 @@ trait ParallelMatching extends ast.TreeDSL
}
}
- object TypedUnapply {
- def unapply(x: Tree): Option[Boolean] = condOpt(x) {
- case Typed(UnapplyParamType(tpe), tpt) => !(tpt.tpe <:< tpe)
- }
- }
-
def mkRule(rest: Rep): RuleApplication = {
tracing("Rule")(head match {
case x if isEquals(x.tree.tpe) => new MixEquals(this, rest)
case x: SequencePattern => new MixSequence(this, rest, x)
- case AnyUnapply(false) => new MixUnapply(this, rest, false)
+ case AnyUnapply(false) => new MixUnapply(this, rest)
case _ =>
isPatternSwitch(scrut, ps) match {
case Some(x) => new MixLiteralInts(x, rest)
@@ -327,7 +329,7 @@ trait ParallelMatching extends ast.TreeDSL
/** mixture rule for unapply pattern
*/
- class MixUnapply(val pmatch: PatternMatch, val rest: Rep, typeTest: Boolean) extends RuleApplication {
+ class MixUnapply(val pmatch: PatternMatch, val rest: Rep) extends RuleApplication {
val uapattern = head match { case x: UnapplyPattern => x ; case _ => abort("XXX") }
val ua @ UnApply(app, args) = head.tree
@@ -494,7 +496,9 @@ trait ParallelMatching extends ast.TreeDSL
val compareFn: Tree => Tree = (t: Tree) => compareOp((t DOT methodOp)(LIT(pivotLen)), ZERO)
// wrapping in a null check on the scrutinee
+ // XXX this needs to use the logic in "def condition"
nullSafe(compareFn, FALSE)(scrut.id)
+ // condition(head.tpe, scrut.id, head.boundVariables.nonEmpty)
}
lazy val success = squeezedBlock(pvs map (_.valDef), remake(successRows, pvs, hasStar).toTree)
lazy val failure = remake(failRows).toTree
@@ -521,7 +525,7 @@ trait ParallelMatching extends ast.TreeDSL
lazy val success = remake(List(
rest.rows.head.insert2(List(NoPattern), head.boundVariables, scrut.sym),
- Row(emptyPatterns(1 + rest.tvars.size), NoBinding, EmptyTree, shortCut(label))
+ Row(emptyPatterns(1 + rest.tvars.size), NoBinding, EmptyTree, createShortCut(label))
)).toTree
lazy val failure = LabelDef(label, Nil, labelBody)
@@ -615,8 +619,6 @@ trait ParallelMatching extends ast.TreeDSL
case class Row(pats: List[Pattern], subst: Bindings, guard: Tree, bx: Int) {
private def nobindings = subst.get().isEmpty
private def bindstr = if (nobindings) "" else pp(subst)
- // if (pats exists (p => !p.isDefault))
- // traceCategory("Row", "%s%s", pats, bindstr)
/** Extracts the 'i'th pattern. */
def extractColumn(i: Int) = {
@@ -655,29 +657,6 @@ trait ParallelMatching extends ast.TreeDSL
}
}
- object ExpandedMatrix {
- def unapply(x: ExpandedMatrix) = Some((x.rows, x.targets))
- def apply(rowz: List[(Row, FinalState)]) =
- new ExpandedMatrix(rowz map (_._1), rowz map (_._2) toIndexedSeq)
- }
-
- class ExpandedMatrix(val rows: List[Row], val targets: IndexedSeq[FinalState]) {
- require(rows.size == targets.size)
-
- override def toString() = {
- def vprint(vs: List[Any]) = if (vs.isEmpty) "" else ": %s".format(pp(vs))
- def rprint(r: Row) = pp(r)
- def tprint(t: FinalState) =
- if (t.params.isEmpty) " ==> %s".format(pp(t.body))
- else " ==>\n %s".format(pp(t.params -> t.body))
-
- val xs = rows zip targets map { case (r,t) => rprint(r) + tprint(t) }
- val ppstr = pp(xs, newlines = true)
-
- "ExpandedMatrix(%d rows)".format(rows.size) + ppstr
- }
- }
-
case class FinalState(bx: Int, body: Tree, params: List[Symbol]) {
private var referenceCount = 0
// typer is not able to digest a body of type Nothing being assigned result type Unit
@@ -762,21 +741,19 @@ trait ParallelMatching extends ast.TreeDSL
}
/** Expands the patterns recursively. */
- final def expand(roots: List[PatternVar], cases: List[CaseDef]) =
- tracing("Expanded")(ExpandedMatrix(
- for ((CaseDef(pat, guard, body), index) <- cases.zipWithIndex) yield {
- def mkRow(ps: List[Tree]) = Row(toPats(ps), NoBinding, guard, index)
-
- val pattern = Pattern(pat)
- val row = mkRow(pat match {
- case x if roots.length <= 1 => List(x)
- case Apply(_, args) => args
- case WILD() => emptyTrees(roots.length)
- })
-
- row -> FinalState(index, body, pattern.deepBoundVariables)
- })
- )
+ final def expand(roots: List[PatternVar], cases: List[CaseDef]) = tracing("expand") {
+ for ((CaseDef(pat, guard, body), index) <- cases.zipWithIndex) yield {
+ val subtrees = pat match {
+ case x if roots.length <= 1 => List(x)
+ case Apply(_, args) => args
+ case WILD() => emptyTrees(roots.length)
+ }
+ val row = Row(toPats(subtrees), NoBinding, guard, index)
+ val state = FinalState(index, body, Pattern(pat).deepBoundVariables)
+
+ row -> state
+ }
+ }
/** returns the condition in "if (cond) k1 else k2"
*/