diff options
author | buraq <buraq@epfl.ch> | 2005-01-26 12:05:37 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2005-01-26 12:05:37 +0000 |
commit | 0afb3068dacf780770558b9dc940c7f762fe1ed8 (patch) | |
tree | 9c8b03675f9239d24d8a8229f2b5a5d0e0f80ac2 | |
parent | 0b6ef8dc59098780b588f3ecda2489c59990c82b (diff) | |
download | scala-0afb3068dacf780770558b9dc940c7f762fe1ed8.tar.gz scala-0afb3068dacf780770558b9dc940c7f762fe1ed8.tar.bz2 scala-0afb3068dacf780770558b9dc940c7f762fe1ed8.zip |
translations from Java
18 files changed, 1069 insertions, 83 deletions
diff --git a/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala b/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala index f4de977abe..9d566fcb1d 100644 --- a/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala +++ b/sources/scala/tools/scalac/transformer/matching/AlgebraicMatcher.scala @@ -17,12 +17,9 @@ import scalac.util._; // Names import scala.tools.scalac.util.NewArray; import scalac.transformer.{ OwnerTransformer => scalac_transformer_OwnerTransformer }; -import scalac.transformer.matching.PartialMatcher ; -//import scalac.transformer.matching.PatternMatcher ; - -import scalac.transformer.matching.PatternNode ; +//import scalac.transformer.matching.PatternNode ; //import scalac.transformer.matching.SequenceMatcher ; -import PatternNode._ ; +//import PatternNode._ ; package scala.tools.scalac.transformer.matching { diff --git a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala b/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala index 4572c6fbdf..32018a870b 100644 --- a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala +++ b/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala @@ -15,15 +15,12 @@ import scalac.util._; // Names import scala.tools.scalac.util.NewArray; import scalac.transformer.{ OwnerTransformer => scalac_transformer_OwnerTransformer }; -import scalac.transformer.matching.PartialMatcher ; -//import scalac.transformer.matching.PatternMatcher ; - -import scalac.transformer.matching.CodeFactory ; +//import scalac.transformer.matching.CodeFactory ; import scalac.transformer.matching.DetWordAutom ; -import scalac.transformer.matching.PatternNode ; +//import scalac.transformer.matching.PatternNode ; import scalac.transformer.matching.Label ; -//import scalac.transformer.matching.SequenceMatcher ; -import PatternNode._ ; + +//import PatternNode._ ; import Label._ ; diff --git a/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala b/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala new file mode 100644 index 0000000000..2d3a283dac --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/CaseEnv.scala @@ -0,0 +1,73 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + + +import scalac._; +import scalac.ast._; +import scalac.util._; +import scalac.symtab._; +import Tree.ValDef; + +package scala.tools.scalac.transformer.matching { + +/** 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).rhs = newInit; + return; + } + i = i + 1; + } + } + + def newBoundVar(sym:Symbol, tpe: Type, init:Tree ): Unit = { + sym.setOwner( owner ); // FIXME should be corrected earlier + if (numVars == boundVars.length) { + val newVars = new Array[ValDef](numVars * 2); + System.arraycopy(boundVars, 0, newVars, 0, numVars); + this.boundVars = newVars; + } + sym.setType(tpe); + this.boundVars(numVars) = unit.global.treeGen.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) || + !boundVars(i).tpe.getType().isSameAs(env.boundVars(i).tpe.getType()) || + (boundVars(i).rhs != env.boundVars(i).rhs)) + return false; + i = i + 1; + } + return true; + } + +} // class CaseEnv +} diff --git a/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala b/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala new file mode 100644 index 0000000000..f664ec69d8 --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/CodeFactory.scala @@ -0,0 +1,287 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + + +import scala.tools.util.Position; + +import scalac._; +import scalac.ast._; +import scalac.atree.AConstant._; +import scalac.util._; +import scalac.symtab._; +//import PatternNode._; +import Tree._; +package scala.tools.scalac.transformer.matching { + +class CodeFactory(val unit: CompilationUnit, pos1: Int) extends PatternTool(unit) { + + var pos = pos1; + + // --------- these are new + + /** a faked switch statement + */ + def Switch(condition: Array[Tree], body: Array[Tree], defaultBody: Tree ): Tree = { + //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; + while(i >= 0) { + result = gen.If(condition(i), body(i), result); + i = i - 1 + } + + return result ; + } + + /** returns `List[ Tuple2[ scala.Int, <elemType> ] ]' */ + def SeqTraceType( elemType: Type ): Type = { + defs.LIST_TYPE(pairType(defs.int_TYPE(), elemType)); + } + + /** returns `Iterator[ elemType ]' */ + def _seqIterType( elemType: Type ): Type = { + defs.ITERATOR_TYPE(elemType); + } + + /** returns `<seqObj.elements>' */ + def newIterator( seqObj:Tree , elemType:Type ): Tree = { + gen.mkApply__(gen.Select(seqObj, defs.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.getType() )); + } + + // EXPERIMENTAL + def newRef(init: Tree): Tree = { + //System.out.println( "hello:"+refSym().type() ); + gen.New( gen.mkApplyTV( gen.mkPrimaryConstructorGlobalRef( pos, defs.REF_CLASS), + Predef.Array[Type] ( init.getType() ), + Predef.Array[Tree] ( init ) )); + } + + /** returns A for T <: Sequence[ A ] + */ + def getElemType_Sequence( tpe: Type): Type = { + //System.err.println("getElemType_Sequence("+tpe.widen()+")"); + val tpe1 = tpe.widen().baseType( defs.SEQ_CLASS ); + + if( tpe1 == Type.NoType ) + throw new ApplicationError("arg "+tpe+" not subtype of Seq[ A ]"); + + return tpe1.typeArgs()( 0 ); + } + + /** returns A for T <: Iterator[ A ] + */ + def getElemType_Iterator( tpe: Type ): Type = { + //System.err.println("getElemType_Iterator("+tpe+")"); + + val tpe1 = tpe.widen().baseType( defs.ITERATOR_CLASS ); + + tpe1 match { + case Type.TypeRef(_,_,args) => + return args( 0 ); + case _ => + throw new ApplicationError("arg "+tpe+" not subtype of Iterator[ A ]"); + } + + } + + /** `it.next()' + */ + def _next( iter: Tree ): Tree = { + gen.mkApply__(gen.Select(iter, defs.ITERATOR_NEXT())); + } + + /** `it.hasNext()' + */ + def _hasNext( iter: Tree ): Tree = { + gen.mkApply__(gen.Select(iter, defs.ITERATOR_HASNEXT())); + } + + /** `!it.hasCur()' + */ + def _not_hasNext( iter:Tree ): Tree = { + gen.mkApply__(gen.Select(_hasNext(iter), defs.BOOLEAN_NOT())); + } + + /** `trace.isEmpty' + */ + def isEmpty( iter: Tree ): Tree = { + gen.mkApply__(gen.Select(iter, defs.LIST_ISEMPTY())); + } + + def SeqTrace_headElem( arg: Tree ): Tree = { // REMOVE SeqTrace + val t = gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); + gen.mkApply__(gen.Select(t, defs.TUPLE_FIELD(2, 2))); + } + + def SeqTrace_headState( arg: Tree ): Tree = { // REMOVE SeqTrace + val t = gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); + gen.mkApply__(gen.Select(t, defs.TUPLE_FIELD(2, 1))); + + } + + def SeqTrace_tail( arg: Tree ): Tree = { // REMOVE SeqTrace + gen.mkApply__(gen.Select(arg, defs.LIST_TAIL())); + } + + /** `<seqlist>.head()' + */ + def SeqList_head( arg: Tree ): Tree = { + gen.mkApply__(gen.Select(arg, defs.LIST_HEAD())); + } + + def Negate(tree:Tree ): Tree = { + tree match { + case Literal(BOOLEAN(value))=> + gen.mkBooleanLit(tree.pos, !value); + case _ => + gen.mkApply__(gen.Select(tree, defs.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, defs.BOOLEAN_AND()), Predef.Array[Tree](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; + case _ => + } + gen.mkApply_V(gen.Select(left, defs.BOOLEAN_OR()), Predef.Array[Tree](right)); + } + + // used by Equals + private def getCoerceToInt(left: Type): Symbol = { + val sym = left.lookupNonPrivate(Names.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(defs.INT_TYPE())) + return syms(i); + case _ => + } + i = i + 1; + } + //assert false : Debug.show(left); + throw new ApplicationError(left); + } + + // used by Equals + private def getEqEq(left:Type , right:Type ): Symbol = { + val sym = left.lookupNonPrivate(Names.EQEQ); + //assert sym != Symbol.NONE + // : Debug.show(left) + "::" + Debug.show(left.members()); + var fun: Symbol = null; + var ftype:Type = defs.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; + } + } + i = i + 1 + } + //assert fun != null : Debug.show(sym.info()); + fun; + } + + /*protected*/ 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(defs.CHAR_TYPE()) + || ltype.isSameAs(defs.BYTE_TYPE()) + || ltype.isSameAs(defs.SHORT_TYPE()))) + { + right = gen.mkApply__(gen.Select(right, getCoerceToInt(rtype))); + rtype = defs.INT_TYPE(); + } + 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, defs.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, defs.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, defs.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 = { + defs.TUPLE_TYPE(Predef.Array[Type] ( left, right ) ); + } + + def newPair(left: Tree , right: Tree): Tree = { + gen.New( + gen.mkApplyTV( + gen.mkPrimaryConstructorGlobalRef( pos, defs.TUPLE_CLASS(2)), + Predef.Array[Type] ( left.getType(), right.getType() ), + Predef.Array[Tree] ( left, right ))); + } + +} +} diff --git a/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala new file mode 100644 index 0000000000..2f2b0f3f81 --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala @@ -0,0 +1,47 @@ + +import scalac.util.Name ; +import scalac.ast.Tree ; +import scalac.symtab.Symbol ; + + +import java.util.HashSet; + +package scala.tools.scalac.transformer.matching { + +class CollectVariableTraverser extends VariableTraverser { + + protected var nogeneratedVars = new HashSet(); + protected var vars = new HashSet(); + /* + boolean isVariableName( Name name ) { + return ( name.toString().indexOf("$") == -1 ) + && super.isVariableName( name ); + } + */ + def handleVariableSymbol(sym: Symbol): Unit = { + //Console.println("VT:"+sym); // DEBUG + vars.add( sym ); + if( sym.name.toString().indexOf("$") == -1 ) { + nogeneratedVars.add( sym ); + } + } + + def containsBinding(pat: Tree): Boolean = { + + //CollectVariableTraverser cvt = new CollectVariableTraverser(); + //cvt. + nogeneratedVars.clear(); + traverse( pat ); + //return !/*cvt.*/nogeneratedVars.isEmpty(); + !nogeneratedVars.isEmpty(); + + } + + def collectVars( pat:Tree ): HashSet = { + vars.clear(); + traverse( pat ); + return vars; + } + +} +} diff --git a/sources/scala/tools/scalac/transformer/matching/FreshVariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/FreshVariableTraverser.scala new file mode 100644 index 0000000000..51b324e44a --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/FreshVariableTraverser.scala @@ -0,0 +1,85 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +\* */ + +// $Id$ + + + + +import scalac.ast.Traverser; + +import scalac.ast.Tree; +import Tree.Ident; +import Tree.Bind; + +import scalac.util.Name; +import scalac.util.FreshNameCreator; + +import scalac.symtab._; + +import java.util.HashMap; +import java.util.Vector; + +package scala.tools.scalac.transformer.matching { + +/** A tree traverser for handling fresh variables + * todo: access method instead of + * @author Burak Emir + * @version 1.0 + */ +class FreshVariableTraverser(val pos: Int, val owner:Symbol, val fresh: FreshNameCreator ) +extends VariableTraverser { + +/* + int pos; + Symbol owner; + FreshNameCreator fresh; +*/ + /** + */ + private val helpMap = new HashMap(); + + /** + * @param pos + * @param owner + * @param fresh + public FreshVariableTraverser + this.pos = pos; + this.owner = owner; + this.fresh = fresh; + + helpMap + } + */ + + def getHelpMap(): HashMap = { + return helpMap; + } + + /** + * @param sym + */ + def handleVariableSymbol(sym: Symbol ): Unit = { + //Console.println("FreshVT:"+sym); // DEBUG + val helpVar = + owner.newVariable(pos, + 0, + fresh.newName(sym.name.toString())); + helpVar.setType(sym.getType()); + + helpMap.put(sym, helpVar); + } + +} + +object FreshVariableTraverser { + def getVars( t:Tree, owner:Symbol, fresh:FreshNameCreator ) = { + val fvt = new FreshVariableTraverser( t.pos, owner, fresh ); + fvt.traverse( t ); + fvt.getHelpMap(); + } +} +} diff --git a/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala index f3254f0c77..34fd084d7c 100644 --- a/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala @@ -8,10 +8,9 @@ import java.util._ ; import scala.tools.util.Position; //import scalac.transformer.matching._ ; -import scalac.transformer.matching.CodeFactory ; +//import scalac.transformer.matching.CodeFactory ; import scalac.transformer.matching.DetWordAutom ; import scalac.transformer.matching.Label ; -import scalac.transformer.matching.PartialMatcher ; package scala.tools.scalac.transformer.matching { class LeftTracerInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory, val selector: Tree ) diff --git a/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala new file mode 100644 index 0000000000..f277499d70 --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala @@ -0,0 +1,43 @@ + + +import scalac.util.Name ; +import scalac.ast.Tree ; +import scalac.ast.Traverser ; +import scalac.symtab.Symbol ; + +import java.util.HashSet; + +package scala.tools.scalac.transformer.matching { + +class NoSeqVariableTraverser extends CollectVariableTraverser { + + override def traverse(tree:Tree ): Unit = { + tree.match { + case Tree.Sequence(_) => + return ; + case _ => + super.traverse( tree ); + } + } + + def varsNoSeq(pat: Tree):HashSet = { + vars.clear(); + traverse( pat ); + return vars; + + } + + def varsNoSeq(pats: Array[Tree]): HashSet = { + + //NoSeqVariableTraverser nvt = new NoSeqVariableTraverser(); + var i = 0; + while(i < pats.length) { + traverse( pats( i ) ); + i = i + 1; + } + vars; + + } + +} +} diff --git a/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala b/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala new file mode 100644 index 0000000000..f841427049 --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/PartialMatcher.scala @@ -0,0 +1,46 @@ +import scalac.ast.Tree; +import scalac.symtab.Symbol; +import scalac.symtab.Type; +import java.util.HashMap ; + +package scala.tools.scalac.transformer.matching { + +/** container. classes AlgebraicMatcher and SequenceMatcher get input and store their results in here. + * resembles the 'Memento' design pattern, could also be named 'Liaison' + */ +class PartialMatcher(owner1: Symbol, root1: Tree, resultType1: Type) { + + /** owner of the code we create (input) + */ + var owner: Symbol = owner1; + + /** the selector value (input) + */ + var selector:Tree = root1; + + /** type of the result of the whole match (input) + */ + var resultType:Type = resultType1 ; + + /** tree representing the matcher (output) + */ + var tree: Tree = _ ; + + var pos: int = root1.pos; + + //assert( owner != null ) : "owner is null"; + //assert owner != Symbol.NONE ; + //this.owner = owner; + + //assert root != null; + //assert root.type != null; + //this.selector = root; + + //assert this.resultType != Type.NoType; + //this.resultType = resultType; + + //this.pos = root.pos; // for convenience only + + } + +} diff --git a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala b/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala index 64de165434..b5afd2101b 100644 --- a/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala +++ b/sources/scala/tools/scalac/transformer/matching/PatternMatcher.scala @@ -13,12 +13,12 @@ import scalac.ast._; import scalac.atree.AConstant; import scalac.util._; import scalac.symtab._; -import scalac.transformer.matching.CodeFactory; -import scalac.transformer.matching.PatternNodeCreator; -import scalac.transformer.matching.PatternNode; -import scalac.transformer.matching.CaseEnv; -import scalac.transformer.matching.PatternTool; -import PatternNode._; +//import scalac.transformer.matching.CodeFactory; +//import scalac.transformer.matching.PatternNodeCreator; +//import scalac.transformer.matching.PatternNode; +//import scalac.transformer.matching.CaseEnv; +//import scalac.transformer.matching.PatternTool; +//import PatternNode._; import Tree._; package scala.tools.scalac.transformer.matching { @@ -98,16 +98,18 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { else patNode.match { - case Header(selector, next) => - Console.println(indent + "HEADER(" + patNode.getType() + + case _h: Header => + val selector = _h.selector; + val next = _h.next; + Console.println(indent + "HEADER(" + patNode.getTpe() + ", " + selector + ")"); print(patNode.or, indent + "|"); if (next != null) print(next, indent); case ConstrPat(casted) => - val s = "-- " + patNode.getType().symbol().name + - "(" + patNode.getType() + ", " + casted + ") -> "; + val s = "-- " + patNode.getTpe().symbol().name + + "(" + patNode.getTpe() + ", " + casted + ") -> "; val nindent = newIndent(s); Console.println(nindent + s); print(patNode.and, nindent); @@ -115,8 +117,8 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { print(patNode.or, indent); case SequencePat( casted, plen ) => - val s = "-- " + patNode.getType().symbol().name + "(" + - patNode.getType() + + val s = "-- " + patNode.getTpe().symbol().name + "(" + + patNode.getTpe() + ", " + casted + ", " + plen + ") -> "; val nindent = newIndent(s); Console.println(indent + s); @@ -140,7 +142,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { print(patNode.or, indent); case VariablePat(tree) => - val s = "-- STABLEID(" + tree + ": " + patNode.getType() + ") -> "; + val s = "-- STABLEID(" + tree + ": " + patNode.getTpe() + ") -> "; val nindent = newIndent(s); Console.println(indent + s); print(patNode.and, nindent); @@ -154,11 +156,11 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { if (patNode.or != null) print(patNode.or, indent); - case Body(_, guards, stats) => - if ((guards.length == 0) && (stats.length == 0)) + case _b:Body => + if ((_b.guard.length == 0) && (_b.body.length == 0)) Console.println(indent + "true"); else - Console.println(indent + "BODY(" + stats.length + ")"); + Console.println(indent + "BODY(" + _b.body.length + ")"); } } @@ -183,9 +185,9 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { // if (target.and != null) // unit.error(pat.pos, "duplicate case"); if (null == target.and) - target.and = mk.Body(caseDef.pos, env.boundVars(), guard, body); + target.and = mk.Body(caseDef.pos, env.getBoundVars(), guard, body); else if (target.and.isInstanceOf[Body]) - updateBody(target.and.asInstanceOf[Body], env.boundVars(), guard, body); + updateBody(target.and.asInstanceOf[Body], env.getBoundVars(), guard, body); else unit.error(pat.pos, "duplicate case"); } @@ -204,9 +206,9 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { bd(bd.length - 1) = bound; ng(ng.length - 1) = guard; nb(nb.length - 1) = body; - tree.bound = bd; - tree.guard = ng; - tree.body = nb; + tree.bound = bd ; + tree.guard = ng ; + tree.body = nb ; } } @@ -250,7 +252,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { //Console.println("patternNode("+tree+","+header+")"); tree.match { case Bind(name, Typed(Ident(Names.PATTERN_WILDCARD), tpe)) => // x@_:Type - if(header.getType().isSubType(tpe.getType())) { + if(header.getTpe().isSubType(tpe.getType())) { val node = mk.DefaultPat(tree.pos, tpe.getType()); env.newBoundVar( tree.symbol(), tree.getType(), header.selector ); node; @@ -260,7 +262,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { node; } case Bind(name, Ident(Names.PATTERN_WILDCARD)) => // x @ _ - val node = mk.DefaultPat(tree.pos, header.getType()); + val node = mk.DefaultPat(tree.pos, header.getTpe()); if ((env != null) && (tree.symbol() != defs.PATTERN_WILDCARD)) env.newBoundVar( tree.symbol(), tree.getType(), header.selector); node; @@ -281,7 +283,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { } } else { val res = mk.ConstrPat(tree.pos, tree.getType()); - res.and = mk.Header(tree.pos, header.getType(), header.selector); + res.and = mk.Header(tree.pos, header.getTpe(), header.selector); res.and.and = mk.SeqContainerPat(tree.pos, tree.getType(), args(0)); res; } @@ -295,7 +297,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { mk.ConstrPat(tree.pos, tree.getType()); case t @ Typed(ident, tpe) => // variable pattern - val doTest = header.getType().isSubType(tpe.getType()); + val doTest = header.getTpe().isSubType(tpe.getType()); val node = { if(doTest) mk.DefaultPat(tree.pos, tpe.getType()) @@ -317,7 +319,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { case Ident(name) => // pattern without args or variable if (tree.symbol() == defs.PATTERN_WILDCARD) - mk.DefaultPat(tree.pos, header.getType()); + mk.DefaultPat(tree.pos, header.getTpe()); else if (tree.symbol().isPrimaryConstructor()) { throw new ApplicationError("this may not happen"); // Burak } else if (name.isVariable()) {// Burak @@ -343,8 +345,8 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { case Alternative(ts) => if(ts.length < 2) throw new ApplicationError("ill-formed Alternative"); - val subroot = mk.ConstrPat(header.pos, header.getType()); - subroot.and = mk.Header(header.pos, header.getType(), header.selector.duplicate()); + 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); var i = 0; while(i < ts.length) { val target = enter1(ts(i), -1, subroot, subroot.symbol(), subenv); @@ -430,9 +432,9 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { (patNode.isDefaultPat() || next.subsumes(patNode)))) { // new node is default or subsumed var header = mk.Header(patNode.pos, - curHeader.getType(), + curHeader.getTpe(), curHeader.selector); - curHeader.next = header; + {curHeader.next = header; header}; header.or = patNode; return enter(patArgs, patNode, @@ -520,22 +522,22 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { case VariablePat(tree) => Console.println(((tree.symbol().flags & Modifiers.CASE) != 0)); case ConstrPat(_) => - Console.println(node.getType().toString() + " / " + ((node.getType().symbol().flags & Modifiers.CASE) != 0)); + Console.println(node.getTpe().toString() + " / " + ((node.getTpe().symbol().flags & Modifiers.CASE) != 0)); var inner = node.and; def funct(inner: PatternNode): Boolean = { //outer: while (true) { inner.match { - case Header(_, next) => - if (next != null) + case _h:Header => + if (_h.next != null) throw Break(false); funct(inner.or) case DefaultPat() => funct(inner.and); - case Body(bound, guard, _) => - if ((guard.length > 1) || - (guard(0) != Tree.Empty)) + case b:Body => + if ((b.guard.length > 1) || + (b.guard(0) != Tree.Empty)) throw Break(false); throw Break2() // break outer @@ -559,7 +561,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { return false; } } - patNode = patNode.next(); + patNode = patNode.nextH(); } return true; } @@ -576,16 +578,16 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { return false; } node.and.match { - case Body(bound, guard, _) => - if ((guard.length > 1) || - (guard(0) != Tree.Empty) || - (bound(0).length > 0)) + case _b:Body => + if ((_b.guard.length > 1) || + (_b.guard(0) != Tree.Empty) || + (_b.bound(0).length > 0)) return false; case _ => return false; } } - patNode = patNode.next(); + patNode = patNode.nextH(); } return true; } else @@ -635,7 +637,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { return bodyToTree(node.and); case _ => } - patNode = patNode.next(); + patNode = patNode.nextH(); } otherwise; } @@ -665,7 +667,8 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { // // if we have more than 2 cases than use a switch statement root.and.match { - case Header(_, next) => + case _h:Header => + val next = _h.next; var mappings: TagBodyPair = null; var defaultBody = matchError; var patNode = root.and; @@ -690,7 +693,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { throw new ApplicationError(node.toString()); } } - patNode = patNode.next(); + patNode = patNode.nextH(); } if (mappings == null) { return gen.Switch(selector, new Array[int](0), new Array[Tree](0), defaultBody, resultVar.getType()); @@ -714,8 +717,8 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { protected def bodyToTree(node: PatternNode): Tree = { node.match { - case Body(_, _, body) => - return body(0); + case _b:Body => + return _b.body(0); case _ => throw new ApplicationError(); } @@ -742,17 +745,21 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { var res = gen.mkBooleanLit(node.pos, false); while (node != null) node.match { - case Header(selector, next) => + case _h:Header => + val selector = _h.selector; + val next = _h.next; //res = cf.And(mkNegate(res), toTree(node.or, selector)); //Console.println("HEADER TYPE = " + selector.type); - if (optimize(node.getType(), node.or)) + if (optimize(node.getTpe(), node.or)) res = cf.Or(res, toOptTree(node.or, selector)); else res = cf.Or(res, toTree(node.or, selector)); node = next; - case Body(bound1, guard, body) => - var bound = bound1; + case _b:Body => + var bound = _b.bound; + val guard = _b.guard; + val body = _b.body; if ((bound.length == 0) && (guard.length == 0) && (body.length == 0)) { @@ -784,7 +791,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { while (alternatives != null) { alternatives match { case ConstrPat(_) => - if (alternatives.getType().symbol().isCaseClass()) + if (alternatives.getTpe().symbol().isCaseClass()) cases = cases +1; else return false; @@ -836,7 +843,7 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { while (node != null) node.match { case ConstrPat(casted) => - cases = insertNode(node.getType().symbol().tag(), node, cases); + cases = insertNode(node.getTpe().symbol().tag(), node, cases); node = node.or; case DefaultPat() => @@ -873,18 +880,18 @@ class PatternMatcher(unit: CompilationUnit) extends PatternTool(unit) { return toTree(node.and); case ConstrPat(casted) => - return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.getType()), + return gen.If(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()), gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.getType())), + gen.mkAsInstanceOf(selector.duplicate(), node.getTpe())), toTree(node.and)), toTree(node.or, selector.duplicate())); case SequencePat(casted, len) => - return gen.If(cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.getType()), - cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.duplicate(), node.getType()), + return gen.If(cf.And(gen.mkIsInstanceOf(selector.duplicate(), node.getTpe()), + cf.Equals(gen.mkApply__(gen.Select(gen.mkAsInstanceOf(selector.duplicate(), node.getTpe()), defs.SEQ_LENGTH())), gen.mkIntLit(selector.pos, len))), gen.mkBlock(gen.ValDef(casted, - gen.mkAsInstanceOf(selector.duplicate(), node.getType())), + gen.mkAsInstanceOf(selector.duplicate(), node.getTpe())), toTree(node.and)), toTree(node.or, selector.duplicate())); case ConstantPat(value) => diff --git a/sources/scala/tools/scalac/transformer/matching/PatternNode.scala b/sources/scala/tools/scalac/transformer/matching/PatternNode.scala new file mode 100644 index 0000000000..0515d5a95a --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/PatternNode.scala @@ -0,0 +1,219 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + + +import scala.tools.util.Position; +import scalac._; +import scalac.ast._; +import scalac.atree.AConstant; +import scalac.symtab._; +import scalac.typechecker._; + +package scala.tools.scalac.transformer.matching { + +/** 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 _ => + throw new ApplicationError(); + } + res.pos = pos; + res.tpe = tpe; + res.or = or; + res.and = and; + return res; + } + + def symbol(): Symbol = { + this match { + case ConstrPat(casted) => + return casted; + case SequencePat(casted, _) => + return casted; + case SeqContainerPat(casted, _) => + return casted; + case _ => + return Symbol.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(_) => + q.getTpe().isSameAs(this.getTpe()); + case _ => + false + } + case SequencePat(_, plen) => + q match { + case SequencePat(_, qlen) => + return (plen == qlen) && q.getTpe().isSameAs(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(_) => + q.getTpe().isSubType(this.getTpe()); + case _ => + false; + } + case SequencePat(_, plen) => + q match { + case SequencePat(_, qlen) => + (plen == qlen) && q.getTpe().isSubType(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().isNone()) && + (!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[Tree.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: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 + } diff --git a/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala b/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala new file mode 100644 index 0000000000..1b656e6af1 --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/PatternNodeCreator.scala @@ -0,0 +1,109 @@ +import scala.tools.util.Position; + +import scalac._; +import scalac.ast._; +import scalac.atree.AConstant; +import scalac.util._; +import scalac.symtab._; +//import PatternNode._; +import Tree._; + +import java.util.Vector ; + +package scala.tools.scalac.transformer.matching { + + /** PatternNode factory. + * we inherit the globals from PatternTool. + */ + + class PatternNodeCreator(unit:CompilationUnit, val owner:Symbol) + extends PatternTool(unit) { + + /** the owner of the variable symbols that might be created */ + //Symbol owner; + + def SequencePat(pos: Int , tpe:Type , len:int) = { + val sym = newVar(Position.FIRSTPOS, tpe); + val node = new SequencePat(sym, len); + node.pos = pos; + node.setType(tpe); + node; + } + + def SeqContainerPat(pos: int, tpe: Type, seqpat:Tree ) = { + val sym = newVar(Position.NOPOS, tpe); + val node = new SeqContainerPat(sym, seqpat); + node.pos = pos; + node.setType(tpe); + node; + } + + def DefaultPat(pos: int, tpe: Type) = { + val node = new DefaultPat(); + node.pos = pos; + node.setType(tpe); + node; + } + + def ConstrPat(pos: int, tpe: Type) = { + val node = new ConstrPat(newVar(pos, tpe)); + node.pos = pos; + node.setType(tpe); + node; + } + + def ConstantPat(pos: int, tpe: Type, value:AConstant ) = { + val node = new ConstantPat( value ); + node.pos = pos; + node.setType(tpe); + node; + } + + def VariablePat(pos: int, tree:Tree) = { + val node = new VariablePat( tree ); + node.pos = pos; + node.setType(tree.getType()); + node; + } + + def AltPat(pos: int, header:Header ) = { + val node = new AltPat(header); + node.pos = pos; + node.setType(header.getTpe()); + node; + } + + // factories + + def Header(pos: int, tpe: Type, selector:Tree) = { + val node = new Header(selector, null); + node.pos = pos; + node.setType(tpe); + node; + } + + def Body(pos: int) = { + val node = new Body(new Array[Array[ValDef]](0), new Array[Tree](0), new Array[Tree](0)); + node.pos = pos; + node; + } + + def Body(pos: int, 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: int, name: Name, tpe: Type): Symbol= { + val sym = owner.newVariable(pos, 0, name); + sym.setType(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); + } + } +} diff --git a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala new file mode 100644 index 0000000000..d3f43d84ab --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala @@ -0,0 +1,27 @@ +/* ____ ____ ____ ____ ______ *\ +** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala ** +** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL ** +** /_____/\____/\___/\____/____/ ** +** ** +** $Id$ +\* */ + + + +import scalac.CompilationUnit; +//import scalac.ast.TreeGen; +//import scalac.util.*; +//import scalac.symtab.*; + +package scala.tools.scalac.transformer.matching { +/** this class takes care of tedious stuff which has nothing to do with + * matching + */ + abstract class PatternTool(unit: CompilationUnit) { + + final def fresh = unit.fresh; + final def gen = unit.global.treeGen; + final def defs = unit.global.definitions; + + } // class PatternTool +} diff --git a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala index b929b0ba70..74d804db12 100644 --- a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala @@ -15,10 +15,9 @@ import scalac.util.Names ; import scala.tools.util.Position; -import scalac.transformer.matching.CodeFactory ; +//import scalac.transformer.matching.CodeFactory ; import scalac.transformer.matching.DetWordAutom ; import scalac.transformer.matching.Label ; -import scalac.transformer.matching.PartialMatcher ; package scala.tools.scalac.transformer.matching { diff --git a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala b/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala index cbf1722f8f..a9e43e211b 100644 --- a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala +++ b/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala @@ -12,16 +12,13 @@ import scalac.symtab._ ; import java.util._ ; import scala.tools.util.Position; -import scalac.transformer.matching.PatternTool; -import scalac.transformer.matching.PartialMatcher; +//import scalac.transformer.matching.PatternTool; import scalac.transformer.matching.{BerrySethi, BindingBerrySethi}; -import scalac.transformer.matching.CollectVariableTraverser; -import scalac.transformer.matching.CodeFactory; +//import scalac.transformer.matching.CodeFactory; import scalac.transformer.matching.DetWordAutom; import scalac.transformer.matching.Label; import scalac.transformer.matching.NondetWordAutom; -import scalac.transformer.matching.PartialMatcher; package scala.tools.scalac.transformer.matching { /** constructs a matcher for a sequence pattern. plays two roles in diff --git a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala index 393d97aa60..79a573c62a 100644 --- a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala @@ -1,8 +1,7 @@ import scalac.ast.Tree; import scalac.symtab.Symbol; import scalac.symtab.Type; -import scalac.transformer.matching.CodeFactory ; -import scalac.transformer.matching.CollectVariableTraverser ; +//import scalac.transformer.matching.CodeFactory ; import scalac.transformer.matching.DetWordAutom ; package scala.tools.scalac.transformer.matching { diff --git a/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala new file mode 100644 index 0000000000..74d613c66f --- /dev/null +++ b/sources/scala/tools/scalac/transformer/matching/VariableTraverser.scala @@ -0,0 +1,56 @@ +import scalac.ast.Tree; +import scalac.util.Name; +import scalac.symtab.Symbol ; +import scalac.ast.Traverser ; + +import Tree.Ident; +import Tree.Bind; +import Tree.Select; + +package scala.tools.scalac.transformer.matching { + +abstract class VariableTraverser extends Traverser { + + def isVariableName(name: Name): Boolean = { + ( name.isVariable() ) && ( name != Name.fromString("_") ) ; + } + + def isVariableSymbol(sym: Symbol): Boolean = { + ( sym != null )&&( !sym.isPrimaryConstructor() ); + } + + def handleVariableSymbol(sym: Symbol): Unit; + + override def traverse(tree: Tree): Unit = { + tree.match { + case Ident(name)=> + var sym: Symbol = _; + + if( isVariableName( name ) + && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} ) ) + handleVariableSymbol( sym ); + + return; + + case Bind(name, subtree) => + var sym: Symbol = _; + + if( isVariableName( name ) + && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) + handleVariableSymbol( sym ); + + traverse( subtree ); + + return; + + case Select(_,_) => + return; + + case _ => + super.traverse( tree ); + } + } + + +} +} diff --git a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala b/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala index 916dfb51af..2ce7ddb3f1 100644 --- a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala @@ -22,10 +22,9 @@ import Tree._; import java.util._; import scala.tools.scalac.util.NewArray; -import scalac.transformer.matching.CodeFactory; +//import scalac.transformer.matching.CodeFactory; import scalac.transformer.matching.DetWordAutom; import scalac.transformer.matching.Label; -import scalac.transformer.matching.PartialMatcher; import scalac.util.Names; package scala.tools.scalac.transformer.matching { |