summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
Diffstat (limited to 'sources/scalac')
-rw-r--r--sources/scalac/transformer/matching/BerrySethi.java2
-rw-r--r--sources/scalac/transformer/matching/CodeFactory.java30
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java135
-rw-r--r--sources/scalac/transformer/matching/TestRegTraverser.java39
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;
+ }
+
+}