diff options
7 files changed, 127 insertions, 159 deletions
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java index e89383087e..985e166c14 100644 --- a/sources/scalac/transformer/matching/AlgebraicMatcher.java +++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java @@ -167,7 +167,7 @@ public class AlgebraicMatcher extends PatternTool { CaseEnv env = new CaseEnv( _m.owner, unit ); //PatternNode matched = match(pat, root); - PatternNode target = enter1(pat, null /*-1*/, root, root.symbol(), env, case_index); + PatternNode target = enter1(pat, /*null*/ -1, root, root.symbol(), env, case_index); //if (target.and != null) // unit.error(pat.pos, "duplicate case"); @@ -190,8 +190,14 @@ public class AlgebraicMatcher extends PatternTool { 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 + + } return args; default: return Tree.EMPTY_ARRAY; @@ -226,13 +232,8 @@ public class AlgebraicMatcher extends PatternTool { Type theType = getConstrType( tree.type ); 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): - PatternNode res = mk.ConstrPat( tree.pos, theType ); - res.and = mk.SequencePat(tree.pos, tree.type, ts.length, args[0]); - return res; - } + if( isSeqApply( (Apply) tree )) + return mk.SeqContainerPat( tree.pos, theType, args[ 0 ] ); return mk.ConstrPat(tree.pos, theType); case Typed(Ident(Name name), Tree tpe): // typed pattern theType = getConstrType( tpe.type ); @@ -279,8 +280,8 @@ public class AlgebraicMatcher extends PatternTool { case Sequence( _ ): throw new ApplicationError("Illegal pattern"); - //return mk.SequencePat(tree.pos, tree, case_index); - //return mk.SequencePat(tree.pos, null, 0, tree); + //return mk.SeqContainerPat(tree.pos, tree, case_index); + //return mk.SeqContainerPat(tree.pos, null, 0, tree); //case Subsequence( _ ): // this may not appear here. /*case Bind( Name n, Tree t ): // ignore for now, treat as var x @@ -359,17 +360,17 @@ public class AlgebraicMatcher extends PatternTool { * possibly creating a new header. */ public PatternNode enter1(Tree pat, - //int index, - Symbol typeSym, + int index, + //Symbol typeSym, PatternNode target, Symbol casted, CaseEnv env, int case_index) { - //System.out.println("enter(" + pat + ", " + typeSym /*index*/ + ", " + target + ", " + casted + ")"); + System.out.println("enter(" + pat + ", " + /*typeSym*/ index + ", " + target + ", " + casted + ")"); // get pattern arguments (if applicable) Tree[] patArgs = patternArgs(pat); // get case fields - assert patArgs.length == nCaseComponents(pat); + //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 @@ -377,11 +378,11 @@ public class AlgebraicMatcher extends PatternTool { //assert index >= 0 : casted; // <casted>.as[ <caseFieldAccessor[ index ]> ] - assert typeSym != null; - /* + //assert typeSym != null; + Symbol typeSym = ((ClassSymbol) casted.type().symbol()) .caseFieldAccessor(index); - */ + Type castType = getHeaderType( typeOf0( typeSym )); target.and = curHeader = mk.Header(pat.pos, @@ -429,23 +430,37 @@ public class AlgebraicMatcher extends PatternTool { env, case_index); } - else if (next.or == null) - return enter(patArgs, next.or = patNode, casted, env, case_index); - else + else if (next.or == null) { + next.or = patNode; + + if (patArgs.length == 1 && (casted.flags & Modifiers.CASE) == 0) { + return enter( patArgs, patNode, casted, env, case_index ); // FIX + } + + return enter( patArgs, patNode, casted, env, case_index ); + } else next = next.or; } + boolean isSeqApply( Tree.Apply tree ) { + return (tree.args.length == 1 && (tree.type.symbol().flags & Modifiers.CASE) == 0); + } + /** calls enter for an array of patterns, see enter */ public PatternNode enter(Tree[] pats, PatternNode target, Symbol casted, CaseEnv env, int case_index) { switch (target) { case ConstrPat(Symbol newCasted): casted = newCasted; + break; + case SeqContainerPat(Symbol newCasted, _): + casted = newCasted; + //target = enter(pats, target.or, casted, env, case_index); } for (int i = 0; i < pats.length; i++) { - Symbol typeSym = ((ClassSymbol) casted.type().symbol()) - .caseFieldAccessor( i ); - target = enter1(pats[i], typeSym /*i*/, target, casted, env, case_index); + //Symbol typeSym = ((ClassSymbol) casted.type().symbol()) + // .caseFieldAccessor( i ); + target = enter1(pats[i], /*typeSym*/ i, target, casted, env, case_index); } return target; } @@ -574,7 +589,7 @@ public class AlgebraicMatcher extends PatternTool { cf.Equals(selector, tree), toTree(node.and), toTree(node.or, selector)).setType(defs.BOOLEAN_TYPE); - case SequencePat( _, _, _ ): + case SeqContainerPat( _, _ ): return callSequenceMatcher( node, selector ); default: @@ -595,7 +610,7 @@ public class AlgebraicMatcher extends PatternTool { break;// defaultNode = node; else switch( node ) { - case SequencePat( _, _, _ ): + case SeqContainerPat( _, _ ): seqPatNodes.add( node ); bodies.add( toTree( node.and ) ); node = node.or; @@ -617,7 +632,7 @@ public class AlgebraicMatcher extends PatternTool { ... */ - // translate the _.and subtree of this SequencePat + // translate the _.and subtree of this SeqContainerPat Vector seqPatNodes = new Vector(); Vector bodies = new Vector(); @@ -641,7 +656,7 @@ public class AlgebraicMatcher extends PatternTool { int j = 0; for( Iterator it = seqPatNodes.iterator(); it.hasNext();) { - pats[ j ] = ((SequencePat) it.next()).seqpat; + pats[ j ] = ((SeqContainerPat) it.next()).seqpat; body[ j ] = (Tree) tmp[j]; j++; } diff --git a/sources/scalac/transformer/matching/BerrySethi.java b/sources/scalac/transformer/matching/BerrySethi.java index 72b39ff106..0396db20c2 100644 --- a/sources/scalac/transformer/matching/BerrySethi.java +++ b/sources/scalac/transformer/matching/BerrySethi.java @@ -99,7 +99,8 @@ class BerrySethi { //DEBUG.print( pat ); //System.out.println("</compFirst>"); switch( pat ) { - case Sequence( _ ): + case Sequence( Tree[] trees ): + return compFirst( trees ); case Typed(_,_): case Select(_,_): case Apply(_, _): @@ -249,8 +250,9 @@ class BerrySethi { * the way */ TreeSet compFollow1( TreeSet fol, Tree pat ) { + System.out.println("compFollow1("+fol+","+pat+")"); switch( pat ) { - case Sequence(Tree[] trees): + case Sequence( Tree[] trees ): TreeSet first = null; int i = trees.length; if( i > 0 ) { // is nonempty @@ -266,7 +268,7 @@ class BerrySethi { if( null == first ) first = new TreeSet(); return first; - case Alternative(Tree[] choices): + case Alternative( Tree[] choices ): TreeSet first = new TreeSet(); for( int i = choices.length - 1; i >= 0; --i ) { first.addAll( compFollow1( fol, choices[ i ] )); @@ -278,7 +280,7 @@ class BerrySethi { Integer p = (Integer) this.posMap.get( pat ); TreeSet first = compFirst( t ); - //System.out.print("BIND" + first); + System.out.print("BIND" + first); recVars.put( pat.symbol(), first ); // if( appearsRightmost( n, t )) @@ -543,7 +545,7 @@ class BerrySethi { this.finalTag = finalTag; - //System.out.println( "enter automatonFrom(...)"); // UNIT TEST + System.out.println( "enter automatonFrom("+pat+","+finalTag+")"); // UNIT TEST //System.out.println( TextTreePrinter.toString(pat) ); /*DEBUG = new TextTreePrinter( System.out ); DEBUG.begin(); @@ -552,8 +554,6 @@ 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 b3240dfbbf..9a6d0ef9a8 100644 --- a/sources/scalac/transformer/matching/CodeFactory.java +++ b/sources/scalac/transformer/matching/CodeFactory.java @@ -37,19 +37,27 @@ class CodeFactory extends PatternTool { Symbol seqListSym() { - return defs.getType( Name.fromString("scala.List") ).symbol() ; + return defs.getType( Names.scala_List ).symbol() ; } Symbol seqConsSym() { - return defs.getType( Name.fromString("scala.::") ).symbol() ; + return defs.getType( Names.scala_COLONCOLON ).symbol() ; } Symbol seqNilSym() { - return defs.getType( Name.fromString( "scala.Nil" ) ).symbol(); // no need for TypeApply anymore!x + return defs.getType( Names.scala_Nil ).symbol(); // no need for TypeApply anymore!x } Symbol seqIterSym() { - return defs.getType( Name.fromString( "scala.Iterator" ) ).symbol(); + return defs.getType( Names.scala_Iterator ).symbol(); + } + + Symbol seqIterSym_next() { + Scope scp = seqIterSym().members(); return scp.lookup( Names.next ); + } + + Symbol seqIterSym_hasNext() { + Scope scp = seqIterSym().members(); return scp.lookup( Names.hasNext ); } Symbol seqTraceSym() { @@ -254,10 +262,13 @@ class CodeFactory extends PatternTool { } Tree newSeqNil( Type tpe ) { + /* assert tpe != null :"tpe = null !?"; return gen.New( Position.NOPOS, defs.SCALA_TYPE, seqNilSym(), new Type[] { tpe }, new Tree[] {}); + */ + return gen.Select(gen.Ident(0, defs.SCALA), Names.Nil/*seqNilSym()*/); } Tree newSeqCons( Tree head, Tree tail ) { @@ -266,19 +277,22 @@ class CodeFactory extends PatternTool { new Tree[] { head, tail }); } + /** gets first arg of typeref ( can be Seq, Iterator, whatever ) + */ Type getElemType( Type seqType ) { //System.err.println("getElemType("+seqType+")"); - Symbol seqClass = defs.getType( Name.fromString("scala.Seq") ).symbol(); - assert seqClass != Symbol.NONE : "did not find Seq"; + //Symbol seqClass = defs.getType( Name.fromString("scala.Seq") ).symbol(); + //assert seqClass != Symbol.NONE : "did not find Seq"; - Type seqType1 = seqType.baseType( seqClass ); + //Type seqType1 = seqType.baseType( seqClass ); - switch( seqType1 ) { + switch( seqType ) { case TypeRef(_,_,Type[] args): - assert (args.length==1) : "weird type:"+seqType; + assert( args.length==1 ) : "weird type:"+seqType; return args[ 0 ]; default: - return seqType; + //System.err.println("somethings wrong: "+seqType); + return seqType.widen(); } } @@ -286,27 +300,19 @@ class CodeFactory extends PatternTool { */ public Tree _next( Tree iter ) { Type elemType = getElemType( iter.type() ); + System.err.println("elemType of next *** "+elemType); + Symbol nextSym = seqIterSym_next(); - Scope scp = defs.getType( Names.scala_Iterator ).symbol() /* seqIterSym */ - .members(); - - Symbol nextSym = scp.lookup( Names.next ); - - return _applyNone( gen.Select( iter, nextSym )) /* todo: nextSym() */ - .setType( iter.type() ); + return _applyNone( gen.Select( iter, nextSym )).setType( elemType ); } /** `it.hasNext()' */ public Tree _hasNext( Tree iter ) { - Scope scp = defs.getType( Names.scala_Iterator ).symbol() /* seqIterSym */ - .members(); + Symbol hasNextSym = seqIterSym_hasNext(); - Symbol hasNextSym = scp.lookup( Names.hasNext ); - - return _applyNone( gen.Select( iter, hasNextSym )) /* todo: hasNextSym() */ - .setType( defs.BOOLEAN_TYPE ); + return _applyNone( gen.Select( iter, hasNextSym )).setType( defs.BOOLEAN_TYPE ); } /** `!it.hasCur()' diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index ec36c1dd5a..429221f6d7 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -70,7 +70,7 @@ public class PatternMatcher extends PatternTool { this._m = m; initialize(); for( int i = 0; i < cases.length; i++ ) { - enter( (CaseDef) cases[i]/*, i*/ ); + addCase( (CaseDef) cases[i]/*, i*/ ); } _m.tree = toTree(); } @@ -181,7 +181,7 @@ public class PatternMatcher extends PatternTool { if (patNode.or != null) print(patNode.or, ind); break; - case SequencePat(Symbol casted, int plen, _): + case SequencePat( Symbol casted, int plen ): String s = "-- " + patNode.type.symbol().name + "(" + patNode.type + ", " + casted + ", " + plen + ") -> "; String ind = indent; @@ -234,11 +234,11 @@ public class PatternMatcher extends PatternTool { } } - public void enter(CaseDef tree) { - enter(tree.pos, tree.pat, tree.guard, tree.body); + public void addCase( CaseDef tree ) { + addCase(tree.pos, tree.pat, tree.guard, tree.body); } - protected CaseEnv enter(int pos, Tree pat, Tree guard, Tree body) { + protected CaseEnv addCase(int pos, Tree pat, Tree guard, Tree body) { CaseEnv env = new CaseEnv( _m.owner, unit ); //PatternNode matched = match(pat, root); PatternNode target = enter1(pat, -1, root, root.symbol(), env); @@ -253,6 +253,10 @@ public class PatternMatcher extends PatternTool { return env; } + /* + + // unused, thus commented out ! + public PatternNode match(Tree pat, PatternNode target) { // advance one step in pattern PatternNode next = target.and; @@ -290,6 +294,7 @@ public class PatternMatcher extends PatternTool { return null; return target; } + */ protected Tree[] patternArgs(Tree tree) { switch (tree) { @@ -335,7 +340,7 @@ public class PatternMatcher extends PatternTool { 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.SequencePat( tree.pos, tree.type, ts.length ); } return mk.ConstrPat(tree.pos, getConstrType(tree.type)); case Typed(Ident(Name name), Tree tpe): // variable pattern @@ -383,7 +388,7 @@ public class PatternMatcher extends PatternTool { 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); + return mk.SequencePat(tree.pos, tree.type, ts.length); case Alternative(Tree[] ts): // CAN THIS WORK ? assert ts.length > 0; PatternNode res = patternNode( ts[ 0 ], header, env ); @@ -414,9 +419,9 @@ public class PatternMatcher extends PatternTool { return q.type.isSubType(p.type); } return false; - case SequencePat(_, int plen, _): + case SequencePat(_, int plen): switch (q) { - case SequencePat(_, int qlen, _): + case SequencePat(_, int qlen): return (plen == qlen) && q.type.isSubType(p.type); } return false; @@ -456,7 +461,7 @@ public class PatternMatcher extends PatternTool { switch (target) { case ConstrPat(Symbol newCasted): return enter1(pat, index, target, newCasted, env); - case SequencePat(Symbol newCasted, int len, _): + case SequencePat(Symbol newCasted, int len): return enter1(pat, index, target, newCasted, env); default: return enter1(pat, index, target, casted, env); @@ -572,7 +577,7 @@ public class PatternMatcher extends PatternTool { case ConstrPat(Symbol newCasted): casted = newCasted; break; - case SequencePat(Symbol newCasted, int len, _): + case SequencePat(Symbol newCasted, int len): casted = newCasted; break; } @@ -686,7 +691,7 @@ 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, Tree tree): + case SequencePat(Symbol casted, int len): Symbol lenSym = casted.type().lookup(LENGTH_N); Tree t = make.Select(selector.pos, cf.As(selector.duplicate(), node.type), LENGTH_N); switch (typeOf(lenSym)) { @@ -738,75 +743,4 @@ public class PatternMatcher extends PatternTool { } } - /** collects all sequence patterns and returns the default - */ - PatternNode collectSeqPats( PatternNode node, - Vector seqPatNodes, - Vector bodies ) { - - PatternNode defaultNode = null; - - do { - if( node == null ) - break;// defaultNode = node; - else - switch( node ) { - case SequencePat( _, _, _ ): - seqPatNodes.add( node ); - bodies.add( toTree( node.and ) ); - node = node.or; - break; - default: - defaultNode = node; - } - } while (defaultNode == null) ; - System.out.println("collectSeqPats(1):"+seqPatNodes); - System.out.println("collectSeqPats(2):"+bodies); - return defaultNode; - } - - Tree callSequenceMatcher( PatternNode node, - Tree selector) { - System.out.println("callSequenceMatcher("+node+","+selector+")"); - - /* ???????????????????????? necessary to test whether is a Seq? - make.If(selector.pos, - maybe cf.And( cf.Is(selector, seqpat.type()) - ... - */ - - // translate the _.and subtree of this SequencePat - - Vector seqPatNodes = new Vector(); - Vector bodies = new Vector(); - - PatternNode defaultNode = collectSeqPats( node, - seqPatNodes, - bodies ); - - Tree defaultCase = toTree( defaultNode, selector ); - - SequenceMatcher wordRec = new SequenceMatcher(unit, infer); - - Matcher m = new Matcher( _m.owner, - selector, - defs.BOOLEAN_TYPE ); - - Tree pats[] = new Tree[ seqPatNodes.size() ]; - Tree body[] = new Tree[ seqPatNodes.size() ]; - - Object tmp[] = bodies.toArray(); - int j = 0; - for( Iterator it = seqPatNodes.iterator(); - it.hasNext();) { - pats[ j ] = ((SequencePat) it.next()).seqpat; - body[ j ] = (Tree) tmp[j]; - j++; - } - - wordRec.construct( m, pats, body, defaultCase, true /*doBinding*/ ); - - return m.tree; - - } } diff --git a/sources/scalac/transformer/matching/PatternNode.java b/sources/scalac/transformer/matching/PatternNode.java index 6feb28dd21..d089c6f432 100644 --- a/sources/scalac/transformer/matching/PatternNode.java +++ b/sources/scalac/transformer/matching/PatternNode.java @@ -23,20 +23,23 @@ public class PatternNode { public PatternNode or; public PatternNode and; - public case Header(Tree selector, Header next); - public case Body(Tree.ValDef[][] bound, Tree[] guard, Tree[] body); + public case Header( Tree selector, Header next ); + public case Body( Tree.ValDef[][] bound, Tree[] guard, Tree[] body ); public case DefaultPat(); - public case ConstrPat(Symbol casted); - public case SequencePat(Symbol casted, int len, Tree seqpat); - public case ConstantPat(Object value); - public case VariablePat(Tree tree); + public case ConstrPat( Symbol casted ); + public case SequencePat( Symbol casted, int len ); // only used in PatternMatcher + public case SeqContainerPat( Symbol casted, Tree seqpat ); // in AlgebraicMatcher + public case ConstantPat( Object value ); + public case VariablePat( Tree tree ); public Symbol symbol() { switch (this) { - case ConstrPat(Symbol casted): + case ConstrPat( Symbol casted ): return casted; - case SequencePat(Symbol casted, _, _): + case SequencePat( Symbol casted, _ ): + return casted; + case SeqContainerPat( Symbol casted, _ ): return casted; default: return Symbol.NONE; @@ -45,19 +48,21 @@ public class PatternNode { public String toString() { switch (this) { - case Header(Tree selector, Header next): + case Header( Tree selector, Header next ): return "Header(" + selector + ")"; - case Body(_, _, _): + case Body( _, _, _ ): return "Body"; case DefaultPat(): return "DefaultPat"; - case ConstrPat(Symbol casted): + case ConstrPat( Symbol casted ): return "ConstrPat(" + casted + ")"; - case SequencePat(Symbol casted, int len, Tree seqpat): + case SequencePat( Symbol casted, int len ): return "SequencePat(" + casted + ", " + len + "...)"; - case ConstantPat(Object value): + case SeqContainerPat( Symbol casted, Tree seqpat ): + return "SeqContainerPat(" + casted + ", " + seqpat + ")"; + case ConstantPat( Object value ): return "ConstantPat(" + value + ")"; - case VariablePat(Tree tree): + case VariablePat( Tree tree ): return "VariablePat"; default: return "<unknown pat>"; diff --git a/sources/scalac/transformer/matching/PatternNodeCreator.java b/sources/scalac/transformer/matching/PatternNodeCreator.java index 082f8db418..cecb9dc7bf 100644 --- a/sources/scalac/transformer/matching/PatternNodeCreator.java +++ b/sources/scalac/transformer/matching/PatternNodeCreator.java @@ -18,9 +18,16 @@ import java.util.Vector ; public class PatternNodeCreator extends PatternTool { - public SequencePat SequencePat(int pos, Type type, int len, Tree seqpat) { + public SequencePat SequencePat(int pos, Type type, int len) { Symbol sym = newVar(Position.NOPOS, type); - SequencePat node = new SequencePat(sym, len, seqpat); + SequencePat node = new SequencePat(sym, len); + node.pos = pos; + node.type = type; + return node; + } + public SeqContainerPat SeqContainerPat(int pos, Type type, Tree seqpat) { + Symbol sym = newVar(Position.NOPOS, type); + SeqContainerPat node = new SeqContainerPat(sym, seqpat); node.pos = pos; node.type = type; return node; diff --git a/sources/scalac/transformer/matching/RightTracerInScala.java b/sources/scalac/transformer/matching/RightTracerInScala.java index f41370708c..698a726321 100644 --- a/sources/scalac/transformer/matching/RightTracerInScala.java +++ b/sources/scalac/transformer/matching/RightTracerInScala.java @@ -121,7 +121,6 @@ public class RightTracerInScala extends Autom2Scala { rhs = cf.ignoreValue( realVar.type() ); else rhs = cf.newSeqNil( elementType ); - Tree varDef = gen.ValDef(helpVar, rhs); //((ValDef) varDef).kind = Kinds.VAR; helpVarDefs.add( varDef ); @@ -471,9 +470,11 @@ public class RightTracerInScala extends Autom2Scala { */ Tree run_finished( int state ) { //return gen.Ident( accumSym.pos, accumSym ); - return gen.New( pos, defs.SCALA_TYPE, defs.UNIT_CLASS, + return gen.Block(0, Tree.EMPTY_ARRAY).setType( defs.UNIT_TYPE ); + /* gen.Ident(0, defs.NULL); */ + /*gen.New( pos, defs.SCALA_TYPE, defs.NULL, //UNIT_CLASS, Type.EMPTY_ARRAY, - Tree.EMPTY_ARRAY); + Tree.EMPTY_ARRAY); */ } |