diff options
author | buraq <buraq@epfl.ch> | 2003-06-17 09:32:55 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2003-06-17 09:32:55 +0000 |
commit | 85d4773be7e8ba98bfe2e69a2483f88d5e085401 (patch) | |
tree | 8696f8cc53b3f377e341429d14a49d547ca06662 /sources/scalac | |
parent | c4335d55bc2a71c1689b9f377c9f83b568b19db8 (diff) | |
download | scala-85d4773be7e8ba98bfe2e69a2483f88d5e085401.tar.gz scala-85d4773be7e8ba98bfe2e69a2483f88d5e085401.tar.bz2 scala-85d4773be7e8ba98bfe2e69a2483f88d5e085401.zip |
moved to subpackage matching
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/transformer/PatternMatcher.java | 978 | ||||
-rw-r--r-- | sources/scalac/transformer/PatternNode.java | 64 | ||||
-rw-r--r-- | sources/scalac/transformer/TransMatch.java | 1 | ||||
-rw-r--r-- | sources/scalac/transformer/matching/PatternMatcher.java | 2 | ||||
-rw-r--r-- | sources/scalac/transformer/matching/PatternNode.java | 2 |
5 files changed, 3 insertions, 1044 deletions
diff --git a/sources/scalac/transformer/PatternMatcher.java b/sources/scalac/transformer/PatternMatcher.java deleted file mode 100644 index 0e725ca302..0000000000 --- a/sources/scalac/transformer/PatternMatcher.java +++ /dev/null @@ -1,978 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.transformer; - -import ch.epfl.lamp.util.Position; - -import scalac.*; -import scalac.ast.*; -import scalac.util.*; -import scalac.symtab.*; -import scalac.typechecker.*; -import PatternNode.*; -import Tree.*; - - -public class PatternMatcher { - - public static final Name RESULT_N = Name.fromString("$result"); - public static final Name SCALA_N = Name.fromString("scala"); - public static final Name BOOLEAN_N = Name.fromString("Boolean"); - public static final Name AND_N = Name.fromString("$amp$amp"); - public static final Name OR_N = Name.fromString("$bar$bar"); - public static final Name NOT_N = Name.fromString("$bang"); - public static final Name EQUALS_N = Name.fromString("$eq$eq"); - public static final Name SCALA_MATCHERROR_N = Name.fromString("scala.MatchError"); - public static final Name MATCHERROR_N = Name.fromString("MatchError"); - public static final Name FAIL_N = Name.fromString("fail"); - public static final Name WILDCARD_N = Name.fromString("_"); - public static final Name LENGTH_N = Name.fromString("length"); - public static final Name AT_N = Name.fromString("at"); - - /** the current compilation unit - */ - Unit unit; - - /** the global fresh name creator - */ - FreshNameCreator fresh; - - /** the global tree factory - */ - TreeFactory make; - - /** the global definitions component - */ - Definitions defs; - - /** the global tree generation component - */ - TreeGen gen; - - /** type inference engine - */ - Infer infer; - - /** the owner of the pattern matching expression - */ - Symbol owner; - - /** the selector expression - */ - Tree selector; - - /** the root of the pattern node structure - */ - PatternNode root; - - /** the symbol of the result variable - */ - Symbol resultVar; - - /** the statics of class Boolean - */ - Symbol statics; - - - /** constructor - */ - public PatternMatcher(Unit unit, Infer infer, Symbol owner, Tree selector, Type tpe) { - this.unit = unit; - this.fresh = unit.global.freshNameCreator; - this.make = unit.global.make; - this.gen = unit.global.treeGen; - this.defs = unit.global.definitions; - this.owner = owner; - this.selector = selector; - this.root = makeConstrPat(selector.pos, - selector.type.widen()); - this.root.and = makeHeader(selector.pos, - selector.type.widen(), - make.Ident(selector.pos, - root.symbol().name) - .setType(selector.type.widen()) - .setSymbol(root.symbol())); - this.resultVar = new TermSymbol(selector.pos, - RESULT_N, - owner, - Modifiers.MUTABLE); - this.resultVar.setType(tpe); - this.statics = defs.getModule(Names.scala_Boolean); - this.infer = infer; - } - - /** return the analyzed type - */ - public Type typeOf(Symbol sym) { - return sym.type(); - //return sym.typeAt(unit.global.ANALYZER_PHASE.id); - } - - /** return the analyzed type - */ - public Type typeOf0(Symbol sym) { - return sym.typeAt(unit.global.PHASE.ANALYZER.id); - } - - /** factories - */ - public Header makeHeader(int pos, Type type, Tree selector) { - Header node = new Header(selector, null); - node.pos = pos; - node.type = type; - return node; - } - - public Body makeBody(int pos, ValDef[] bound, Tree guard, Tree body) { - Body node = new Body(new ValDef[][]{bound}, new Tree[]{guard}, new Tree[]{body}); - node.pos = pos; - return node; - } - - public void updateBody(Body tree, ValDef[] bound, Tree guard, Tree body) { - if (tree.guard[tree.guard.length - 1] == Tree.Empty) - unit.error(body.pos, "unreachable code"); - ValDef[][] bd = new ValDef[tree.bound.length + 1][]; - Tree[] ng = new Tree[tree.guard.length + 1]; - Tree[] nb = new Tree[tree.body.length + 1]; - System.arraycopy(tree.bound, 0, bd, 0, tree.bound.length); - System.arraycopy(tree.guard, 0, ng, 0, tree.guard.length); - System.arraycopy(tree.body, 0, nb, 0, tree.body.length); - bd[bd.length - 1] = bound; - ng[ng.length - 1] = guard; - nb[nb.length - 1] = body; - tree.bound = bd; - tree.guard = ng; - tree.body = nb; - } - - public DefaultPat makeDefaultPat(int pos, Type type) { - DefaultPat node = new DefaultPat(); - node.pos = pos; - node.type = type; - return node; - } - - public ConstrPat makeConstrPat(int pos, Type type) { - //System.out.println("making constructor pattern for " + type); - ConstrPat node = new ConstrPat(newVar(pos, type)); - node.pos = pos; - node.type = type; - return node; - } - - public SequencePat makeSequencePat(int pos, Type type, int len) { - Symbol sym = newVar(Position.NOPOS, type); - SequencePat node = new SequencePat(sym, len); - node.pos = pos; - node.type = type; - return node; - } - - public ConstantPat makeConstantPat(int pos, Type type, Object value) { - //System.out.println("making constant pattern for " + type + " of value " + value); - ConstantPat node = new ConstantPat(value); - node.pos = pos; - node.type = type; - return node; - } - - public VariablePat makeVariablePat(int pos, Tree tree) { - //System.out.println("making variable pattern for " + tree.type); - VariablePat node = new VariablePat(tree); - node.pos = pos; - node.type = tree.type; - return node; - } - - public TermSymbol newVar(int pos, Name name, Type type) { - TermSymbol sym = new TermSymbol(pos, name, owner, 0); - sym.setType(type); - return sym; - } - - public TermSymbol newVar(int pos, Type type) { - return newVar(pos, fresh.newName("temp"), type); - } - - public Tree copy(Tree tree) { - return tree; // insert copy function here - } - - /** pretty printer - */ - public void print() { - print(root.and, ""); - } - - public void print(PatternNode patNode, String indent) { - if (patNode == null) - 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(Object 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 Body(_, _, Tree[] stats): - System.out.println(indent + "BODY(" + stats.length + ")"); - break; - } - } - - public void enter(CaseDef tree) { - enter(tree.pos, tree.pat, tree.guard, tree.body); - } - - protected CaseEnv enter(int pos, Tree pat, Tree guard, Tree body) { - CaseEnv env = new CaseEnv(); - //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 = makeBody(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"); - return env; - } - - public PatternNode match(Tree pat, PatternNode target) { - // advance one step in pattern - PatternNode next = target.and; - // we are done (no match yet) - if (next == null) - return null; - // check if matched - switch (next) { - case Body(_, _, _): - return next; - case Header(_, _): - Header header = (Header)next; - // get pattern arguments - Tree[] patArgs = patternArgs(pat); - // get next pattern node - PatternNode patNode = patternNode(pat, header, null); - do { - next = header; - while ((next = next.or) != null) - if (superPat(next, patNode) && - ((target = match(patArgs, next)) != null)) - return target; - else if (isDefaultPat(next)) - return next.and; - } while ((header = header.next) != null); - return null; - default: - throw new ApplicationError(); - } - } - - public PatternNode match(Tree[] pats, PatternNode target) { - for (int i = 0; i < pats.length; i++) - if ((target = match(pats[i], target)) == null) - return null; - return target; - } - - protected Tree[] patternArgs(Tree tree) { - switch (tree) { - case Apply(_, Tree[] args): - if (args.length == 1 && (tree.type.symbol().flags & Modifiers.CASE) == 0) - switch (args[0]) { - case Sequence(Tree[] ts): - return ts; - } - return args; - case Sequence(Tree[] ts): - return ts; - default: - return Tree.EMPTY_ARRAY; - } - } - - protected Type getConstrType(Type tpe) { - return tpe; - /* - switch (tpe) { - case ConstructorType(Type result): - return result; - default: - return tpe; - } */ - } - - protected Type getHeaderType(Type tpe) { - switch (tpe) { - case PolyType(_, Type res): - return res; - default: - return tpe; - } - } - - 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 makeSequencePat(tree.pos, tree.type, ts.length); - } - return makeConstrPat(tree.pos, getConstrType(tree.type)); - case Typed(Ident(Name name), Tree tpe): // variable pattern - PatternNode node = - (header.type.isSubType(getConstrType(tpe.type))) ? - makeDefaultPat(tree.pos, getConstrType(tpe.type)) - : makeConstrPat(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 makeConstrPat(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 makeDefaultPat(tree.pos, getConstrType(header.type)); - } else - return makeVariablePat(tree.pos, tree); - case Select(_, Name name): // variable - if (tree.symbol().isPrimaryConstructor()) - return makeConstrPat(tree.pos, getConstrType(tree.type)); - else - return makeVariablePat(tree.pos, tree); - case Literal(Object value): - return makeConstantPat(tree.pos, getConstrType(tree.type), value); - case Sequence(Tree[] ts): - return makeSequencePat(tree.pos, tree.type, ts.length); - default: - new scalac.ast.printer.TextTreePrinter().print(tree).flush(); - throw new ApplicationError(tree); - } - } - - protected boolean superPat(PatternNode p, PatternNode q) { - switch (p) { - case DefaultPat(): - switch (q) { - case DefaultPat(): - return true; - //case ConstantPat(_, _): - // return q.type.isSubType(p.type); - } - return false; - case ConstrPat(_): - switch (q) { - case ConstrPat(_): - return q.type.isSubType(p.type); - } - return false; - case SequencePat(_, int plen): - switch (q) { - case SequencePat(_, int qlen): - return (plen == qlen) && q.type.isSubType(p.type); - } - return false; - case ConstantPat(Object pval): - switch (q) { - case ConstantPat(Object qval): - return pval.equals(qval); - } - return false; - case VariablePat(Tree tree): - switch (q) { - case VariablePat(Tree other): - return (tree.symbol() != null) && - (tree.symbol().kind != Kinds.NONE) && - (tree.symbol().kind != Kinds.ERROR) && - (tree.symbol() == other.symbol()); - } - return false; - } - return false; - } - - protected boolean isDefaultPat(PatternNode p) { - switch (p) { - case DefaultPat(): - return true; - default: - return false; - } - } - - public PatternNode enter(Tree pat, - 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); - } - } - - public PatternNode enter1(Tree pat, - int index, - PatternNode target, - Symbol casted, - CaseEnv env) { - //System.out.println("enter(" + pat + ", " + index + ", " + target + ", " + casted + ")"); - // get pattern arguments - Tree[] patArgs = patternArgs(pat); - // get case fields - //assert patArgs.length == nCaseComponents(pat); - // advance one step in pattern - Header curHeader = (Header)target.and; - // check if we have to add a new header - if (curHeader == null) { - assert index >= 0 : casted; - if (casted.pos == Position.NOPOS) { - Symbol atSym = casted.type().lookup(AT_N); - //System.out.println("casted type = " + typeOf(casted)); - Type seqType = casted.type().baseType(defs.SEQ_CLASS).typeArgs()[0]; - Tree t = make.Select( - pat.pos, - make.Ident(pat.pos, casted.name) - .setType(typeOf(casted)) - .setSymbol(casted), - AT_N); - switch (typeOf(atSym)) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - infer.methodAlternative(t, alts, alttypes, - new Type[]{defs.INT_TYPE}, seqType); - t = make.Apply(pat.pos, t, - new Tree[]{ - make.Literal(pat.pos, new Integer(index)) - .setType(defs.INT_TYPE) - }).setType(seqType); - break; - default: - t.setSymbol(atSym); - t.setType(typeOf(atSym)); - t = make.Apply(pat.pos, t, - new Tree[]{ - make.Literal(pat.pos, new Integer(index)) - .setType(defs.INT_TYPE) - }).setType(seqType); - } - target.and = curHeader = makeHeader(pat.pos, seqType, t); - } else { - Symbol ts = ((ClassSymbol) casted.type().symbol()) - .caseFieldAccessor(index); -// target.and = curHeader = makeHeader( -// pat.pos, -// getHeaderType(typeOf0(ts)), -// make.Select( -// pat.pos, -// make.Ident(pat.pos, casted.name) -// .setType(typeOf(casted)) -// .setSymbol(casted), -// ts.name) -// .setType(getHeaderType(typeOf0(ts))) -// .setSymbol(ts)); - target.and = curHeader = makeHeader( - pat.pos, - getHeaderType(typeOf0(ts)), - make.Apply( - pat.pos, - make.Select( - pat.pos, - make.Ident(pat.pos, casted.name) - .setType(typeOf(casted)) - .setSymbol(casted), - ts.name) - .setType(Type.MethodType( - Symbol.EMPTY_ARRAY, - getHeaderType(typeOf0(ts)))) - .setSymbol(ts), - Tree.EMPTY_ARRAY).setType(getHeaderType(typeOf0(ts)))); - } - curHeader.or = patternNode(pat, curHeader, env); - return enter(patArgs, curHeader.or, casted, env); - } - // find most recent header - while (curHeader.next != null) - curHeader = curHeader.next; - // create node - PatternNode patNode = patternNode(pat, curHeader, env); - PatternNode next = curHeader; - // enter node - while (true) - if (superPat(next, patNode)) - return enter(patArgs, next, casted, env); - else if (isDefaultPat(next) || - ((next.or == null) && isDefaultPat(patNode))) - return enter( - patArgs, - (curHeader = (curHeader.next = - makeHeader(patNode.pos, curHeader.type, curHeader.selector))).or - = patNode, - casted, - env); - else if (next.or == null) - return enter(patArgs, next.or = patNode, casted, env); - else - next = next.or; - } - - public 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; - } - for (int i = 0; i < pats.length; i++) - target = enter1(pats[i], i, target, casted, env); - return target; - } - - protected int nCaseComponents(Tree tree) { - switch (tree) { - case Apply(Tree fn, _): - Type tpe = typeOf(tree.type.symbol().constructor()); - //System.out.println("~~~ " + tree.type() + ", " + tree.type().symbol().constructor()); - 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: - 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; - } - - -//////////// generator methods - - public Tree toTree() { - TreeList ts = new TreeList(); - ts.append( - make.ValDef(selector.pos, - 0, - root.symbol().name, - gen.mkType(selector.pos, selector.type), - selector).setType(defs.UNIT_TYPE).setSymbol(root.symbol())); - ts.append( - make.ValDef(selector.pos, - Modifiers.MUTABLE, - resultVar.name, - gen.mkType(selector.pos, typeOf(resultVar)), - Tree.Empty).setType(defs.UNIT_TYPE).setSymbol(resultVar)); - ts.append( - make.If( - selector.pos, - toTree(root.and), - make.Ident(selector.pos, - resultVar.name).setType(typeOf(resultVar)).setSymbol(resultVar), - mkThrowMatchError(selector.pos, typeOf(resultVar))).setType(typeOf(resultVar))); - return mkBlock(selector.pos, ts.toArray(), typeOf(resultVar)); - } - - protected Tree toTree(PatternNode node) { - Tree res = gen.mkBooleanLit(node.pos, false); - while (node != null) - switch (node) { - case Header(Tree selector, Header next): - //res = mkAnd(mkNegate(res), toTree(node.or, selector)); - //System.out.println("HEADER TYPE = " + selector.type); - res = mkOr(res, toTree(node.or, selector)); - node = next; - break; - case Body(ValDef[][] bound, Tree[] guard, Tree[] body): - for (int i = guard.length - 1; i >= 0; i--) { - Tree[] ts = new Tree[bound[i].length + 1]; - System.arraycopy(bound[i], 0, ts, 0, bound[i].length); - ts[bound[i].length] = mkBlock(body[i].pos, - new Tree[]{ - make.Assign( - body[i].pos, - make.Ident(body[i].pos, resultVar.name) - .setType(typeOf(resultVar)).setSymbol(resultVar), - body[i]).setType(defs.UNIT_TYPE), - gen.mkBooleanLit(body[i].pos, true) - }, defs.BOOLEAN_TYPE); - if (guard[i] != Tree.Empty) - ts[bound[i].length] = mkAnd(guard[i], ts[bound[i].length]); - res = mkOr(mkBlock(body[i].pos, ts, defs.BOOLEAN_TYPE), res); - } - return res; - default: - throw new ApplicationError(); - } - return res; - } - - protected Tree toTree(PatternNode node, Tree selector) { - if (node == null) - return gen.mkBooleanLit(selector.pos, false); - switch (node) { - case DefaultPat(): - return toTree(node.and); - case ConstrPat(Symbol casted): - return make.If( - selector.pos, - mkIs(selector.duplicate(), node.type), - mkBlock(selector.pos, - new Tree[]{ - make.ValDef(selector.pos, - 0, - casted.name, - gen.mkType(selector.pos, node.type), - mkAs(selector.duplicate(), node.type)) - .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): - Symbol lenSym = casted.type().lookup(LENGTH_N); - Tree t = make.Select(selector.pos, mkAs(selector.duplicate(), node.type), LENGTH_N); - switch (typeOf(lenSym)) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - infer.methodAlternative(t, alts, alttypes, new Type[0], defs.INT_TYPE); - break; - default: - t.setSymbol(lenSym); - t.setType(typeOf(lenSym)); - } - return make.If( - selector.pos, - mkAnd( - mkIs(selector.duplicate(), node.type), - mkEquals( - make.Apply( - selector.pos, t, - Tree.EMPTY_ARRAY).setType(defs.INT_TYPE), - make.Literal(selector.pos, new Integer(len)) - .setType(defs.INT_TYPE))), - mkBlock(selector.pos, - new Tree[]{ - make.ValDef(selector.pos, - 0, - casted.name, - gen.mkType(selector.pos, node.type), - mkAs(selector.duplicate(), node.type)) - .setType(defs.UNIT_TYPE).setSymbol(casted), - toTree(node.and)}, defs.BOOLEAN_TYPE), - toTree(node.or, selector.duplicate())) - .setType(defs.BOOLEAN_TYPE); - case ConstantPat(Object value): - return make.If( - selector.pos, - mkEquals(selector.duplicate(), - make.Literal(selector.pos, value) - .setType(node.type)), - toTree(node.and), - toTree(node.or, selector.duplicate())).setType(defs.BOOLEAN_TYPE); - case VariablePat(Tree tree): - return make.If( - selector.pos, - mkEquals(selector.duplicate(), tree), - toTree(node.and), - toTree(node.or, selector.duplicate())).setType(defs.BOOLEAN_TYPE); - default: - throw new ApplicationError(); - } - } - - protected Tree mkBlock(int pos, Tree[] ts, Type tpe) { - if (ts.length == 1) - return ts[0]; - else if (ts.length > 1) - switch (ts[ts.length - 1]) { - case Block(Tree[] ts0): - Tree[] ts1 = new Tree[ts0.length + ts.length - 1]; - System.arraycopy(ts, 0, ts1, 0, ts.length - 1); - System.arraycopy(ts0, 0, ts1, ts.length - 1, ts0.length); - return mkBlock(pos, ts1, tpe); - } - return make.Block(pos, ts).setType(tpe); - } - - protected Tree mkNegate(Tree tree) { - switch (tree) { - case Literal(Object value): - return gen.mkBooleanLit(tree.pos, !((Boolean)value).booleanValue()); - } - return make.Apply( - tree.pos, - gen.Select(tree, NOT_N), - Tree.EMPTY_ARRAY).setType(defs.BOOLEAN_TYPE); - } - - protected Tree mkAnd(Tree left, Tree right) { - switch (left) { - case Literal(Object value): - return ((Boolean)value).booleanValue() ? right : left; - } - switch (right) { - case Literal(Object value): - if (((Boolean)value).booleanValue()) return left; - } - Symbol fun = left.type.lookup(AND_N); - return make.Apply( - left.pos, - make.Select( - left.pos, - left, - AND_N).setType(typeOf(fun)).setSymbol(fun), - new Tree[]{right}).setType(defs.BOOLEAN_TYPE); - } - - protected Tree mkOr(Tree left, Tree right) { - switch (left) { - case Literal(Object value): - return ((Boolean)value).booleanValue() ? left : right; - } - switch (right) { - case Literal(Object value): - if (!((Boolean)value).booleanValue()) return left; - } - Symbol fun = left.type.lookup(OR_N); - return make.Apply( - left.pos, - make.Select( - left.pos, - left, - OR_N).setType(typeOf(fun)).setSymbol(fun), - new Tree[]{right}).setType(defs.BOOLEAN_TYPE); - } - - protected Tree mkIs(Tree tree, Type type) { - return - make.Apply( - tree.pos, - make.TypeApply( - tree.pos, - make.Select( - tree.pos, - tree, - defs.IS.name).setType(typeOf(defs.IS)).setSymbol(defs.IS), - new Tree[]{gen.mkType(tree.pos, type)}) - .setType(Type.MethodType(Symbol.EMPTY_ARRAY, defs.BOOLEAN_TYPE)), - Tree.EMPTY_ARRAY).setType(defs.BOOLEAN_TYPE); - } - - protected Tree mkAs(Tree tree, Type type) { - return - make.Apply( - tree.pos, - make.TypeApply( - tree.pos, - make.Select( - tree.pos, - tree, - defs.AS.name).setType(typeOf(defs.AS)).setSymbol(defs.AS), - new Tree[]{gen.mkType(tree.pos, type)}) - .setType(Type.MethodType(Symbol.EMPTY_ARRAY, type)), - Tree.EMPTY_ARRAY).setType(type); - } - - protected Tree mkEquals(Tree left, Tree right) { - Symbol fun = left.type.lookup(EQUALS_N); - switch (typeOf(fun)) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - //System.out.println("**** " + left.type); - Tree t = make.Select(left.pos, left, EQUALS_N); - //for (int i = 0; i < alttypes.length; i++) - // System.out.println(alts[i] + ": " + alttypes[i]); - infer.methodAlternative(t, alts, alttypes, - new Type[]{right.type}, defs.BOOLEAN_TYPE); - return make.Apply(left.pos, t, new Tree[]{right}).setType(defs.BOOLEAN_TYPE); - default: - //System.out.println("#### " + left.type + ": " + fun); - return make.Apply( - left.pos, - make.Select( - left.pos, - left, - EQUALS_N).setType(typeOf(fun)).setSymbol(fun), - new Tree[]{right}).setType(defs.BOOLEAN_TYPE); - } - } - - protected Tree mkThrowMatchError(int pos, Type type) { - Symbol matchErrorModule = defs.SCALA.members().lookup(MATCHERROR_N); - outer: switch (typeOf(matchErrorModule)) { - case OverloadedType(Symbol[] alts, Type[] alttypes): - for (int i = 0; i < alts.length; i++) - switch (alttypes[i]) { - case TypeRef(_, _, _): - matchErrorModule = alts[i]; - break outer; - } - } - Symbol failMethod = typeOf(matchErrorModule).lookup(FAIL_N); - return - make.Apply( - pos, - make.TypeApply( - pos, - make.Select( - pos, - make.Select( - pos, - make.Ident(pos, Names.scala).setType(typeOf(defs.SCALA)).setSymbol(defs.SCALA), - MATCHERROR_N) - .setSymbol(matchErrorModule) - .setType(typeOf(matchErrorModule)), - FAIL_N).setType(typeOf(failMethod)).setSymbol(failMethod), - new Tree[]{gen.mkType(pos, type)}) - .setType(((Type.PolyType) typeOf(failMethod)).result.subst( - typeOf(failMethod).typeParams(), - new Type[]{type})), - new Tree[]{ - make.Literal(pos, unit.toString()).setType(defs.STRING_TYPE), - make.Literal(pos, new Integer(Position.line(pos))).setType(defs.INT_TYPE) - }).setType(type); - } - - class CaseEnv { - protected ValDef[] boundVars = new ValDef[4]; - protected int numVars = 0; - - public void newBoundVar(int pos, Symbol sym, Type type, Tree init) { - sym.setOwner(PatternMatcher.this.owner); // FIXME should be corrected earlier - if (numVars == boundVars.length) { - ValDef[] newVars = new ValDef[numVars * 2]; - System.arraycopy(boundVars, 0, newVars, 0, numVars); - boundVars = newVars; - } - sym.setType(type); - boundVars[numVars++] = (ValDef)make.ValDef( - pos, - 0, - sym.name, - gen.mkType(pos, type), - init.duplicate()).setType(defs.UNIT_TYPE).setSymbol(sym); - } - - public ValDef[] boundVars() { - ValDef[] newVars = new ValDef[numVars]; - System.arraycopy(boundVars, 0, newVars, 0, numVars); - return newVars; - } - - public boolean equals(Object obj) { - if (!(obj instanceof CaseEnv)) - return false; - CaseEnv env = (CaseEnv)obj; - if (env.numVars != numVars) - return false; - for (int i = 0; i < numVars; i++) - if ((boundVars[i].name != env.boundVars[i].name) || - !boundVars[i].tpe.type.isSameAs(env.boundVars[i].tpe.type) || - (boundVars[i].rhs != env.boundVars[i].rhs)) - return false; - return true; - } - } -} diff --git a/sources/scalac/transformer/PatternNode.java b/sources/scalac/transformer/PatternNode.java deleted file mode 100644 index e4abdae047..0000000000 --- a/sources/scalac/transformer/PatternNode.java +++ /dev/null @@ -1,64 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ - -package scalac.transformer; - -import ch.epfl.lamp.util.Position; -import scalac.*; -import scalac.ast.*; -import scalac.symtab.*; -import scalac.typechecker.*; - - -public class PatternNode { - public int pos = Position.NOPOS; - public Type type; - 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 DefaultPat(); - public case ConstrPat(Symbol casted); - public case SequencePat(Symbol casted, int len); - public case ConstantPat(Object value); - public case VariablePat(Tree tree); - - - public Symbol symbol() { - switch (this) { - case ConstrPat(Symbol casted): - return casted; - case SequencePat(Symbol casted, _): - return casted; - default: - return Symbol.NONE; - } - } - - public String toString() { - switch (this) { - case Header(Tree selector, Header next): - return "Header(" + selector + ")"; - case Body(_, _, _): - return "Body"; - case DefaultPat(): - return "DefaultPat"; - case ConstrPat(Symbol casted): - return "ConstrPat(" + casted + ")"; - case SequencePat(Symbol casted, int len): - return "SequencePat(" + casted + ", " + len + ")"; - case ConstantPat(Object value): - return "ConstantPat(" + value + ")"; - case VariablePat(Tree tree): - return "VariablePat"; - default: - return "<unknown pat>"; - } - } -} diff --git a/sources/scalac/transformer/TransMatch.java b/sources/scalac/transformer/TransMatch.java index d986ffaf4f..ab3182c50e 100644 --- a/sources/scalac/transformer/TransMatch.java +++ b/sources/scalac/transformer/TransMatch.java @@ -17,6 +17,7 @@ import scalac.typechecker.*; import scalac.util.*; import Tree.*; +import scalac.transformer.matching.PatternMatcher ; /** A transformer for expanding match expressions into * flat sequences of .is and .as method calls diff --git a/sources/scalac/transformer/matching/PatternMatcher.java b/sources/scalac/transformer/matching/PatternMatcher.java index 0e725ca302..437e51a80c 100644 --- a/sources/scalac/transformer/matching/PatternMatcher.java +++ b/sources/scalac/transformer/matching/PatternMatcher.java @@ -6,7 +6,7 @@ ** $Id$ \* */ -package scalac.transformer; +package scalac.transformer.matching; import ch.epfl.lamp.util.Position; diff --git a/sources/scalac/transformer/matching/PatternNode.java b/sources/scalac/transformer/matching/PatternNode.java index e4abdae047..f75600c98f 100644 --- a/sources/scalac/transformer/matching/PatternNode.java +++ b/sources/scalac/transformer/matching/PatternNode.java @@ -6,7 +6,7 @@ ** $Id$ \* */ -package scalac.transformer; +package scalac.transformer.matching; import ch.epfl.lamp.util.Position; import scalac.*; |