summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-06 17:04:40 +0000
committerPaul Phillips <paulp@improving.org>2009-10-06 17:04:40 +0000
commite3d9ce3e0923077911fbc26df0cac3a9137be966 (patch)
tree96beebcb576406136688b2dd6d1bce4afc75c8b2
parentac5c2b3c67090ee7b7c6e3b5f212829de82c8ca0 (diff)
downloadscala-e3d9ce3e0923077911fbc26df0cac3a9137be966.tar.gz
scala-e3d9ce3e0923077911fbc26df0cac3a9137be966.tar.bz2
scala-e3d9ce3e0923077911fbc26df0cac3a9137be966.zip
Debugging code - pattern matcher activity tracing.
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala5
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala59
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala67
3 files changed, 79 insertions, 52 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index edd6d60fab..527c01b1a8 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -95,7 +95,7 @@ trait Matrix extends PatternOptimizer {
{
val n: Name = if (name == null) newName(pos, "temp") else name
// careful: pos has special meaning
- owner.newVariable(pos, n) setInfo tpe setFlag (0L /: flags)(_|_)
+ traceAndReturn("[newVar] ", owner.newVariable(pos, n) setInfo tpe setFlag (0L /: flags)(_|_))
}
def typedValDef(x: Symbol, rhs: Tree) = {
@@ -107,8 +107,7 @@ trait Matrix extends PatternOptimizer {
case _ =>
typer.typed(rhs, x.tpe)
}
- typer typed (VAL(x) === finalRhs)
+ traceAndReturn("[typedValDef] ", typer typed (VAL(x) === finalRhs))
}
}
-
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 8f354c2be9..e7f3c3784e 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -39,12 +39,13 @@ trait ParallelMatching extends ast.TreeDSL
def ifDebug(body: => Unit): Unit = { if (settings.debug.value) body }
def DBG(msg: => String): Unit = { ifDebug(println(msg)) }
- @elidable(elidable.FINE)
+ // @elidable(elidable.FINE)
def TRACE(f: String, xs: Any*): Unit = { if (trace) println(if (xs.isEmpty) f else f.format(xs : _*)) }
-
- def logAndReturn[T](s: String, x: T): T = { log(s + x.toString) ; x }
def traceAndReturn[T](s: String, x: T): T = { TRACE(s + x.toString) ; x }
+ def indent(s: Any) = s.toString() split "\n" map (" " + _) mkString "\n"
+ def indentAll(s: Seq[Any]) = s map (" " + _.toString() + "\n") mkString
+
/** Transition **/
def isRightIgnoring(t: Tree) = cond(unbind(t)) { case ArrayValue(_, xs) if !xs.isEmpty => isStar(xs.last) }
def toPats(xs: List[Tree]): List[Pattern] = xs map Pattern.apply
@@ -91,7 +92,7 @@ trait ParallelMatching extends ast.TreeDSL
else Rep(tvars, rows).checkExhaustive
}
- override def toString() = "MatchMatrix(%s)".format(targets)
+ override def toString() = "MatchMatrix(%s) { %s }".format(matchResultType, indentAll(targets))
/**
* Encapsulates a symbol being matched on.
@@ -123,7 +124,7 @@ trait ParallelMatching extends ast.TreeDSL
def seqType = tpe.widen baseType SeqClass
def elemType = tpe typeArgs 0 // can this happen? if (seqType == NoType) error("...")
- def newVarOfTpe(tpe: Type) = context.newVar(pos, tpe, flags)
+ def newVarOfTpe(tpe: Type) = newVar(pos, tpe, flags)
def newVarOfSeqType = newVar(pos, seqType)
def newVarOfElemType = newVar(pos, elemType)
@@ -134,7 +135,7 @@ trait ParallelMatching extends ast.TreeDSL
if (tpe =:= headType) this
else new Scrutinee(newVar(pos, headType, flags))
- override def toString() = "Scrutinee(sym = %s, tpe = %s, id = %s)".format(sym, tpe, id)
+ override def toString() = "(%s: %s)".format(id, tpe)
}
def isPatternSwitch(scrut: Scrutinee, ps: List[Pattern]): Option[PatternSwitch] = {
@@ -187,7 +188,7 @@ trait ParallelMatching extends ast.TreeDSL
}
def mkRule(rest: Rep): RuleApplication = {
- logAndReturn("mkRule: ", head.tree match {
+ traceAndReturn("[mkRule] ", head.tree match {
case x if isEquals(x.tpe) => new MixEquals(this, rest)
case x: ArrayValue => new MixSequence(this, rest)
case AnyUnapply(false) => new MixUnapply(this, rest, false)
@@ -199,6 +200,7 @@ trait ParallelMatching extends ast.TreeDSL
}
)
}
+ override def toString() = "%s match {%s}".format(scrut, indentAll(ps))
} // PatternMatch
/** picks which rewrite rule to apply
@@ -225,24 +227,25 @@ trait ParallelMatching extends ast.TreeDSL
def rest: Rep
lazy val PatternMatch(scrut, patterns) = pats
lazy val head = pats.head
- private def sym = scrut.sym
/** Creates Some(fail rule) even if xs == Nil. */
- def mkFail(xs: List[Row]): Option[Rep] = Some(make(sym :: rest.tvars, xs))
+ def mkFail(xs: List[Row]): Option[Rep] = Some(make(scrut.sym :: rest.tvars, xs))
/** Returns None if xs == Nil, Some(fail rule) otherwise. */
def mkFailOpt(xs: List[Row]): Option[Rep] = if (xs.isEmpty) None else mkFail(xs)
/** Splices scrutinee's symbol in between the given lists */
def mkNewRep(pre: List[Symbol], post: List[Symbol], rows: List[Row]) =
- make(pre ::: sym :: post, rows)
+ make(pre ::: scrut.sym :: post, rows)
/** translate outcome of the rule application into code (possible involving recursive application of rewriting) */
def tree(): Tree
override def toString = {
- "RuleApplication/%s (%s: %s) { %s ... }".format(
- getClass(), scrut, scrut.tpe, head
+ "Rule/%s (%s =^= %s) {\n%s}".format(
+ getClass.getSimpleName,
+ scrut, head,
+ indentAll(patterns)
)
}
}
@@ -338,11 +341,6 @@ trait ParallelMatching extends ast.TreeDSL
target MATCH (casesWithDefault: _*)
}
}
- override def toString = {
- "MixLiteralInts {\n pats: %s\n varMap: %s\n}".format(
- pats, varMap
- )
- }
}
/** mixture rule for unapply pattern
@@ -430,11 +428,6 @@ trait ParallelMatching extends ast.TreeDSL
IF (cond) THEN squeezedBlock(vdefs, succ) ELSE fail
)
}
- override def toString = {
- "MixUnapply {\n pats: %s\n ua: %s\n}".format(
- pats, ua
- )
- }
}
/** handle sequence pattern and ArrayValue (but not star patterns)
@@ -533,8 +526,9 @@ trait ParallelMatching extends ast.TreeDSL
/** condition (to be used in IF), success and failure Rep */
final def getTransition(): (Branch[Tree], Symbol) = {
val value = {
- // how is it known these are the only possible typerefs here?
- val TypeRef(_,_,List(arg)) = head.tpe
+ // val TypeRef(_,_,List(arg)) = head.tpe
+ val arg = decodedEqualsType(head.tpe)
+
arg match {
case SingleType(pre, sym) => REF(pre, sym)
case PseudoType(o) => o.duplicate
@@ -563,6 +557,7 @@ trait ParallelMatching extends ast.TreeDSL
IF (handleOuter(cond)) THEN srep.toTree ELSE LabelDef(failLabel, Nil, fail)
)
}
+ override def toString() = "MixEquals(%s == %s)".format(scrut, head)
}
/** mixture rule for type tests
@@ -638,9 +633,8 @@ trait ParallelMatching extends ast.TreeDSL
) match { case (x,y,z) => (join(x), join(y), join(z)) }
override def toString = {
- "MixTypes(%s: %s) {\n moreSpecific: %s\n subsumed: %s\n remaining: %s\n}".format(
- scrut, scrut.tpe, moreSpecific, subsumed, remaining
- )
+ super.toString() +
+ indentAll(List("moreSpecific: " + moreSpecific, "subsumed: " + subsumed, "remaining: " + remaining))
}
/** returns casted symbol, success matrix and optionally fail matrix for type test on the top of this column */
@@ -734,11 +728,12 @@ trait ParallelMatching extends ast.TreeDSL
}
}
override def toString() = {
- val patStr = pat.mkString
- val others = List(subst, guard) map (_.toString) filter (_ != "")
- val otherStr = if (others.isEmpty) "" else " // " + others.mkString(" ")
-
- "Row(%d) %s%s".format(bx, patStr, otherStr)
+ val str = indent(
+ "%s\n%s\n%s\n".format(
+ subst, pat.mkString("\n"), guard
+ )
+ )
+ "Row(%d) {\n%s}".format(bx, str)
}
}
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 017840d0c6..04c46d7e2a 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -61,6 +61,7 @@ trait Patterns extends ast.TreeDSL {
val tree = EmptyTree
override def irrefutableFor(tpe: Type) = true
override def isDefault = true
+ override def toString() = "_"
}
// 8.1.2
@@ -80,16 +81,28 @@ trait Patterns extends ast.TreeDSL {
def isSwitchable = cond(const.tag) { case ByteTag | ShortTag | IntTag | CharTag => true }
def intValue = const.intValue
+ override def toString() = if (value == null) "null" else value.toString()
}
// 8.1.4
- case class StableIdPattern(tree: Ident) extends IdentifierPattern {
- val Ident(name) = tree
+ case class StableIdPattern(tree: Select) extends IdentifierPattern {
+ val Select(qualifier, name) = tree
+
+ def pathSegments = getPathSegments(tree)
+ private def getPathSegments(t: Tree): List[Name] = t match {
+ case Select(q, name) => name :: getPathSegments(q)
+ case Apply(f, Nil) => getPathSegments(f)
+ case _ => Nil
+ }
+
+ override def toString() = "StableId(%s)".format(pathSegments.mkString(" . "))
}
// 8.1.4 (b)
case class SelectPattern(tree: Select) extends IdentifierPattern {
val Select(qualifier, name) = tree
+
+ override def toString() = "Select(%s, %s)".format(qualifier, name)
}
trait IdentifierPattern extends Pattern {
@@ -110,12 +123,21 @@ trait Patterns extends ast.TreeDSL {
if (args.isEmpty) this rebindToEmpty tree.tpe
else this
+ override def toString() = "Constructor(%s)".format(toPats(args).mkString(", "))
+
// XXX todo
// override def irrefutableFor(tpe: Type) = false
}
// XXX temp
case class ApplyValuePattern(tree: Apply) extends ApplyPattern {
require(!fn.isType)
+ //
+ // val Apply(Select(qualifier, name), Nil) = tree
+ //
+ // Examples where the above does not match:
+ // files/pos/t0710.scala Child()
+ // files/run/lazy-exprs.scala Z1()
+ // files/run/patmatnew.scala Child()
override def simplify(testVar: Symbol) = {
def examinePrefix(path: Tree) = (path, path.tpe) match {
@@ -247,21 +269,30 @@ trait Patterns extends ast.TreeDSL {
object Pattern {
- def apply(tree: Tree): Pattern = tree match {
- case x: Bind => apply(unbind(tree)) withBoundTree x
- case EmptyTree => WildcardPattern()
- case Ident(nme.WILDCARD) => WildcardPattern()
- case x @ Alternative(ps) => AlternativePattern(x)
- case x: Apply => ApplyPattern(x)
- case x: Typed => TypedPattern(x)
- case x: Literal => LiteralPattern(x)
- case x: UnApply => UnapplyPattern(x)
- case x: Ident => if (isVarPattern(x)) VariablePattern(x) else StableIdPattern(x)
- // case x: ArrayValue => if (isRightIgnoring(x)) SequenceStarPattern(x) else SequencePattern(x)
- case x: ArrayValue => SequencePattern(x)
- case x: Select => SelectPattern(x)
- case x: Star => StarPattern(x)
- case _ => abort("Unknown Tree reached pattern matcher: %s/%s".format(tree, tree.getClass))
+ def apply(tree: Tree): Pattern = {
+ val p = tree match {
+ case x: Bind => apply(unbind(tree)) withBoundTree x
+ case EmptyTree => WildcardPattern()
+ case Ident(nme.WILDCARD) => WildcardPattern()
+ case x @ Alternative(ps) => AlternativePattern(x)
+ case x: Apply => ApplyPattern(x)
+ case x: Typed => TypedPattern(x)
+ case x: Literal => LiteralPattern(x)
+ case x: UnApply => UnapplyPattern(x)
+ case x: Ident => VariablePattern(x)
+ // case x: Ident => if (isVarPattern(x)) VariablePattern(x) else StableIdPattern(x)
+ // case x: ArrayValue => if (isRightIgnoring(x)) SequenceStarPattern(x) else SequencePattern(x)
+ case x: ArrayValue => SequencePattern(x)
+ case x: Select => SelectPattern(x)
+ case x: Star => StarPattern(x)
+ case _ => abort("Unknown Tree reached pattern matcher: %s/%s".format(tree, tree.getClass))
+ }
+
+ p match {
+ case WildcardPattern() => p
+ case _: LiteralPattern => p
+ case _ => traceAndReturn("[Pattern] ", p)
+ }
}
def unapply(other: Any): Option[(Tree, List[Symbol])] = other match {
case x: Tree => unapply(Pattern(x))
@@ -308,6 +339,8 @@ trait Patterns extends ast.TreeDSL {
def apply(x: Apply): Pattern = {
val Apply(fn, args) = x
+ // case x @ Apply(sel: Select, Nil) => StableIdPattern(sel)
+
if (fn.isType) {
if (isTupleType(fn.tpe)) TuplePattern(x)
else ConstructorPattern(x)