diff options
author | Paul Phillips <paulp@improving.org> | 2010-01-28 22:55:42 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-01-28 22:55:42 +0000 |
commit | f5dc89196d6a0ed9738ab1c97f76d15223a678a3 (patch) | |
tree | 4dd959e7245046147ced0642b6106cbf4a2bd19a /src | |
parent | 690542dbe4743e5c4fcc9ca4497351cde339391d (diff) | |
download | scala-f5dc89196d6a0ed9738ab1c97f76d15223a678a3.tar.gz scala-f5dc89196d6a0ed9738ab1c97f76d15223a678a3.tar.bz2 scala-f5dc89196d6a0ed9738ab1c97f76d15223a678a3.zip |
Added a command line option for desugaring matc...
Added a command line option for desugaring match blocks differently for
debugging purposes. No review.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 31 |
3 files changed, 37 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 6cf232b368..05e12760a2 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -925,6 +925,7 @@ trait ScalacSettings { BooleanSetting ("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.") val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignements") val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.") + val Ypmatnaive = BooleanSetting ("-Ypmat-naive", "Desugar matches as naively as possible..") val Ytailrec = BooleanSetting ("-Ytailrecommend", "Alert methods which would be tail-recursive if private or final.") val Yjenkins = BooleanSetting ("-Yjenkins-hashCodes", "Use jenkins hash algorithm for case class generated hashCodes.") diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 70d8c5d23f..35048c7a7d 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1104,7 +1104,11 @@ self => } } else if (in.token == MATCH) { t = atPos(t.pos.startOrPoint, in.skipToken()) { - Match(stripParens(t), surround(LBRACE, RBRACE)(caseClauses(), Nil)) + /** For debugging pattern matcher transition issues */ + if (settings.Ypmatnaive.value) + makeSequencedMatch(stripParens(t), surround(LBRACE, RBRACE)(caseClauses(), Nil)) + else + Match(stripParens(t), surround(LBRACE, RBRACE)(caseClauses(), Nil)) } } // in order to allow anonymous functions as statements (as opposed to expressions) inside diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index 6802757083..bb87a9248e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -452,6 +452,37 @@ abstract class TreeBuilder { def makePatDef(pat: Tree, rhs: Tree): List[Tree] = makePatDef(Modifiers(0), pat, rhs) + /** For debugging only. Desugar a match statement like so: + * val x = scrutinee + * x match { + * case case1 => ... + * case _ => x match { + * case case2 => ... + * case _ => x match ... + * } + * } + * + * This way there are never transitions between nontrivial casedefs. + * Of course many things break: exhaustiveness and unreachable checking + * do not work, no switches will be generated, etc. + */ + def makeSequencedMatch(selector: Tree, cases: List[CaseDef]): Tree = { + require(cases.nonEmpty) + + val selectorName = freshName() + val valdef = atPos(selector.pos)(ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC), selectorName, TypeTree(), selector)) + val nselector = Ident(selectorName) + + def loop(cds: List[CaseDef]): Match = { + def mkNext = CaseDef(Ident(nme.WILDCARD), EmptyTree, loop(cds.tail)) + + if (cds.size == 1) Match(nselector, cds) + else Match(selector, List(cds.head, mkNext)) + } + + Block(List(valdef), loop(cases)) + } + /** Create tree for pattern definition <mods val pat0 = rhs> */ def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree): List[Tree] = matchVarPattern(pat) match { case Some((name, tpt)) => |