summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2005-05-27 17:57:30 +0000
committerburaq <buraq@epfl.ch>2005-05-27 17:57:30 +0000
commit958dd64c52fd7e1555b6d179474cfe1c6d025014 (patch)
treec6e0452882e218fe01acc9f31c6dd066f4cf11bc /sources
parentc20c973f9fda2ed1833122132e84d83636df1a53 (diff)
downloadscala-958dd64c52fd7e1555b6d179474cfe1c6d025014.tar.gz
scala-958dd64c52fd7e1555b6d179474cfe1c6d025014.tar.bz2
scala-958dd64c52fd7e1555b6d179474cfe1c6d025014.zip
hello
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/nsc/matching/CodeFactory.scala307
-rw-r--r--sources/scala/tools/nsc/matching/PatternMatcher.scala379
-rw-r--r--sources/scala/tools/nsc/matching/PatternNode.scala276
-rw-r--r--sources/scala/tools/nsc/matching/PatternNodeCreator.scala18
-rw-r--r--sources/scala/tools/nsc/matching/PatternUtil.scala19
-rw-r--r--sources/scala/tools/nsc/matching/TransMatcher.scala6
-rwxr-xr-xsources/scala/tools/nsc/symtab/Definitions.scala15
7 files changed, 633 insertions, 387 deletions
diff --git a/sources/scala/tools/nsc/matching/CodeFactory.scala b/sources/scala/tools/nsc/matching/CodeFactory.scala
index 99226d2bbd..fa2d2dfe95 100644
--- a/sources/scala/tools/nsc/matching/CodeFactory.scala
+++ b/sources/scala/tools/nsc/matching/CodeFactory.scala
@@ -3,6 +3,7 @@
*/
package scala.tools.nsc.matching ;
+import scala.tools.util.Position;
abstract class CodeFactory extends PatternUtil {
@@ -31,244 +32,164 @@ abstract class CodeFactory extends PatternUtil {
return result ;
}
- /** returns `List[ Tuple2[ scala.Int, <elemType> ] ]'
- def SeqTraceType( elemType: Type ): Type = {
- definitions.LIST_TYPE(pairType(definitions.int_TYPE(), elemType));
- }
- */
+ /** returns code `<seqObj>.elements' */
+ def newIterator( seqObj:Tree ): Tree =
+ Apply(Select(seqObj, newTermName("elements")), List());
- /** returns `Iterator[ elemType ]'
- def _seqIterType( elemType: Type ): Type = {
- definitions.ITERATOR_TYPE(elemType);
- }
- */
-
- /** returns `<seqObj.elements>' */
- def newIterator( seqObj:Tree , elemType:Type ): Tree = {
- typed(
- Apply(Select(seqObj, Name("elements")), Nil)
- )
- //gen.mkApply__(gen.Select(seqObj, definitions.ITERABLE_ELEMENTS()));
- }
- /** returns code `<seqObj>.elements'
- * the parameter needs to have type attribute `Sequence[<elemType>]'
- */
- def newIterator( seqObj:Tree ): Tree = {
- newIterator( seqObj, getElemType_Sequence( seqObj.tpe ));
- }
+ /** `it.next()' */
+ def _next(iter: Tree) =
+ Apply(Select(iter, definitions.Iterator_next), List());
- /** returns A for T <: Sequence[ A ]
- */
- def getElemType_Sequence( tpe: Type): Type = {
- //System.err.println("getElemType_Sequence("+tpe.widen+")");
- val tpe1 = tpe.widen.baseType( definitions.IteratorClass );
- if( tpe1 == NoType )
- throw new ApplicationError("arg "+tpe+" not subtype of Seq[ A ]");
+ /** `it.hasNext()' */
+ def _hasNext(iter: Tree) =
+ Apply(Select(iter, definitions.Iterator_hasNext), List());
- return tpe1.typeArgs()( 0 );
- }
- /** returns A for T <: Iterator[ A ]
- */
- def getElemType_Iterator( tpe: Type ): Type = {
- //System.err.println("getElemType_Iterator("+tpe+")");
+ /** `!it.hasCur()' */
+ def _not_hasNext( iter:Tree ) =
+ Apply(Select(_hasNext(iter), definitions.Boolean_not), List());
- val tpe1 = tpe.widen.baseType( definitions.IteratorClass );
- tpe1 match {
- case Type.TypeRef(_,_,args) =>
- return args( 0 );
- case _ =>
- throw new ApplicationError("arg "+tpe+" not subtype of Iterator[ A ]");
- }
+ /** `trace.isEmpty' */
+ def isEmpty( iter: Tree ): Tree =
+ Apply(Select(iter, definitions.List_isEmpty), List());
- }
- /** `it.next()'
- */
- def _next( iter: Tree ): Tree = {
- gen.mkApply__(gen.Select(iter, definitions.ITERATOR_NEXT()));
+ def SeqTrace_headElem( arg: Tree ) = { // REMOVE SeqTrace
+ val t = Apply(Select(arg, definitions.List_head), List());
+ Apply(Select(t, definitions.tupleField(2,2)),List())
}
- /** `it.hasNext()'
- */
- def _hasNext( iter: Tree ): Tree = {
- gen.mkApply__(gen.Select(iter, definitions.ITERATOR_HASNEXT()));
- }
-
- /** `!it.hasCur()'
- */
- def _not_hasNext( iter:Tree ): Tree = {
- gen.mkApply__(gen.Select(_hasNext(iter), definitions.BOOLEAN_NOT()));
+ def SeqTrace_headState( arg: Tree ) = { // REMOVE SeqTrace
+ val t = Apply(Select(arg, definitions.List_head), List());
+ Apply(Select(t, definitions.tupleField(2,1)),List())
}
- /** `trace.isEmpty'
- */
- def isEmpty( iter: Tree ): Tree = {
- gen.mkApply__(gen.Select(iter, definitions.LIST_ISEMPTY()));
- }
+ def SeqTrace_tail( arg: Tree ): Tree = // REMOVE SeqTrace
+ Apply(Select(arg, definitions.List_tail), List());
- def SeqTrace_headElem( arg: Tree ): Tree = { // REMOVE SeqTrace
- val t = gen.mkApply__(gen.Select(arg, definitions.LIST_HEAD()));
- gen.mkApply__(gen.Select(t, definitions.TUPLE_FIELD(2, 2)));
- }
+ /** `arg.head' */
+ def SeqList_head( arg: Tree ) =
+ Apply(Select(arg, definitions.List_head), List());
- def SeqTrace_headState( arg: Tree ): Tree = { // REMOVE SeqTrace
- val t = gen.mkApply__(gen.Select(arg, definitions.LIST_HEAD()));
- gen.mkApply__(gen.Select(t, definitions.TUPLE_FIELD(2, 1)));
+ def Negate(tree: Tree) = tree match {
+ case Literal(value:Boolean)=>
+ Literal(!value)
+ case _ =>
+ Apply(Select(tree, definitions.Boolean_not), List());
}
- def SeqTrace_tail( arg: Tree ): Tree = { // REMOVE SeqTrace
- gen.mkApply__(gen.Select(arg, definitions.LIST_TAIL()));
- }
-
- /** `<seqlist>.head()'
- */
- def SeqList_head( arg: Tree ): Tree = {
- gen.mkApply__(gen.Select(arg, definitions.LIST_HEAD()));
- }
-
- def Negate(tree: Tree): Tree = {
- tree match {
- case Literal(BOOLEAN(value))=>
- gen.mkBooleanLit(tree.pos, !value);
- case _ =>
- gen.mkApply__(gen.Select(tree, definitions.BOOLEAN_NOT()));
- }
- }
-
- /*protected*/ def And(left: Tree, right: Tree): Tree = {
- left match {
- case Literal(BOOLEAN(value)) =>
- return if(value) right else left;
- case _ =>
- }
- right match {
- case Literal(BOOLEAN(value)) =>
- if (value) return left;
- case _ =>
- }
- gen.mkApply_V(gen.Select(left, definitions.BOOLEAN_AND()), Predef.Array[Tree](right));
+ /*protected*/ def And(left: Tree, right: Tree): Tree = left match {
+ case Literal(value:Boolean) =>
+ if(value) right else left;
+ case _ =>
+ right match {
+ case Literal(true) =>
+ left;
+ case _ =>
+ Apply(Select(left, definitions.Boolean_and), List(right));
+ }
}
- /*protected*/ def Or(left: Tree, right: Tree): Tree = {
- left match {
- case Literal(BOOLEAN(value))=>
- return if(value) left else right;
- case _ =>
- }
- right match {
- case Literal(BOOLEAN(value)) =>
- if (!value) return left;
+ /*protected*/ def Or(left: Tree, right: Tree): Tree = left match {
+ case Literal(value: Boolean)=>
+ if(value) left else right;
case _ =>
- }
- gen.mkApply_V(gen.Select(left, definitions.BOOLEAN_OR()), Predef.Array[Tree](right));
+ right match {
+ case Literal(false) =>
+ left;
+ case _ =>
+ Apply(Select(left, definitions.Boolean_or), List(right));
+ }
}
// used by Equals
- private def getCoerceToInt(left: Type): Symbol = {
- val sym = left.lookupNonPrivate(Names.coerce);
+ private def getCoerceToInt(left: Type): Symbol = {
+ val sym = left.nonPrivateMember( nme.coerce );
//assert sym != Symbol.NONE : Debug.show(left);
- val syms = sym.alternativeSymbols();
- var i = 0; while( i < syms.length) {
- syms(i).info() match {
- case Type.MethodType(vparams, restpe) =>
- if (vparams.length == 0 && restpe.isSameAs(definitions.INT_TYPE()))
- return syms(i);
- case _ =>
+
+ sym.alternatives.find {
+ x => x.info match {
+ case MethodType(vparams, restpe) =>
+ vparams.length == 0 && isSameType(restpe,definitions.IntClass.info)
}
- i = i + 1;
- }
- //assert false : Debug.show(left);
- throw new ApplicationError(left);
+ }.get
}
// used by Equals
private def getEqEq(left: Type, right: Type): Symbol = {
- val sym = left.lookupNonPrivate(Names.EQEQ);
+ val sym = left.nonPrivateMember( nme.EQEQ );
+
//assert sym != Symbol.NONE
// : Debug.show(left) + "::" + Debug.show(left.members());
+
var fun: Symbol = null;
- var ftype:Type = definitions.ANY_TYPE();
- val syms = sym.alternativeSymbols();
- var i = 0; while(i < syms.length) {
- val vparams = syms(i).valueParams();
- if (vparams.length == 1) {
- val vptype = vparams(0).info();
- if (right.isSubType(vptype) && vptype.isSubType(ftype)) {
- fun = syms(i);
- ftype = vptype;
+ var ftype:Type = definitions.AnyClass.info;
+
+ sym.alternatives.foreach {
+ x =>
+ val vparams = x.info.paramTypes;
+ if (vparams.length == 1) {
+ val vptype = vparams(0);
+ if (isSubType(right, vptype) && isSubType(vptype, ftype)) {
+ fun = x;
+ ftype = vptype;
+ }
}
- }
- i = i + 1
}
//assert fun != null : Debug.show(sym.info());
fun;
}
- /*protected*/ def Equals(left1:Tree , right1:Tree ): Tree = {
+ def Equals(left1:Tree , right1:Tree ): Tree = {
var left = left1;
var right = right1;
- val ltype = left.getType().widen;
- var rtype = right.getType().widen;
- if (ltype.isSameAs(rtype)
- && (ltype.isSameAs(definitions.CHAR_TYPE())
- || ltype.isSameAs(definitions.BYTE_TYPE())
- || ltype.isSameAs(definitions.SHORT_TYPE())))
+ val ltype = left.tpe.widen;
+ var rtype = right.tpe.widen;
+ if (isSameType(ltype, rtype)
+ && (isSameType(ltype, definitions.CharClass.info)
+ || isSameType(ltype,definitions.ByteClass.info)
+ || isSameType(ltype,definitions.ShortClass.info)))
{
- right = gen.mkApply__(gen.Select(right, getCoerceToInt(rtype)));
- rtype = definitions.INT_TYPE();
+ right = Apply(Select(right, getCoerceToInt(rtype)), List());
+ rtype = definitions.IntClass.info;
}
val eqsym = getEqEq(ltype, rtype);
- gen.mkApply_V(gen.Select(left, eqsym), Predef.Array[Tree](right));
- }
-
- /*protected*/ def ThrowMatchError(pos: Int, tpe: Type ): Tree = {
- gen.mkApplyTV(
- gen.mkGlobalRef(pos, definitions.MATCHERROR_FAIL()),
- Predef.Array[Tree](gen.mkType(pos, tpe)),
- Predef.Array[Tree](
- gen.mkStringLit(pos, unit.toString()),
- gen.mkIntLit(pos, Position.line(pos))
- ));
- }
-
- def ThrowMatchError(pos:int , tpe:Type , tree:Tree ): Tree = {
- gen.mkApplyTV(
- gen.mkGlobalRef(pos, definitions.MATCHERROR_REPORT()),
- Predef.Array[Tree](gen.mkType(pos, tpe)),
- Predef.Array[Tree](
- gen.mkStringLit(pos, unit.toString()),
- gen.mkIntLit(pos, Position.line(pos)),
- tree
- ));
- }
-
- def Error(pos: Int, tpe: Type): Tree = {
- gen.mkApplyTV(
- gen.mkGlobalRef(pos, definitions.MATCHERROR_FAIL()),
- Predef.Array[Tree](gen.mkType(pos, tpe)),
- Predef.Array[Tree](
- gen.mkStringLit(pos, unit.toString()),
- gen.mkIntLit(pos, Position.line(pos))
- ));
- }
-
-
- def pairType(left: Type, right: Type): Type = {
- definitions.TUPLE_TYPE(Predef.Array[Type] ( left, right ) );
- }
-
- def newPair(left: Tree, right: Tree): Tree = {
- gen.New(
- gen.mkApplyTV(
- gen.mkPrimaryConstructorGlobalRef( pos, definitions.TUPLE_CLASS(2)),
- Predef.Array[Type] ( left.getType(), right.getType() ),
- Predef.Array[Tree] ( left, right )));
- }
+ Apply(Select(left, eqsym), List(right));
+ }
+
+ def ThrowMatchError(pos: Int, tpe: Type ) =
+ Apply(
+ gen.mkRef(definitions.MatchError_fail),
+ List(
+ Literal(unit.toString()),
+ Literal(Position.line(pos))
+ )
+ );
+
+ def ThrowMatchError(pos:int , tpe:Type , tree:Tree ) =
+ Apply(
+ gen.mkRef(definitions.MatchError_report),
+ List(
+ Literal(unit.toString()),
+ Literal(Position.line(pos)),
+ tree
+ )
+ );
+
+ def Error(pos: Int, tpe: Type) =
+ ThrowMatchError(pos: Int, tpe: Type );
+
+ def newPair(left: Tree, right: Tree) =
+ New(
+ Apply(
+ gen.mkRef(definitions.TupleClass(2)),
+ List(left,right)
+ )
+ );
}
diff --git a/sources/scala/tools/nsc/matching/PatternMatcher.scala b/sources/scala/tools/nsc/matching/PatternMatcher.scala
index c9d422e1a2..6215fde0ef 100644
--- a/sources/scala/tools/nsc/matching/PatternMatcher.scala
+++ b/sources/scala/tools/nsc/matching/PatternMatcher.scala
@@ -6,10 +6,14 @@
package scala.tools.nsc.matching ;
-abstract class PatternMatch extends PatternUtil {
+import scala.tools.util.Position;
+
+abstract class PatternMatcher extends PatternUtil with PatternNodes with PatternNodeCreator with CodeFactory {
import global._;
+ import symtab.Flags;
+
protected var optimize = true;
protected var delegateSequenceMatching = false;
protected var doBinding = true;
@@ -32,28 +36,41 @@ abstract class PatternMatch extends PatternUtil {
/** methods to generate scala code
*/
- protected var cf: CodeFactory = _;
+ protected val cf: this.type = this;
/** methods to create pattern nodes
*/
- protected var mk: PatternNodeCreator = _;
+ protected val mk: this.type = this;
+ def defs = definitions;
/** init method, also needed in subclass AlgebraicMatcher
*/
def initialize(selector: Tree, owner: Symbol, resultType: Type, doBinding: Boolean): Unit = {
- this.mk = new PatternNodeCreator(unit, owner);
- this.cf = new CodeFactory(unit, selector.pos);
- this.root = mk.ConstrPat(selector.pos, selector.getType().widen());
+
+ /*
+ this.mk = new PatternNodeCreator {
+ val global = PatternMatcher.this.global;
+ val unit = PatternMatcher.this.unit;
+ val owner = PatternMatcher.this.owner;
+ }
+ */
+ /*
+ this.cf = new CodeFactory {
+ val global = PatternMatcher.this.global;
+ val unit = PatternMatcher.this.unit;
+ val owner = PatternMatcher.this.owner;
+ }
+ */
+ this.root = mk.ConstrPat(selector.pos, selector.tpe.widen);
this.root.and = mk.Header(selector.pos,
- selector.getType().widen(),
- gen.Ident(selector.pos, root.symbol()));
- this.resultVar = owner.newVariable(selector.pos,
- Modifiers.MUTABLE,
- Names.result);
- this.resultVar.setType(resultType);
+ selector.tpe.widen,
+ Ident(root.symbol));
+ this.resultVar = owner.newVariable(Flags.MUTABLE,
+ "result");
+ this.resultVar.setInfo(resultType);
this.owner = owner;
this.selector = selector;
- this.optimize = this.optimize & (unit.global.target == Global.TARGET_JVM);
+ this.optimize = this.optimize & (settings.target == "jvm");
this.doBinding = doBinding;
}
@@ -65,6 +82,9 @@ abstract class PatternMatch extends PatternUtil {
def print(patNode: PatternNode, indent: String, sb: StringBuffer): StringBuffer = {
+ def cont = if (patNode.or != null) print(patNode.or, indent, sb); else sb;
+
+
def newIndent(s: String) = {
val removeBar: Boolean = (null == patNode.or);
val sb = new StringBuffer();
@@ -91,55 +111,50 @@ abstract class PatternMatch extends PatternUtil {
print(patNode.or, indent + "|", sb);
if (next != null)
print(next, indent, sb);
-
+ else
+ sb
case ConstrPat(casted) =>
- val s = "-- " + patNode.getTpe().symbol().name +
+ val s = "-- " + patNode.getTpe().symbol.name +
"(" + patNode.getTpe() + ", " + casted + ") -> ";
val nindent = newIndent(s);
sb.append(nindent + s).append('\n');
print(patNode.and, nindent, sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case SequencePat( casted, plen ) =>
- val s = "-- " + patNode.getTpe().symbol().name + "(" +
+ val s = "-- " + patNode.getTpe().symbol.name + "(" +
patNode.getTpe() +
", " + casted + ", " + plen + ") -> ";
val nindent = newIndent(s);
sb.append(indent + s).append('\n');
print(patNode.and, nindent, sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case DefaultPat() =>
sb.append(indent + "-- _ -> ").append('\n');
print(patNode.and, indent.substring(0, indent.length() - 1) +
" ", sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case ConstantPat(value) =>
val s = "-- CONST(" + value + ") -> ";
val nindent = newIndent(s);
sb.append(indent + s).append('\n');
print(patNode.and, nindent, sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case VariablePat(tree) =>
val s = "-- STABLEID(" + tree + ": " + patNode.getTpe() + ") -> ";
val nindent = newIndent(s);
sb.append(indent + s).append('\n');
print(patNode.and, nindent, sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case AltPat(header) =>
sb.append(indent + "-- ALTERNATIVES:").append('\n');
print(header, indent + " * ", sb);
print(patNode.and, indent + " * -> ", sb);
- if (patNode.or != null)
- print(patNode.or, indent, sb);
+ cont;
case _b:Body =>
if ((_b.guard.length == 0) && (_b.body.length == 0))
@@ -161,9 +176,9 @@ abstract class PatternMatch extends PatternUtil {
protected def enter(caseDef: Tree): Unit = {
caseDef match {
case CaseDef(pat, guard, body) =>
- val env = new CaseEnv(owner, unit);
+ val env = new CaseEnv;
// PatternNode matched = match(pat, root);
- val target = enter1(pat, -1, root, root.symbol(), env);
+ val target = enter1(pat, -1, root, root.symbol, env);
// if (target.and != null)
// unit.error(pat.pos, "duplicate case");
if (null == target.and)
@@ -176,7 +191,7 @@ abstract class PatternMatch extends PatternUtil {
}
protected def updateBody(tree: Body, bound: Array[ValDef], guard: Tree , body: Tree): Unit = {
- if (tree.guard(tree.guard.length - 1) == Tree.Empty) {
+ if (tree.guard(tree.guard.length - 1) == EmptyTree) {
//unit.error(body.pos, "unreachable code");
} else {
val bd = new Array[Array[ValDef]](tree.bound.length + 1);
@@ -194,7 +209,7 @@ abstract class PatternMatch extends PatternUtil {
}
}
- protected def patternArgs(tree: Tree):Array[Tree] = {
+ protected def patternArgs(tree: Tree):List[Tree] = {
tree match {
case Bind(_, pat) =>
patternArgs(pat);
@@ -207,13 +222,10 @@ abstract class PatternMatch extends PatternUtil {
args;
}
else args
- case Sequence(ts) =>
- if (!delegateSequenceMatching)
- ts;
- else
- Tree.EMPTY_ARRAY;
+ case Sequence(ts) if (!delegateSequenceMatching) =>
+ ts;
case _ =>
- Tree.EMPTY_ARRAY;
+ List();
}
}
@@ -229,37 +241,37 @@ abstract class PatternMatch extends PatternUtil {
* (( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence])
* but fails
*/
- protected def isSeqApply( tree: Tree.Apply ): Boolean =
+ protected def isSeqApply( tree: Apply ): Boolean =
(( tree.args.length == 1 ) && tree.args(0).isInstanceOf[Sequence])
- && (tree.getType().symbol().flags & Modifiers.CASE) == 0;
+ && (tree.tpe.symbol.flags & Flags.CASE) == 0;
protected def patternNode(tree:Tree , header:Header , env: CaseEnv ): PatternNode = {
//Console.println("patternNode("+tree+","+header+")");
- //Console.println("tree.getType()"+tree.getType());
+ //Console.println("tree.tpe"+tree.tpe);
tree match {
- case Bind(name, Typed(Ident(Names.PATTERN_WILDCARD), tpe)) => // x@_:Type
- if (header.getTpe().isSubType(tpe.getType())) {
- val node = mk.DefaultPat(tree.pos, tpe.getType());
- env.newBoundVar( tree.symbol(), tree.getType(), header.selector );
+ case Bind(name, Typed(Ident( nme.WILDCARD ), tpe)) => // x@_:Type
+ if (isSubType(header.getTpe(),tpe.tpe)) {
+ val node = mk.DefaultPat(tree.pos, tpe.tpe);
+ env.newBoundVar( tree.symbol, tree.tpe, header.selector );
node;
} else {
- val node = mk.ConstrPat(tree.pos, tpe.getType());
- env.newBoundVar( tree.symbol(), tree.getType(), gen.Ident(tree.pos, node.casted));
+ val node = mk.ConstrPat(tree.pos, tpe.tpe);
+ env.newBoundVar( tree.symbol, tree.tpe, Ident( node.casted ));
node;
}
- case Bind(name, Ident(Names.PATTERN_WILDCARD)) => // x @ _
+ case Bind(name, Ident(nme.WILDCARD)) => // x @ _
val node = mk.DefaultPat(tree.pos, header.getTpe());
- if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD))
- env.newBoundVar( tree.symbol(), tree.getType(), header.selector);
+ if ((env != null) && (tree.symbol != defs.PatternWildcard))
+ env.newBoundVar( tree.symbol, tree.tpe, header.selector);
node;
case Bind(name, pat) =>
val node = patternNode(pat, header, env);
- if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) {
- val casted = node.symbol();
- val theValue = if (casted == Symbol.NONE) header.selector else gen.Ident(tree.pos, casted);
- env.newBoundVar(tree.symbol(), tree.getType(), theValue);
+ if ((env != null) && (tree.symbol != defs.PatternWildcard)) {
+ val casted = node.symbol;
+ val theValue = if (casted == NoSymbol) header.selector else Ident( casted);
+ env.newBoundVar(tree.symbol, tree.tpe, theValue);
}
node;
@@ -268,90 +280,92 @@ abstract class PatternMatch extends PatternUtil {
if (!delegateSequenceMatching) {
args(0) match {
case Sequence(ts)=>
- mk.SequencePat(tree.pos, tree.getType(), ts.length);
+ mk.SequencePat(tree.pos, tree.tpe, ts.length);
}
} else {
- val res = mk.ConstrPat(tree.pos, tree.getType());
+ val res = mk.ConstrPat(tree.pos, tree.tpe);
res.and = mk.Header(tree.pos, header.getTpe(), header.selector);
- res.and.and = mk.SeqContainerPat(tree.pos, tree.getType(), args(0));
+ res.and.and = mk.SeqContainerPat(tree.pos, tree.tpe, args(0));
res;
}
- } else if ((fn.symbol() != null) &&
- fn.symbol().isStable() &&
- !(fn.symbol().isModule() &&
- ((fn.symbol().flags & Modifiers.CASE) != 0))) {
+ } else if ((fn.symbol != null) &&
+ fn.symbol.isStable &&
+ !(fn.symbol.isModule &&
+ ((fn.symbol.flags & Flags.CASE) != 0))) {
mk.VariablePat(tree.pos, tree);
}
else {
/*
Console.println("apply but not seqApply");
- Console.println("tree.getType()="+tree.getType());
- Console.println("tree.symbol()="+tree.symbol());
+ Console.println("tree.tpe="+tree.tpe);
+ Console.println("tree.symbol="+tree.symbol);
*/
- mk.ConstrPat(tree.pos, tree.getType());
+ mk.ConstrPat(tree.pos, tree.tpe);
}
case t @ Typed(ident, tpe) => // variable pattern
- val doTest = header.getTpe().isSubType(tpe.getType());
+ val doTest = isSubType(header.getTpe(),tpe.tpe);
val node = {
if(doTest)
- mk.DefaultPat(tree.pos, tpe.getType())
+ mk.DefaultPat(tree.pos, tpe.tpe)
else
- mk.ConstrPat(tree.pos, tpe.getType());
+ mk.ConstrPat(tree.pos, tpe.tpe);
}
- if ((null != env) && (ident.symbol() != defs.PATTERN_WILDCARD))
+ if ((null != env) && (ident.symbol != defs.PatternWildcard))
node match {
case ConstrPat(casted) =>
- env.newBoundVar(t.expr.symbol(),
- tpe.getType(),
- gen.Ident(tree.pos, casted));
+ env.newBoundVar(t.expr.symbol,
+ tpe.tpe,
+ Ident( casted ));
case _ =>
- env.newBoundVar(t.expr.symbol(),
- tpe.getType(),
- {if(doTest) header.selector else gen.Ident(tree.pos, node.asInstanceOf[ConstrPat].casted)});
+ env.newBoundVar(t.expr.symbol,
+ tpe.tpe,
+ {if(doTest) header.selector else Ident(node.asInstanceOf[ConstrPat].casted)});
}
node;
case Ident(name) => // pattern without args or variable
- if (tree.symbol() == defs.PATTERN_WILDCARD)
+ if (tree.symbol == defs.PatternWildcard)
mk.DefaultPat(tree.pos, header.getTpe());
- else if (tree.symbol().isPrimaryConstructor()) {
- throw new ApplicationError("this may not happen"); // Burak
- } else if (name.isVariable()) {// Burak
- throw new ApplicationError("this may not happen"); // Burak
+ else if (tree.symbol.isPrimaryConstructor) {
+ error("error may not happen"); // Burak
+ null
+ } else if (treeInfo.isVariableName(name)) {// Burak
+ error("this may not happen"); // Burak
+ null
} else
mk.VariablePat(tree.pos, tree);
case Select(_, name) => // variable
- if (tree.symbol().isPrimaryConstructor())
- mk.ConstrPat(tree.pos, tree.getType());
+ if (tree.symbol.isPrimaryConstructor)
+ mk.ConstrPat(tree.pos, tree.tpe);
else
mk.VariablePat(tree.pos, tree);
case Literal(value) =>
- mk.ConstantPat(tree.pos, tree.getType(), value);
+ mk.ConstantPat(tree.pos, tree.tpe, value);
case Sequence(ts) =>
if ( !delegateSequenceMatching ) {
- //throw new ApplicationError("cannot happen:"+tree);
- mk.SequencePat(tree.pos, tree.getType(), ts.length);
+ mk.SequencePat(tree.pos, tree.tpe, ts.length);
} else {
- mk.SeqContainerPat(tree.pos, tree.getType(), tree);
+ mk.SeqContainerPat(tree.pos, tree.tpe, tree);
}
case Alternative(ts) =>
if(ts.length < 2)
- throw new ApplicationError("ill-formed Alternative");
+ error("ill-formed Alternative");
val subroot = mk.ConstrPat(header.pos, header.getTpe());
- subroot.and = mk.Header(header.pos, header.getTpe(), header.selector.duplicate());
- val subenv = new CaseEnv(owner, unit);
+ subroot.and = mk.Header(header.pos, header.getTpe(), header.selector.duplicate);
+ val subenv = new CaseEnv;
var i = 0; while(i < ts.length) {
- val target = enter1(ts(i), -1, subroot, subroot.symbol(), subenv);
+ val target = enter1(ts(i), -1, subroot, subroot.symbol, subenv);
target.and = mk.Body(tree.pos);
i = i + 1
}
mk.AltPat(tree.pos, subroot.and.asInstanceOf[Header]);
case _ =>
- throw new ApplicationError("unit = " + unit + "; tree = "+tree);
+ error("unit = " + unit + "; tree = "+tree);
+ null
}
}
@@ -368,25 +382,24 @@ abstract class PatternMatch extends PatternUtil {
private def newHeader(pos: Int, casted: Symbol, index: Int): Header = {
//Console.println("newHeader(pos,"+casted+","+index+")");
- //Console.println(" casted.getType()"+casted.getType());
- val ident = gen.Ident(pos, casted);
+ //Console.println(" casted.tpe"+casted.tpe);
+ val ident = Ident(casted);
if (casted.pos == Position.FIRSTPOS) {
//Console.println("FIRSTPOS");
- val t = gen.mkApply_V(
- gen.Select( ident, defs.FUNCTION_APPLY( 1 )),
- Predef.Array[Tree]( gen.mkIntLit( pos, index ) ));
- val seqType = t.getType();
+ val t = Apply(Select( ident, defs.functionApply( 1 )),
+ List( Literal( index ) ));
+ val seqType = t.tpe;
mk.Header( pos, seqType, t );
} else {
//Console.println("NOT FIRSTPOS");
- val ts = casted.getType().symbol().asInstanceOf[ClassSymbol]
+ val ts = casted.tpe.symbol.asInstanceOf[ClassSymbol]
.caseFieldAccessor(index);
//Console.println("ts="+ts);
- val accType = casted.getType().memberType(ts);
+ val accType = casted.tpe.memberType(ts);
val accTree = gen.Select( ident, ts);
accType match {
// scala case accessor
- case Type.MethodType(_, _) =>
+ case MethodType(_, _) =>
mk.Header(pos, accType.resultType(), gen.mkApply__(accTree));
// jaco case accessor
case _ =>
@@ -405,7 +418,7 @@ abstract class PatternMatch extends PatternUtil {
var curHeader = target.and.asInstanceOf[Header]; // advance one step in intermediate representation
if (curHeader == null) { // check if we have to add a new header
//assert index >= 0 : casted;
- if (index < 0) throw new ApplicationError("error entering:" + casted);
+ if (index < 0) { error("error entering:" + casted); return null }
target.and = {curHeader = newHeader(pat.pos, casted, index); curHeader};
curHeader.or = patternNode(pat, curHeader, env);
enter(patArgs, curHeader.or, casted, env);
@@ -423,8 +436,7 @@ abstract class PatternMatch extends PatternUtil {
// substitute... !!!
patNode match {
case ConstrPat(ocasted) =>
- env.substitute(ocasted, gen.Ident(patNode.pos,
- next.asInstanceOf[ConstrPat].casted));
+ env.substitute(ocasted, Ident(next.asInstanceOf[ConstrPat].casted));
case _ =>
}
return enter(patArgs, next, casted, env);
@@ -447,14 +459,14 @@ abstract class PatternMatch extends PatternUtil {
} else
next = next.or;
}
- throw new ApplicationError("must not happen");
- null // never reached
+ error("must not happen");
+ null
}
}
/** calls enter for an array of patterns, see enter
*/
- protected def enter(pats:Array[Tree], target1: PatternNode , casted1: Symbol , env: CaseEnv): PatternNode = {
+ protected def enter(pats:List[Tree], target1: PatternNode , casted1: Symbol , env: CaseEnv): PatternNode = {
var target = target1;
var casted = casted1;
target match {
@@ -474,23 +486,23 @@ abstract class PatternMatch extends PatternUtil {
protected def nCaseComponents(tree: Tree): int = {
tree match {
case Apply(fn, _) =>
- val tpe = tree.getType().symbol().primaryConstructor().getType();
- //Console.println("~~~ " + tree.type() + ", " + tree.type().symbol().primaryConstructor());
+ val tpe = tree.tpe.symbol.primaryConstructor.tpe;
+ //Console.println("~~~ " + tree.type() + ", " + tree.type().symbol.primaryConstructor());
tpe match {
// I'm not sure if this is a good idea, but obviously, currently all case classes
// without constructor arguments have type NoType
- case Type.NoType =>
- throw new ApplicationError("this cannot happen");
+ case NoType =>
+ error("this cannot happen");
0
- case Type.MethodType(args, _) =>
+ case MethodType(args, _) =>
args.length;
- case Type.PolyType(tvars, Type.MethodType(args, _)) =>
+ case PolyType(tvars, Type.MethodType(args, _)) =>
args.length;
- case Type.PolyType(tvars, _) =>
+ case PolyType(tvars, _) =>
0;
case _ =>
- throw new ApplicationError("not yet implemented;" +
- "pattern matching for " + tree + ": " + tpe);
+ error("not yet implemented;" +
+ "pattern matching for " + tree + ": " + tpe);
}
}
return 0;
@@ -521,9 +533,9 @@ abstract class PatternMatch extends PatternUtil {
while (({node = node.or; node}) != null) {
node match {
case VariablePat(tree) =>
- Console.println(((tree.symbol().flags & Modifiers.CASE) != 0));
+ Console.println(((tree.symbol.flags & Flags.CASE) != 0));
case ConstrPat(_) =>
- Console.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol().flags & Modifiers.CASE) != 0));
+ Console.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol.flags & Flags.CASE) != 0));
var inner = node.and;
def funct(inner: PatternNode): Boolean = {
//outer: while (true) {
@@ -538,7 +550,7 @@ abstract class PatternMatch extends PatternUtil {
case b:Body =>
if ((b.guard.length > 1) ||
- (b.guard(0) != Tree.Empty))
+ (b.guard(0) != EmptyTree))
throw Break(false);
throw Break2() // break outer
@@ -568,7 +580,7 @@ abstract class PatternMatch extends PatternUtil {
}
protected def isSimpleIntSwitch(): Boolean = {
- if (selector.getType().widen().isSameAs(defs.int_TYPE())) {
+ if (isSameType(selector.tpe.widen, defs.IntClass.info)) {
var patNode = root.and;
while (patNode != null) {
var node = patNode;
@@ -581,7 +593,7 @@ abstract class PatternMatch extends PatternUtil {
node.and match {
case _b:Body =>
if ((_b.guard.length > 1) ||
- (_b.guard(0) != Tree.Empty) ||
+ (_b.guard(0) != EmptyTree) ||
(_b.bound(0).length > 0))
return false;
case _ =>
@@ -649,7 +661,7 @@ abstract class PatternMatch extends PatternUtil {
def intSwitchToTree(): Tree = {
//print();
val ncases = numCases(root.and);
- val matchError = cf.ThrowMatchError(selector.pos, resultVar.getType());
+ val matchError = cf.ThrowMatchError(selector.pos, resultVar.tpe);
// without a case, we return a match error if there is no default case
if (ncases == 0)
return defaultBody(root.and, matchError);
@@ -657,10 +669,9 @@ abstract class PatternMatch extends PatternUtil {
else if (ncases == 1) {
root.and.or match {
case ConstantPat(value) =>
- return gen.If(cf.Equals(selector,
- gen.Literal(root.and.or.pos, value)),
- bodyToTree(root.and.or.and),
- defaultBody(root.and, matchError));
+ return If(cf.Equals(selector, Literal(value)),
+ bodyToTree(root.and.or.and),
+ defaultBody(root.and, matchError));
case _ =>
return generalSwitchToTree();
}
@@ -671,7 +682,7 @@ abstract class PatternMatch extends PatternUtil {
case _h:Header =>
val next = _h.next;
var mappings: TagBodyPair = null;
- var defaultBody = matchError;
+ var defaultBody: Tree = matchError;
var patNode = root.and;
while (patNode != null) {
var node = patNode.or;
@@ -679,11 +690,11 @@ abstract class PatternMatch extends PatternUtil {
node match {
case DefaultPat() =>
if (defaultBody != null)
- throw new ApplicationError();
+ error("not your day today");
defaultBody = bodyToTree(node.and);
node = node.or;
- case ConstantPat(AConstant.INT(value))=>
+ case ConstantPat( value: Int )=>
mappings = insert(
value,
bodyToTree(node.and),
@@ -691,13 +702,13 @@ abstract class PatternMatch extends PatternUtil {
node = node.or;
case _ =>
- throw new error("intSwitchToTree/Header " + node.toString());
+ error("intSwitchToTree/Header " + node.toString());
}
}
patNode = patNode.nextH();
}
if (mappings == null) {
- return gen.Switch(selector, new Array[int](0), new Array[Tree](0), defaultBody, resultVar.getType());
+ return Switch(selector, List(0), List(0), defaultBody, resultVar.tpe);
} else {
var n = mappings.length();
val tags = new Array[Int](n);
@@ -709,7 +720,7 @@ abstract class PatternMatch extends PatternUtil {
n = n + 1;
mappings = mappings.next;
}
- return gen.Switch(selector, tags, bodies, defaultBody, resultVar.getType());
+ return Switch(selector, tags, bodies, defaultBody, resultVar.tpe);
}
case _ =>
error("intSwitchToTree / not a header")
@@ -727,19 +738,19 @@ abstract class PatternMatch extends PatternUtil {
def generalSwitchToTree(): Tree = {
val ts = Predef.Array[Tree] (
- gen.ValDef(root.symbol(), selector),
- gen.ValDef(resultVar, gen.mkDefaultValue(selector.pos, resultVar.getType())));
- val res = gen.If(
- selector.pos,
- toTree(root.and),
- gen.Ident(selector.pos, resultVar),
- cf.ThrowMatchError(selector.pos, resultVar.getType(), gen.Ident(selector.pos, root.symbol())));
- return gen.mkBlock(selector.pos, ts, res);
+ ValDef(root.symbol, selector),
+ ValDef(resultVar, gen.mkDefaultValue(selector.pos, resultVar.tpe)));
+ val res = If(toTree(root.and),
+ Ident(resultVar),
+ cf.ThrowMatchError(selector.pos,
+ resultVar.tpe,
+ Ident(root.symbol)));
+ return Block(ts, res);
}
/*protected*/ def toTree(node1: PatternNode): Tree = {
var node = node1;
- var res = gen.mkBooleanLit(node.pos, false);
+ var res = Literal(false);
while (node != null)
node match {
case _h:Header =>
@@ -760,35 +771,34 @@ abstract class PatternMatch extends PatternUtil {
if ((bound.length == 0) &&
(guard.length == 0) &&
(body.length == 0)) {
- return gen.mkBooleanLit(node.pos, true); // cf.Or(res, gen.mkBooleanLit(node.pos, true));
+ return Literal(true);
} else if (!doBinding)
bound = Predef.Array[Array[ValDef]]( Predef.Array[ValDef]() );
var i = guard.length - 1; while(i >= 0) {
val ts = bound(i).asInstanceOf[Array[Tree]];
- var res0 = gen.mkBlock(gen.Assign(gen.Ident(body(i).pos, resultVar),
- body(i)),
- gen.mkBooleanLit(body(i).pos, true));
- if (guard(i) != Tree.Empty)
+ var res0 = Block(Assign(Ident(resultVar), body(i)),
+ Literal(true));
+ if (guard(i) != EmptyTree)
res0 = cf.And(guard(i), res0);
- res = cf.Or(gen.mkBlock(body(i).pos, ts, res0), res);
+ res = cf.Or(Block(ts, res0), res);
i = i - 1
}
return res;
case _ =>
- throw new ApplicationError();
+ error("I am tired");
}
return res;
}
protected def optimize(selType:Type, alternatives1: PatternNode ): boolean = {
var alternatives = alternatives1;
- if (!optimize || !selType.isSubType(defs.SCALAOBJECT_TYPE()))
+ if (!optimize || !isSubType(selType, defs.ScalaObjectClass.info))
return false;
var cases = 0;
while (alternatives != null) {
alternatives match {
case ConstrPat(_) =>
- if (alternatives.getTpe().symbol().isCaseClass())
+ if (alternatives.getTpe().symbol.isCaseClass())
cases = cases +1;
else
return false;
@@ -840,7 +850,7 @@ abstract class PatternMatch extends PatternUtil {
while (node != null)
node match {
case ConstrPat(casted) =>
- cases = insertNode(node.getTpe().symbol().tag(), node, cases);
+ cases = insertNode(node.getTpe().symbol.tag(), node, cases);
node = node.or;
case DefaultPat() =>
@@ -848,7 +858,7 @@ abstract class PatternMatch extends PatternUtil {
node = node.or;
case _ =>
- throw new ApplicationError();
+ error("errare humanum est");
}
var n = cases.length();
val tags = new Array[int](n);
@@ -860,55 +870,66 @@ abstract class PatternMatch extends PatternUtil {
n = n + 1;
cases = cases.next;
}
- return gen.Switch(gen.mkApply__(gen.Select(selector.duplicate(), defs.SCALAOBJECT_TAG())),
- tags,
- bodies,
- { if (defaultCase == null) gen.mkBooleanLit(selector.pos, false) else toTree(defaultCase.and) },
+ return
+ Switch(
+ Apply(
+ Select(selector.duplicate, defs.ScalaObjectClass_tag),
+ List()),
+ tags,
+ bodies,
+ { if (defaultCase == null) Literal(false) else toTree(defaultCase.and) },
defs.boolean_TYPE());
}
protected def toTree(node:PatternNode , selector:Tree ): Tree = {
//System.err.println("pm.toTree("+node+","+selector+")");
if (node == null)
- return gen.mkBooleanLit(selector.pos, false);
+ return Literal(false);
else
node match {
case DefaultPat() =>
return toTree(node.and);
case ConstrPat(casted) =>
- return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()),
- gen.mkBlock(gen.ValDef(casted,
- gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true)),
- toTree(node.and)),
- toTree(node.or, selector.duplicate()));
+ return If(gen.mkIsInstanceOf(selector.duplicate, node.getTpe()),
+ Block(ValDef(casted,
+ gen.mkAsInstanceOf(selector.pos, selector.duplicate, node.getTpe(), true)),
+ toTree(node.and)),
+ toTree(node.or, selector.duplicate));
case SequencePat(casted, len) =>
return
cf.Or(
cf.And(
- cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()),
- cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true),
- defs.SEQ_LENGTH())),
- gen.mkIntLit(selector.pos, len))),
- gen.mkBlock(gen.ValDef(casted,
- gen.mkAsInstanceOf(selector.pos, selector.duplicate(), node.getTpe(), true)),
- toTree(node.and))),
- toTree(node.or, selector.duplicate()));
+ cf.And(gen.mkIsInstanceOf(selector.duplicate, node.getTpe()),
+ cf.Equals(
+ Apply(
+ Select(
+ gen.mkAsInstanceOf(selector.pos,
+ selector.duplicate,
+ node.getTpe(),
+ true),
+ defs.Seq_length)
+ List()),
+ Literal(len))),
+ Block(ValDef(casted,
+ gen.mkAsInstanceOf(selector.pos, selector.duplicate, node.getTpe(), true)),
+ toTree(node.and))),
+ toTree(node.or, selector.duplicate));
case ConstantPat(value) =>
- return gen.If(cf.Equals(selector.duplicate(),
- gen.Literal(selector.pos, value)),
- toTree(node.and),
- toTree(node.or, selector.duplicate()));
+ return If(cf.Equals(selector.duplicate,
+ Literal(value)),
+ toTree(node.and),
+ toTree(node.or, selector.duplicate));
case VariablePat(tree) =>
- return gen.If(cf.Equals(selector.duplicate(), tree),
- toTree(node.and),
- toTree(node.or, selector.duplicate()));
+ return If(cf.Equals(selector.duplicate, tree),
+ toTree(node.and),
+ toTree(node.or, selector.duplicate));
case AltPat(header) =>
- return gen.If(toTree(header),
- toTree(node.and),
- toTree(node.or, selector.duplicate()));
+ return If(toTree(header),
+ toTree(node.and),
+ toTree(node.or, selector.duplicate));
case _ =>
- throw new ApplicationError();
+ error("can't plant this tree");
}
}
}
diff --git a/sources/scala/tools/nsc/matching/PatternNode.scala b/sources/scala/tools/nsc/matching/PatternNode.scala
new file mode 100644
index 0000000000..97aa7821ee
--- /dev/null
+++ b/sources/scala/tools/nsc/matching/PatternNode.scala
@@ -0,0 +1,276 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+** **
+** $Id$
+\* */
+
+package scala.tools.nsc.matching ;
+
+import scala.tools.util.Position;
+
+abstract class PatternNodes {
+
+ val global: Global;
+
+ import global._;
+
+ /** Intermediate data structure for algebraic + pattern matcher
+ */
+ class PatternNode {
+ var pos = Position.FIRSTPOS;
+ var tpe: Type = _;
+ var or: PatternNode = _;
+ var and: PatternNode = _;
+
+ def getTpe(): Type = {
+ tpe;
+ }
+ def setType(tpe: Type): Unit = {
+ this.tpe = tpe;
+ }
+
+ def dup(): PatternNode = {
+ var res: PatternNode = _;
+ this match {
+ case h:Header =>
+ res = new Header(h.selector, h.next);
+
+ case b:Body=>
+ res = new Body(b.bound, b.guard, b.body);
+
+ case DefaultPat() =>
+ res = DefaultPat();
+
+ case ConstrPat(casted) =>
+ res = ConstrPat(casted);
+
+ case SequencePat(casted, len) =>
+ res = SequencePat(casted, len);
+
+ case SeqContainerPat(casted, seqpat) =>
+ res = SeqContainerPat(casted, seqpat);
+
+ case ConstantPat(value) =>
+ res = ConstantPat(value);
+
+ case VariablePat(tree) =>
+ res = VariablePat(tree);
+
+ case AltPat(subheader) =>
+ res = AltPat(subheader);
+
+ case _ =>
+ error("")
+ }
+ res.pos = pos;
+ res.tpe = tpe;
+ res.or = or;
+ res.and = and;
+ res;
+ }
+
+ def symbol: Symbol = {
+ this match {
+ case ConstrPat(casted) =>
+ return casted;
+ case SequencePat(casted, _) =>
+ return casted;
+ case SeqContainerPat(casted, _) =>
+ return casted;
+ case _ =>
+ return NoSymbol; //.NONE;
+ }
+ }
+
+ def nextH(): PatternNode = {
+ this match {
+ case _h:Header =>
+ return _h.next;
+ case _ =>
+ return null;
+ }
+ }
+
+ def isDefaultPat(): boolean = {
+ this match {
+ case DefaultPat() =>
+ return true;
+ case _ =>
+ return false;
+ }
+ }
+
+ /** returns true if
+ * p and q are equal (constructor | sequence) type tests, or
+ * "q matches" => "p matches"
+ */
+ def isSameAs(q: PatternNode): boolean = {
+ this match {
+ case ConstrPat(_) =>
+ q match {
+ case ConstrPat(_) =>
+ isSameType(q.getTpe(), this.getTpe());
+ case _ =>
+ false
+ }
+ case SequencePat(_, plen) =>
+ q match {
+ case SequencePat(_, qlen) =>
+ return (plen == qlen) && isSameType(q.getTpe(), this.getTpe());
+ case _ =>
+ false
+ }
+ case _ =>
+ subsumes(q);
+ }
+ }
+
+ /** returns true if "q matches" => "p matches"
+ */
+ def subsumes(q:PatternNode): Boolean = {
+ this match {
+ case DefaultPat() =>
+ q match {
+ case DefaultPat() =>
+ true;
+ case _ =>
+ false;
+ }
+ case ConstrPat(_) =>
+ q match {
+ case ConstrPat(_) =>
+ isSubType(q.getTpe(), this.getTpe());
+ case _ =>
+ false;
+ }
+ case SequencePat(_, plen) =>
+ q match {
+ case SequencePat(_, qlen) =>
+ (plen == qlen) && isSubType(q.getTpe(), this.getTpe());
+ case _ =>
+ false;
+ }
+ case ConstantPat(pval) =>
+ q match {
+ case ConstantPat(qval) =>
+ pval.equals(qval);
+ case _ =>
+ false;
+ }
+ case VariablePat(tree) =>
+ q match {
+ case VariablePat(other) =>
+ (tree.symbol != null) &&
+ (tree.symbol != NoSymbol) &&
+ (!tree.symbol.isError) &&
+ (tree.symbol == other.symbol);
+ case _ =>
+ false;
+ }
+ case _ =>
+ false;
+ }
+ }
+
+ override def toString(): String = {
+ this match {
+ case _h:Header =>
+ return "Header(" + _h.selector + ")";
+ case _b:Body =>
+ return "Body";
+ case DefaultPat() =>
+ return "DefaultPat";
+ case ConstrPat(casted) =>
+ return "ConstrPat(" + casted + ")";
+ case SequencePat(casted, len) =>
+ return "SequencePat(" + casted + ", " + len + "...)";
+ case SeqContainerPat(casted, seqpat) =>
+ return "SeqContainerPat(" + casted + ", " + seqpat + ")";
+ case ConstantPat(value) =>
+ return "ConstantPat(" + value + ")";
+ case VariablePat(tree) =>
+ return "VariablePat";
+ case _ =>
+ return "<unknown pat>";
+ }
+ }
+ }
+
+ class Header(sel1: Tree, next1: Header ) extends PatternNode {
+ var selector: Tree = sel1;
+ var next: Header = next1;
+ }
+
+ class Body(bound1: Array[Array[ValDef]] , guard1:Array[Tree] , body1:Array[Tree] ) extends PatternNode {
+ var bound = bound1;
+ var guard = guard1;
+ var body = body1;
+ }
+
+ case class DefaultPat()extends PatternNode;
+ case class ConstrPat(casted:Symbol ) extends PatternNode;
+ case class ConstantPat(value: Any /*AConstant*/ ) extends PatternNode;
+ case class VariablePat(tree: Tree ) extends PatternNode;
+ case class AltPat(subheader: Header ) extends PatternNode;
+ case class SequencePat( casted: Symbol, len:int) extends PatternNode; // only used in PatternMatcher
+ case class SeqContainerPat(casted: Symbol , seqpat: Tree ) extends PatternNode; // in AlgebraicMatcher
+
+ /** the environment for a body of a case
+ * @param owner the owner of the variables created here
+ */
+ class CaseEnv {
+// (val owner:Symbol, unit:CompilationUnit)
+ private var boundVars:scala.Array[ValDef] = new Array[ValDef](4);
+ private var numVars = 0;
+
+ /** substitutes a symbol on the right hand side of a ValDef
+ */
+ def substitute(oldSym: Symbol, newInit: Tree): Unit = {
+ var i = 0; while( i < numVars) {
+ if( boundVars(i).rhs.symbol == oldSym ) {
+ boundVars(i) = ValDef(boundVars(i).symbol, newInit);
+ return;
+ }
+ i = i + 1;
+ }
+ }
+
+ def newBoundVar(sym:Symbol, tpe: Type, init:Tree ): Unit = {
+ // sym.setOwner( owner ); // FIXME should be corrected earlier
+ // @maybe is corrected now? bq
+ if (numVars == boundVars.length) {
+ val newVars = new Array[ValDef](numVars * 2);
+ System.arraycopy(boundVars, 0, newVars, 0, numVars);
+ this.boundVars = newVars;
+ }
+ sym.setInfo(tpe);
+ this.boundVars(numVars) = ValDef(sym, init.duplicate);
+ numVars = numVars + 1;
+ }
+
+ def getBoundVars(): Array[ValDef] = {
+ val newVars = new Array[ValDef](numVars);
+ System.arraycopy(boundVars, 0, newVars, 0, numVars);
+ return newVars;
+ }
+
+ override def equals(obj: Any): Boolean = {
+ if (!(obj.isInstanceOf[CaseEnv]))
+ return false;
+ val env = obj.asInstanceOf[CaseEnv];
+ if (env.numVars != numVars)
+ return false;
+ var i = 0; while(i < numVars) {
+ if ((boundVars(i).name != env.boundVars(i).name) ||
+ !isSameType(boundVars(i).tpe, env.boundVars(i).tpe) ||
+ (boundVars(i).rhs != env.boundVars(i).rhs))
+ return false;
+ i = i + 1;
+ }
+ return true;
+ }
+
+ } // class CaseEnv
+}
diff --git a/sources/scala/tools/nsc/matching/PatternNodeCreator.scala b/sources/scala/tools/nsc/matching/PatternNodeCreator.scala
index 42c76c2863..60eab3d92e 100644
--- a/sources/scala/tools/nsc/matching/PatternNodeCreator.scala
+++ b/sources/scala/tools/nsc/matching/PatternNodeCreator.scala
@@ -1,12 +1,16 @@
package scala.tools.nsc.matching;
+import scala.tools.util.Position;
/** PatternNode factory.
* we inherit the globals from PatternTool.
*/
-abstract class PatternNodeCreator(val owner:Symbol) extends PatternUtil {
+abstract class PatternNodeCreator extends PatternUtil with PatternNodes {
+ import global._;
+
+ var owner:Symbol = _;
/** the owner of the variable symbols that might be created */
//Symbol owner;
@@ -14,7 +18,7 @@ abstract class PatternNodeCreator(val owner:Symbol) extends PatternUtil {
val sym = newVar(Position.FIRSTPOS, tpe);
val node = new SequencePat(sym, len);
node.pos = pos;
- node.setType(tpe);
+ node.tpe = tpe;
node;
}
@@ -40,7 +44,7 @@ abstract class PatternNodeCreator(val owner:Symbol) extends PatternUtil {
node;
}
- def ConstantPat(pos: int, tpe: Type, value:AConstant ) = {
+ def ConstantPat(pos: int, tpe: Type, value: Any /*AConstant*/ ) = {
val node = new ConstantPat( value );
node.pos = pos;
node.setType(tpe);
@@ -50,7 +54,7 @@ abstract class PatternNodeCreator(val owner:Symbol) extends PatternUtil {
def VariablePat(pos: int, tree:Tree) = {
val node = new VariablePat( tree );
node.pos = pos;
- node.setType(tree.getType());
+ node.setType(tree.tpe);
node;
}
@@ -83,15 +87,15 @@ abstract class PatternNodeCreator(val owner:Symbol) extends PatternUtil {
}
def newVar(pos: int, name: Name, tpe: Type): Symbol= {
- val sym = owner.newVariable(pos, 0, name);
- sym.setType(tpe);
+ val sym = owner.newVariable(0, name);
+ sym.setInfo(tpe);
//System.out.println("PatternNodeCreator::newVar creates symbol "+sym);
//System.out.println("owner: "+sym.owner());
sym;
}
def newVar(pos: int, tpe: Type): Symbol = {
- newVar(pos, fresh.newName("temp"), tpe);
+ newVar(pos, unit.fresh.newName("temp"), tpe);
}
}
diff --git a/sources/scala/tools/nsc/matching/PatternUtil.scala b/sources/scala/tools/nsc/matching/PatternUtil.scala
index 7da24e445b..1607c44856 100644
--- a/sources/scala/tools/nsc/matching/PatternUtil.scala
+++ b/sources/scala/tools/nsc/matching/PatternUtil.scala
@@ -9,15 +9,20 @@
package scala.tools.nsc.matching;
-/** utility function
+import scala.tools.util.Position;
+
+/** utility functions
*/
abstract class PatternUtil {
val global: Global;
- val unit: CompilationUnit;
+ import global._;
+
var pos: Position;
+ var unit: CompilationUnit = _;
+
import global.definitions;
def containsBinding(pat: Tree): Boolean = {
@@ -29,23 +34,23 @@ abstract class PatternUtil {
}
def isVariableName(name: Name): Boolean =
- ( name.isVariable() ) && ( name != Name.fromString("_") ) ;
+ ( treeInfo.isVariableName(name) ) && ( name != nme.USCOREkw ) ;
def isVariableSymbol(sym: Symbol): Boolean =
- ( sym != null )&&( !sym.isPrimaryConstructor() );
+ ( sym != null )&&( !sym.isPrimaryConstructor );
def traverse(tree: Tree): Unit = {
tree match {
case x @ Ident(name) =>
- if(x.symbol() != definitions.PATTERN_WILDCARD)
- throw new ApplicationError("shouldn't happen?!");
+ if(x.symbol != definitions.PatternWildcard)
+ error("shouldn't happen?!");
case Bind(name, subtree) =>
var sym: Symbol = _;
if (isVariableName(name)
- && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} ))
+ && isVariableSymbol( {sym = tree.symbol; tree.symbol} ))
handleVariableSymbol(sym);
traverse( subtree );
diff --git a/sources/scala/tools/nsc/matching/TransMatcher.scala b/sources/scala/tools/nsc/matching/TransMatcher.scala
index 862e356cd3..7cb1a3ccd3 100644
--- a/sources/scala/tools/nsc/matching/TransMatcher.scala
+++ b/sources/scala/tools/nsc/matching/TransMatcher.scala
@@ -15,11 +15,15 @@ abstract class TransMatcher {
import definitions._;
import posAssigner.atPos;
+ private var unit: CompilationUnit;
+
class TransMatchPhase(prev: Phase) extends StdPhase(prev) {
def name = "transmatcher";
val global: TransMatcher.this.global.type = TransMatcher.this.global;
- def apply(unit: CompilationUnit): unit =
+ def apply(unit: CompilationUnit): unit = {
+ TransMatcher.this.unit = unit;
unit.body = newTransMatcher.transform(unit.body);
+ }
}
def newTransMatcher = new TransMatch();
diff --git a/sources/scala/tools/nsc/symtab/Definitions.scala b/sources/scala/tools/nsc/symtab/Definitions.scala
index 75a3cc4ddd..c3b325addb 100755
--- a/sources/scala/tools/nsc/symtab/Definitions.scala
+++ b/sources/scala/tools/nsc/symtab/Definitions.scala
@@ -37,6 +37,9 @@ abstract class Definitions: SymbolTable {
// the scala value classes
var UnitClass: Symbol = _;
var BooleanClass: Symbol = _;
+ def Boolean_not = IterableClass.info.decl(nme.ZNOT);
+ def Boolean_and = IterableClass.info.decl(nme.ZAND);
+ def Boolean_or = IterableClass.info.decl(nme.ZOR);
var ByteClass: Symbol = _;
var ShortClass: Symbol = _;
var CharClass: Symbol = _;
@@ -47,6 +50,7 @@ abstract class Definitions: SymbolTable {
// the scala reference classes
var ScalaObjectClass: Symbol = _;
+ def ScalaObjectClass_tag = ScalaObjectClass.info.decl( nme.tag );
var AttributeClass: Symbol = _;
var RefClass: Symbol = _;
var PartialFunctionClass: Symbol = _;
@@ -55,12 +59,18 @@ abstract class Definitions: SymbolTable {
def Iterable_hasNext = IterableClass.info.decl("hasNext");
var IteratorClass: Symbol = _;
var SeqClass: Symbol = _;
+ def Seq_length = SeqClass.info.decl("length");
var ListClass: Symbol = _;
+ def List_isEmpty = ListClass.info.decl("isEmpty");
+ def List_head = ListClass.info.decl("head");
+ def List_tail = ListClass.info.decl("tail");
var ArrayClass: Symbol = _;
var TypeClass: Symbol = _;
var PredefModule: Symbol = _;
var ConsoleModule: Symbol = _;
var MatchErrorModule: Symbol = _;
+ def MatchError_fail = MatchErrorModule.info.decl("fail");
+ def MatchError_report = MatchErrorModule.info.decl("report");
var RepeatedParamClass: Symbol = _;
var ByNameParamClass: Symbol = _;
@@ -75,12 +85,17 @@ abstract class Definitions: SymbolTable {
typeRef(sym.typeConstructor.prefix, sym, elems)
} else NoType;
+ def tupleField(n:int, j:int) =
+ TupleClass(n).info.decl("_"+j.toString());
+
def functionType(formals: List[Type], restpe: Type) =
if (formals.length <= MaxFunctionArity) {
val sym = FunctionClass(formals.length);
typeRef(sym.typeConstructor.prefix, sym, formals ::: List(restpe))
} else NoType;
+ def functionApply(n:int) = FunctionClass(n).info.decl("apply");
+
def isTupleType(tp: Type): boolean = tp match {
case TypeRef(_, sym, elems) =>
elems.length <= MaxTupleArity && sym == TupleClass(elems.length);