diff options
12 files changed, 142 insertions, 249 deletions
diff --git a/config/list/scalac.lst b/config/list/scalac.lst index 2a616474fa..b0f49ed7c2 100644 --- a/config/list/scalac.lst +++ b/config/list/scalac.lst @@ -113,31 +113,6 @@ ../../../scalac/transformer/TailCallPhase.java ../../../scalac/transformer/TypesAsValuesPhase.java -#../../../scalac/transformer/matching/AlgebraicMatcher.java -#../../../scalac/transformer/matching/Autom2Scala.java -#../../../scalac/transformer/matching/BindingBerrySethi.java -#../../../scalac/transformer/matching/BerrySethi.java -#../../../scalac/transformer/matching/CaseEnv.java -#../../../scalac/transformer/matching/CodeFactory.java -#../../../scalac/transformer/matching/CollectVariableTraverser.java -#../../../scalac/transformer/matching/DetWordAutom.java -#../../../scalac/transformer/matching/FreshVariableTraverser.java -#../../../scalac/transformer/matching/Label.java -#../../../scalac/transformer/matching/TracerInScala.java -#../../../scalac/transformer/matching/LeftTracerInScala.java -#../../../scalac/transformer/matching/NondetWordAutom.java -#../../../scalac/transformer/matching/NoSeqVariableTraverser.java -#../../../scalac/transformer/matching/PartialMatcher.java -#../../../scalac/transformer/matching/PatternMatcher.java -#../../../scalac/transformer/matching/PatternNode.java -#../../../scalac/transformer/matching/PatternNodeCreator.java -#../../../scalac/transformer/matching/PatternTool.java -#../../../scalac/transformer/matching/RightTracerInScala.java -#../../../scalac/transformer/matching/SequenceMatcher.java -#../../../scalac/transformer/matching/StateSetComparator.java -#../../../scalac/transformer/matching/VariableTraverser.java -#../../../scalac/transformer/matching/WordAutomInScala.java - ../../../scalac/typechecker/AnalyzerPhase.java ../../../scalac/typechecker/Infer.java @@ -189,14 +164,11 @@ transformer/matching/BindingBerrySethi.scala transformer/matching/BerrySethi.scala transformer/matching/CaseEnv.scala transformer/matching/CodeFactory.scala -transformer/matching/CollectVariableTraverser.scala transformer/matching/DetWordAutom.scala -transformer/matching/FreshVariableTraverser.scala transformer/matching/Label.scala transformer/matching/LeftTracerInScala.scala transformer/matching/NondetWordAutom.scala transformer/matching/PartialMatcher.scala -transformer/matching/NoSeqVariableTraverser.scala transformer/matching/PatternMatcher.scala transformer/matching/PatternNode.scala transformer/matching/PatternNodeCreator.scala @@ -205,7 +177,6 @@ transformer/matching/RightTracerInScala.scala transformer/matching/TracerInScala.scala transformer/matching/StateSetComparator.scala transformer/matching/Npair.scala -transformer/matching/VariableTraverser.scala transformer/matching/WordAutomInScala.scala transformer/matching/SequenceMatcher.scala diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala index 837fd300ff..d8a7320f69 100644 --- a/sources/scala/tools/scalac/ast/parser/Parser.scala +++ b/sources/scala/tools/scalac/ast/parser/Parser.scala @@ -18,6 +18,7 @@ import java.lang.{Integer, Long, Float, Double}; import scala.Iterator; import scala.tools.scalac.util.NewArray; import scala.collection.immutable.ListMap ; +import scala.collection.mutable; import scala.collection.mutable.ListBuffer; package scala.tools.scalac.ast.parser { @@ -1455,13 +1456,19 @@ class Parser(unit: CompilationUnit) { //////// PARAMETERS ////////////////////////////////////////////////////////// + // invariant: only only activation record of paramClauses on stack + var paramClauses_buffer = new mutable.ArrayBuffer[Array[Tree.ValDef]](); + /** ParamClauses ::= {ParamClause} */ - def paramClauses(): Array[Array[Tree.ValDef]] = { - val ts = new ListBuffer[Array[Tree.ValDef]](); + def paramClauses(): Array[Array[Tree.ValDef]] = { //pre: buffer empty while (s.token == LPAREN) - ts += paramClause(false); - ts.copyToArray(new Array[Array[Tree.ValDef]](ts.length), 0) + paramClauses_buffer += paramClause(false); + + val res = new Array[Array[Tree.ValDef]](paramClauses_buffer.length); + paramClauses_buffer.elements.copyToArray(res, 0); + paramClauses_buffer.clear; //post: buffer empty + res } /** ParamClauseOpt ::= [ParamClause] @@ -1494,17 +1501,18 @@ class Parser(unit: CompilationUnit) { def param(ofPrimaryConstructor: boolean): Tree.ValDef = { val pos = s.pos; var mods = if (ofPrimaryConstructor) modifiers() | Modifiers.PARAM else Modifiers.PARAM; - if (s.token == VAL) { - s.nextToken(); mods = mods | Modifiers.PARAMACCESSOR; - } else if (mods != Modifiers.PARAM) { - accept(VAL); + if(ofPrimaryConstructor) { + if (s.token == VAL) { + s.nextToken(); mods = mods | Modifiers.PARAMACCESSOR; + } else if (mods != Modifiers.PARAM) { + accept(VAL); + } } if (s.token == DEF) { mods = mods | Modifiers.DEF; - /* notyet - s.unit.warning(s.pos, "def-parameter syntax `def x: T' is deprecated \n" + - "use `x: => T' instead"); - */ + if(ofPrimaryConstructor) + s.unit.warning(s.pos, "def-parameter syntax `def x: T' is deprecated \n" + + "use `x: => T' instead"); s.nextToken(); } val name = ident(); diff --git a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala b/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala index f091982f9b..dffd1f77d5 100644 --- a/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala +++ b/sources/scala/tools/scalac/transformer/matching/Autom2Scala.scala @@ -25,7 +25,7 @@ package scala.tools.scalac.transformer.matching { /** @param owner owner of the pattern matching expression */ - class Autom2Scala(val dfa: DetWordAutom, val elementType: Type, val owner: Symbol, val cf: CodeFactory) { + class Autom2Scala(val dfa: DetWordAutom, val elementType: Type, val owner: Symbol, val cf: CodeFactory) with PatternTool(cf.unit) { protected var optimize = true; @@ -60,7 +60,6 @@ package scala.tools.scalac.transformer.matching { case _ => throw new RuntimeException(); } } - final def gen = cf.gen; def callFun(args: Array[Tree]): Tree = { gen.mkApply_V(gen.Ident(pos, funSym), args); diff --git a/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala deleted file mode 100644 index 2f2b0f3f81..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/CollectVariableTraverser.scala +++ /dev/null @@ -1,47 +0,0 @@ - -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 deleted file mode 100644 index 51b324e44a..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/FreshVariableTraverser.scala +++ /dev/null @@ -1,85 +0,0 @@ -/* ____ ____ ____ ____ ______ *\ -** / __// __ \/ __// __ \/ ____/ 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 b13c7680b5..9813bd4fee 100644 --- a/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/LeftTracerInScala.scala @@ -13,7 +13,7 @@ package scala.tools.scalac.transformer.matching { class LeftTracerInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory, val selector: Tree ) extends TracerInScala( dfa, elementType, owner, cf ) { - final def defs = cf.defs; + //final def defs = cf.defs; /** symbol of the accumulator ( scala.SequenceList ) */ diff --git a/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala b/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala deleted file mode 100644 index f277499d70..0000000000 --- a/sources/scala/tools/scalac/transformer/matching/NoSeqVariableTraverser.scala +++ /dev/null @@ -1,43 +0,0 @@ - - -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/PatternTool.scala b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala index d3f43d84ab..b6b81bc52b 100644 --- a/sources/scala/tools/scalac/transformer/matching/PatternTool.scala +++ b/sources/scala/tools/scalac/transformer/matching/PatternTool.scala @@ -12,15 +12,79 @@ import scalac.CompilationUnit; //import scalac.ast.TreeGen; //import scalac.util.*; //import scalac.symtab.*; + import scalac.util.Name ; + import scalac.ast.Tree ; + import scalac.symtab.Symbol ; + +import scalac.ApplicationError ; 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) { + def containsBinding(pat: Tree): Boolean = { + var generatedVars = false; + + def handleVariableSymbol(sym: Symbol): Unit = + if( sym.name.toString().indexOf("$") == -1 ) { + generatedVars = true; // .add( sym ); + } + + def isVariableName(name: Name): Boolean = + ( name.isVariable() ) && ( name != Name.fromString("_") ) ; + + def isVariableSymbol(sym: Symbol): Boolean = + ( sym != null )&&( !sym.isPrimaryConstructor() ); + + def traverse1(trees: Array[Tree]): Unit = { + var i = 0; while(i < trees.length) { + traverse(trees(i)); + i = i + 1 + } + } + def traverse(tree: Tree): Unit = { + + import Tree._ ; + + tree.match { + case x @ Ident(name)=> + if(x.symbol() != unit.global.definitions.PATTERN_WILDCARD) + throw new ApplicationError("shouldn't happen?!"); + + case Bind(name, subtree) => + var sym: Symbol = _; + + if( isVariableName( name ) + && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) + handleVariableSymbol( sym ); + + traverse( subtree ); + + case Select(_,_) => ; + + // congruence + case Apply(fun, args) => + traverse1(args); + case Sequence(trees) => + traverse1(trees); + case Typed(expr, tpe) => // needed?? + traverse(expr); + case _ : Alternative | _ : Select | _ : Literal => ; // no variables + + case _ => + throw new ApplicationError("unknown pattern node:"+tree+" = "+tree.getClass()); + } + } + traverse( pat ); + generatedVars; + } + 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 08a395225d..c098b0f36a 100644 --- a/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/RightTracerInScala.scala @@ -27,7 +27,59 @@ package scala.tools.scalac.transformer.matching { class RightTracerInScala(dfa: DetWordAutom, seqVars: Set, owner: Symbol, cf: CodeFactory, pat:Tree, elementType: Type) extends TracerInScala( dfa, elementType, owner, cf ) { - final def defs = cf.defs; + + final def collectVars( pat:Tree ): HashSet = { + var vars = new HashSet(); + + def handleVariableSymbol(sym: Symbol): Unit = { + vars.add( sym ); + } + def isVariableName(name: Name): Boolean = { + ( name.isVariable() ) && ( name != Name.fromString("_") ) ; + } + def isVariableSymbol(sym: Symbol): Boolean = { + ( sym != null )&&( !sym.isPrimaryConstructor() ); + } + + def traverse1(trees: Array[Tree]): Unit = { + var i = 0; while(i < trees.length) { + traverse(trees(i)); + i = i + 1 + } + } + def traverse(tree: Tree): Unit = { + import Tree._ ; + tree.match { + case x @ Ident(name)=> + if(x.symbol() != cf.unit.global.definitions.PATTERN_WILDCARD) + throw new ApplicationError("shouldn't happen?!"); + case Bind(name, subtree) => + var sym: Symbol = _; + if( isVariableName( name ) + && isVariableSymbol( {sym = tree.symbol(); tree.symbol()} )) + handleVariableSymbol( sym ); + + traverse( subtree ); + + case Select(_,_) => ; + + // congruence cases + case Apply(fun, args) => + traverse1(args); + case Sequence(trees) => + traverse1(trees); + case Typed(expr, tpe) => // needed?? + traverse(expr); + case _ : Alternative | _ : Select | _ : Literal => ; // no variables + case _ => + throw new ApplicationError("unknown pattern node:"+tree+" = "+tree.getClass()); + } + } + traverse( pat ); + return vars; + } + + //final def defs = cf.defs; val allVars: Set = collectVars( pat ); diff --git a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala b/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala index fbce115eea..17d840b29a 100644 --- a/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala +++ b/sources/scala/tools/scalac/transformer/matching/SequenceMatcher.scala @@ -148,7 +148,7 @@ class SequenceMatcher(unit: CompilationUnit) extends PatternTool(unit) { newbody = new Array[Tree](body.length); var i = 0; while(i < body.length) { - if( !new CollectVariableTraverser().containsBinding( pat( i ) ) ) + if( !containsBinding( pat( i ) ) ) newbody( i ) = body( i ); // no need for binding else newbody( i ) = addBinderToBody( pat( i ), body( i ) ); diff --git a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala b/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala index 5838ed7991..448c9fb17e 100644 --- a/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/TracerInScala.scala @@ -10,15 +10,5 @@ extends Autom2Scala(dfa, elementType, owner, cf) { override var optimize = true; - final def collectVars(pat: Tree) = { - val c = new CollectVariableTraverser(); - c.collectVars(pat) - } - - final def containsBinding(pat: Tree) = { - val c = new CollectVariableTraverser(); - c.containsBinding(pat); - } - } } diff --git a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala b/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala index c04972af37..fa1cee2467 100644 --- a/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala +++ b/sources/scala/tools/scalac/transformer/matching/WordAutomInScala.scala @@ -13,9 +13,7 @@ import scala.tools.util.Position; import scalac._; import scalac.ast.Tree; import scalac.ast.TreeGen; -import scalac.symtab.Type; -import scalac.symtab.Symbol; -import scalac.symtab.Modifiers; // test +import scalac.symtab.{ Modifiers, Symbol, Type }; import Tree._; import java.util._; @@ -38,27 +36,13 @@ package scala.tools.scalac.transformer.matching { class WordAutomInScala(dfa: DetWordAutom, elementType: Type, owner: Symbol, cf: CodeFactory, optim: Boolean ) extends Autom2Scala(dfa, elementType, owner, cf) { - final def defs = cf.defs; this.optimize = this.optimize && optim; + var theDefDef: Tree = _ ; def getMatcherSwitch(selector: Tree, failTree: Tree, body: Array[Tree], resultType: Type ): Tree = { var result: Tree = _; - - /* - boolean insane = true; // if you set this to false, you get some VerifyErrors - // seems fixed - if( insane ) { // cascading ifs - - Tree cond[] = new Tree[body.length]; - for( int i = body.length - 1; i >= 0; i-- ) { - cond[i] = cf.Equals(_swres(), gen.mkIntLit( cf.pos, i )); - } - result = cf.Switch( cond, body, failTree ); - - } else { // real switch - */ val tags = new Array[int](body.length); var i = body.length - 1; while( i >= 0 ) { |