diff options
author | buraq <buraq@epfl.ch> | 2003-07-04 20:07:20 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-07-04 20:07:20 +0000 |
commit | fe7e260075dc9c27b31c0ec535a139e3744fdbb7 (patch) | |
tree | 14d717114bffccb6fc8006c6cf8fe574f4b868e6 | |
parent | a4392e6d759f8c2197d1a72020597cedaff5fd8f (diff) | |
download | scala-fe7e260075dc9c27b31c0ec535a139e3744fdbb7.tar.gz scala-fe7e260075dc9c27b31c0ec535a139e3744fdbb7.tar.bz2 scala-fe7e260075dc9c27b31c0ec535a139e3744fdbb7.zip |
hooking up pattern matcher with sequence matcher
4 files changed, 135 insertions, 71 deletions
diff --git a/sources/scalac/transformer/matching/BerrySethi.java b/sources/scalac/transformer/matching/BerrySethi.java index e502c75c7c..1d2bc1ec87 100644 --- a/sources/scalac/transformer/matching/BerrySethi.java +++ b/sources/scalac/transformer/matching/BerrySethi.java @@ -553,6 +553,8 @@ class BerrySethi { */ //System.out.println( nullableSequence( pat )); // UNIT TEST switch( pat ) { + case Subsequence( Tree[] subexpr ): // NEW VERSION + return automatonFrom( new Tree.Sequence( subexpr ), finalTag ); // NEW VERSION case Sequence( Tree[] subexpr ): initialize( subexpr ); diff --git a/sources/scalac/transformer/matching/CodeFactory.java b/sources/scalac/transformer/matching/CodeFactory.java index 77797ca9c0..9d8d4c174b 100644 --- a/sources/scalac/transformer/matching/CodeFactory.java +++ b/sources/scalac/transformer/matching/CodeFactory.java @@ -129,23 +129,21 @@ class CodeFactory extends PatternTool { new Type[] { elemType }); } - /** returns code `<seqObj>.newIterator' + /** returns code `<seqObj>.elements' * the parameter needs to have type attribute `Sequence[<elemType>]' * it is not checked whether seqObj really has type `Sequence' */ Tree newIterator( Tree seqObj ) { - Type args[] = seqObj.type().typeArgs(); - assert ( args.length== 1 ) : "seqObj does not have right type"; - Type elemType = args[ 0 ]; + Type elemType = getElemType( seqObj.type() ); //System.out.println( "elemType:"+elemType ); //Tree t1 = gen.Select(seqObj, newIterSym); - Scope scp = defs.getClass( Names.scala_Seq ) /* sequenceSym */ + Scope scp = defs.getClass( Names.scala_Iterable ) /* sequenceSym */ .members(); Symbol newIterSym = scp.lookup/*Term */( Names.elements ); - Tree t1 = make.Select( Position.NOPOS, seqObj, newIterSym.name ) + Tree t1 = make.Select( Position.NOPOS, seqObj, newIterSym.name ) /*todo: newIterSym() */ .setSymbol( newIterSym ) .setType( Type.MethodType(new Symbol[] {},_seqIterType( elemType ))); @@ -268,12 +266,20 @@ class CodeFactory extends PatternTool { new Tree[] { head, tail }); } - // todo: more defensive checking Type getElemType( Type seqType ) { - Type[] args = seqType.typeArgs(); /*use typeArgs instead of args*/ - assert (args.length==1); - return args[ 0 ]; + System.err.println("getElemType("+seqType+")"); + Symbol seqClass = defs.getType( Name.fromString("scala.Seq") ).symbol(); + assert seqClass != Symbol.NONE : "did not find Seq"; + Type seqType1 = seqType.baseType( seqClass ); + + switch( seqType1 ) { + case TypeRef(_,_,Type[] args): + assert (args.length==1) : "weird type:"+seqType; + return args[ 0 ]; + default: + return seqType; + } } /** `it.next()' @@ -286,7 +292,7 @@ class CodeFactory extends PatternTool { Symbol nextSym = scp.lookup( Names.next ); - return _applyNone( gen.Select( iter, nextSym )) + return _applyNone( gen.Select( iter, nextSym )) /* todo: nextSym() */ .setType( iter.type() ); } @@ -299,7 +305,7 @@ class CodeFactory extends PatternTool { Symbol hasNextSym = scp.lookup( Names.hasNext ); - return _applyNone( gen.Select( iter, hasNextSym )) + return _applyNone( gen.Select( iter, hasNextSym )) /* todo: hasNextSym() */ .setType( defs.BOOLEAN_TYPE ); } diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 749fde85fe..784a96377b 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -329,62 +329,72 @@ public class PatternMatcher extends PatternTool { protected PatternNode patternNode(Tree tree, Header header, CaseEnv env) { switch (tree) { - case Apply(Tree fn, Tree[] args): // pattern with args - if (args.length == 1 && (tree.type.symbol().flags & Modifiers.CASE) == 0) - switch (args[0]) { - case Sequence(Tree[] ts): - return mk.SequencePat(tree.pos, tree.type, ts.length, args[0]); - } - return mk.ConstrPat(tree.pos, getConstrType(tree.type)); - case Typed(Ident(Name name), Tree tpe): // variable pattern - PatternNode node = - (header.type.isSubType(getConstrType(tpe.type))) ? - mk.DefaultPat(tree.pos, getConstrType(tpe.type)) - : mk.ConstrPat(tree.pos, getConstrType(tpe.type)); - if ((env != null) && (name != WILDCARD_N)) - switch (node) { - case ConstrPat(Symbol casted): - env.newBoundVar( - tree.pos, - ((Tree.Typed)tree).expr.symbol(), - getConstrType(tpe.type), - make.Ident(tree.pos, casted.name). - setType(typeOf(casted)). - setSymbol(casted)); - break; - default: - env.newBoundVar( - tree.pos, - ((Tree.Typed)tree).expr.symbol(), - getConstrType(tpe.type), - header.selector); - } - return node; - case Ident(Name name): // pattern without args or variable - if (tree.symbol().isPrimaryConstructor()) - return mk.ConstrPat(tree.pos, getConstrType(tree.type)); - else if (name.isVariable()) { - if ((env != null) && (name != WILDCARD_N)) - env.newBoundVar( - tree.pos, - tree.symbol(), - getConstrType(tree.type), - header.selector); - return mk.DefaultPat(tree.pos, getConstrType(header.type)); - } else - return mk.VariablePat(tree.pos, tree); - case Select(_, Name name): // variable - if (tree.symbol().isPrimaryConstructor()) - return mk.ConstrPat(tree.pos, getConstrType(tree.type)); - else - return mk.VariablePat(tree.pos, tree); - case Literal(Object value): - return mk.ConstantPat(tree.pos, getConstrType(tree.type), value); - case Sequence(Tree[] ts): - return mk.SequencePat(tree.pos, tree.type, ts.length, tree); - default: - new scalac.ast.printer.TextTreePrinter().print(tree).flush(); - throw new ApplicationError(tree); + case Apply(Tree fn, Tree[] args): // pattern with args + if (args.length == 1 && (tree.type.symbol().flags & Modifiers.CASE) == 0) + switch (args[0]) { + case Sequence(Tree[] ts): + return mk.SequencePat(tree.pos, tree.type, ts.length, args[0]); + } + return mk.ConstrPat(tree.pos, getConstrType(tree.type)); + case Typed(Ident(Name name), Tree tpe): // variable pattern + PatternNode node = + (header.type.isSubType(getConstrType(tpe.type))) ? + mk.DefaultPat(tree.pos, getConstrType(tpe.type)) + : mk.ConstrPat(tree.pos, getConstrType(tpe.type)); + if ((env != null) && (name != WILDCARD_N)) + switch (node) { + case ConstrPat(Symbol casted): + env.newBoundVar( + tree.pos, + ((Tree.Typed)tree).expr.symbol(), + getConstrType(tpe.type), + make.Ident(tree.pos, casted.name). + setType(typeOf(casted)). + setSymbol(casted)); + break; + default: + env.newBoundVar( + tree.pos, + ((Tree.Typed)tree).expr.symbol(), + getConstrType(tpe.type), + header.selector); + } + return node; + case Ident(Name name): // pattern without args or variable + if (tree.symbol().isPrimaryConstructor()) + return mk.ConstrPat(tree.pos, getConstrType(tree.type)); + else if (name.isVariable()) { + if ((env != null) && (name != WILDCARD_N)) + env.newBoundVar( + tree.pos, + tree.symbol(), + getConstrType(tree.type), + header.selector); + return mk.DefaultPat(tree.pos, getConstrType(header.type)); + } else + return mk.VariablePat(tree.pos, tree); + case Select(_, Name name): // variable + if (tree.symbol().isPrimaryConstructor()) + return mk.ConstrPat(tree.pos, getConstrType(tree.type)); + else + return mk.VariablePat(tree.pos, tree); + case Literal(Object value): + return mk.ConstantPat(tree.pos, getConstrType(tree.type), value); + case Sequence(Tree[] ts): + return mk.SequencePat(tree.pos, tree.type, ts.length, tree); + case Subsequence(Tree[] ts): + return mk.SequencePat(tree.pos, tree.type, ts.length, tree); + case Alternative(Tree[] ts): // CAN THIS WORK ? + assert ts.length > 0; + PatternNode res = patternNode( ts[ 0 ], header, env ); + for( int i = 1; i<ts.length; i++ ) { + res.or = patternNode( ts[ i ], header, env ); + res = res.or ; + } + return res; + default: + new scalac.ast.printer.TextTreePrinter().print(tree).flush(); + throw new ApplicationError(tree); } } @@ -676,7 +686,13 @@ public class PatternMatcher extends PatternTool { .setType(defs.UNIT_TYPE).setSymbol(casted), toTree(node.and)}, defs.BOOLEAN_TYPE), toTree(node.or, selector.duplicate())).setType(defs.BOOLEAN_TYPE); - case SequencePat(Symbol casted, int len, _): + case SequencePat(Symbol casted, int len, Tree tree): + if( TestRegTraverser.apply( tree ) ) + { + //System.err.println("calling sequence matcher"); + return callSequenceMatcher( node, selector ); + } + Symbol lenSym = casted.type().lookup(LENGTH_N); Tree t = make.Select(selector.pos, cf.As(selector.duplicate(), node.type), LENGTH_N); switch (typeOf(lenSym)) { @@ -708,6 +724,7 @@ public class PatternMatcher extends PatternTool { toTree(node.and)}, defs.BOOLEAN_TYPE), toTree(node.or, selector.duplicate())) .setType(defs.BOOLEAN_TYPE); + case ConstantPat(Object value): return make.If( selector.pos, @@ -773,7 +790,7 @@ public class PatternMatcher extends PatternTool { Tree defaultCase = toTree( defaultNode, selector ); - // SequenceMatcher wordRec = new SequenceMatcher(unit, infer); FIX ME FOR THE NEW VERSION + SequenceMatcher wordRec = new SequenceMatcher(unit, infer); Matcher m = new Matcher( _m.owner, selector, @@ -791,7 +808,7 @@ public class PatternMatcher extends PatternTool { j++; } - // wordRec.construct( m, pats, body, defaultCase /*, doBinding*/ ); FIX ME FOR THE NEW VERSION + wordRec.construct( m, pats, body, defaultCase, true /*doBinding*/ ); return m.tree; diff --git a/sources/scalac/transformer/matching/TestRegTraverser.java b/sources/scalac/transformer/matching/TestRegTraverser.java new file mode 100644 index 0000000000..b9d070ea85 --- /dev/null +++ b/sources/scalac/transformer/matching/TestRegTraverser.java @@ -0,0 +1,39 @@ +package scalac.transformer.matching ; + +import scalac.ast.Tree; +import scalac.util.Name; +import scalac.symtab.Symbol ; +import scalac.ast.Traverser ; + +import Tree.Ident; +import Tree.Bind; + + class TestRegTraverser extends Traverser { + + boolean result; + + public TestRegTraverser() { + super(); + result = false; + } + + public void traverse(Tree tree) { + switch (tree) { + case Alternative(Tree[] ts): + case Bind(_, _): + case Subsequence(_): + result = true; + break; + default: + super.traverse( tree ); + } + } + + static boolean apply( Tree t ) { + TestRegTraverser trt = new TestRegTraverser(); + trt.traverse( t ); + //System.err.println("TestRegTraverser says "+t+" -> "+trt.result); + return trt.result; + } + +} |