diff options
author | buraq <buraq@epfl.ch> | 2003-10-30 11:06:14 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-10-30 11:06:14 +0000 |
commit | eb7da0de46695829b4459250c19bfa25b3dda75b (patch) | |
tree | 1554d19fb95437b941110774e7ced92d7f037448 /sources/scalac | |
parent | c48e8b69eb030c8ad0b62ae1b41b64a871af80c7 (diff) | |
download | scala-eb7da0de46695829b4459250c19bfa25b3dda75b.tar.gz scala-eb7da0de46695829b4459250c19bfa25b3dda75b.tar.bz2 scala-eb7da0de46695829b4459250c19bfa25b3dda75b.zip |
fixed bugs and cleaned up code in AlgMatcher th...
fixed bugs and cleaned up code in AlgMatcher that was duplicated of
Pattern Matcher
Diffstat (limited to 'sources/scalac')
4 files changed, 12 insertions, 281 deletions
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java index 20c9e2536c..9bcddb3e11 100644 --- a/sources/scalac/transformer/matching/AlgebraicMatcher.java +++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java @@ -51,7 +51,7 @@ public class AlgebraicMatcher extends PatternMatcher { this._m = m; super.initialize( _m.selector, _m.owner, _m.resultType, doBinding ); for( int i = 0; i < cases.length; i++ ) { - addCase( (CaseDef) cases[i], i); + enter( cases[ i ] );//(CaseDef) cases[i], i); } _m.tree = toTree(); } @@ -62,155 +62,6 @@ public class AlgebraicMatcher extends PatternMatcher { } */ - /** return the analyzed type - */ - public Type typeOf(Symbol sym) { - return sym.type(); - } - - /* - public Tree copy(Tree tree) { - return tree; // insert copy function here - } - */ - - /** convenience method, see addCase below - */ - public void addCase(CaseDef tree, int case_index) { - //System.out.println( "addCase(" + - // TextTreePrinter.toString(tree.pat) + - // ")" ); - addCase(tree.pos, tree.pat, tree.guard, tree.body, case_index); - //root.and.prettyPrint(); - } - /** adds a case definition to the intermediate presentation - */ - protected CaseEnv addCase(int pos, Tree pat, Tree guard, Tree body, int case_index) { - - CaseEnv env = new CaseEnv( _m.owner, unit ); - //System.err.println("root"+root); - //PatternNode matched = match(pat, root); - PatternNode target = enter1(pat, //null - -1, root, root.symbol(), env - ); - //if (target.and != null) - // unit.error(pat.pos, "duplicate case"); - - if (target.and == null) - target.and = mk.Body(pos, env.boundVars(), guard, body); - else if (target.and instanceof Body) - updateBody((Body)target.and, env.boundVars(), guard, body); - else - unit.error(pat.pos, "duplicate case"); - - return env; - } - - - protected Tree[] patternArgs(Tree tree) { - //System.err.println("patternArgs("+tree+")"); - switch (tree) { - case Apply(_, Tree[] args): - /* - if( isSeqApply( (Apply) tree )) { - //System.err.println("patternArgs: is seq apply !"); - return Tree.EMPTY_ARRAY;// let sequence matcher handle this - - } - if( isStarApply( (Apply) tree )) { - return Tree.EMPTY_ARRAY;// let sequence matcher handle this - - } - */ - return args; - default: - return Tree.EMPTY_ARRAY; - } - } - - protected Type getConstrType(Type tpe) { - return tpe; - } - - protected Type getHeaderType(Symbol sym) { - return sym.type().resultType(); - } - - /** constructs a pattern node depending on the case of argument `tree' - * @param tree the pattern node that needs to be translated - * @param castType cast type of the position that is tested - * @param selector selector tree of the position that is tested - * @param env an environment - */ - - protected PatternNode patternNode__(Tree tree, - Type castType, - Tree selector, - CaseEnv env) { - //System.err.println("patternNode:"+tree ); - Type theType = getConstrType( tree.type ); - switch (tree) { - case Apply(Tree fn, Tree[] args): // pattern with args - //System.err.println("Apply, isSeq?" + isSeqApply( (Apply) tree )); - //System.err.println("Apply, isStar?" + isStarApply( (Apply) tree )); - if( isSeqApply( (Apply) tree )) { - PatternNode res = mk.ConstrPat(tree.pos, theType); - res.and = mk.Header(tree.pos, castType, selector); - res.and.and = mk.SeqContainerPat( tree.pos, theType, args[ 0 ] ); - return res; - } - return mk.ConstrPat(tree.pos, theType); - case Typed(Ident ident, Tree tpe): // typed pattern - theType = getConstrType( tpe.type ); - assert (env != null ) : "env is null"; - if (/*(env != null) &&*/ (ident.symbol() != defs.PATTERN_WILDCARD)) - env.newBoundVar( - ((Tree.Typed)tree).expr.symbol(), - theType, - selector); - if (castType.isSubType( theType )) - // castType is a subtype of theType - return mk.DefaultPat( tree.pos, theType ); - else - return mk.ConstrPat( tree.pos, theType ); - case Bind(Name name, Ident ident): // x @ _ - if( ident.symbol() == defs.PATTERN_WILDCARD ) { - env.newBoundVar( - tree.symbol(), - theType, - selector); - return mk.DefaultPat(tree.pos, getConstrType(castType)); - } - throw new ApplicationError("cannot handle "+tree); - case Ident(Name name): // pattern without args or variable - Symbol symbol = tree.symbol(); - assert symbol != null: tree; - if (symbol.isPrimaryConstructor()) - return mk.ConstrPat(tree.pos, theType); - else if (name.isVariable()) { - assert (env != null ) : "env is null"; - if (/*(env != null) &&*/ (symbol != defs.PATTERN_WILDCARD)) - env.newBoundVar( - tree.symbol(), - theType, - selector); - return mk.DefaultPat(tree.pos, getConstrType(castType)); - } else - return mk.VariablePat(tree.pos, tree); - case Select(_, Name name): // variable - if (tree.symbol().isPrimaryConstructor()) - return mk.ConstrPat(tree.pos, theType); - else - return mk.VariablePat(tree.pos, tree); - case Literal(Object value): - return mk.ConstantPat(tree.pos, theType, value); - - case Sequence( _ ): - return mk.SeqContainerPat( tree.pos, theType, tree ); - default: - throw new ApplicationError("cannot handle "+tree); - } - } /** returns true if p and q are pattern nodes of the same kind and p matches * whenever q matches, possibly even more often @@ -250,91 +101,7 @@ public class AlgebraicMatcher extends PatternMatcher { } } - /** the main enter function. - * @param target we hang the result to the .and successor of this node, - * possibly creating a new header. - */ - - - public PatternNode enter1__(Tree pat, - int index, - PatternNode target, - Symbol casted, - CaseEnv env ) { - //System.out.println("enter("+pat+", "+index+", "+target+", "+casted+")"); - // get pattern arguments (if applicable) - Tree[] patArgs = patternArgs(pat); - // get case fields - //assert patArgs.length == nCaseComponents(pat); // commented out also in new matcher - // advance one step in pattern - Header curHeader = (Header)target.and; - // check if we have to add a new header - if (curHeader == null) { - //assert index >= 0 : casted; - // <casted>.as[ <caseFieldAccessor[ index ]> ] - - //assert typeSym != null; - - Symbol typeSym = ((ClassSymbol) casted.type().symbol()) - .caseFieldAccessor(index); - - Type castType = getHeaderType(typeSym).asSeenFrom(typeOf(casted), typeSym.owner()); - target.and = curHeader = - mk.Header(pat.pos, - castType, - gen.mkApply__(gen.Select(gen.Ident(pat.pos, casted), typeSym))); - // translate the root of `pat' - curHeader.or = patternNode(pat, - curHeader,/*.type, - curHeader.selector, */ - env); - // translate the args of `pat' - return enter(patArgs, curHeader.or, casted, env); - } - // find most recent header - (the last -next- successor of curHeader) - while (curHeader.next != null) - curHeader = curHeader.next; - // translate the root of `pat' - PatternNode patNode = patternNode(pat, - curHeader,/*.type, - curHeader.selector, */ - env); - PatternNode next = curHeader; - // enter node - while (true) - if (superPat(next, patNode)) - // next is of the same kind as patNode and matches (supertype) - return enter(patArgs, next, casted, env); - else if (isDefaultPat(next) || - ((next.or == null) && isDefaultPat(patNode))) { - curHeader.next = mk.Header(patNode.pos, - curHeader.type, curHeader.selector); - curHeader.next.or = patNode; - return enter(patArgs, - patNode, - casted, - env); - } - else if (next.or == null) { - next.or = patNode; - - if (patArgs.length == 1 && (casted.flags & Modifiers.CASE) == 0) { - return enter( patArgs, patNode, casted, env ); // FIX - } - - return enter( patArgs, patNode, casted, env ); - } else - next = next.or; - } - - - /* - boolean isSeqApply( Tree.Apply tree ) { - return (tree.args.length == 1 && - (tree.type.symbol().flags & Modifiers.CASE) == 0); - } - */ - boolean isStarApply( Tree.Apply tree ) { + boolean isStarApply( Tree.Apply tree ) { Symbol params[] = tree.fun.type.valueParams(); //System.err.println( tree.fun.type.resultType().symbol() ); return (tree.args.length == 1) @@ -362,42 +129,7 @@ public class AlgebraicMatcher extends PatternMatcher { */ return gen.mkBlock(_m.pos, ts.toArray()); } - /* - protected Tree toTree__(PatternNode node) { - Tree res = gen.mkBooleanLit( node.pos, false ); - while (node != null) - switch (node) { - case Header(Tree selector, Header next): - res = cf.Or(res, toTree(node.or, selector)); - node = next; - break; - case Body(ValDef[][] bound, Tree[] guard, Tree[] body): - for (int i = guard.length - 1; i >= 0; i--) { - Tree[] ts; - if( doBinding ) { - ts = new Tree[bound[i].length + 1]; - System.arraycopy(bound[i], 0, ts, 0, bound[i].length); - } else - ts = new Tree[ 1 ]; - - int last = ts.length - 1; - ts[ last ] = gen.mkBlock( - new Tree[]{ - gen.Assign(gen.Ident( body[i].pos, resultVar ), - body[i]), - gen.mkBooleanLit(body[i].pos, true) - }); - if (guard[i] != Tree.Empty) - ts[ last ] = cf.And(guard[i], ts[ last ]); - res = cf.Or(gen.mkBlock(body[i].pos, ts), res); - } - return res; - default: - throw new ApplicationError(); - } - return res; - } - */ + protected Tree toTree(PatternNode node, Tree selector) { //System.err.println("AM.toTree called"+node); if (node == null) diff --git a/sources/scalac/transformer/matching/Label.java b/sources/scalac/transformer/matching/Label.java index 1759d67b16..cbad3ac3bf 100644 --- a/sources/scalac/transformer/matching/Label.java +++ b/sources/scalac/transformer/matching/Label.java @@ -32,7 +32,7 @@ public class Label { case TreeLabel( Tree pat ): switch( pat ) { case Apply( Tree fun, Tree[] args ): - return pat.type().hashCode() + args.hashCode(); // incorrect? + return pat.type().hashCode() + args.hashCode(); } return pat.hashCode(); case TypeLabel( Type type ): diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 4572d565ba..6445034f10 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -187,8 +187,9 @@ public class PatternMatcher extends PatternTool { target.and = mk.Body(caseDef.pos, env.boundVars(), guard, body); else if (target.and instanceof Body) updateBody((Body)target.and, env.boundVars(), guard, body); - else + else { unit.error(pat.pos, "duplicate case"); + } } } @@ -257,14 +258,16 @@ public class PatternMatcher extends PatternTool { case Bind(_, Tree pat): return patternArgs(pat); case Apply(_, Tree[] args): - if ( isSeqApply((Apply) tree) )// && !delegateSequenceMatching) + if ( isSeqApply((Apply) tree) && !delegateSequenceMatching) switch (args[0]) { case Sequence(Tree[] ts): return ts; } return args; case Sequence(Tree[] ts): - return ts; + if (!delegateSequenceMatching) + return ts; + return Tree.EMPTY_ARRAY; default: return Tree.EMPTY_ARRAY; } @@ -286,17 +289,12 @@ public class PatternMatcher extends PatternTool { return node; case Apply(Tree fn, Tree[] args): // pattern with args if( isSeqApply((Apply) tree ) ) { - //System.err.println( "isSeqApply!"+tree); - //System.err.println( "deleg ?"+delegateSequenceMatching); - if ( !delegateSequenceMatching ) { switch (args[0]) { case Sequence(Tree[] ts): return mk.SequencePat( tree.pos, tree.type, ts.length ); } } else { - //System.err.println( "CONTAIN"); - PatternNode res = mk.ConstrPat(tree.pos, tree.type); res.and = mk.Header(tree.pos, header.type, header.selector); res.and.and = mk.SeqContainerPat( tree.pos, tree.type, args[ 0 ] ); diff --git a/sources/scalac/transformer/matching/TestRegTraverser.java b/sources/scalac/transformer/matching/TestRegTraverser.java index 9510b566b9..ac00c3a366 100644 --- a/sources/scalac/transformer/matching/TestRegTraverser.java +++ b/sources/scalac/transformer/matching/TestRegTraverser.java @@ -31,6 +31,7 @@ public class TestRegTraverser extends Traverser { // annoying special case: b@() [or b@(()|()) after normalization] //System.err.println("bindin empty "+tree.symbol()); nilVariables.add(tree.symbol()); + result = true; } else { variables.add(tree.symbol()); } @@ -49,7 +50,7 @@ public class TestRegTraverser extends Traverser { case Sequence( Tree[] trees): //result = true; traverse( trees ); - result = true; + //result = true; break; default: |