diff options
author | buraq <buraq@epfl.ch> | 2003-07-03 17:41:20 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-07-03 17:41:20 +0000 |
commit | 55424e716cc88e65650faec1ce997a2c1931faab (patch) | |
tree | 4a57987c6f45be46f5cc1bb51ce2ccff8a9e6de0 | |
parent | ddf59687e3dfe27efa537a6cb4ad704cbaf7fea4 (diff) | |
download | scala-55424e716cc88e65650faec1ce997a2c1931faab.tar.gz scala-55424e716cc88e65650faec1ce997a2c1931faab.tar.bz2 scala-55424e716cc88e65650faec1ce997a2c1931faab.zip |
changed code for sequence matching, not yet ope...
changed code for sequence matching, not yet operational
4 files changed, 203 insertions, 16 deletions
diff --git a/sources/scalac/transformer/matching/CodeFactory.java b/sources/scalac/transformer/matching/CodeFactory.java index 9c2a828cbe..b91007401c 100644 --- a/sources/scalac/transformer/matching/CodeFactory.java +++ b/sources/scalac/transformer/matching/CodeFactory.java @@ -20,6 +20,21 @@ import Tree.*; class CodeFactory extends PatternTool { + Symbol seqConsSym() { + return defs.getType( Name.fromString("scala.::") ).symbol() ; + } + + Symbol seqNilSym() { + return defs.getType( Name.fromString( "scala.Nil" ) ).symbol(); // no need for TypeApply anymore!x + } + + Symbol seqTraceConsSym() { + return defs.getType( Name.fromString( "scala.SeqTraceCons" ) ).symbol(); + } + Symbol seqTraceNilSym() { + return defs.getType( Name.fromString( "scala.SeqTraceNil" ) ).symbol(); + } + public CodeFactory( Unit unit, Infer infer ) { super( unit, infer ); } @@ -105,11 +120,112 @@ class CodeFactory extends PatternTool { } + Tree ignoreValue( Type asType ) { + if( asType.isSameAs(defs.BYTE_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.INT_TYPE ); + else if( asType.isSameAs( defs.CHAR_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.CHAR_TYPE ); + else if( asType.isSameAs(defs.SHORT_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.SHORT_TYPE ); + else if( asType.isSameAs(defs.INT_TYPE )) + return Int( 0 ); + else if( asType.isSameAs(defs.LONG_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.LONG_TYPE ); + else if( asType.isSameAs(defs.FLOAT_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.FLOAT_TYPE ); + else if( asType.isSameAs(defs.DOUBLE_TYPE )) + return make.Literal(Position.NOPOS, new Long( 0 )) + .setType( defs.DOUBLE_TYPE ); + else if( asType.isSameAs(defs.BOOLEAN_TYPE )) + return gen.mkBooleanLit(Position.NOPOS, false); + else if( asType.isSameAs(defs.STRING_TYPE )) + return make.Literal(Position.NOPOS, "") + .setType( defs.STRING_TYPE ); + /** FIX ME FOR THE NEW VERSION + else + return gen.Apply( Null( asType ), + Tree.EMPTY_ARRAY); + */ + return null; // should not happen FIXME + } + + /** FIX ME FOR THE NEW VERSION + Tree Null( Type asType ) { + return gen.TypeApply(pos, gen.mkId(pos, defs.NULL ), + new Tree[] { gen.mkType(pos, asType) } ); + } + */ + // the caller needs to set the type ! Tree _applyNone( Tree arg ) { return make.Apply(Position.NOPOS, arg, Tree.EMPTY_ARRAY ); } + /** code `new SeqTraceNil[ elemType ]()' + */ + + Tree _seqTraceNil( Type elemType ) { + assert elemType != null : "elemType = null??"; + return gen.New( Position.NOPOS, defs.SCALA_TYPE, seqTraceNilSym(), + new Type[] { elemType }, + new Tree[] {}); + } + + + /** creates an scala.Int constant + */ + Tree Int( int val ) { + return make.Literal(Position.NOPOS, new Long((long)val)) + .setType( defs.INT_TYPE ); + } + + Tree Int( Integer valI ) { + return Int( valI.intValue() ); + } + + /** code `new SeqTraceCons[ elemType ]( state, head, tail )' + */ + Tree newSeqTraceCons( Integer state, Tree head, Tree tail ) { + return gen.New( Position.NOPOS, defs.SCALA_TYPE, seqTraceConsSym(), + new Type[] { head.type() }, + new Tree[] { Int( state ), head, tail }); + } + + + /* + Type _seqTraceConsType( Type elemType ) { + return Type.TypeRef( defs.SCALA_TYPE, + seqTraceConsSym, + new Type[] { elemType }); + } + */ + + // `SeqCons[ elemType ]' + + Type _seqConsType( Type elemType ) { + return Type.TypeRef( defs.SCALA_TYPE, + seqConsSym(), + new Type[] { elemType }); + } + + Tree newSeqNil( Type tpe ) { + assert tpe != null :"tpe = null !?"; + return gen.New( Position.NOPOS, defs.SCALA_TYPE, seqNilSym(), + new Type[] { tpe }, + new Tree[] {}); + } + + Tree newSeqCons( Tree head, Tree tail ) { + return gen.New( Position.NOPOS, defs.SCALA_TYPE, seqConsSym(), + new Type[] { head.type() }, + new Tree[] { head, tail }); + } + // todo: more defensive checking Type getElemType( Type seqType ) { Type[] args = seqType.typeArgs(); /*use typeArgs instead of args*/ diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index c90de53a60..749fde85fe 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -19,6 +19,8 @@ import PatternNode.*; import Tree.*; import scalac.transformer.TransMatch.Matcher ; +import java.util.Vector ; +import java.util.Iterator ; public class PatternMatcher extends PatternTool { @@ -82,10 +84,10 @@ public class PatternMatcher extends PatternTool { this.owner = _m.owner; this.selector = _m.selector; - this.root = mk.ConstrPat/*mk.ConstrPat*/( _m.pos, + this.root = mk.ConstrPat( _m.pos, _m.selector.type.widen() ); - this.root.and = mk.Header/*mk.Header*/( _m.pos, + this.root.and = mk.Header( _m.pos, _m.selector.type.widen(), gen.Ident( _m.pos, root.symbol() ) .setType(_m.selector.type.widen())); @@ -179,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; @@ -331,7 +333,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); + 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 @@ -379,7 +381,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); + return mk.SequencePat(tree.pos, tree.type, ts.length, tree); default: new scalac.ast.printer.TextTreePrinter().print(tree).flush(); throw new ApplicationError(tree); @@ -402,9 +404,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; @@ -444,7 +446,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); @@ -560,7 +562,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; } @@ -674,7 +676,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): + 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)) { @@ -725,4 +727,73 @@ 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) ; + + return defaultNode; + } + + Tree callSequenceMatcher( PatternNode node, + Tree 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); FIX ME FOR THE NEW VERSION + + 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 /*, doBinding*/ ); FIX ME FOR THE NEW VERSION + + return m.tree; + + } } diff --git a/sources/scalac/transformer/matching/PatternNode.java b/sources/scalac/transformer/matching/PatternNode.java index 4c598768f5..6feb28dd21 100644 --- a/sources/scalac/transformer/matching/PatternNode.java +++ b/sources/scalac/transformer/matching/PatternNode.java @@ -27,7 +27,7 @@ public class PatternNode { 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); + public case SequencePat(Symbol casted, int len, Tree seqpat); public case ConstantPat(Object value); public case VariablePat(Tree tree); @@ -36,7 +36,7 @@ public class PatternNode { switch (this) { case ConstrPat(Symbol casted): return casted; - case SequencePat(Symbol casted, _): + case SequencePat(Symbol casted, _, _): return casted; default: return Symbol.NONE; @@ -53,8 +53,8 @@ public class PatternNode { return "DefaultPat"; case ConstrPat(Symbol casted): return "ConstrPat(" + casted + ")"; - case SequencePat(Symbol casted, int len): - return "SequencePat(" + casted + ", " + len + ")"; + case SequencePat(Symbol casted, int len, Tree seqpat): + return "SequencePat(" + casted + ", " + len + "...)"; case ConstantPat(Object value): return "ConstantPat(" + value + ")"; case VariablePat(Tree tree): diff --git a/sources/scalac/transformer/matching/PatternNodeCreator.java b/sources/scalac/transformer/matching/PatternNodeCreator.java index 17876c86e3..082f8db418 100644 --- a/sources/scalac/transformer/matching/PatternNodeCreator.java +++ b/sources/scalac/transformer/matching/PatternNodeCreator.java @@ -18,9 +18,9 @@ import java.util.Vector ; public class PatternNodeCreator extends PatternTool { - public SequencePat SequencePat(int pos, Type type, int len) { + public SequencePat SequencePat(int pos, Type type, int len, Tree seqpat) { Symbol sym = newVar(Position.NOPOS, type); - SequencePat node = new SequencePat(sym, len); + SequencePat node = new SequencePat(sym, len, seqpat); node.pos = pos; node.type = type; return node; |