diff options
author | buraq <buraq@epfl.ch> | 2005-06-16 13:05:21 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2005-06-16 13:05:21 +0000 |
commit | ebe1c8f2722d7cd644cda2122856aaa1660675f6 (patch) | |
tree | 2a089d2232681e205e66024a2b5eb636e8f46aae | |
parent | 7fe5ed6df81d9a1ca0a6e333426b5ac77abcde39 (diff) | |
download | scala-ebe1c8f2722d7cd644cda2122856aaa1660675f6.tar.gz scala-ebe1c8f2722d7cd644cda2122856aaa1660675f6.tar.bz2 scala-ebe1c8f2722d7cd644cda2122856aaa1660675f6.zip |
fixed bug!
4 files changed, 79 insertions, 40 deletions
diff --git a/sources/scala/tools/scalac/transformer/TransMatch.scala b/sources/scala/tools/scalac/transformer/TransMatch.scala index d7034d1f3d..97da7a1894 100644 --- a/sources/scala/tools/scalac/transformer/TransMatch.scala +++ b/sources/scala/tools/scalac/transformer/TransMatch.scala @@ -39,6 +39,13 @@ class TransMatch( global:scalac_Global ) var cunit:CompilationUnit = null; + + //def debugLog(s:String) = { + //if(currentOwner.toString().indexOf("traverse") != -1) { + //Console.println(s); + //} + //} + override def apply( cunit:CompilationUnit ):unit = { this.cunit = cunit; super.apply( cunit ); @@ -111,7 +118,11 @@ class TransMatch( global:scalac_Global ) } - // @pre cases are all nonregular + /** removes alternative notes by unfolding them, adding casedefs, + * and duplication righthand sides + * + * @pre cases are all nonregular + */ def removeAlterns(cases: Array[CaseDef]) = { def lst2arr(l:List[Tree]):Array[Tree] = { @@ -134,6 +145,36 @@ class TransMatch( global:scalac_Global ) } } + def newCloner() = { + val sc = new SymbolCloner(); + sc.owners.put(currentOwner,currentOwner); + + new GenTreeCloner(global, Type.IdMap, sc) { + + override def getSymbolFor(tree:Tree): Symbol = { + //Console.println("getSymbolFor "+tree.getClass()); + tree match { + case Bind(_,_) => + val symbol = cloner.cloneSymbol(tree.symbol()); + + //System.out.println("TreeCloner: Bind"+symbol); + //System.out.println("TreeCloner: Bind - old owner "+tree.symbol().owner()); + //System.out.println("TreeCloner: Bind - new owner "+symbol.owner()); + //Console.println("in TreeCloner: type = "+symbol.getType()); + symbol.setType(transform(symbol.getType())); + //Console.println("in TreeCloner: type (post) = "+symbol.getType()); + //System.out.println("done TreeCloner: Bind"+symbol); + return symbol; + case _ => + //if(tree.definesSymbol()) + // tree.symbol(); + super.getSymbolFor(tree); + } + + } + } + } + def remove(pat:Tree): List[Tree] = { //Console.println("remove("+pat+"), currentOwner = "+currentOwner); val res = pat.match { @@ -182,7 +223,8 @@ class TransMatch( global:scalac_Global ) case Ident(_) => List(pat); case Literal(_) => List(pat); case Select(_,_) => List(pat); - case Typed(_,_) => List(pat); + case Typed(_,_) => + List(pat); case _ => error("in TransMatch.nilVariables: unknown node"+pat.getClass()); @@ -197,41 +239,25 @@ class TransMatch( global:scalac_Global ) case CaseDef(pat,guard,body) => //Console.println("removeAlterns - ("+x+"), currentOwner = "+currentOwner); - val sc = new SymbolCloner(); - - sc.owners.put(currentOwner,currentOwner); - - val tc = new GenTreeCloner(global, Type.IdMap, sc) { - - override def getSymbolFor(tree:Tree): Symbol = { - tree match { - case Bind(_,_) => - val symbol = cloner.cloneSymbol(tree.symbol()); - - //System.out.println("TreeCloner: Bind"+symbol); - //System.out.println("TreeCloner: Bind - old owner "+tree.symbol().owner()); - //System.out.println("TreeCloner: Bind - new owner "+symbol.owner()); - //Console.println("in TreeCloner: type = "+symbol.getType()); - symbol.setType(transform(symbol.getType())); - //Console.println("in TreeCloner: type (post) = "+symbol.getType()); - //System.out.println("done TreeCloner: Bind"+symbol); - return symbol; - case _ => - if(tree.definesSymbol()) - tree.symbol(); - super.getSymbolFor(tree); - } - - } - } - remove(pat) map { x => - val res = tc.transform(new CaseDef(x,guard,body)); - /*Console.println(sc.owners);*/res} + remove(pat) match { + case List(p) => List(x); + case pats => + //debugLog("removal yields patterns (before trans) in "+cunit); + //debugLog( pats.mkString("","\n","") ); + pats map { + npat => + val tc = newCloner(); + //Console.println("start cloning! casedef in "+cunit); + val res = tc.transform(new CaseDef(npat, + guard.duplicate(), + body.duplicate())); + /*Console.println(sc.owners);*/res} } } + } lst2arr(List.flatten(ncases)); - } + } //val bsf = new scala.util.automaton.BerrySethi[ matching.PatternTest ]( pe ); @@ -272,6 +298,7 @@ class TransMatch( global:scalac_Global ) j = j + 1; } // TEST */ + //debugLog("containsReg!"); val am = new matching.AlgebraicMatcher( cunit ); val matcher = new PartialMatcher( currentOwner, root, restpe ); am.construct( matcher, cases.asInstanceOf[ Array[Tree] ] ); @@ -281,8 +308,17 @@ class TransMatch( global:scalac_Global ) val pm = new matching.PatternMatcher( cunit ); pm.initialize(root, currentOwner, restpe, true ); try{ - //val ncases = removeAlterns(cases); - pm.construct( cases.asInstanceOf[Array[Tree]] ); + val ncases = removeAlterns(cases); + if(ncases.length > cases.length) { + //debugLog("did some removal!"); + var kk = 0; while (kk<ncases.length) { + //debugLog(ncases(kk).toString()); + kk = kk + 1; + } + } + else + //debugLog("did NOT do removal!"); + pm.construct( ncases.asInstanceOf[Array[Tree]] ); } catch { case e:Throwable => e.printStackTrace(); diff --git a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala b/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala index 6a739a55a1..641d3dd6cf 100644 --- a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala +++ b/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala @@ -82,6 +82,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { /** enters a sequence of cases into the pattern matcher */ def construct(cases: Array[Tree]): Unit = { + //Console.println("pattern matcher.construct "+cases); var i = 0; while(i < cases.length) { enter(cases(i)); i = i + 1 @@ -102,8 +103,13 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { target.and = mk.Body(caseDef.pos, env.getBoundVars(), guard, body); else if (target.and.isInstanceOf[Body]) updateBody(target.and.asInstanceOf[Body], env.getBoundVars(), guard, body); - else + else { + //Console.println("target is "+target.getClass()); + //Console.println("target.and is "+target.and.getClass()); + //Console.println("target.or is "+target.or.getClass()); + unit.error(pat.pos, "duplicate case"); + } } } @@ -225,6 +231,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { mk.ConstrPat(tree.pos, tree.getType()); } case t @ Typed(ident, tpe) => // variable pattern + //Console.println("typed! header:" + header.getTpe() +" "+tpe.getType()); val doTest = header.getTpe().isSubType(tpe.getType()); val node = { if(doTest) diff --git a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala index 8bff11742b..d71a9e384a 100644 --- a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala +++ b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala @@ -60,8 +60,6 @@ package scala.tools.scalac.transformer.matching { traverse( subtree ); - case Select(_,_) => ; - // congruence case Apply(fun, args) => traverse1(args); diff --git a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala index 6c8c239f6e..2958da8e03 100644 --- a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala @@ -65,8 +65,6 @@ extends TracerInScala(dfa, elementType, owner, cf) { traverse( subtree ); - case Select(_,_) => ; - // congruence cases case Apply(fun, args) => traverse1(args); |