diff options
Diffstat (limited to 'sources/scalac/transformer/matching')
9 files changed, 527 insertions, 493 deletions
diff --git a/sources/scalac/transformer/matching/AlgebraicMatcher.java b/sources/scalac/transformer/matching/AlgebraicMatcher.java index fc70741cd4..a366eee16e 100644 --- a/sources/scalac/transformer/matching/AlgebraicMatcher.java +++ b/sources/scalac/transformer/matching/AlgebraicMatcher.java @@ -16,7 +16,6 @@ import scalac.symtab.*; import PatternNode.*; import Tree.*; -import scalac.transformer.TransMatch.Matcher ; import scalac.util.Name ; import scalac.util.Names ; //import scalac.ast.printer.TextTreePrinter ; @@ -30,7 +29,7 @@ import java.util.Iterator ; public class AlgebraicMatcher extends PatternMatcher { - Matcher _m; + PartialMatcher _m; /** constructor */ @@ -42,13 +41,13 @@ public class AlgebraicMatcher extends PatternMatcher { /** constructs an algebraic pattern matcher from cases */ - public void construct( Matcher m, Tree[] cases) { + public void construct( PartialMatcher m, Tree[] cases) { construct(m, cases, true); } /** constructs an algebraic pattern matcher from cases */ - public void construct( Matcher m, Tree[] cases, boolean doBinding) { + public void construct( PartialMatcher m, Tree[] cases, boolean doBinding) { this._m = m; super.initialize( _m.selector, _m.owner, _m.resultType, doBinding ); for( int i = 0; i < cases.length; i++ ) { @@ -157,9 +156,9 @@ public class AlgebraicMatcher extends PatternMatcher { SequenceMatcher wordRec = new SequenceMatcher(unit); - Matcher m = new Matcher( _m.owner, - selector, - defs.BOOLEAN_TYPE() ); + PartialMatcher m = new PartialMatcher( _m.owner, + selector, + defs.BOOLEAN_TYPE() ); Tree pats[] = new Tree[ seqPatNodes.size() ]; Tree body[] = new Tree[ seqPatNodes.size() ]; diff --git a/sources/scalac/transformer/matching/Autom2Scala.java b/sources/scalac/transformer/matching/Autom2Scala.java index db742b8f5e..8453ed8f3a 100644 --- a/sources/scalac/transformer/matching/Autom2Scala.java +++ b/sources/scalac/transformer/matching/Autom2Scala.java @@ -11,7 +11,6 @@ import scalac.util.Name; import scalac.util.Names; import Tree.*; -import scalac.transformer.TransMatch.Matcher ; import java.util.* ; import scala.tools.util.Position; @@ -168,9 +167,9 @@ public class Autom2Scala { */ // calling the /*AlgebraicMatcher*/PatternMatcher here Tree _cur_match( Tree pat ) { - Matcher m = new Matcher( this.funSym, /* owner*/ - currentElem(), /* root */ - defs.BOOLEAN_TYPE() /* restype */); + PartialMatcher m = new PartialMatcher( this.funSym, /* owner*/ + currentElem(), /* root */ + defs.BOOLEAN_TYPE() /* restype */); am.construct( m, new CaseDef[] { cf.gen.CaseDef( pat, diff --git a/sources/scalac/transformer/matching/LeftTracerInScala.java b/sources/scalac/transformer/matching/LeftTracerInScala.java index 05f4b32fa4..4fabce0586 100644 --- a/sources/scalac/transformer/matching/LeftTracerInScala.java +++ b/sources/scalac/transformer/matching/LeftTracerInScala.java @@ -7,8 +7,6 @@ import Tree.*; import scalac.util.Name; import scalac.util.Names; -import scalac.transformer.TransMatch.Matcher ; - import java.util.* ; import scala.tools.util.Position; @@ -203,9 +201,9 @@ public class LeftTracerInScala extends TracerInScala { //System.out.println("calling algebraic matcher on type:"+pat.type); - Matcher m = new Matcher( owner, - currentElem(), - defs.BOOLEAN_TYPE() ); + PartialMatcher m = new PartialMatcher( owner, + currentElem(), + defs.BOOLEAN_TYPE() ); if( CollectVariableTraverser.containsBinding( pat )) { switch( pat ) { diff --git a/sources/scalac/transformer/matching/PartialMatcher.java b/sources/scalac/transformer/matching/PartialMatcher.java new file mode 100644 index 0000000000..c7b5c9230e --- /dev/null +++ b/sources/scalac/transformer/matching/PartialMatcher.java @@ -0,0 +1,53 @@ +package scalac.transformer.matching; + +import scalac.ast.Tree; +import scalac.symtab.Symbol; +import scalac.symtab.Type; +import java.util.HashMap ; + +/** container. classes AlgebraicMatcher and SequenceMatcher get input and store their results in here. + * resembles the 'Memento' design pattern, could also be named 'Liaison' + */ +public class PartialMatcher { + + /** owner of the code we create (input) + */ + public Symbol owner; + + /** the selector value (input) + */ + public Tree selector; + + /** type of the result of the whole match (input) + */ + public Type resultType; + + /** tree representing the matcher (output) + */ + public Tree tree; + + public int pos; + + //public HashMap varMap; // needed in LeftTracerInScala + //public Tree[] stms; // needed in LeftTracerInScala + + public PartialMatcher(Symbol owner, + Tree root, + Type resultType) { + + assert( owner != null ) : "owner is null"; + assert owner != Symbol.NONE ; + this.owner = owner; + + assert root != null; + assert root.type != null; + this.selector = root; + + assert this.resultType != Type.NoType; + this.resultType = resultType; + + this.pos = root.pos; // for convenience only + + } + +} diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 655fcda218..dc85594953 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -92,87 +92,87 @@ public class PatternMatcher extends PatternTool { System.out.println(indent + "NULL"); else switch (patNode) { - case Header(Tree selector, Header next): - System.out.println(indent + "HEADER(" + patNode.type + - ", " + selector + ")"); - print(patNode.or, indent + "|"); - if (next != null) - print(next, indent); - break; - case ConstrPat(Symbol casted): - String s = "-- " + patNode.type.symbol().name + - "(" + patNode.type + ", " + casted + ") -> "; - String ind = indent; - indent = (patNode.or != null) ? - indent : - indent.substring(0, indent.length() - 1) + " "; - for (int i = 0; i < s.length(); i++) - indent += " "; - System.out.println(ind + s); - print(patNode.and, indent); - if (patNode.or != null) - print(patNode.or, ind); - break; - case SequencePat( Symbol casted, int plen ): - String s = "-- " + patNode.type.symbol().name + "(" + patNode.type + - ", " + casted + ", " + plen + ") -> "; - String ind = indent; - indent = (patNode.or != null) ? - indent : - indent.substring(0, indent.length() - 1) + " "; - for (int i = 0; i < s.length(); i++) - indent += " "; - System.out.println(ind + s); - print(patNode.and, indent); - if (patNode.or != null) - print(patNode.or, ind); - break; - case DefaultPat(): - System.out.println(indent + "-- _ -> "); - print(patNode.and, indent.substring(0, indent.length() - 1) + - " "); - if (patNode.or != null) - print(patNode.or, indent); - break; - case ConstantPat(AConstant value): - String s = "-- CONST(" + value + ") -> "; - String ind = indent; - indent = (patNode.or != null) ? - indent : - indent.substring(0, indent.length() - 1) + " "; - for (int i = 0; i < s.length(); i++) - indent += " "; - System.out.println(ind + s); - print(patNode.and, indent); - if (patNode.or != null) - print(patNode.or, ind); - break; - case VariablePat(Tree tree): - String s = "-- STABLEID(" + tree + ": " + patNode.type + ") -> "; - String ind = indent; - indent = (patNode.or != null) ? - indent : - indent.substring(0, indent.length() - 1) + " "; - for (int i = 0; i < s.length(); i++) - indent += " "; - System.out.println(ind + s); - print(patNode.and, indent); - if (patNode.or != null) - print(patNode.or, ind); - break; - case AltPat(Header header): - System.out.println(indent + "-- ALTERNATIVES:"); - print(header, indent + " * "); - print(patNode.and, indent + " * -> "); - if (patNode.or != null) - print(patNode.or, indent); - break; - case Body(_, Tree[] guards, Tree[] stats): - if ((guards.length == 0) && (stats.length == 0)) - System.out.println(indent + "true"); - else - System.out.println(indent + "BODY(" + stats.length + ")"); - break; + case Header(Tree selector, Header next): + System.out.println(indent + "HEADER(" + patNode.type + + ", " + selector + ")"); + print(patNode.or, indent + "|"); + if (next != null) + print(next, indent); + break; + case ConstrPat(Symbol casted): + String s = "-- " + patNode.type.symbol().name + + "(" + patNode.type + ", " + casted + ") -> "; + String ind = indent; + indent = (patNode.or != null) ? + indent : + indent.substring(0, indent.length() - 1) + " "; + for (int i = 0; i < s.length(); i++) + indent += " "; + System.out.println(ind + s); + print(patNode.and, indent); + if (patNode.or != null) + print(patNode.or, ind); + break; + case SequencePat( Symbol casted, int plen ): + String s = "-- " + patNode.type.symbol().name + "(" + patNode.type + + ", " + casted + ", " + plen + ") -> "; + String ind = indent; + indent = (patNode.or != null) ? + indent : + indent.substring(0, indent.length() - 1) + " "; + for (int i = 0; i < s.length(); i++) + indent += " "; + System.out.println(ind + s); + print(patNode.and, indent); + if (patNode.or != null) + print(patNode.or, ind); + break; + case DefaultPat(): + System.out.println(indent + "-- _ -> "); + print(patNode.and, indent.substring(0, indent.length() - 1) + + " "); + if (patNode.or != null) + print(patNode.or, indent); + break; + case ConstantPat(AConstant value): + String s = "-- CONST(" + value + ") -> "; + String ind = indent; + indent = (patNode.or != null) ? + indent : + indent.substring(0, indent.length() - 1) + " "; + for (int i = 0; i < s.length(); i++) + indent += " "; + System.out.println(ind + s); + print(patNode.and, indent); + if (patNode.or != null) + print(patNode.or, ind); + break; + case VariablePat(Tree tree): + String s = "-- STABLEID(" + tree + ": " + patNode.type + ") -> "; + String ind = indent; + indent = (patNode.or != null) ? + indent : + indent.substring(0, indent.length() - 1) + " "; + for (int i = 0; i < s.length(); i++) + indent += " "; + System.out.println(ind + s); + print(patNode.and, indent); + if (patNode.or != null) + print(patNode.or, ind); + break; + case AltPat(Header header): + System.out.println(indent + "-- ALTERNATIVES:"); + print(header, indent + " * "); + print(patNode.and, indent + " * -> "); + if (patNode.or != null) + print(patNode.or, indent); + break; + case Body(_, Tree[] guards, Tree[] stats): + if ((guards.length == 0) && (stats.length == 0)) + System.out.println(indent + "true"); + else + System.out.println(indent + "BODY(" + stats.length + ")"); + break; } } @@ -187,18 +187,18 @@ public class PatternMatcher extends PatternTool { */ protected void enter(Tree caseDef) { switch (caseDef) { - case CaseDef(Tree pat, Tree guard, Tree body): - CaseEnv env = new CaseEnv(owner, unit); - // PatternNode matched = match(pat, root); - PatternNode target = enter1(pat, -1, root, root.symbol(), env); - // if (target.and != null) - // unit.error(pat.pos, "duplicate case"); - if (target.and == null) - target.and = mk.Body(caseDef.pos, env.boundVars(), guard, body); - else if (target.and instanceof Body) - updateBody((Body)target.and, env.boundVars(), guard, body); - else - unit.error(pat.pos, "duplicate case"); + case CaseDef(Tree pat, Tree guard, Tree body): + CaseEnv env = new CaseEnv(owner, unit); + // PatternNode matched = match(pat, root); + PatternNode target = enter1(pat, -1, root, root.symbol(), env); + // if (target.and != null) + // unit.error(pat.pos, "duplicate case"); + if (target.and == null) + target.and = mk.Body(caseDef.pos, env.boundVars(), guard, body); + else if (target.and instanceof Body) + updateBody((Body)target.and, env.boundVars(), guard, body); + else + unit.error(pat.pos, "duplicate case"); } } @@ -223,21 +223,21 @@ public class PatternMatcher extends PatternTool { protected Tree[] patternArgs(Tree tree) { switch (tree) { - case Bind(_, Tree pat): - return patternArgs(pat); - case Apply(_, Tree[] args): - if ( isSeqApply((Apply) tree) && !delegateSequenceMatching) - switch (args[0]) { - case Sequence(Tree[] ts): - return ts; - } - return args; - case Sequence(Tree[] ts): - if (!delegateSequenceMatching) - return ts; - return Tree.EMPTY_ARRAY; - default: - return Tree.EMPTY_ARRAY; + case Bind(_, Tree pat): + return patternArgs(pat); + case Apply(_, Tree[] args): + if ( isSeqApply((Apply) tree) && !delegateSequenceMatching) + switch (args[0]) { + case Sequence(Tree[] ts): + return ts; + } + return args; + case Sequence(Tree[] ts): + if (!delegateSequenceMatching) + return ts; + return Tree.EMPTY_ARRAY; + default: + return Tree.EMPTY_ARRAY; } } @@ -248,123 +248,123 @@ public class PatternMatcher extends PatternTool { protected PatternNode patternNode(Tree tree, Header header, CaseEnv env) { //System.out.println("patternNode("+tree+","+header+")"); - switch (tree) { - case Bind(Name name, - Typed(Ident(Names.PATTERN_WILDCARD), Tree tpe)): // x@_:Type - if(header.type.isSubType(tpe.type)) { - PatternNode node = mk.DefaultPat(tree.pos, tpe.type); - env.newBoundVar( tree.symbol(), tree.type, header.selector ); - return node; - } else { - ConstrPat node = mk.ConstrPat(tree.pos, tpe.type); - env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted)); - return node; - } - case Bind(Name name, Ident(Names.PATTERN_WILDCARD)): // x @ _ - PatternNode node = mk.DefaultPat(tree.pos, header.type); - if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) - env.newBoundVar( tree.symbol(), tree.type, header.selector); - return node; - case Bind(Name name, Tree pat): - PatternNode node = patternNode(pat, header, env); - if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) { - Symbol casted = node.symbol(); - Tree theValue = (casted == Symbol.NONE) ? header.selector : gen.Ident(tree.pos, casted); - env.newBoundVar(tree.symbol(), tree.type, theValue); - } - return node; - case Apply(Tree fn, Tree[] args): // pattern with args - if(isSeqApply((Apply)tree)) { - if (!delegateSequenceMatching) { - switch (args[0]) { - case Sequence(Tree[] ts): - return mk.SequencePat(tree.pos, tree.type, ts.length); - } - } else { - PatternNode res = mk.ConstrPat(tree.pos, tree.type); - res.and = mk.Header(tree.pos, header.type, header.selector); - res.and.and = mk.SeqContainerPat(tree.pos, tree.type, args[0]); - return res; - } - } else if ((fn.symbol() != null) && - fn.symbol().isStable() && - !(fn.symbol().isModule() && - ((fn.symbol().flags & Modifiers.CASE) != 0))) - return mk.VariablePat(tree.pos, tree); - return mk.ConstrPat(tree.pos, tree.type); - case Typed(Ident ident, Tree tpe): // variable pattern - boolean doTest = header.type.isSubType(tpe.type); - PatternNode node = doTest ? - mk.DefaultPat(tree.pos, tpe.type) : - mk.ConstrPat(tree.pos, tpe.type); - if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD)) - switch (node) { - case ConstrPat(Symbol casted): - env.newBoundVar(((Tree.Typed)tree).expr.symbol(), - tpe.type, - gen.Ident(tree.pos, casted)); - break; - default: - env.newBoundVar(((Tree.Typed)tree).expr.symbol(), - tpe.type, - doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted)); - } - return node; - case Ident(Name name): // pattern without args or variable - if (tree.symbol() == defs.PATTERN_WILDCARD) - return mk.DefaultPat(tree.pos, header.type); - else if (tree.symbol().isPrimaryConstructor()) { - assert false; // this may not happen ?? ----------------- Burak - return mk.ConstrPat(tree.pos, tree.type); - } else if (name.isVariable()) {// should be Bind ------------ Burak - assert false; - if (env != null) - env.newBoundVar(tree.symbol(), - tree.type, - header.selector); - return mk.DefaultPat(tree.pos, header.type); - } else - return mk.VariablePat(tree.pos, tree); - case Select(_, Name name): // variable - if (tree.symbol().isPrimaryConstructor()) - return mk.ConstrPat(tree.pos, tree.type); - else - return mk.VariablePat(tree.pos, tree); - case Literal(AConstant value): - return mk.ConstantPat(tree.pos, tree.type, value); - case Sequence(Tree[] ts): - if ( !delegateSequenceMatching ) { - return mk.SequencePat(tree.pos, tree.type, ts.length); - } else { - return mk.SeqContainerPat(tree.pos, tree.type, tree); - } - case Alternative(Tree[] ts): - assert ts.length > 1; - PatternNode subroot = mk.ConstrPat(header.pos, header.type); - subroot.and = mk.Header(header.pos, header.type, header.selector.duplicate()); - CaseEnv subenv = new CaseEnv(owner, unit); - for (int i = 0; i < ts.length; i++) { - PatternNode target = enter1(ts[i], -1, subroot, subroot.symbol(), subenv); - target.and = mk.Body(tree.pos); - } - return mk.AltPat(tree.pos, (Header)subroot.and); - default: - throw new ApplicationError("unit = " + unit + "; tree = "+tree); + switch (tree) { + case Bind(Name name, + Typed(Ident(Names.PATTERN_WILDCARD), Tree tpe)): // x@_:Type + if(header.type.isSubType(tpe.type)) { + PatternNode node = mk.DefaultPat(tree.pos, tpe.type); + env.newBoundVar( tree.symbol(), tree.type, header.selector ); + return node; + } else { + ConstrPat node = mk.ConstrPat(tree.pos, tpe.type); + env.newBoundVar( tree.symbol(), tree.type, gen.Ident(tree.pos, node.casted)); + return node; + } + case Bind(Name name, Ident(Names.PATTERN_WILDCARD)): // x @ _ + PatternNode node = mk.DefaultPat(tree.pos, header.type); + if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) + env.newBoundVar( tree.symbol(), tree.type, header.selector); + return node; + case Bind(Name name, Tree pat): + PatternNode node = patternNode(pat, header, env); + if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) { + Symbol casted = node.symbol(); + Tree theValue = (casted == Symbol.NONE) ? header.selector : gen.Ident(tree.pos, casted); + env.newBoundVar(tree.symbol(), tree.type, theValue); + } + return node; + case Apply(Tree fn, Tree[] args): // pattern with args + if(isSeqApply((Apply)tree)) { + if (!delegateSequenceMatching) { + switch (args[0]) { + case Sequence(Tree[] ts): + return mk.SequencePat(tree.pos, tree.type, ts.length); + } + } else { + PatternNode res = mk.ConstrPat(tree.pos, tree.type); + res.and = mk.Header(tree.pos, header.type, header.selector); + res.and.and = mk.SeqContainerPat(tree.pos, tree.type, args[0]); + return res; + } + } else if ((fn.symbol() != null) && + fn.symbol().isStable() && + !(fn.symbol().isModule() && + ((fn.symbol().flags & Modifiers.CASE) != 0))) + return mk.VariablePat(tree.pos, tree); + return mk.ConstrPat(tree.pos, tree.type); + case Typed(Ident ident, Tree tpe): // variable pattern + boolean doTest = header.type.isSubType(tpe.type); + PatternNode node = doTest ? + mk.DefaultPat(tree.pos, tpe.type) : + mk.ConstrPat(tree.pos, tpe.type); + if ((env != null) && (ident.symbol() != defs.PATTERN_WILDCARD)) + switch (node) { + case ConstrPat(Symbol casted): + env.newBoundVar(((Tree.Typed)tree).expr.symbol(), + tpe.type, + gen.Ident(tree.pos, casted)); + break; + default: + env.newBoundVar(((Tree.Typed)tree).expr.symbol(), + tpe.type, + doTest ? header.selector : gen.Ident(tree.pos, ((ConstrPat) node).casted)); + } + return node; + case Ident(Name name): // pattern without args or variable + if (tree.symbol() == defs.PATTERN_WILDCARD) + return mk.DefaultPat(tree.pos, header.type); + else if (tree.symbol().isPrimaryConstructor()) { + assert false; // this may not happen ?? ----------------- Burak + return mk.ConstrPat(tree.pos, tree.type); + } else if (name.isVariable()) {// should be Bind ------------ Burak + assert false; + if (env != null) + env.newBoundVar(tree.symbol(), + tree.type, + header.selector); + return mk.DefaultPat(tree.pos, header.type); + } else + return mk.VariablePat(tree.pos, tree); + case Select(_, Name name): // variable + if (tree.symbol().isPrimaryConstructor()) + return mk.ConstrPat(tree.pos, tree.type); + else + return mk.VariablePat(tree.pos, tree); + case Literal(AConstant value): + return mk.ConstantPat(tree.pos, tree.type, value); + case Sequence(Tree[] ts): + if ( !delegateSequenceMatching ) { + return mk.SequencePat(tree.pos, tree.type, ts.length); + } else { + return mk.SeqContainerPat(tree.pos, tree.type, tree); + } + case Alternative(Tree[] ts): + assert ts.length > 1; + PatternNode subroot = mk.ConstrPat(header.pos, header.type); + subroot.and = mk.Header(header.pos, header.type, header.selector.duplicate()); + CaseEnv subenv = new CaseEnv(owner, unit); + for (int i = 0; i < ts.length; i++) { + PatternNode target = enter1(ts[i], -1, subroot, subroot.symbol(), subenv); + target.and = mk.Body(tree.pos); + } + return mk.AltPat(tree.pos, (Header)subroot.and); + default: + throw new ApplicationError("unit = " + unit + "; tree = "+tree); } } protected PatternNode enter(Tree pat, - int index, - PatternNode target, - Symbol casted, - CaseEnv env) { + int index, + PatternNode target, + Symbol casted, + CaseEnv env) { switch (target) { - case ConstrPat(Symbol newCasted): - return enter1(pat, index, target, newCasted, env); - case SequencePat(Symbol newCasted, int len): - return enter1(pat, index, target, newCasted, env); - default: - return enter1(pat, index, target, casted, env); + case ConstrPat(Symbol newCasted): + return enter1(pat, index, target, newCasted, env); + case SequencePat(Symbol newCasted, int len): + return enter1(pat, index, target, newCasted, env); + default: + return enter1(pat, index, target, casted, env); } } @@ -384,13 +384,13 @@ public class PatternMatcher extends PatternTool { Tree accTree = gen.Select( ident, ts); switch (accType) { // scala case accessor - case MethodType(_, _): - return mk.Header(pos, - accType.resultType(), - gen.mkApply__(accTree)); - // jaco case accessor - default: - return mk.Header(pos, accType, accTree); + case MethodType(_, _): + return mk.Header(pos, + accType.resultType(), + gen.mkApply__(accTree)); + // jaco case accessor + default: + return mk.Header(pos, accType, accTree); } } } @@ -400,10 +400,10 @@ public class PatternMatcher extends PatternTool { * invariant: ( curHeader == (Header)target.and ) holds */ protected PatternNode enter1(Tree pat, - int index, - PatternNode target, - Symbol casted, - CaseEnv env) { + int index, + PatternNode target, + Symbol casted, + CaseEnv env) { //System.err.println("enter(" + pat + ", " + index + ", " + target + ", " + casted + ")"); Tree[] patArgs = patternArgs(pat); // get pattern arguments Header curHeader = (Header)target.and; // advance one step in intermediate representation @@ -422,22 +422,22 @@ public class PatternMatcher extends PatternTool { // add branch to curHeader, but reuse tests if possible while (true) if (next.isSameAs(patNode)) { // test for patNode already present --> reuse - // substitute... !!! - switch(patNode) { - case ConstrPat(Symbol ocasted): - env.substitute(ocasted, gen.Ident(patNode.pos, - ((ConstrPat) next).casted)); - } - return enter(patArgs, next, casted, env); + // substitute... !!! + switch(patNode) { + case ConstrPat(Symbol ocasted): + env.substitute(ocasted, gen.Ident(patNode.pos, + ((ConstrPat) next).casted)); + } + return enter(patArgs, next, casted, env); } else if (next.isDefaultPat() || // default case reached, or - ((next.or == null) && // no more alternatives and - (patNode.isDefaultPat() || next.subsumes(patNode)))) { + ((next.or == null) && // no more alternatives and + (patNode.isDefaultPat() || next.subsumes(patNode)))) { // new node is default or subsumed return enter(patArgs, (curHeader = - (curHeader.next = - mk.Header(patNode.pos, curHeader.type, curHeader.selector))).or = - patNode, + (curHeader.next = + mk.Header(patNode.pos, curHeader.type, curHeader.selector))).or = + patNode, casted, env); } else if (next.or == null) { @@ -450,13 +450,13 @@ public class PatternMatcher extends PatternTool { */ protected PatternNode enter(Tree[] pats, PatternNode target, Symbol casted, CaseEnv env) { switch (target) { - case ConstrPat(Symbol newCasted): - casted = newCasted; - break; - case SequencePat(Symbol newCasted, int len): - casted = newCasted; - break; - } + case ConstrPat(Symbol newCasted): + casted = newCasted; + break; + case SequencePat(Symbol newCasted, int len): + casted = newCasted; + break; + } for (int i = 0; i < pats.length; i++) target = enter1(pats[i], i, target, casted, env); return target; @@ -464,25 +464,25 @@ public class PatternMatcher extends PatternTool { protected int nCaseComponents(Tree tree) { switch (tree) { - case Apply(Tree fn, _): - Type tpe = tree.type.symbol().primaryConstructor().type(); - //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor()); - switch (tpe) { - // I'm not sure if this is a good idea, but obviously, currently all case classes - // without constructor arguments have type NoType - case NoType: - assert false; - return 0; - case MethodType(Symbol[] args, _): - return args.length; - case PolyType(Symbol[] tvars, MethodType(Symbol[] args, _)): - return args.length; - case PolyType(Symbol[] tvars, _): - return 0; - default: - throw new ApplicationError("not yet implemented;" + - "pattern matching for " + tree + ": " + tpe); - } + case Apply(Tree fn, _): + Type tpe = tree.type.symbol().primaryConstructor().type(); + //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor()); + switch (tpe) { + // I'm not sure if this is a good idea, but obviously, currently all case classes + // without constructor arguments have type NoType + case NoType: + assert false; + return 0; + case MethodType(Symbol[] args, _): + return args.length; + case PolyType(Symbol[] tvars, MethodType(Symbol[] args, _)): + return args.length; + case PolyType(Symbol[] tvars, _): + return 0; + default: + throw new ApplicationError("not yet implemented;" + + "pattern matching for " + tree + ": " + tpe); + } } return 0; } @@ -506,20 +506,20 @@ public class PatternMatcher extends PatternTool { PatternNode node = patNode; while ((node = node.or) != null) { switch (node) { - case ConstantPat(_): - break; - default: - return false; + case ConstantPat(_): + break; + default: + return false; } switch (node.and) { - case Body(ValDef[][] bound, Tree[] guard, _): - if ((guard.length > 1) || - (guard[0] != Tree.Empty) || - (bound[0].length > 0)) - return false; - break; - default: - return false; + case Body(ValDef[][] bound, Tree[] guard, _): + if ((guard.length > 1) || + (guard[0] != Tree.Empty) || + (bound[0].length > 0)) + return false; + break; + default: + return false; } } patNode = patNode.next(); @@ -537,35 +537,35 @@ public class PatternMatcher extends PatternTool { while ((node = node.or) != null) { boolean isCase = false; switch (node) { - case VariablePat(Tree tree): - System.out.println(((tree.symbol().flags & Modifiers.CASE) != 0)); - break; - case ConstrPat(_): - System.out.println(node.type + " / " + ((node.type.symbol().flags & Modifiers.CASE) != 0)); - PatternNode inner = node.and; - outer: while (true) { - switch (inner) { - case Header(_, Header next): - if (next != null) - return false; - inner = inner.or; - break; - case DefaultPat(): - inner = inner.and; - break; - case Body(ValDef[][] bound, Tree[] guard, _): - if ((guard.length > 1) || - (guard[0] != Tree.Empty)) - return false; - break outer; - default: - System.out.println(inner); - return false; - } - } - break; - default: - return false; + case VariablePat(Tree tree): + System.out.println(((tree.symbol().flags & Modifiers.CASE) != 0)); + break; + case ConstrPat(_): + System.out.println(node.type + " / " + ((node.type.symbol().flags & Modifiers.CASE) != 0)); + PatternNode inner = node.and; + outer: while (true) { + switch (inner) { + case Header(_, Header next): + if (next != null) + return false; + inner = inner.or; + break; + case DefaultPat(): + inner = inner.and; + break; + case Body(ValDef[][] bound, Tree[] guard, _): + if ((guard.length > 1) || + (guard[0] != Tree.Empty)) + return false; + break outer; + default: + System.out.println(inner); + return false; + } + } + break; + default: + return false; } } patNode = patNode.next(); @@ -602,10 +602,10 @@ public class PatternMatcher extends PatternTool { int n = 0; while ((patNode = patNode.or) != null) switch (patNode) { - case DefaultPat(): - break; - default: - n++; + case DefaultPat(): + break; + default: + n++; } return n; } @@ -615,8 +615,8 @@ public class PatternMatcher extends PatternTool { PatternNode node = patNode; while ((node = node.or) != null) switch (node) { - case DefaultPat(): - return bodyToTree(node.and); + case DefaultPat(): + return bodyToTree(node.and); } patNode = patNode.next(); } @@ -636,70 +636,70 @@ public class PatternMatcher extends PatternTool { // for one case we use a normal if-then-else instruction else if (ncases == 1) { switch (root.and.or) { - case ConstantPat(AConstant value): - return gen.If(cf.Equals(selector, - gen.Literal(root.and.or.pos, value)), - bodyToTree(root.and.or.and), - defaultBody(root.and, matchError)); - default: - return generalSwitchToTree(); + case ConstantPat(AConstant value): + return gen.If(cf.Equals(selector, + gen.Literal(root.and.or.pos, value)), + bodyToTree(root.and.or.and), + defaultBody(root.and, matchError)); + default: + return generalSwitchToTree(); } } // // if we have more than 2 cases than use a switch statement switch (root.and) { - case Header(_, Header next): - TagBodyPair mappings = null; - Tree defaultBody = matchError; - PatternNode patNode = root.and; - while (patNode != null) { - PatternNode node = patNode.or; - while (node != null) { - switch (node) { - case DefaultPat(): - if (defaultBody != null) - throw new ApplicationError(); - defaultBody = bodyToTree(node.and); - node = node.or; - break; - case ConstantPat(INT(int value)): - mappings = insert( - value, - bodyToTree(node.and), - mappings); - node = node.or; - break; - default: - throw new ApplicationError(node.toString()); - } - } - patNode = patNode.next(); - } - if (mappings == null) { - return gen.Switch(selector, new int[0], new Tree[0], defaultBody, resultVar.getType()); - } else { - int n = mappings.length(); - int[] tags = new int[n]; - Tree[] bodies = new Tree[n]; - n = 0; - while (mappings != null) { - tags[n] = mappings.tag; - bodies[n++] = mappings.body; - mappings = mappings.next; - } - return gen.Switch(selector, tags, bodies, defaultBody, resultVar.getType()); - } - default: - throw new ApplicationError(); + case Header(_, Header next): + TagBodyPair mappings = null; + Tree defaultBody = matchError; + PatternNode patNode = root.and; + while (patNode != null) { + PatternNode node = patNode.or; + while (node != null) { + switch (node) { + case DefaultPat(): + if (defaultBody != null) + throw new ApplicationError(); + defaultBody = bodyToTree(node.and); + node = node.or; + break; + case ConstantPat(INT(int value)): + mappings = insert( + value, + bodyToTree(node.and), + mappings); + node = node.or; + break; + default: + throw new ApplicationError(node.toString()); + } + } + patNode = patNode.next(); + } + if (mappings == null) { + return gen.Switch(selector, new int[0], new Tree[0], defaultBody, resultVar.getType()); + } else { + int n = mappings.length(); + int[] tags = new int[n]; + Tree[] bodies = new Tree[n]; + n = 0; + while (mappings != null) { + tags[n] = mappings.tag; + bodies[n++] = mappings.body; + mappings = mappings.next; + } + return gen.Switch(selector, tags, bodies, defaultBody, resultVar.getType()); + } + default: + throw new ApplicationError(); } } protected Tree bodyToTree(PatternNode node) { switch (node) { - case Body(_, _, Tree[] body): - return body[0]; - default: - throw new ApplicationError(); + case Body(_, _, Tree[] body): + return body[0]; + default: + throw new ApplicationError(); } } @@ -723,34 +723,34 @@ public class PatternMatcher extends PatternTool { Tree res = gen.mkBooleanLit(node.pos, false); while (node != null) switch (node) { - case Header(Tree selector, Header next): - //res = cf.And(mkNegate(res), toTree(node.or, selector)); - //System.out.println("HEADER TYPE = " + selector.type); - if (optimize(node.type, node.or)) - res = cf.Or(res, toOptTree(node.or, selector)); - else - res = cf.Or(res, toTree(node.or, selector)); - node = next; - break; - case Body(ValDef[][] bound, Tree[] guard, Tree[] body): - if ((bound.length == 0) && - (guard.length == 0) && - (body.length == 0)) { - return gen.mkBooleanLit(node.pos, true); // cf.Or(res, gen.mkBooleanLit(node.pos, true)); - } else if (!doBinding) - bound = new ValDef[][]{new ValDef[]{}}; - for (int i = guard.length - 1; i >= 0; i--) { - Tree[] ts = bound[i]; - Tree res0 = gen.mkBlock(gen.Assign(gen.Ident(body[i].pos, resultVar), - body[i]), - gen.mkBooleanLit(body[i].pos, true)); - if (guard[i] != Tree.Empty) - res0 = cf.And(guard[i], res0); - res = cf.Or(gen.mkBlock(body[i].pos, ts, res0), res); - } - return res; - default: - throw new ApplicationError(); + case Header(Tree selector, Header next): + //res = cf.And(mkNegate(res), toTree(node.or, selector)); + //System.out.println("HEADER TYPE = " + selector.type); + if (optimize(node.type, node.or)) + res = cf.Or(res, toOptTree(node.or, selector)); + else + res = cf.Or(res, toTree(node.or, selector)); + node = next; + break; + case Body(ValDef[][] bound, Tree[] guard, Tree[] body): + if ((bound.length == 0) && + (guard.length == 0) && + (body.length == 0)) { + return gen.mkBooleanLit(node.pos, true); // cf.Or(res, gen.mkBooleanLit(node.pos, true)); + } else if (!doBinding) + bound = new ValDef[][]{new ValDef[]{}}; + for (int i = guard.length - 1; i >= 0; i--) { + Tree[] ts = bound[i]; + Tree res0 = gen.mkBlock(gen.Assign(gen.Ident(body[i].pos, resultVar), + body[i]), + gen.mkBooleanLit(body[i].pos, true)); + if (guard[i] != Tree.Empty) + res0 = cf.And(guard[i], res0); + res = cf.Or(gen.mkBlock(body[i].pos, ts, res0), res); + } + return res; + default: + throw new ApplicationError(); } return res; } @@ -761,16 +761,16 @@ public class PatternMatcher extends PatternTool { int cases = 0; while (alternatives != null) { switch (alternatives) { - case ConstrPat(_): - if (alternatives.type.symbol().isCaseClass()) - cases++; - else - return false; - break; - case DefaultPat(): - break; - default: - return false; + case ConstrPat(_): + if (alternatives.type.symbol().isCaseClass()) + cases++; + else + return false; + break; + case DefaultPat(): + break; + default: + return false; } alternatives = alternatives.or; } @@ -818,16 +818,16 @@ public class PatternMatcher extends PatternTool { PatternNode defaultCase = null; while (node != null) switch (node) { - case ConstrPat(Symbol casted): - cases = insertNode(node.type.symbol().tag(), node, cases); - node = node.or; - break; - case DefaultPat(): - defaultCase = node; - node = node.or; - break; - default: - throw new ApplicationError(); + case ConstrPat(Symbol casted): + cases = insertNode(node.type.symbol().tag(), node, cases); + node = node.or; + break; + case DefaultPat(): + defaultCase = node; + node = node.or; + break; + default: + throw new ApplicationError(); } int n = cases.length(); int[] tags = new int[n]; @@ -847,42 +847,42 @@ public class PatternMatcher extends PatternTool { } protected Tree toTree(PatternNode node, Tree selector) { - //System.err.println("pm.toTree("+node+","+selector+")"); + //System.err.println("pm.toTree("+node+","+selector+")"); if (node == null) return gen.mkBooleanLit(selector.pos, false); switch (node) { - case DefaultPat(): - return toTree(node.and); - case ConstrPat(Symbol casted): - return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.type), - gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.type)), - toTree(node.and)), - toTree(node.or, selector.duplicate())); - case SequencePat(Symbol casted, int len): - return gen.If(cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.type), - cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.duplicate(), node.type), - defs.SEQ_LENGTH())), - gen.mkIntLit(selector.pos, len))), - gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.type)), - toTree(node.and)), - toTree(node.or, selector.duplicate())); - case ConstantPat(AConstant value): - return gen.If(cf.Equals(selector.duplicate(), - gen.Literal(selector.pos, value)), - toTree(node.and), - toTree(node.or, selector.duplicate())); - case VariablePat(Tree tree): - return gen.If(cf.Equals(selector.duplicate(), tree), - toTree(node.and), - toTree(node.or, selector.duplicate())); - case AltPat(Header header): - return gen.If(toTree(header), - toTree(node.and), - toTree(node.or, selector.duplicate())); - default: - throw new ApplicationError(); + case DefaultPat(): + return toTree(node.and); + case ConstrPat(Symbol casted): + return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.type), + gen.mkBlock(gen.ValDef(casted, + gen.mkAsInstanceOf(selector.duplicate(), node.type)), + toTree(node.and)), + toTree(node.or, selector.duplicate())); + case SequencePat(Symbol casted, int len): + return gen.If(cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.type), + cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.duplicate(), node.type), + defs.SEQ_LENGTH())), + gen.mkIntLit(selector.pos, len))), + gen.mkBlock(gen.ValDef(casted, + gen.mkAsInstanceOf(selector.duplicate(), node.type)), + toTree(node.and)), + toTree(node.or, selector.duplicate())); + case ConstantPat(AConstant value): + return gen.If(cf.Equals(selector.duplicate(), + gen.Literal(selector.pos, value)), + toTree(node.and), + toTree(node.or, selector.duplicate())); + case VariablePat(Tree tree): + return gen.If(cf.Equals(selector.duplicate(), tree), + toTree(node.and), + toTree(node.or, selector.duplicate())); + case AltPat(Header header): + return gen.If(toTree(header), + toTree(node.and), + toTree(node.or, selector.duplicate())); + default: + throw new ApplicationError(); } } } diff --git a/sources/scalac/transformer/matching/RightTracerInScala.java b/sources/scalac/transformer/matching/RightTracerInScala.java index 5f25e0a083..a86b041bae 100644 --- a/sources/scalac/transformer/matching/RightTracerInScala.java +++ b/sources/scalac/transformer/matching/RightTracerInScala.java @@ -9,8 +9,6 @@ import scalac.ast.*; import scalac.symtab.*; import Tree.*; -import scalac.transformer.TransMatch.Matcher ; - import java.util.* ; import Scope.SymbolIterator; @@ -276,9 +274,9 @@ public class RightTracerInScala extends TracerInScala { //System.out.println("calling algebraic matcher on type:"+pat.type); //System.err.println( "curT"+currentElem().type().widen() ); - Matcher m = new Matcher( owner,//funSym,//this.funSym, - currentElem(), - defs.BOOLEAN_TYPE() ); + PartialMatcher m = new PartialMatcher( owner,//funSym,//this.funSym, + currentElem(), + defs.BOOLEAN_TYPE() ); final HashMap freshenMap = new HashMap(); // sym2exp -> new sym HashMap helpMap3 = new HashMap(); // new sym -> original sym diff --git a/sources/scalac/transformer/matching/SequenceMatcher.java b/sources/scalac/transformer/matching/SequenceMatcher.java index 64443dd9f0..5b0ff01ef4 100644 --- a/sources/scalac/transformer/matching/SequenceMatcher.java +++ b/sources/scalac/transformer/matching/SequenceMatcher.java @@ -7,7 +7,6 @@ import Tree.*; //import scala.compiler.printer.TextTreePrinter ; // DEBUGGING\ //import scala.compiler.printer.XMLAutomPrinter ; // DEBUGGING\ - import scalac.transformer.TransMatch.Matcher ; import scalac.ast.* ; import scalac.symtab.* ; @@ -26,7 +25,7 @@ public class SequenceMatcher extends PatternTool { final static Integer IGNORED = new Integer(42); CodeFactory cf; - Matcher _m; + PartialMatcher _m; //Tree pat[]; //Tree body[]; @@ -93,7 +92,7 @@ public class SequenceMatcher extends PatternTool { * becomes a ThrowMatchError then * @param doBinding flasg that indicates whether variables should be bound */ - public void construct( Matcher _m, + public void construct( PartialMatcher _m, Tree[] pat, Tree[] body, Tree defaultCase, @@ -151,7 +150,7 @@ public class SequenceMatcher extends PatternTool { defaultCase, newbody, _m.resultType ); - } // construct (Matcher, Tree[], Tree[], Tree, boolean ) + } // construct (PartialMatcher, Tree[], Tree[], Tree, boolean ) /** constructor, invoked by AlgebraicMatcher */ diff --git a/sources/scalac/transformer/matching/TracerInScala.java b/sources/scalac/transformer/matching/TracerInScala.java index b40444980d..d5d4177b40 100644 --- a/sources/scalac/transformer/matching/TracerInScala.java +++ b/sources/scalac/transformer/matching/TracerInScala.java @@ -1,18 +1,7 @@ package scalac.transformer.matching ; -import scalac.*; -import scalac.ast.*; -import scalac.symtab.*; -import Tree.*; -import scalac.util.Name; -import scalac.util.Names; - -import scalac.transformer.TransMatch.Matcher ; - -import java.util.* ; - -import scala.tools.util.Position; - +import scalac.symtab.Symbol; +import scalac.symtab.Type; /** 2do: factor common things of LeftTracerInScala and RightTracerInScala */ diff --git a/sources/scalac/transformer/matching/WordAutomInScala.java b/sources/scalac/transformer/matching/WordAutomInScala.java index 11a8853404..8fde263608 100644 --- a/sources/scalac/transformer/matching/WordAutomInScala.java +++ b/sources/scalac/transformer/matching/WordAutomInScala.java @@ -16,7 +16,6 @@ import scalac.ast.TreeGen; import scalac.symtab.Type; import scalac.symtab.Symbol; import scalac.symtab.Modifiers; // test -import scalac.transformer.TransMatch.Matcher; //import scalac.typechecker.*; import Tree.*; @@ -110,9 +109,9 @@ public class WordAutomInScala extends Autom2Scala { // calling the /*AlgebraicMatcher*/PatternMatcher here Tree _cur_match( Tree pat ) { // TE ST - Matcher m = new Matcher( this.owner, /* owner*/ - currentElem(), /* root */ - defs.BOOLEAN_TYPE() /* restype */); + PartialMatcher m = new PartialMatcher( this.owner, /* owner*/ + currentElem(), /* root */ + defs.BOOLEAN_TYPE() /* restype */); am.construct( m, new CaseDef[] { cf.gen.CaseDef( pat, |