diff options
author | buraq <buraq@epfl.ch> | 2004-01-28 15:13:42 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2004-01-28 15:13:42 +0000 |
commit | 95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148 (patch) | |
tree | 9afd9eb58f4f56148882bcbaaf755790055f00c3 /sources | |
parent | 244e7010744283642301251995b9926277219951 (diff) | |
download | scala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.tar.gz scala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.tar.bz2 scala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.zip |
bugfix in PatternMatcher.
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scalac/transformer/matching/CaseEnv.java | 13 | ||||
-rw-r--r-- | sources/scalac/transformer/matching/PatternMatcher.java | 90 |
2 files changed, 66 insertions, 37 deletions
diff --git a/sources/scalac/transformer/matching/CaseEnv.java b/sources/scalac/transformer/matching/CaseEnv.java index 20a77776f8..cfeb1f9b74 100644 --- a/sources/scalac/transformer/matching/CaseEnv.java +++ b/sources/scalac/transformer/matching/CaseEnv.java @@ -42,6 +42,19 @@ class CaseEnv { protected ValDef[] boundVars = new ValDef[4]; protected int numVars = 0; + /** substitutes a symbol on the right hand side of a ValDef + */ + public void substitute( Symbol oldSym, Tree newInit ) { + int i = 0; + while( i < numVars) { + if( boundVars[ i ].rhs.symbol() == oldSym ) { + boundVars[ i ].rhs = newInit; + return; + } + i++ ; + } + } + public void newBoundVar(Symbol sym, Type type, Tree init) { sym.setOwner( owner ); // FIXME should be corrected earlier if (numVars == boundVars.length) { diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 8e4836325b..2db3b81164 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -19,7 +19,7 @@ import Tree.*; public class PatternMatcher extends PatternTool { - protected boolean optimize = true; + protected boolean optimize = true; protected boolean delegateSequenceMatching = false; protected boolean doBinding = true; @@ -290,24 +290,29 @@ public class PatternMatcher extends PatternTool { } protected PatternNode patternNode(Tree tree, Header header, CaseEnv env) { - switch (tree) { - case Bind(Name name, Typed( Ident( Names.PATTERN_WILDCARD ), Tree tpe)): // little opt. for x@_:Type - if(header.type.isSubType(tpe.type)) { - PatternNode node = mk.DefaultPat(tree.pos, tpe.type); - env.newBoundVar( tree.symbol(), tree.type, header.selector ); - return node; - } else { - ConstrPat node = mk.ConstrPat(tree.pos, tpe.type); - env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted)); - return node; - } - case Bind(Name name, Ident( Names.PATTERN_WILDCARD )): // little opt. for x@_ + //System.out.println("patternNode("+tree+","+header+")"); + switch (tree) { + + case Bind(Name name, + Typed( Ident( Names.PATTERN_WILDCARD ), Tree tpe)): // x@_:Type + + if(header.type.isSubType(tpe.type)) { + PatternNode node = mk.DefaultPat(tree.pos, tpe.type); + env.newBoundVar( tree.symbol(), tree.type, header.selector ); + return node; + } else { + ConstrPat node = mk.ConstrPat(tree.pos, tpe.type); + env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted)); + return node; + } + + case Bind( Name name, Ident( Names.PATTERN_WILDCARD )): // x @ _ PatternNode node = mk.DefaultPat(tree.pos, header.type); if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) env.newBoundVar( tree.symbol(), tree.type, header.selector); return node; - case Bind(Name name, Tree pat): + case Bind( Name name, Tree pat): PatternNode node = patternNode(pat, header, env); if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) { Symbol casted = node.symbol(); @@ -332,23 +337,23 @@ public class PatternMatcher extends PatternTool { return mk.VariablePat(tree.pos, tree); return mk.ConstrPat(tree.pos, tree.type); case Typed(Ident ident, Tree tpe): // variable pattern - boolean doTest = header.type.isSubType(tpe.type); - PatternNode node = doTest ? - mk.DefaultPat(tree.pos, tpe.type) - : mk.ConstrPat(tree.pos, tpe.type); - if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD)) - switch (node) { - case ConstrPat(Symbol casted): - env.newBoundVar( - ((Tree.Typed)tree).expr.symbol(), - tpe.type, - gen.Ident(tree.pos, casted)); - break; - default: - env.newBoundVar( - ((Tree.Typed)tree).expr.symbol(), - tpe.type, - doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted)); + boolean doTest = header.type.isSubType(tpe.type); + PatternNode node = doTest ? + mk.DefaultPat(tree.pos, tpe.type) + : mk.ConstrPat(tree.pos, tpe.type); + if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD)) + switch (node) { + case ConstrPat(Symbol casted): + env.newBoundVar( + ((Tree.Typed)tree).expr.symbol(), + tpe.type, + gen.Ident(tree.pos, casted)); + break; + default: + env.newBoundVar( + ((Tree.Typed)tree).expr.symbol(), + tpe.type, + doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted)); } return node; case Ident(Name name): // pattern without args or variable @@ -447,7 +452,7 @@ public class PatternMatcher extends PatternTool { PatternNode target, Symbol casted, CaseEnv env) { - //System.err.println("enter(" + pat + ", " + index + ", " + target + ", " + casted + ")"); + //System.err.println("enter(" + pat + ", " + index + ", " + target + ", " + casted + ")"); Tree[] patArgs = patternArgs(pat); // get pattern arguments Header curHeader = (Header)target.and; // advance one step in intermediate representation @@ -467,11 +472,20 @@ public class PatternMatcher extends PatternTool { // add branch to curHeader, but reuse tests if possible while (true) - if ( next.isSameAs( patNode ) ) // test for patNode already present --> reuse - return enter(patArgs, next, casted, env); + if ( next.isSameAs( patNode ) ) { // test for patNode already present --> reuse + // substitute... !!! + switch( patNode ) { + case ConstrPat( Symbol ocasted ): + env.substitute( ocasted, gen.Ident(patNode.pos, + ((ConstrPat) next).casted)); + } + return enter(patArgs, next, casted, env); + } else if ( next.isDefaultPat() || // default case reached, or ((next.or == null) && // no more alternatives and - ( patNode.isDefaultPat() || next.subsumes( patNode )))) // new node is default or subsumed + ( patNode.isDefaultPat() || next.subsumes( patNode )))) { + // new node is default or subsumed + return enter( // create independent new header , because cannot use this one patArgs, (curHeader = (curHeader.next = @@ -479,8 +493,10 @@ public class PatternMatcher extends PatternTool { = patNode, casted, env); - else if (next.or == null) + } + else if (next.or == null) { return enter(patArgs, next.or = patNode, casted, env); // add new branch + } else next = next.or; } @@ -895,7 +911,7 @@ public class PatternMatcher extends PatternTool { } protected Tree toTree(PatternNode node, Tree selector) { - //System.err.println("pm.toTree called"+node); + //System.err.println("pm.toTree("+node+","+selector+")"); if (node == null) return gen.mkBooleanLit(selector.pos, false); switch (node) { |