diff options
author | Burak Emir <emir@epfl.ch> | 2007-07-25 12:07:04 +0000 |
---|---|---|
committer | Burak Emir <emir@epfl.ch> | 2007-07-25 12:07:04 +0000 |
commit | 39b0a1fbf3406861f0386bdec52b606dbb2c534d (patch) | |
tree | ab5ec6e9f70e52d9c182e9df9b01993f70cfeb7e /src | |
parent | 81442501d0d943e26ac50e90b67fe62f426857db (diff) | |
download | scala-39b0a1fbf3406861f0386bdec52b606dbb2c534d.tar.gz scala-39b0a1fbf3406861f0386bdec52b606dbb2c534d.tar.bz2 scala-39b0a1fbf3406861f0386bdec52b606dbb2c534d.zip |
new algo supports guards
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/ParallelMatching.scala | 40 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/matching/PatternMatchers.scala | 2 |
2 files changed, 28 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index b41a188585..4368ec7074 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -31,7 +31,7 @@ trait ParallelMatching { sealed trait RuleApplication case class ErrorRule extends RuleApplication - case class VariableRule(subst:List[Pair[Symbol,Symbol]], guard: Tree, body: Tree) extends RuleApplication + case class VariableRule(subst:List[Pair[Symbol,Symbol]], guard: Tree, body: Tree, guardedRest:Rep) extends RuleApplication def MixtureRule(scrutinee:Symbol, column:List[Tree], rest:Rep): RuleApplication = { def isSimpleIntSwitch: Boolean = { @@ -433,7 +433,7 @@ trait ParallelMatching { subpatterns(p) case app @ Apply(fn, pats) if isCaseClass(app.tpe) && (fn.symbol eq null)=> if(isCaseHead) pats else dummies - case Apply(fn,xs) => assert((xs.isEmpty) && (fn.symbol ne null)); dummies // named constant + case Apply(fn,xs) => assert((xs.isEmpty) && (fn.symbol ne null), "strange Apply"); dummies // named constant case _: UnApply => dummies case pat => @@ -595,6 +595,21 @@ trait ParallelMatching { } + final def genBody(subst: List[Pair[Symbol,Symbol]], guard:Tree, origbody:Tree, rest:Tree)(implicit theOwner: Symbol, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = { + bodies(origbody) = null // placeholder, for unreachable-code-detection + val vdefs = targetParams(subst) + val typedThen = origbody//typed{origbody.duplicate} + //Console.println("typedThen = "+typedThen); + val typedElse = rest//typed{rest} + //Console.println("typedElse = "+typedElse); + val untypedIf = If(guard, typedThen, typedElse) + //Console.println("typedIf = "+typedIf); + //val typedBlock = typed{ squeezedBlock(vdefs, typedIf) } + //Console.println("typedBlock= "+typedBlock); + //typedBlock + atPhase(phase.prev) { typed { Block(vdefs, untypedIf) }} + } + final def genBody(subst: List[Pair[Symbol,Symbol]], origbody:Tree)(implicit theOwner: Symbol, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = { origbody match { case _: Literal => // small trees @@ -614,7 +629,7 @@ trait ParallelMatching { var su = subst // lookup symbol in pattern variables while(su ne Nil) { val sh = su.head; - if(sh._1 eq bsym) return typed{ Ident(sh._2) } + if(sh._1 eq bsym) return { Ident(sh._2) setType origbody.symbol.tpe } su = su.tail } val res = typed{ origbody.duplicate } @@ -636,7 +651,7 @@ trait ParallelMatching { val body = Apply(Ident(theLabel), args) return typed{body} - case None => + case Some(null) | None => // sharing bodies var argtpes = subst map { case (v,_) => v.tpe } val theLabel = targetLabel(theOwner, origbody.pos, "body"+origbody.hashCode, argtpes, origbody.tpe) @@ -660,13 +675,12 @@ trait ParallelMatching { */ final def repToTree(rep:Rep, handleOuter: Tree => Tree)(implicit theOwner: Symbol, failTree: Tree, bodies: collection.mutable.Map[Tree,(Tree, Tree, Symbol)]): Tree = { rep.applyRule match { - case VariableRule(subst, EmptyTree, b) => + case ErrorRule() => failTree + case VariableRule(subst, EmptyTree, b, _) => genBody(subst,b) - case VariableRule(subst,g,b) => - assert(false) // throw CantHandleGuard - null - + case VariableRule(subst,g,b,restRep) => + genBody(subst,g,b,repToTree(restRep, handleOuter)) case mc: MixCases => val (branches, defaultV, default) = mc.getTransition // tag body pairs @@ -686,7 +700,7 @@ trait ParallelMatching { { val pat = mc.column(mc.tagIndexPairs.find(tag)); val ptpe = pat.tpe - if(mc.scrutinee.tpe./*?type?*/symbol.hasFlag(symtab.Flags.SEALED) && strip2(pat).isInstanceOf[Apply]) { + if(mc.scrutinee.tpe.typeSymbol.hasFlag(symtab.Flags.SEALED) && strip2(pat).isInstanceOf[Apply]) { //cast val vtmp = newVar(pat.pos, ptpe) squeezedBlock( @@ -700,7 +714,7 @@ trait ParallelMatching { renamingBind(defaultV, mc.scrutinee, ndefault) // each v in defaultV gets bound to scrutinee // make first case a default case. - if(mc.scrutinee.tpe./*?type?*/symbol.hasFlag(symtab.Flags.SEALED) && defaultV.isEmpty) { + if(mc.scrutinee.tpe.typeSymbol.hasFlag(symtab.Flags.SEALED) && defaultV.isEmpty) { ndefault = genBody(Nil, cases.head.body) cases = cases.tail } @@ -912,7 +926,7 @@ object Rep { //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 !sym.hasFlag(symtab.Flags.CAPTURED) && // indicates @unchecked - sym.tpe./*?type?*/symbol.hasFlag(symtab.Flags.SEALED)) { + sym.tpe.typeSymbol.hasFlag(symtab.Flags.SEALED)) { sym.resetFlag(symtab.Flags.MUTABLE) sealedCols = i::sealedCols @@ -1002,7 +1016,7 @@ object Rep { case (p,tmp) => strip1(p).toList.zipAll(Nil,null,tmp) // == vars map { (v,tmp) } } - VariableRule (subst:::subst1, g, b) + VariableRule (subst:::subst1, g, b, Rep(temp, xs)) } else { val i = pats findIndexOf {x => !isDefaultPattern(x)} diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index 281e45ed56..1a68d873dc 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -165,7 +165,7 @@ trait PatternMatchers { self: transform.ExplicitOuter with PatternNodes with Par def constructParallel(cases: List[Tree]): Any = { var cases1 = cases; while(cases1 ne Nil) { val c = cases1.head.asInstanceOf[CaseDef] - if(c.guard != EmptyTree) return CantHandleGuard + //if(c.guard != EmptyTree) return CantHandleGuard // TEST //hasUnapply.traverse(c.pat) val e = isImplemented(c.pat); if(e ne null) return e cases1 = cases1.tail |