summaryrefslogtreecommitdiff
path: root/sources/scalac/transformer/matching
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-01-28 15:13:42 +0000
committerburaq <buraq@epfl.ch>2004-01-28 15:13:42 +0000
commit95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148 (patch)
tree9afd9eb58f4f56148882bcbaaf755790055f00c3 /sources/scalac/transformer/matching
parent244e7010744283642301251995b9926277219951 (diff)
downloadscala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.tar.gz
scala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.tar.bz2
scala-95bd5979f69cdd2f99dcb9ec42ecd416f5bf1148.zip
bugfix in PatternMatcher.
Diffstat (limited to 'sources/scalac/transformer/matching')
-rw-r--r--sources/scalac/transformer/matching/CaseEnv.java13
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java90
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) {