From 3a4a6a3b66a98cc18cda27b0d008ee6aba425250 Mon Sep 17 00:00:00 2001 From: michelou Date: Fri, 1 Sep 2006 12:38:40 +0000 Subject: cleaned up code in matching/*.scala --- .../scala/tools/nsc/matching/CodeFactory.scala | 108 ++-- src/compiler/scala/tools/nsc/matching/Npair.scala | 64 ++- .../scala/tools/nsc/matching/PatternMatchers.scala | 565 +++++++++++---------- .../tools/nsc/matching/PatternNodeCreator.scala | 204 +++++--- .../scala/tools/nsc/matching/PatternNodes.scala | 549 ++++++++++---------- .../tools/nsc/matching/StateSetComparator.scala | 42 +- 6 files changed, 771 insertions(+), 761 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala index 4e33b386d5..a989c84587 100644 --- a/src/compiler/scala/tools/nsc/matching/CodeFactory.scala +++ b/src/compiler/scala/tools/nsc/matching/CodeFactory.scala @@ -1,52 +1,49 @@ -/* -** $Id$ -*/ -package scala.tools.nsc.matching ; +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir + */ +// $Id$ + +package scala.tools.nsc.matching -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.Position trait CodeFactory requires TransMatcher { - import global._ ; + import global._ - import definitions._; // standard classes and methods - import typer.typed; // methods to type trees - import posAssigner.atPos; // for filling in tree positions + import definitions._ // standard classes and methods + import typer.typed // methods to type trees + import posAssigner.atPos // for filling in tree positions /** returns `List[ Tuple2[ scala.Int, ] ]' */ - def SeqTraceType( elemType: Type ): Type = { + def SeqTraceType(elemType: Type): Type = appliedType(definitions.ListClass.typeConstructor, List(pairType(definitions.IntClass.info, elemType))) - } - - - def pairType(left: Type, right: Type) = { - appliedType( definitions.TupleClass(2).typeConstructor, + def pairType(left: Type, right: Type) = + appliedType(definitions.TupleClass(2).typeConstructor, List(left,right)) - } /** returns `Iterator[ elemType ]' */ - def _seqIterType( elemType: Type ): Type = { - appliedType( definitions.IteratorClass.typeConstructor, + def _seqIterType(elemType: Type): Type = + appliedType(definitions.IteratorClass.typeConstructor, List(elemType)) - } /** 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.SeqClass ); + def getElemType_Sequence(tpe: Type): Type = { + //System.err.println("getElemType_Sequence("+tpe.widen()+")") + val tpe1 = tpe.widen.baseType(definitions.SeqClass) - if( tpe1 == NoType ) - Predef.error("arg "+tpe+" not subtype of Seq[ A ]"); + if (tpe1 == NoType) + Predef.error("arg " + tpe + " not subtype of Seq[A]") - return tpe1.typeArgs( 0 ); + tpe1.typeArgs(0) } - // --------- these are new /** a faked switch statement @@ -55,46 +52,38 @@ trait CodeFactory requires TransMatcher { //assert condition != null:"cond is null"; //assert body != null:"body is null"; //assert defaultBody != null:"defaultBody is null"; - var result = defaultBody; - - var i = condition.length-1; + var result = defaultBody + var i = condition.length - 1 while (i >= 0) { - result = If(condition(i), body(i), result); + result = If(condition(i), body(i), result) i = i - 1 } - - return result ; + result } /** returns code `.elements' */ - def newIterator( seqObj:Tree ): Tree = - Apply(Select(seqObj, newTermName("elements")), List()); - + def newIterator(seqObj: Tree): Tree = + Apply(Select(seqObj, newTermName("elements")), List()) /** `it.next()' */ - def _next(iter: Tree) = - Apply(Select(iter, definitions.Iterator_next), List()); - + def _next(iter: Tree) = + Apply(Select(iter, definitions.Iterator_next), List()) /** `it.hasNext()' */ def _hasNext(iter: Tree) = - Apply(Select(iter, definitions.Iterator_hasNext), List()); - + Apply(Select(iter, definitions.Iterator_hasNext), List()) /** `!it.hasCur()' */ - def _not_hasNext( iter:Tree ) = - Apply(Select(_hasNext(iter), definitions.Boolean_not), List()); - + def _not_hasNext(iter: Tree) = + Apply(Select(_hasNext(iter), definitions.Boolean_not), List()) /** `trace.isEmpty' */ def isEmpty( iter: Tree ): Tree = - Apply(Select(iter, definitions.List_isEmpty), List()); - + Apply(Select(iter, definitions.List_isEmpty), List()) /** `arg.head' */ - def SeqList_head( arg: Tree ) = - Apply(Select(arg, definitions.List_head), List()); - + def SeqList_head(arg: Tree) = + Apply(Select(arg, definitions.List_head), List()) def Negate(tree: Tree) = tree match { case Literal(Constant(value:Boolean))=> @@ -104,14 +93,14 @@ trait CodeFactory requires TransMatcher { } /*protected*/ def And(left: Tree, right: Tree): Tree = left match { - case Literal(Constant(value:Boolean)) => - if(value) right else left; + case Literal(Constant(value: Boolean)) => + if (value) right else left case _ => right match { case Literal(Constant(true)) => - left; + left case _ => - Apply(Select(left, definitions.Boolean_and), List(right)); + Apply(Select(left, definitions.Boolean_and), List(right)) } } @@ -122,11 +111,11 @@ trait CodeFactory requires TransMatcher { If(cond, thenp, right) */ case Literal(Constant(value: Boolean))=> - if(value) left else right; + if(value) left else right case _ => right match { case Literal(Constant(false)) => - left; + left case _ => Apply(Select(left, definitions.Boolean_or), List(right)); } @@ -184,13 +173,16 @@ trait CodeFactory requires TransMatcher { fun; } */ - def Equals(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.EQEQ), List(right)); + def Equals(left: Tree, right: Tree): Tree = + Apply(Select(left, nme.EQEQ), List(right)) - def Eq(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.eq), List(right)); + def Eq(left: Tree, right: Tree): Tree = + Apply(Select(left, nme.eq), List(right)) - def GreaterThanOrEquals(left: Tree , right: Tree ): Tree = Apply(Select(left, nme.GE), List(right)); + def GreaterThanOrEquals(left: Tree, right: Tree): Tree = + Apply(Select(left, nme.GE), List(right)) - def ThrowMatchError(pos: PositionType, obj: Tree ) = + def ThrowMatchError(pos: PositionType, obj: Tree) = atPos(pos) { Throw( New( diff --git a/src/compiler/scala/tools/nsc/matching/Npair.scala b/src/compiler/scala/tools/nsc/matching/Npair.scala index 8cb050de2e..b6d87cb270 100644 --- a/src/compiler/scala/tools/nsc/matching/Npair.scala +++ b/src/compiler/scala/tools/nsc/matching/Npair.scala @@ -1,11 +1,13 @@ -/* NSC -- new scala compiler - * Copyright 2005 LAMP/EPFL - * @author buraq +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir */ // $Id$ -package scala.tools.nsc.matching ; -import java.util.{ HashMap, TreeSet }; +package scala.tools.nsc.matching + +import java.util.{HashMap, TreeSet} + /** cartesian */ @@ -13,52 +15,46 @@ import java.util.{ HashMap, TreeSet }; */ case class Npair(nstate: Integer, nset: TreeSet) { - override def equals(that: Any): Boolean = { - this match { - case Npair(nstate, nset) => - that match { - case Npair(_nstate, _nset) => - return ((nstate == _nstate) - && (nset == _nset)); - case _ => return false - } - case _ => return false - } + override def equals(that: Any): Boolean = this match { + case Npair(nstate, nset) => + that match { + case Npair(_nstate, _nset) => + (nstate == _nstate) && (nset == _nset) + case _ => + false + } + case _ => + false } override def toString(): String = this match { case Npair(nstate, nset) => //Integer dstate = (Integer) indexMap.get(nset); ""; - case _ => null + case _ => + null } - def toString(indexMap: HashMap): String = { - //assert indexMap != null; + def toString(indexMap: HashMap): String = { + //assert indexMap != null this match { case Npair(nstate, nset) => - //assert nstate != null; - val dstate = indexMap.get( nset ).asInstanceOf[Integer]; - return ""; + //assert nstate != null + val dstate = indexMap.get( nset ).asInstanceOf[Integer] + "" case _ => - return null; + null } } - } class NpairComparator extends StateSetComparator { - override def compare(o1: Any, o2: Any): Int = { - o1 match { - case Npair(nstate, nset) => o2 match { - case Npair(_nstate, _nset) => - val res = nstate.compareTo(_nstate); - if (res != 0) - return res; - else - return super.compare(nset, _nset); - } + override def compare(o1: Any, o2: Any): Int = o1 match { + case Npair(nstate, nset) => o2 match { + case Npair(_nstate, _nset) => + val res = nstate.compareTo(_nstate) + if (res != 0) res else super.compare(nset, _nset) } } } diff --git a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala index 527f41f21d..e32cb7aa4a 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternMatchers.scala @@ -1,68 +1,73 @@ -/* NSC -- new scala compiler - * Copyright 2005 LAMP/EPFL - * @author buraq +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir */ // $Id$ -package scala.tools.nsc.matching ; +package scala.tools.nsc.matching -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.Position -trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef with PatternNodeCreator { - - - import global._; - import typer.typed ; - import symtab.Flags; +/** This trait ... + * + * @author Burak Emir + * @version 1.0 + */ +trait PatternMatchers requires (TransMatcher with PatternNodes) + extends AnyRef with PatternNodeCreator { + import global._ + import typer.typed + import symtab.Flags // -- begin new data structure for matcher - abstract class Node{} + abstract class Node class Test(var tpe: Type, var casted: Symbol) extends Node { var thenp: Node = _ - var vbles = List[Symbol](); + var vbles = List[Symbol]() def bindTo(v: Symbol): this.type = { vbles = v::vbles; this } - override def toString() = tpe.toString+"?" + override def toString() = tpe.toString + "?" } + class Load(var expr: Tree) extends Node { - def tpe = expr.tpe; + def tpe = expr.tpe var thenp: PatNodeList = Snil } - case class Return(b:Tree) extends Node {} - abstract class PatNodeList {}; - case class Snoc(sx:PatNodeList, x:Test) extends PatNodeList; - case object Snil extends PatNodeList; + case class Return(b:Tree) extends Node - // -- end + abstract class PatNodeList + case class Snoc(sx: PatNodeList, x:Test) extends PatNodeList + case object Snil extends PatNodeList - class PatternMatcher { + // -- end + class PatternMatcher { + protected var optimize = true - protected var optimize = true; + /** the owner of the pattern matching expression + */ + var owner:Symbol = _ - /** the owner of the pattern matching expression - */ - var owner:Symbol = _ ; + /** the selector expression + */ + protected var selector: Tree = _ - /** the selector expression - */ - protected var selector: Tree = _; + /** the root of the pattern node structure + */ + protected var root: PatternNode = _ - /** the root of the pattern node structure - */ - protected var root: PatternNode = _; + /** the symbol of the result variable + */ + //protected var resultVar: Symbol = _ - /** the symbol of the result variable - */ -// protected var resultVar: Symbol = _; + def defs = definitions - def defs = definitions; - /** init method, also needed in subclass AlgebraicMatcher - */ - def initialize(selector: Tree, owner: Symbol): Unit = { + /** init method, also needed in subclass AlgebraicMatcher + */ + def initialize(selector: Tree, owner: Symbol): Unit = { //Konsole.println("pm.initialize selector.tpe = "+selector.tpe); @@ -88,105 +93,101 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w this.root.and = pHeader(selector.pos, selector.tpe.widen, Ident(root.symbol).setType(root.tpe)); - //Konsole.println("resultType = "+resultType); - this.owner = owner; - this.selector = selector; + //Konsole.println("resultType = "+resultType); + this.owner = owner + this.selector = selector - //this.optimize = this.optimize && (settings.target.value == "jvm"); - } + //this.optimize = this.optimize && (settings.target.value == "jvm"); + } - /** pretty printer - */ - def print(): Unit = { Console.println ( - root.and.print("", new StringBuffer()).toString() - )} + /** pretty printer + */ + def print(): Unit = + Console.println(root.and.print("", new StringBuffer()).toString()) - /** enters a sequence of cases into the pattern matcher - */ - def construct(cases: List[Tree]): Unit = { - cases foreach enter; - } + /** enters a sequence of cases into the pattern matcher + */ + def construct(cases: List[Tree]): Unit = + cases foreach enter - /** enter a single case into the pattern matcher - */ - protected def enter(caseDef: Tree): Unit = { - caseDef match { + /** enter a single case into the pattern matcher + */ + protected def enter(caseDef: Tree): Unit = caseDef match { case CaseDef(pat, guard, body) => - val env = new CaseEnv; - // PatternNode matched = match(pat, root); - val target = enter1(pat, -1, root, root.symbol, env); + val env = new CaseEnv + // PatternNode matched = match(pat, root) + val target = enter1(pat, -1, root, root.symbol, env) // if (target.and != null) - // unit.error(pat.pos, "duplicate case"); + // unit.error(pat.pos, "duplicate case"); if (null == target.and) - target.and = pBody(caseDef.pos, env.getBoundVars(), guard, body); + target.and = pBody(caseDef.pos, env.getBoundVars(), guard, body) else if (target.and.isInstanceOf[Body]) - updateBody(target.and.asInstanceOf[Body], env.getBoundVars(), guard, body); + updateBody(target.and.asInstanceOf[Body], env.getBoundVars(), guard, body) else - cunit.error(pat.pos, "duplicate case"); + cunit.error(pat.pos, "duplicate case") } - } - protected def updateBody(tree: Body, bound: Array[ValDef], guard: Tree , body: Tree): Unit = { - if (tree.guard(tree.guard.length - 1) == EmptyTree) { - cunit.error(body.pos, "unreachable code"); - } else { - val bd = new Array[Array[ValDef]](tree.bound.length + 1); - val ng = new Array[Tree](tree.guard.length + 1); - val nb = new Array[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 ; - } - } + protected def updateBody(tree: Body, bound: Array[ValDef], + guard: Tree, body: Tree): Unit = + if (tree.guard(tree.guard.length - 1) == EmptyTree) { + cunit.error(body.pos, "unreachable code") + } else { + val bd = new Array[Array[ValDef]](tree.bound.length + 1) + val ng = new Array[Tree](tree.guard.length + 1) + val nb = new Array[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 + } - /** returns the child patterns of a pattern - */ - protected def patternArgs(tree: Tree):List[Tree] = { - //Console.println("patternArgs "+tree.toString()); - val res = tree match { - case Bind(_, pat) => - patternArgs(pat); + /** returns the child patterns of a pattern + */ + protected def patternArgs(tree: Tree): List[Tree] = { + //Console.println("patternArgs "+tree.toString()) + val res = tree match { + case Bind(_, pat) => + patternArgs(pat) - case a @ Apply(_, List(av @ ArrayValue(_, ts))) if isSeqApply(a) && isRightIgnoring(av) => - ts.reverse.drop(1).reverse + case a @ Apply(_, List(av @ ArrayValue(_, ts))) if isSeqApply(a) && isRightIgnoring(av) => + ts.reverse.drop(1).reverse - case a @ Apply(_, List(av @ ArrayValue(_, ts))) if isSeqApply(a) => - ts + case a @ Apply(_, List(av @ ArrayValue(_, ts))) if isSeqApply(a) => + ts - case a @ Apply(_, args) => - args; + case a @ Apply(_, args) => + args - case av @ ArrayValue(_, ts) if isRightIgnoring(av) => - ts.reverse.drop(1).reverse + case av @ ArrayValue(_, ts) if isRightIgnoring(av) => + ts.reverse.drop(1).reverse - case av @ ArrayValue(_, ts) => - ts; + case av @ ArrayValue(_, ts) => + ts - case _ => - List(); + case _ => + List() + } + //Console.println("patternArgs returns "+res.toString()) + res } - //Console.println("patternArgs returns "+res.toString()); - res - } /* currently no need for extendedSeqApply, ArrayValue in Elem(... _*) style patterns * handled in the ArrayValue case protected def isExtendedSeqApply( tree: Apply ): Boolean = { // NEW // Console.print("isSeqApply? "+tree.toString()); // val res = - tree match { - case Apply(_, list) if list.last.isInstanceOf[ArrayValue] => + tree match { + case Apply(_, list) if list.last.isInstanceOf[ArrayValue] => (tree.tpe.symbol.flags & Flags.CASE) == 0 - case _ => false; - } - //Console.println(res); - //res; + case _ => false; + } + //Console.println(res); + //res; } */ @@ -194,30 +195,30 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w protected def patternNode(tree:Tree , header:Header , env: CaseEnv ): PatternNode = { //if(tree!=null) Console.println("patternNode("+tree+","+header+")"); - //else scala.Predef.error("got null tree in patternNode"); + //else scala.Predef.error("got null tree in patternNode"); //Console.println("tree.tpe "+tree.tpe); //Console.println("tree.getClass() "+tree.getClass()); tree match { case Bind(name, Typed(Ident( nme.WILDCARD ), tpe)) => // x@_:Type if (isSubType(header.getTpe(),tpe.tpe)) { - //Console.println("U"); - val node = pDefaultPat(tree.pos, tpe.tpe); - env.newBoundVar( tree.symbol, tree.tpe, header.selector ); - node; + //Console.println("U") + val node = pDefaultPat(tree.pos, tpe.tpe) + env.newBoundVar(tree.symbol, tree.tpe, header.selector) + node } else { - //Console.println("X"); - val node = pConstrPat(tree.pos, tpe.tpe); + //Console.println("X") + val node = pConstrPat(tree.pos, tpe.tpe) env.newBoundVar( tree.symbol, tpe.tpe, /*scalac: tree.tpe */ typed(Ident( node.casted ))); - node; + node } case Bind(name, Ident(nme.WILDCARD)) => // x @ _ - val node = pDefaultPat(tree.pos, header.getTpe()); + val node = pDefaultPat(tree.pos, header.getTpe()) if ((env != null) && (tree.symbol != defs.PatternWildcard)) env.newBoundVar( tree.symbol, tree.tpe, header.selector); - node; + node case Bind(name, pat) => val node = patternNode(pat, header, env); @@ -226,7 +227,7 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w val theValue = if (casted == NoSymbol) header.selector else Ident( casted).setType(casted.tpe); env.newBoundVar(tree.symbol, tree.tpe, theValue); } - node; + node case t @ Apply(fn, args) => // pattern with args //Console.println("Apply node: "+t); @@ -246,7 +247,7 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w //Console.println(av.toString()+" IS N O T RIGHTIGNORING"); pSequencePat(tree.pos, tree.tpe, ts.length); } - } else if ((fn.symbol != null) && + } else if ((fn.symbol != null) && fn.symbol.isStable && !(fn.symbol.isModule && ((fn.symbol.flags & Flags.CASE) != 0))) { @@ -261,11 +262,11 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w pConstrPat(tree.pos, tree.tpe); } case Typed(Ident( nme.WILDCARD ), tpe) => // x@_:Type - val doTest = isSubType(header.getTpe(),tpe.tpe); // this is already an optimization - if(doTest) - pDefaultPat(tree.pos, tpe.tpe) - else - pConstrPat(tree.pos, tpe.tpe); + val doTest = isSubType(header.getTpe(), tpe.tpe) // this is already an optimization + if (doTest) + pDefaultPat(tree.pos, tpe.tpe) + else + pConstrPat(tree.pos, tpe.tpe) case t @ Typed(ident, tpe) => // variable pattern //Console.println("Z"); @@ -292,9 +293,9 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w .asInstanceOf[ConstrPat] .casted))}); } - node; + node - case Ident(nme.WILDCARD) => pDefaultPat(tree.pos, header.getTpe()); + case Ident(nme.WILDCARD) => pDefaultPat(tree.pos, header.getTpe()) case Ident(name) => // pattern without args or named constant if (tree.symbol.isPrimaryConstructor) @@ -327,17 +328,17 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w } case Alternative(ts) => - if(ts.length < 2) - scala.Predef.error("ill-formed Alternative"); - val subroot = pConstrPat(header.pos, header.getTpe()); - subroot.and = pHeader(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); - target.and = pBody(tree.pos); + if (ts.length < 2) + Predef.error("ill-formed Alternative") + val subroot = pConstrPat(header.pos, header.getTpe()) + subroot.and = pHeader(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) + target.and = pBody(tree.pos) i = i + 1 } - pAltPat(tree.pos, subroot.and.asInstanceOf[Header]); + pAltPat(tree.pos, subroot.and.asInstanceOf[Header]) /* case Star(Ident(nme.WILDCARD)) => header.selector match { @@ -351,41 +352,38 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w // bind the rest ///////////////////////////////////////////////////// */ case _ => - if(tree == null) - scala.Predef.error("unit = " + cunit + "; tree = null"); - else - scala.Predef.error("unit = " + cunit + "; tree = "+tree); + Predef.error("unit = " + cunit + "; tree = " + + (if (tree == null) "null" else tree)) } } - protected def enter(pat: Tree, index: Int, target: PatternNode, casted: Symbol, env: CaseEnv ): PatternNode = { + protected def enter(pat: Tree, index: Int, target: PatternNode, + casted: Symbol, env: CaseEnv): PatternNode = target match { case ConstrPat(newCasted) => - enter1(pat, index, target, newCasted, env); + enter1(pat, index, target, newCasted, env) case SequencePat(newCasted, len) => - enter1(pat, index, target, newCasted, env); + enter1(pat, index, target, newCasted, env) case _ => - enter1(pat, index, target, casted, env); + enter1(pat, index, target, casted, env) } - } - private def newHeader(pos: PositionType, casted: Symbol, index: Int): Header = { //Console.println("newHeader(pos,"+casted+","+index+")"); //Console.println(" casted.tpe"+casted.tpe); //Console.println(" casted.pos "+casted.pos+" equals firstpos?"+(casted.pos == Position.FIRSTPOS)); - val ident = typed(Ident(casted)); + val ident = typed(Ident(casted)) if (casted.pos == Position.FIRSTPOS) { //Console.println("FIRSTPOS"); - //Console.println("DEBUG"); - //Console.println(); + //Console.println("DEBUG") + //Console.println() val t = typed( Apply(Select( ident, ident.tpe.member(nme.apply)/* scalac: defs.functionApply( 1 )*/), List( Literal( Constant(index) ) ))); - val seqType = t.tpe; - pHeader( pos, seqType, t ); + val seqType = t.tpe + pHeader( pos, seqType, t ) } else { //Console.println("NOT FIRSTPOS"); // Console.println("newHeader :: casted="+casted); @@ -428,10 +426,10 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w //System.err.println("patArgs = "+patArgs); var curHeader: Header = target.and match { case null => null - case h: Header => h; // advance one step in intermediate representation + case h: Header => h // advance one step in intermediate representation case b: Body if b.or != null => b.or.asInstanceOf[Header] case b: Body => - if(b.guard(b.guard.length - 1) == EmptyTree) { + if (b.guard(b.guard.length - 1) == EmptyTree) { cunit.error(pat.pos, "unreachable code") null } @@ -442,22 +440,22 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w } if (curHeader == null) { // check if we have to add a new header //assert index >= 0 : casted; - if (index < 0) { scala.Predef.error("error entering:" + casted); return null } + if (index < 0) { Predef.error("error entering:" + casted); return null } target.and = {curHeader = newHeader(pat.pos, casted, index); curHeader}; // (*) - if(bodycond != null) + if (bodycond != null) target.and = bodycond(target.and) // restores body with the guards - curHeader.or = patternNode(pat, curHeader, env); - enter(patArgs, curHeader.or, casted, env); + curHeader.or = patternNode(pat, curHeader, env) + enter(patArgs, curHeader.or, casted, env) } else { // find most recent header while (curHeader.next != null) - curHeader = curHeader.next; + curHeader = curHeader.next // create node - var patNode = patternNode(pat, curHeader, env); - var next: PatternNode = curHeader; + var patNode = patternNode(pat, curHeader, env) + var next: PatternNode = curHeader // add branch to curHeader, but reuse tests if possible while (true) { if (next.isSameAs(patNode)) { // test for patNode already present --> reuse @@ -492,69 +490,74 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w } } - /** calls enter for an array of patterns, see enter - */ - protected def enter(pats:List[Tree], target1: PatternNode , casted1: Symbol , env: CaseEnv): PatternNode = { - var target = target1; - var casted = casted1; - target match { - case ConstrPat(newCasted) => - casted = newCasted; - case SequencePat(newCasted, len) => - casted = newCasted; - case RightIgnoringSequencePat(newCasted, _, len) => - casted = newCasted; - case _ => - } - var i = 0; while(i < pats.length) { - target = enter1(pats(i), i, target, casted, env); - i = i + 1 + /** calls enter for an array of patterns, see enter + * + * @param pats ... + * @param target1 ... + * @param casted1 ... + * @param env ... + * @return ... + */ + protected def enter(pats: List[Tree], target1: PatternNode, + casted1: Symbol, env: CaseEnv): PatternNode = { + var target = target1 + var casted = casted1 + target match { + case ConstrPat(newCasted) => + casted = newCasted + case SequencePat(newCasted, len) => + casted = newCasted + case RightIgnoringSequencePat(newCasted, _, len) => + casted = newCasted + case _ => + } + var i = 0; while (i < pats.length) { + target = enter1(pats(i), i, target, casted, env) + i = i + 1 + } + target } - target; - } protected def nCaseComponents(tree: Tree): int = { - tree match { - case Apply(fn, _) => - val tpe = tree.tpe.symbol.primaryConstructor.tpe; + tree match { + case Apply(fn, _) => + 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 + 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 NoType => - error("this cannot happen"); + error("this cannot happen") 0 case MethodType(args, _) => - args.length; + args.length case PolyType(tvars, MethodType(args, _)) => - args.length; + args.length case PolyType(tvars, _) => - 0; + 0 case _ => error("not yet implemented;" + "pattern matching for " + tree + ": " + tpe); } } - return 0; + 0 } //////////// generator methods - def toTree(): Tree = { + def toTree(): Tree = if (optimize && isSimpleIntSwitch()) - intSwitchToTree(); - - else /* if (false && optimize && isSimpleSwitch()) - switchToTree(); - else */ { - //print(); - generalSwitchToTree(); + intSwitchToTree() + // else if (false && optimize && isSimpleSwitch()) + // switchToTree() + else { + //print() + generalSwitchToTree() } - } - case class Break(res:Boolean) extends java.lang.Throwable; - case class Break2() extends java.lang.Throwable; + case class Break(res:Boolean) extends java.lang.Throwable + case class Break2() extends java.lang.Throwable // TODO disentangle this protected def isSimpleSwitch(): Boolean = { @@ -608,12 +611,12 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w } patNode = patNode.nextH(); } - return true; + true } protected def isSimpleIntSwitch(): Boolean = { if (isSameType(selector.tpe.widen, defs.IntClass.tpe)) { - var patNode = root.and; + var patNode = root.and while (patNode != null) { var node = patNode; while (({node = node.or; node}) != null) { @@ -639,56 +642,54 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w return false; } - class TagBodyPair(tag1: Int, body1: Tree, next1:TagBodyPair ) { + class TagBodyPair(tag1: Int, body1: Tree, next1: TagBodyPair ) { + var tag: int = tag1 + var body: Tree = body1 + var next: TagBodyPair = next1 - var tag: int = tag1; - var body: Tree = body1; - var next: TagBodyPair = next1; - - def length(): Int = { - if (null == next) 1 else (next.length() + 1); - } + def length(): Int = + if (null == next) 1 else (next.length() + 1) } protected def numCases(patNode1: PatternNode): Int = { - var patNode = patNode1; - var n = 0; + var patNode = patNode1 + var n = 0 while (({patNode = patNode.or; patNode}) != null) patNode match { case DefaultPat() => ; case _ => - n = n + 1; + n = n + 1 } - n; + n } protected def defaultBody(patNode1: PatternNode, otherwise: Tree ): Tree = { var patNode = patNode1; while (patNode != null) { - var node = patNode; + var node = patNode while (({node = node.or; node}) != null) node match { case DefaultPat() => return node.and.bodyToTree(); case _ => } - patNode = patNode.nextH(); + patNode = patNode.nextH() } - otherwise; + otherwise } /** This method translates pattern matching expressions that match * on integers on the top level. */ def intSwitchToTree(): Tree = { - def insert1(tag: Int, body: Tree, current: TagBodyPair): TagBodyPair = { - if (current == null) - return new TagBodyPair(tag, body, null); - else if (tag > current.tag) - return new TagBodyPair(current.tag, current.body, insert1(tag, body, current.next)); - else - return new TagBodyPair(tag, body, current); - } + def insert1(tag: Int, body: Tree, current: TagBodyPair): TagBodyPair = { + if (current == null) + new TagBodyPair(tag, body, null) + else if (tag > current.tag) + new TagBodyPair(current.tag, current.body, insert1(tag, body, current.next)) + else + new TagBodyPair(tag, body, current) + } //print(); val ncases = numCases(root.and); @@ -710,14 +711,14 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w } // // if we have more than 2 cases than use a switch statement - val _h:Header = root.and.asInstanceOf[Header]; + val _h:Header = root.and.asInstanceOf[Header] - val next = _h.next; - var mappings: TagBodyPair = null; - var defaultBody1: Tree = matchError; - var patNode = root.and; + val next = _h.next + var mappings: TagBodyPair = null + var defaultBody1: Tree = matchError + var patNode = root.and while (patNode != null) { - var node = patNode.or; + var node = patNode.or while (node != null) { node match { case DefaultPat() => @@ -734,11 +735,11 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w node = node.or; } } - patNode = patNode.nextH(); + patNode = patNode.nextH() } - var n = mappings.length(); - var nCases: List[CaseDef] = Nil; + var n = mappings.length() + var nCases: List[CaseDef] = Nil while (mappings != null) { nCases = CaseDef(Literal(mappings.tag), mappings.body) :: nCases; @@ -757,11 +758,11 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w return Switch(selector, tags, bodies, defaultBody1, resultType); */ nCases = CaseDef(Ident(nme.WILDCARD), Block(List(ValDef(root.symbol, selector)),defaultBody1)) :: nCases; - return Match(selector, nCases) + Match(selector, nCases) } - var exit:Symbol = null; + var exit: Symbol = null /** simple optimization: if the last pattern is `case _' (no guards), we won't generate the ThrowMatchError */ def generalSwitchToTree(): Tree = { @@ -830,9 +831,9 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w node = next; case _b:Body => - var bound = _b.bound; - val guard = _b.guard; - val body = _b.body; + var bound = _b.bound + val guard = _b.guard + val body = _b.body if ((bound.length == 0) && (guard.length == 0) && (body.length == 0)) { @@ -866,15 +867,13 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w return res; } - class TagNodePair(tag1: int, node1: PatternNode, next1: TagNodePair) { - var tag: int = tag1; - var node: PatternNode = node1; - var next: TagNodePair = next1; + var tag: int = tag1 + var node: PatternNode = node1 + var next: TagNodePair = next1 - def length(): Int = { - return if (null == next) 1 else (next.length() + 1); - } + def length(): Int = + if (null == next) 1 else (next.length() + 1) } protected def toOptTree(node1: PatternNode, selector: Tree): Tree = { @@ -891,29 +890,29 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w return new TagNodePair(tag, node, current); } - def insertNode(tag:int , node:PatternNode , current:TagNodePair ): TagNodePair = { - val newnode = node.dup(); - newnode.or = null; - return insert2(tag, newnode, current); + def insertNode(tag: int, node: PatternNode, current:TagNodePair): TagNodePair = { + val newnode = node.dup() + newnode.or = null + insert2(tag, newnode, current) } var node = node1; //System.err.println("pm.toOptTree called"+node); - var cases: TagNodePair = null; - var defaultCase: PatternNode = null; + var cases: TagNodePair = null + var defaultCase: PatternNode = null while (node != null) node match { case ConstrPat(casted) => - cases = insertNode(node.getTpe().symbol.tag, node, cases); - node = node.or; + cases = insertNode(node.getTpe().symbol.tag, node, cases) + node = node.or case DefaultPat() => - defaultCase = node; - node = node.or; + defaultCase = node + node = node.or case _ => - scala.Predef.error("errare humanum est"); + scala.Predef.error("errare humanum est") } - var n = cases.length(); + var n = cases.length() /* val tags = new Array[int](n); val bodies = new Array[Tree](n); @@ -938,17 +937,16 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w { if (defaultCase == null) Literal(false) else toTree(defaultCase.and) }, defs.boolean_TYPE()); */ - var nCases: List[CaseDef] = Nil; + var nCases: List[CaseDef] = Nil while (cases != null) { nCases = CaseDef(Literal(Constant(cases.tag)), toTree(cases.node, selector)) :: nCases; - cases = cases.next; + cases = cases.next } - val defBody = if (defaultCase == null) - Literal(Constant(false)) - else - toTree(defaultCase.and); + val defBody = + if (defaultCase == null) Literal(Constant(false)) + else toTree(defaultCase.and) nCases = CaseDef(Ident(nme.WILDCARD), defBody) :: nCases; return Match(Apply(Select(selector.duplicate, defs.ScalaObjectClass_tag), @@ -956,20 +954,23 @@ trait PatternMatchers requires (TransMatcher with PatternNodes) extends AnyRef w nCases); } - /** why not use plain `if's? the reason is that a failing *guard* must still remain - * on the testing path (a kind of backtracking) in order to test subsequent patterns - * consider for instance bug#440 - * - */ - def myIf(cond:Tree,thenp:Tree,elsep:Tree) = { - Or(And(cond,thenp),elsep); - } - - protected def toTree(node:PatternNode , selector:Tree ): Tree = { - //Console.println("pm.toTree("+node+","+selector+")"); - //Console.println("pm.toTree selector.tpe = "+selector.tpe+")"); - if(selector.tpe == null) - scala.Predef.error("cannot go on"); + /** why not use plain `if's? the reason is that a failing *guard* must still remain + * on the testing path (a kind of backtracking) in order to test subsequent patterns + * consider for instance bug#440 + * + * @param cond ... + * @param thenp ... + * @param elsep ... + * @return ... + */ + def myIf(cond: Tree, thenp: Tree, elsep: Tree) = + Or(And(cond, thenp), elsep) + + protected def toTree(node: PatternNode, selector:Tree): Tree = { + //Console.println("pm.toTree("+node+","+selector+")") + //Console.println("pm.toTree selector.tpe = "+selector.tpe+")") + if (selector.tpe == null) + scala.Predef.error("cannot go on") if (node == null) return Literal(Constant(false)); else diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodeCreator.scala b/src/compiler/scala/tools/nsc/matching/PatternNodeCreator.scala index 577e785745..74fbf6f908 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodeCreator.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodeCreator.scala @@ -1,118 +1,164 @@ -package scala.tools.nsc.matching; +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir + */ +// $Id$ + +package scala.tools.nsc.matching -import scala.tools.nsc.util.Position; -import scala.tools.nsc.symtab.Flags; +import scala.tools.nsc.symtab.Flags +import scala.tools.nsc.util.Position /** PatternNode factory. * we inherit the globals from PatternTool. */ trait PatternNodeCreator requires (TransMatcher with PatternNodes) { - - import global._; - def pSequencePat(pos: PositionType , tpe:Type , len:int) = { - //assert (tpe != null); - val sym = newVar(FirstPos, tpe); - //Console.println("pncrea::sequencePat sym.pos = "+sym.pos); - val node = new SequencePat(sym, len); - node.pos = pos; - node.tpe = tpe; - //Console.println("pncrea::sequencePat sym.pos = "+sym.pos); - node; + import global._ + + /** + * @param pos ... + * @param tpe ... + * @param len ... + * @return ... + */ + def pSequencePat(pos: PositionType, tpe: Type, len: int) = { + //assert (tpe != null) + val sym = newVar(FirstPos, tpe) + //Console.println("pncrea::sequencePat sym.pos = "+sym.pos) + val node = new SequencePat(sym, len) + node.pos = pos + node.tpe = tpe + //Console.println("pncrea::sequencePat sym.pos = "+sym.pos) + node } - def pRightIgnoringSequencePat(pos: PositionType, tpe:Type, castedRest1: Symbol, minlen:int) = { - //assert (tpe != null); - val sym = newVar(FirstPos, tpe); - var castedRest = if(castedRest1 != null) castedRest1 else newVar(pos, tpe); - val node = new RightIgnoringSequencePat(sym, castedRest, minlen); - node.pos = pos; - node.tpe = tpe; - node; + /** + * @param pos ... + * @param tpe ... + * @param castedRest1 ... + * @param minlen ... + * @return ... + */ + def pRightIgnoringSequencePat(pos: PositionType, tpe: Type, + castedRest1: Symbol, minlen: int) = { + //assert (tpe != null) + val sym = newVar(FirstPos, tpe) + var castedRest = if(castedRest1 != null) castedRest1 else newVar(pos, tpe) + val node = new RightIgnoringSequencePat(sym, castedRest, minlen) + node.pos = pos + node.tpe = tpe + node } - def pSeqContainerPat(pos: PositionType, tpe: Type, seqpat:Tree ) = { - //assert (tpe != null); - val sym = newVar(NoPos, tpe); - val node = new SeqContainerPat(sym, seqpat); - node.pos = pos; - node.setType(tpe); - node; + /** + * @param pos ... + * @param tpe ... + * @param seqpat ... + * @return ... + */ + def pSeqContainerPat(pos: PositionType, tpe: Type, seqpat: Tree ) = { + //assert (tpe != null) + val sym = newVar(NoPos, tpe) + val node = new SeqContainerPat(sym, seqpat) + node.pos = pos + node.setType(tpe) + node } + /** + * @param pos ... + * @param tpe ... + * @return ... + */ def pDefaultPat(pos: PositionType, tpe: Type) = { - //assert (tpe != null); - val node = new DefaultPat(); - node.pos = pos; - node.setType(tpe); - node; + //assert (tpe != null) + val node = new DefaultPat() + node.pos = pos + node.setType(tpe) + node } def pConstrPat(pos: PositionType, tpe: Type) = { - //assert (tpe != null); - val node = new ConstrPat(newVar(pos, tpe)); - node.pos = pos; - node.setType(tpe); - node; + //assert (tpe != null) + val node = new ConstrPat(newVar(pos, tpe)) + node.pos = pos + node.setType(tpe) + node } - def pConstantPat(pos: PositionType, tpe: Type, value: Any /*AConstant*/ ) = { - //assert (tpe != null); - val node = new ConstantPat( value ); - node.pos = pos; - node.setType(tpe); - node; + def pConstantPat(pos: PositionType, tpe: Type, value: Any /*AConstant*/) = { + //assert (tpe != null) + val node = new ConstantPat(value) + node.pos = pos + node.setType(tpe) + node } - def pVariablePat(pos: PositionType, tree:Tree) = { - //assert (tree.tpe != null); - val node = new VariablePat( tree ); - node.pos = pos; - node.setType(tree.tpe); - node; + def pVariablePat(pos: PositionType, tree: Tree) = { + //assert (tree.tpe != null) + val node = new VariablePat(tree) + node.pos = pos + node.setType(tree.tpe) + node } - def pAltPat(pos: PositionType, header:Header ) = { - val node = new AltPat(header); - node.pos = pos; - node.setType(header.getTpe()); - node; + /** + * @param pos ... + * @param header ... + * @return ... + */ + def pAltPat(pos: PositionType, header: Header) = { + val node = new AltPat(header) + node.pos = pos + node.setType(header.getTpe()) + node } // factories - def pHeader(pos: PositionType, tpe: Type, selector:Tree) = { - //assert (tpe != null); - val node = new Header(selector, null); - node.pos = pos; - node.setType(tpe); - node; + def pHeader(pos: PositionType, tpe: Type, selector: Tree) = { + //assert (tpe != null) + val node = new Header(selector, null) + node.pos = pos + node.setType(tpe) + node } def pBody(pos: PositionType) = { - val node = new Body(new Array[Array[ValDef]](0), new Array[Tree](0), new Array[Tree](0)); - node.pos = pos; - node; + val node = new Body(new Array[Array[ValDef]](0), + new Array[Tree](0), + new Array[Tree](0)) + node.pos = pos + node } - def pBody(pos: PositionType, bound:Array[ValDef] , guard:Tree, body:Tree) = { - val node = new Body(Predef.Array[Array[ValDef]](bound), Predef.Array[Tree](guard), Predef.Array[Tree](body)); - node.pos = pos; - node; + def pBody(pos: PositionType, bound: Array[ValDef], guard: Tree, body: Tree) = { + val node = new Body(Predef.Array[Array[ValDef]](bound), + Predef.Array[Tree](guard), + Predef.Array[Tree](body)) + node.pos = pos + node } - def newVar(pos: PositionType, name: Name, tpe: Type): Symbol= { + /** + * @param pos ... + * @param name ... + * @param tpe ... + * @return ... + */ + def newVar(pos: PositionType, name: Name, tpe: Type): Symbol = { /** hack: pos has special meaning*/ - val sym = currentOwner.newVariable(pos, name); - //Console.println("patnodcre::newVar sym = "+sym+ "tpe = "+tpe); - sym.setInfo(tpe); - //System.out.println("PatternNodeCreator::newVar creates symbol "+sym); - //System.out.println("owner: "+sym.owner()); - sym; + val sym = currentOwner.newVariable(pos, name) + //Console.println("patnodcre::newVar sym = "+sym+ "tpe = "+tpe) + sym.setInfo(tpe) + //System.out.println("PatternNodeCreator::newVar creates symbol "+sym) + //System.out.println("owner: "+sym.owner()) + sym } - def newVar(pos: PositionType, tpe: Type): Symbol = { - newVar(pos, cunit.fresh.newName("temp"), tpe).setFlag(Flags.SYNTHETIC); - } + def newVar(pos: PositionType, tpe: Type): Symbol = + newVar(pos, cunit.fresh.newName("temp"), tpe).setFlag(Flags.SYNTHETIC) + } diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala index 4a899010b9..80c90d6eff 100644 --- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala +++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala @@ -1,375 +1,350 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** -** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** -** /_____/\____/\___/\____/____/ ** -** ** -** $Id$ -\* */ +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir + */ +// $Id$ -package scala.tools.nsc.matching ; +package scala.tools.nsc.matching -import scala.tools.nsc.util.Position; +import scala.tools.nsc.util.Position trait PatternNodes requires TransMatcher { - import global._; + import global._ /** Intermediate data structure for algebraic + pattern matcher */ class PatternNode { - var pos = FirstPos; - var tpe: Type = _; - var or: PatternNode = _; - var and: PatternNode = _; - - def bodyToTree(): Tree = this match { - case _b:Body => - return _b.body(0); - } - - def getTpe(): Type = { - tpe; - } - def setType(tpe: Type): Unit = { - this.tpe = tpe; - } + var pos = FirstPos + var tpe: Type = _ + var or: PatternNode = _ + var and: PatternNode = _ + + def bodyToTree(): Tree = this match { + case _b:Body => + _b.body(0) + } - def dup(): PatternNode = { - var res: PatternNode = null; - this match { - case h:Header => - res = new Header(h.selector, h.next); + def getTpe(): Type = tpe - case b:Body=> - res = new Body(b.bound, b.guard, b.body); + def setType(tpe: Type): Unit = { this.tpe = tpe } - case DefaultPat() => - res = DefaultPat(); + def dup(): PatternNode = { + var res: PatternNode = this match { + case h:Header => + new Header(h.selector, h.next) + case b:Body=> + new Body(b.bound, b.guard, b.body) + case DefaultPat() => + DefaultPat() + case ConstrPat(casted) => + ConstrPat(casted) + case SequencePat(casted, len) => + SequencePat(casted, len) + case SeqContainerPat(casted, seqpat) => + SeqContainerPat(casted, seqpat) + case ConstantPat(value) => + ConstantPat(value) + case VariablePat(tree) => + VariablePat(tree) + case AltPat(subheader) => + AltPat(subheader) + case _ => + error(""); null + } + res.pos = pos + res.tpe = tpe + res.or = or + res.and = and + res + } + def symbol: Symbol = this match { 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); + casted + case SequencePat(casted, _) => + casted + case SeqContainerPat(casted, _) => + casted + case _ => + NoSymbol //.NONE + } - case AltPat(subheader) => - res = AltPat(subheader); + def nextH(): PatternNode = this match { + case _h:Header => _h.next + case _ => null + } - case _ => - error("") + def isDefaultPat(): boolean = this match { + case DefaultPat() => true + case _ => false } - 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; + /** 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) => + (plen == qlen) && isSameType(q.getTpe(), this.getTpe()) + case _ => + false + } case _ => - return NoSymbol; //.NONE; + subsumes(q) } - } - def nextH(): PatternNode = { - this match { - case _h:Header => - return _h.next; + /** 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 == 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 _ => - return null; + false } - } - def isDefaultPat(): boolean = { - this match { + override def toString(): String = this match { + case _h:Header => + "Header(" + _h.selector + ")"; + case _b:Body => + "Body" case DefaultPat() => - return true; + "DefaultPat" + case ConstrPat(casted) => + "ConstrPat(" + casted + ")" + case SequencePat(casted, len) => + "SequencePat(" + casted + ", " + len + "...)" + case RightIgnoringSequencePat(casted, castedRest, minlen) => + "RightIgnoringSequencePat(" + casted + ", " + castedRest + ", "+ minlen + "...)" + case SeqContainerPat(casted, seqpat) => + "SeqContainerPat(" + casted + ", " + seqpat + ")" + case ConstantPat(value) => + "ConstantPat(" + value + ")" + case VariablePat(tree) => + "VariablePat" 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 == 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 RightIgnoringSequencePat(casted, castedRest, minlen) => - return "RightIgnoringSequencePat(" + casted + ", " + castedRest + ", "+ minlen + "...)"; - case SeqContainerPat(casted, seqpat) => - return "SeqContainerPat(" + casted + ", " + seqpat + ")"; - case ConstantPat(value) => - return "ConstantPat(" + value + ")"; - case VariablePat(tree) => - return "VariablePat"; - case _ => - return ""; - } - } - - def print(indent: String, sb: StringBuffer): StringBuffer = { - - val patNode = this; - - def cont = if (patNode.or != null) patNode.or.print(indent, sb); else sb; - - def newIndent(s: String) = { - val removeBar: Boolean = (null == patNode.or); - val sb = new StringBuffer(); - sb.append(indent); - if (removeBar) - sb.setCharAt(indent.length() - 1, ' '); - var i = 0; while (i < s.length()) { - sb.append(' '); - i = i + 1 + def print(indent: String, sb: StringBuffer): StringBuffer = { + val patNode = this + + def cont = if (patNode.or != null) patNode.or.print(indent, sb) else sb + + def newIndent(s: String) = { + val removeBar: Boolean = (null == patNode.or) + val sb = new StringBuffer() + sb.append(indent) + if (removeBar) + sb.setCharAt(indent.length() - 1, ' ') + var i = 0; while (i < s.length()) { + sb.append(' ') + i = i + 1 + } + sb.toString() } - sb.toString() - } - if (patNode == null) - sb.append(indent).append("NULL"); - else - patNode match { + if (patNode == null) + sb.append(indent).append("NULL") + else + patNode match { case _h: Header => - val selector = _h.selector; - val next = _h.next; + val selector = _h.selector + val next = _h.next sb.append(indent + "HEADER(" + patNode.getTpe() + - ", " + selector + ")").append('\n'); - patNode.or.print(indent + "|", sb); + ", " + selector + ")").append('\n') + patNode.or.print(indent + "|", sb) if (next != null) - next.print(indent, sb); + next.print(indent, sb) else sb case ConstrPat(casted) => val s = ("-- " + patNode.getTpe().symbol.name + - "(" + patNode.getTpe() + ", " + casted + ") -> "); - val nindent = newIndent(s); - sb.append(nindent + s).append('\n'); - patNode.and.print(nindent, sb); - cont; + "(" + patNode.getTpe() + ", " + casted + ") -> ") + val nindent = newIndent(s) + sb.append(nindent + s).append('\n') + patNode.and.print(nindent, sb) + cont case SequencePat( casted, plen ) => val s = ("-- " + patNode.getTpe().symbol.name + "(" + patNode.getTpe() + - ", " + casted + ", " + plen + ") -> "); - val nindent = newIndent(s); - sb.append(indent + s).append('\n'); - patNode.and.print(nindent, sb); - cont; + ", " + casted + ", " + plen + ") -> ") + val nindent = newIndent(s) + sb.append(indent + s).append('\n') + patNode.and.print(nindent, sb) + cont case DefaultPat() => - sb.append(indent + "-- _ -> ").append('\n'); + sb.append(indent + "-- _ -> ").append('\n') patNode.and.print(indent.substring(0, indent.length() - 1) + - " ", sb); - cont; + " ", sb) + cont case ConstantPat(value) => - val s = "-- CONST(" + value + ") -> "; - val nindent = newIndent(s); - sb.append(indent + s).append('\n'); - patNode.and.print( nindent, sb); - cont; + val s = "-- CONST(" + value + ") -> " + val nindent = newIndent(s) + sb.append(indent + s).append('\n') + patNode.and.print( nindent, sb) + cont case VariablePat(tree) => - val s = "-- STABLEID(" + tree + ": " + patNode.getTpe() + ") -> "; - val nindent = newIndent(s); - sb.append(indent + s).append('\n'); - patNode.and.print(nindent, sb); - cont; + val s = "-- STABLEID(" + tree + ": " + patNode.getTpe() + ") -> " + val nindent = newIndent(s) + sb.append(indent + s).append('\n') + patNode.and.print(nindent, sb) + cont case AltPat(header) => - sb.append(indent + "-- ALTERNATIVES:").append('\n'); - header.print(indent + " * ", sb); - patNode.and.print(indent + " * -> ", sb); - cont; + sb.append(indent + "-- ALTERNATIVES:").append('\n') + header.print(indent + " * ", sb) + patNode.and.print(indent + " * -> ", sb) + cont case _b:Body => if ((_b.guard.length == 0) && (_b.body.length == 0)) - sb.append(indent + "true").append('\n') ; + sb.append(indent + "true").append('\n') else - sb.append(indent + "BODY(" + _b.body.length + ")").append('\n'); + sb.append(indent + "BODY(" + _b.body.length + ")").append('\n') } - } // def print + } // def print - } + } // class PatternNode - class Header(sel1: Tree, next1: Header ) extends PatternNode { - var selector: Tree = sel1; - var next: Header = next1; + 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; + 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 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 RightIgnoringSequencePat(casted: Symbol, castedRest: Symbol, minlen: int) extends PatternNode; //PM - case class SeqContainerPat(casted: Symbol , seqpat: Tree ) extends PatternNode; // in AlgebraicMatcher + case class RightIgnoringSequencePat(casted: Symbol, castedRest: Symbol, minlen: int) extends PatternNode //PM + 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; + private var boundVars: Array[ValDef] = new Array[ValDef](4) + private var numVars = 0 + + /** substitutes a symbol on the right hand side of a ValDef + * + * @param oldSymm ... + * @param newInit ... + */ + 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 + } + } - /** 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 = { - //if(sym == Symbol.NoSymbol ) { -// scala.Predef.Error("can't add variable with NoSymbol"); -// } - // 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; + /** + * @param sym ... + * @param tpe ... + * @param init ... + */ + def newBoundVar(sym: Symbol, tpe: Type, init: Tree): Unit = { + //if(sym == Symbol.NoSymbol ) { + // scala.Predef.Error("can't add variable with NoSymbol"); + //} + //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 } - 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; + val newVars = new Array[ValDef](numVars) + System.arraycopy(boundVars, 0, newVars, 0, numVars) + newVars } override def equals(obj: Any): Boolean = { if (!(obj.isInstanceOf[CaseEnv])) - return false; - val env = obj.asInstanceOf[CaseEnv]; + return false + val env = obj.asInstanceOf[CaseEnv] if (env.numVars != numVars) - return false; - var i = 0; while(i < 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 false + i = i + 1 } - return true; + true } } // class CaseEnv - } diff --git a/src/compiler/scala/tools/nsc/matching/StateSetComparator.scala b/src/compiler/scala/tools/nsc/matching/StateSetComparator.scala index 99942f38d5..4caf8f9fa6 100644 --- a/src/compiler/scala/tools/nsc/matching/StateSetComparator.scala +++ b/src/compiler/scala/tools/nsc/matching/StateSetComparator.scala @@ -1,34 +1,34 @@ -package scala.tools.nsc.matching ; +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Burak Emir + */ +// $Id$ -import java.util.{Comparator, TreeSet} ; +package scala.tools.nsc.matching + +import java.util.{Comparator, TreeSet} class StateSetComparator extends Comparator { + // use lexicographic order - def compare(o1: Any , o2: Any ): Int = { - /* - System.out.print("lexi" ); - System.out.print( o1 +" "); - System.out.println( o2 ); - */ - val it1 = o1.asInstanceOf[TreeSet].iterator(); - val it2 = o2.asInstanceOf[TreeSet].iterator(); - while( it1.hasNext() ) { - while( it2.hasNext() ) { - if( !it1.hasNext() ) + def compare(o1: Any, o2: Any): Int = { + val it1 = o1.asInstanceOf[TreeSet].iterator() + val it2 = o2.asInstanceOf[TreeSet].iterator() + while (it1.hasNext()) { + while (it2.hasNext()) { + if (!it1.hasNext()) return -1; - val i1 = it1.next().asInstanceOf[Integer].intValue(); - val i2 = it2.next().asInstanceOf[Integer].intValue(); - if( i1 < i2 ) + val i1 = it1.next().asInstanceOf[Integer].intValue() + val i2 = it2.next().asInstanceOf[Integer].intValue() + if (i1 < i2) return -1; - else if ( i1 > i2 ) + else if (i1 > i2) return 1; } - if( it1.hasNext() ) + if (it1.hasNext()) return 1; } - if( it2.hasNext() ) - return -1; - return 0; + if (it2.hasNext()) -1 else 0 } } -- cgit v1.2.3