From fe7e260075dc9c27b31c0ec535a139e3744fdbb7 Mon Sep 17 00:00:00 2001 From: buraq Date: Fri, 4 Jul 2003 20:07:20 +0000 Subject: hooking up pattern matcher with sequence matcher --- .../scalac/transformer/matching/BerrySethi.java | 2 + .../scalac/transformer/matching/CodeFactory.java | 30 +++-- .../transformer/matching/PatternMatcher.java | 135 ++++++++++++--------- .../transformer/matching/TestRegTraverser.java | 39 ++++++ 4 files changed, 135 insertions(+), 71 deletions(-) create mode 100644 sources/scalac/transformer/matching/TestRegTraverser.java (limited to 'sources/scalac') 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 `.newIterator' + /** returns code `.elements' * the parameter needs to have type attribute `Sequence[]' * 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 "+trt.result); + return trt.result; + } + +} -- cgit v1.2.3