summaryrefslogtreecommitdiff
path: root/sources/scalac
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2003-06-17 09:32:55 +0000
committerburaq <buraq@epfl.ch>2003-06-17 09:32:55 +0000
commit85d4773be7e8ba98bfe2e69a2483f88d5e085401 (patch)
tree8696f8cc53b3f377e341429d14a49d547ca06662 /sources/scalac
parentc4335d55bc2a71c1689b9f377c9f83b568b19db8 (diff)
downloadscala-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.java978
-rw-r--r--sources/scalac/transformer/PatternNode.java64
-rw-r--r--sources/scalac/transformer/TransMatch.java1
-rw-r--r--sources/scalac/transformer/matching/PatternMatcher.java2
-rw-r--r--sources/scalac/transformer/matching/PatternNode.java2
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.*;