summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-08-11 10:26:37 +0000
committerburaq <buraq@epfl.ch>2004-08-11 10:26:37 +0000
commit3db749409608fb39c7e7e3ce2b0b020691bcf6e3 (patch)
treea96cffdd94e71ddd56c4b4c8902023a0f3ff01cf
parent1129ed2878176b506fdf2964d7f09ae7345d4346 (diff)
downloadscala-3db749409608fb39c7e7e3ce2b0b020691bcf6e3.tar.gz
scala-3db749409608fb39c7e7e3ce2b0b020691bcf6e3.tar.bz2
scala-3db749409608fb39c7e7e3ce2b0b020691bcf6e3.zip
toString() for case objects
scanning of /**/
-rw-r--r--config/list/library.lst1
-rw-r--r--config/list/scalac.lst1
-rw-r--r--sources/scala/collection/immutable/BitSet.scala6
-rw-r--r--sources/scala/collection/mutable/BitSet.scala7
-rw-r--r--sources/scala/runtime/matching/Matcher.scala4
-rw-r--r--sources/scala/runtime/matching/PatternGrammar.scala168
-rw-r--r--sources/scala/runtime/matching/PatternTests.scala5
-rw-r--r--sources/scala/tools/scalac/ast/parser/Parser.scala18
-rw-r--r--sources/scala/tools/scalac/ast/parser/Scanner.scala2
-rw-r--r--sources/scala/tools/scalac/transformer/TransMatch.scala3
-rw-r--r--sources/scala/tools/scalac/transformer/matching/GrammarTool.scala105
-rwxr-xr-xsources/scala/tools/scalac/typechecker/RefCheck.scala12
-rw-r--r--sources/scala/util/grammar/ImmutableTreeHedgeGrammar.scala6
-rw-r--r--sources/scalac/symtab/Symbol.java6
14 files changed, 214 insertions, 130 deletions
diff --git a/config/list/library.lst b/config/list/library.lst
index a82958e12d..1a5787aa71 100644
--- a/config/list/library.lst
+++ b/config/list/library.lst
@@ -159,6 +159,7 @@ runtime/matching/TestAlphabet.scala
runtime/matching/Matcher.scala
runtime/matching/NonTerm.scala
runtime/matching/PatternGrammar.scala
+runtime/matching/PatternTests.scala
#runtime/matching/Pebble.scala
runtime/matching/Rule.scala
diff --git a/config/list/scalac.lst b/config/list/scalac.lst
index a79a2fc7d9..a4bfe6d4e4 100644
--- a/config/list/scalac.lst
+++ b/config/list/scalac.lst
@@ -190,7 +190,6 @@ transformer/TransMatchPhase.scala
transformer/UnCurry.scala
transformer/UnCurryPhase.scala
transformer/matching/FullRegularTranslator.scala
-transformer/matching/GrammarTool.scala
transformer/matching/MutableGrammar.scala
transformer/matching/NonTermFactory.scala
transformer/matching/PatternExp.scala
diff --git a/sources/scala/collection/immutable/BitSet.scala b/sources/scala/collection/immutable/BitSet.scala
index f9a629b2e4..30cd679395 100644
--- a/sources/scala/collection/immutable/BitSet.scala
+++ b/sources/scala/collection/immutable/BitSet.scala
@@ -9,9 +9,9 @@
package scala.collection.immutable;
-/** The class <code>BitSet</code>provides an immutable bitset view on a
- * byte array. Instances can conveniently be created from instances of
- * <code>mutable.ResizableBitSet</code>.
+/** The class <code>BitSet</code>provides an immutable bitset view on an
+ * int array. Instances can conveniently be created from instances of
+ * <code>mutable.ResizableBitSet</code>. Bit indices are between 0..(size-1) inclusive
*
* @param <code>n</code> represents the number of relevant bits
* @param ba: array of ints of length <code>n</code>&gt;&gt;&gt;5
diff --git a/sources/scala/collection/mutable/BitSet.scala b/sources/scala/collection/mutable/BitSet.scala
index eac258ef04..e9d4dd6774 100644
--- a/sources/scala/collection/mutable/BitSet.scala
+++ b/sources/scala/collection/mutable/BitSet.scala
@@ -10,6 +10,7 @@
package scala.collection.mutable ;
/** mutable, resizable bit sets, to represent dense sets of small integers
+ * Bit indices are between 0..(size-1) inclusive
* @author Burak Emir
* @param initSize: initial size in nbits
*/
@@ -18,14 +19,14 @@ class BitSet(initSize: Int) extends scala.collection.BitSet {
/** default constructor, initial size of 16 bits */
def this() = this( 16 );
- final def byteSize(size:Int) = { (size >>> 5) + (if( (size & 0x1F)!= 0 ) 1 else 0) };
+ final def intSize(size:Int) = { (size >>> 5) + (if( (size & 0x1F)!= 0 ) 1 else 0) };
class ByteArray with ResizableArray[Int] {
- override protected val initialSize: Int = byteSize( initSize );
+ override protected val initialSize: Int = intSize( initSize );
override protected var array: Array[Int] = new Array[Int](initialSize);
/** size of this bitset in nbits */
- def ensureBits(nbits: Int): Unit = ensureSize( byteSize( nbits ));
+ def ensureBits(nbits: Int): Unit = ensureSize( intSize( nbits ));
final def and(j: Int, mask:Int): Unit = {
array.update( j, array(j) & mask );
diff --git a/sources/scala/runtime/matching/Matcher.scala b/sources/scala/runtime/matching/Matcher.scala
index 80e8f7ed58..5482a78991 100644
--- a/sources/scala/runtime/matching/Matcher.scala
+++ b/sources/scala/runtime/matching/Matcher.scala
@@ -55,6 +55,7 @@ class Matcher( pgram:PatternGrammar ) {
def getChildren( t:Any ):Iterator[Any] = t match {
//case n:scala.xml.Node => n.child;
+ case n:Seq[Any] => n.elements;
case n:CaseClass => Iterator.fromCaseClass( n );
case _ => Iterator.empty[Any];
}
@@ -133,6 +134,7 @@ class Matcher( pgram:PatternGrammar ) {
if( !it.hasNext ) {
var set = immutable.ListSet.Empty[Int];
for( val h <- initialNTs ) {
+ //Console.println("isNullable("+h+")="+pgram.isNullable(h));
if( pgram.isNullable( h )) { set = set + h; }
}
//Console.println("RET isApplicableHedge("+initialNTs+","+h+") " + set.toString());
@@ -200,7 +202,7 @@ class Matcher( pgram:PatternGrammar ) {
}
}
*/
- //Console.println("RET isApplicableHedge( " + initialNTs + "," + h + ") " + applHedgeNTs);
+ //Console.println("RET isApplicableHedge( " + initialNTs + ",...) " + applHedgeNTs);
/* applHNTs */
applHedgeNTs /* no chain rules stuff needed */
}
diff --git a/sources/scala/runtime/matching/PatternGrammar.scala b/sources/scala/runtime/matching/PatternGrammar.scala
index 07bdf8633e..e1fe1f85c6 100644
--- a/sources/scala/runtime/matching/PatternGrammar.scala
+++ b/sources/scala/runtime/matching/PatternGrammar.scala
@@ -1,7 +1,125 @@
package scala.runtime.matching ;
-
+import scala.util.grammar._;
import scala.collection.{ immutable, mutable, Map, Set };
+object PatternGrammar {
+ def encodeTreeRHS(x:TreeRHS):String = x match {
+ case LabelledRHS(TestLabel(test),hnt) =>
+ val sb = new StringBuffer();
+ sb.append(test);
+ sb.append('/');
+ sb.append(hnt);
+ sb.toString();
+ case AnyTreeRHS => "_"
+ }
+ def decodeTreeRHS(s:String):TreeRHS = s.charAt(0) match {
+ case '_' => AnyTreeRHS;
+ case _ =>
+ val s2 = s.split("/");
+ val test = Integer.parseInt(s2(0));
+ val hnt = Integer.parseInt(s2(1));
+ LabelledRHS(TestLabel(test),hnt);
+ }
+ def encodeHedgeRHS(x:HedgeRHS):String = x match {
+ case ConsRHS(tnt, hnt) =>
+ val sb = new StringBuffer();
+ sb.append(tnt);
+ sb.append('/');
+ sb.append(hnt);
+ sb.toString();
+ case AnyHedgeRHS => "A"
+ }
+ def decodeHedgeRHS(s:String):HedgeRHS = s.charAt(0) match {
+ case 'A' => AnyHedgeRHS;
+ case _ =>
+ val s2 = s.split("/");
+ val tnt = Integer.parseInt(s2(0));
+ val hnt = Integer.parseInt(s2(1));
+ ConsRHS(tnt,hnt);
+ }
+ def decode(str: String, tests: PatternTests): PatternGrammar = {
+ val sq:Seq[String] = str.split("#");
+ //Console.println("sq.length"+sq.length);
+ val it = sq.elements;
+
+ def readIntArray(length: Int): Array[Int] = {
+ val arr = new Array[Int](length);
+ var i = 0;
+ while(i < length) {
+ arr(i) = Integer.parseInt(it.next);
+ i = i + 1;
+ }
+ arr
+ }
+ def readBitSet(n: Int): immutable.BitSet = {
+ val len = (n >>> 5) + (if( (n & 0x1F)!= 0 ) 1 else 0);
+ new immutable.BitSet(n,readIntArray(len),false);
+ }
+ def readTransitionsT: immutable.Set[TreeRHS] = {
+ val trans = it.next;
+ //Console.println("T trans = "+trans);
+ var r = new immutable.ListSet[TreeRHS];
+ if(trans.length() == 0)
+ return r;
+ val s:Array[String] = trans.split(",");
+ var i = 1;
+ while( i < s.length) {
+ r = r + PatternGrammar.decodeTreeRHS(s(i));
+ i = i + 1;
+ }
+ r
+ }
+ def readTransitionsH: immutable.Set[HedgeRHS] = {
+ val trans = it.next;
+ //Console.println("H trans = "+trans);
+ val s:Array[String] = trans.split(",");
+ var r = new immutable.ListSet[HedgeRHS];
+ if(trans.length() == 0)
+ return r;
+ var i = 1;
+ while(i < s.length) {
+ r = r + PatternGrammar.decodeHedgeRHS(s(i));
+ i = i + 1;
+ }
+ r
+ }
+
+ val _nTreeNT = Integer.parseInt( it.next );
+ //Console.println("read _nTreeNT:"+_nTreeNT);
+ val _nHedgeNT = Integer.parseInt( it.next );
+ //Console.println("read _nHedge:"+_nHedgeNT);
+ val _treeInitials = readBitSet( _nTreeNT );
+ //Console.println("read treeInitials:" + _treeInitials.toArray);
+ val _hedgeInitials = readBitSet( _nHedgeNT );
+ //Console.println("read hedgeInitials:" + _hedgeInitials.toArray);
+ val _isNullable = readBitSet( _nHedgeNT );
+ //Console.println("read isNullable:" + _isNullable.toArray);
+ var i = 0;
+ val _treeTransitions = new Array[immutable.Set[TreeRHS]](_nTreeNT);
+ while(i < _nTreeNT) {
+ _treeTransitions(i) = readTransitionsT;
+ i = i + 1;
+ }
+ i = 0;
+ val _hedgeTransitions = new Array[immutable.Set[HedgeRHS]](_nHedgeNT);
+ while(i < _nHedgeNT) {
+ _hedgeTransitions(i) = readTransitionsH;
+ i = i + 1;
+ }
+ new PatternGrammar {
+ val nTreeNT = _nTreeNT;
+ val nHedgeNT = _nHedgeNT;
+ val treeInitials = _treeInitials;
+ val hedgeInitials = _hedgeInitials;
+ val isNullable = _isNullable;
+ val treeTransitions = _treeTransitions;
+ val hedgeTransitions = _hedgeTransitions;
+ val vars = new Array[Int](0); // @todo
+ final def test(i:Int, inp:Any) = tests(i,inp);
+ }
+ }
+}
+
/** runtime representation of patterns. This class augments
* scala.util.grammar.TreeHedgeGrammar, with an abstract representation
* of variable bindings. Variables are simply consecutive integers,
@@ -16,4 +134,52 @@ abstract class PatternGrammar extends scala.util.grammar.ImmutableTreeHedgeGramm
def isSequenceType: Boolean = { treeInitials.toSet(true).isEmpty };
+ def encode: String = {
+ val sb = new StringBuffer();
+ def writeInt(i: Int) = {
+ sb.append(i);
+ sb.append('#');
+ }
+ def writeIntArray(arr:Array[Int]) = {
+ var i = 0;
+ while(i < arr.length) {
+ sb.append(arr(i));
+ sb.append('#');
+ i = i + 1;
+ }
+ }
+
+ writeInt( nTreeNT ); // nTreeNT
+ writeInt( nHedgeNT ); // nHedgeNT
+ writeIntArray(treeInitials.toArray); // treeInitials
+ writeIntArray(hedgeInitials.toArray); // hedgeInitials
+ writeIntArray(isNullable.toArray); // isNullable
+ // treeTransitions
+ var i = 0;
+ while(i < nTreeNT) {
+ val set = treeTransitions(i).elements;
+ sb.append('n');
+ while( set.hasNext ) {
+ sb.append(',');
+ sb.append(PatternGrammar.encodeTreeRHS(set.next));
+ }
+ sb.append('#');
+ i = i + 1;
+ }
+ // hedgeTransitions
+ i = 0;
+ while(i < nHedgeNT) {
+ val set = hedgeTransitions(i).elements;
+ sb.append('n');
+ while( set.hasNext ) {
+ sb.append(',');
+ sb.append(PatternGrammar.encodeHedgeRHS(set.next));
+ }
+ sb.append('#');
+ i = i + 1;
+ }
+ sb.toString();
+ }
+
+
}
diff --git a/sources/scala/runtime/matching/PatternTests.scala b/sources/scala/runtime/matching/PatternTests.scala
new file mode 100644
index 0000000000..ea04481d58
--- /dev/null
+++ b/sources/scala/runtime/matching/PatternTests.scala
@@ -0,0 +1,5 @@
+package scala.runtime.matching ;
+
+abstract class PatternTests extends Function2[Int,Any,Boolean]{
+ def apply(i:Int, inp:Any): Boolean;
+}
diff --git a/sources/scala/tools/scalac/ast/parser/Parser.scala b/sources/scala/tools/scalac/ast/parser/Parser.scala
index 92ed12d390..1b811d3aa3 100644
--- a/sources/scala/tools/scalac/ast/parser/Parser.scala
+++ b/sources/scala/tools/scalac/ast/parser/Parser.scala
@@ -1877,7 +1877,7 @@ class Parser(unit: CompilationUnit) {
ts.toArray()
}
- /** ObjectDef ::= Id [`:' SimpleType] ClassTemplate
+ /** ObjectDef ::= Id { , Id } [`:' SimpleType] ClassTemplate
*/
def objectDef(mods: int): Array[Tree] = {
val lhs = new ListBuffer[Pair[Int, Name]];
@@ -1885,16 +1885,16 @@ class Parser(unit: CompilationUnit) {
s.nextToken();
lhs.append(Pair(s.pos, ident()));
} while (s.token == COMMA);
- val thistpe = simpleTypedOpt();
+ val thistpe = simpleTypedOpt();
val template = classTemplate( false );
val ts = new myTreeList();
- lhs foreach { case Pair(p, n) =>
- ts.append(
- make.ModuleDef(
- p, mods, n, thistpe.duplicate(),
- template.duplicate().asInstanceOf[Tree$Template]));
- }
- ts.toArray()
+ lhs foreach { case Pair(p, n) =>
+ ts.append(
+ make.ModuleDef(
+ p, mods, n, thistpe.duplicate(),
+ template.duplicate().asInstanceOf[Tree$Template]));
+ }
+ ts.toArray()
}
/** ClassTemplate ::= [`extends' Constr] {`with' Constr} [TemplateBody]
diff --git a/sources/scala/tools/scalac/ast/parser/Scanner.scala b/sources/scala/tools/scalac/ast/parser/Scanner.scala
index 049699ee92..3b23b4cf3b 100644
--- a/sources/scala/tools/scalac/ast/parser/Scanner.scala
+++ b/sources/scala/tools/scalac/ast/parser/Scanner.scala
@@ -474,7 +474,7 @@ class Scanner(_unit: CompilationUnit) extends TokenData {
nextch(); addCharToDoc(ch);
openComments = openComments + 1;
}
- } else if (ch != SU) {
+ } else if ((ch != '*')&&(ch != SU)) {
nextch(); addCharToDoc(ch);
}
} while ((ch != '*') && (ch != SU));
diff --git a/sources/scala/tools/scalac/transformer/TransMatch.scala b/sources/scala/tools/scalac/transformer/TransMatch.scala
index ae76507081..1ebdcba40a 100644
--- a/sources/scala/tools/scalac/transformer/TransMatch.scala
+++ b/sources/scala/tools/scalac/transformer/TransMatch.scala
@@ -30,7 +30,6 @@ package scala.tools.scalac.transformer {
import matching.FullRegularTranslator ;
-import matching.GrammarTool ; //DEBUG
class TransMatch( global:scalac_Global )
extends scalac_transformer_OwnerTransformer( global ) {
@@ -104,7 +103,7 @@ class TransMatch( global:scalac_Global )
//f.write( gram.encode );
//f.close();
// val gram = Predef.decode( Predef.Array[] );
- Console.println( GrammarTool.encode( gram ));
+ Console.println( gram.encode);
throw new ApplicationError("not impl.");
};
diff --git a/sources/scala/tools/scalac/transformer/matching/GrammarTool.scala b/sources/scala/tools/scalac/transformer/matching/GrammarTool.scala
deleted file mode 100644
index 3ecdc398fe..0000000000
--- a/sources/scala/tools/scalac/transformer/matching/GrammarTool.scala
+++ /dev/null
@@ -1,105 +0,0 @@
-package scala.tools.scalac.transformer.matching ;
-
-import scala.runtime.matching.PatternGrammar; //Grammar ;
-
-//import scalac.ast.{ Tree, TreeGen };
-//import scalac.util.Name;
-
-object GrammarTool {
-
- def encode(gram: PatternGrammar): String = {
- val sb = new StringBuffer();
- def writeInt(i: Int) = {
- sb.append(i);
- sb.append('#');
- }
- def writeIntArray(arr:Array[Int]) = {
- sb.append(arr.length);
- sb.append('#');
- var i = 0;
- while(i < arr.length) {
- sb.append(arr(i));
- sb.append('#');
- }
- }
-
- writeInt( gram.nTreeNT ); // nTreeNT
- writeInt( gram.nHedgeNT ); // nHedgeNT
- writeIntArray(gram.treeInitials.toArray); // treeInitials
- writeIntArray(gram.hedgeInitials.toArray); // hedgeInitials
- writeIntArray(gram.isNullable.toArray); // isNullable
- // treeTransitions
- sb.append(gram.treeTransitions.length);
- sb.append('#');
- var i = 0;
- while(i < gram.treeTransitions.length) {
- val set = gram.treeTransitions(i).elements;
- while( set.hasNext ) {
- sb.append(',');
- sb.append(set.next);
- }
- sb.append('#');
- }
- // hedgeTransitions
- sb.append(gram.hedgeTransitions.length);
- sb.append('#');
- i = 0;
- while(i < gram.hedgeTransitions.length) {
- val set = gram.hedgeTransitions(i).elements;
- while( set.hasNext ) {
- sb.append(',');
- sb.append(set.next);
- }
- sb.append('#');
- }
- sb.toString();
- }
-/*
- def toString(gram: Grammar) = {
- "new Grammar("+gram.treeTransitions+",\n"+gram.hedgeTransitions+",\n"+{
- var k = 1;
- val sb = new java.lang.StringBuffer();
- for( val y <- Iterator.fromArray( gram.vars ) ) {
- sb.append("case "+k+": max var ="+y);
- k = k + 1;
- }
- sb.toString()
- }+")\n";
- }
-*/
- /*
- private val _Grammar = Name.fromString("Grammar");
- private val _runtime = Name.fromString("runtime");
- private val _matching = Name.fromString("matching");
-
- // convenience methods
- private def _scala(pos: int, name: Name) =
- make.Select( pos, make.Ident( pos, Names.scala ), name);
-
- private def _scala_runtime(pos: int, name: Name) =
- make.Select( pos, _scala( pos, _xml ), name );
-
- private def _scala_runtime_matching( pos: int ) = {
- make.Select( pos, _scala_xml( pos, _runtime ), name );
-
- private def _scala_runtime_matching_Grammar( pos: int ) =
- make.Select( pos, _scala_xml_matching( pos, _Grammar ), name );
-
-
- def toTree(gram: Grammar) = {
-
- gen.New(
- gen.mkApplyTV(
- gen.mkPrimaryConstructorGlobalRef(
- pos,
- defs.TUPLE_CLASS[2]),
- new Type[] { left.getType(), right.getType() },
- new Tree[] { left, right }
- )
- );
-
- }
- make.New(pos, init);
- }
- */
-}
diff --git a/sources/scala/tools/scalac/typechecker/RefCheck.scala b/sources/scala/tools/scalac/typechecker/RefCheck.scala
index 04ede04094..8387cb483c 100755
--- a/sources/scala/tools/scalac/typechecker/RefCheck.scala
+++ b/sources/scala/tools/scalac/typechecker/RefCheck.scala
@@ -34,8 +34,11 @@ import scalac.util.NewArray;
* - Local modules are replaced by variables and classes
* - caseArity, caseElement implementations added to case classes
* - equals, and hashCode and toString methods are added to case classes,
- * unless they are defined in the class or a baseclass
- * different from java.lang.Object
+ * unless they are defined in the class or a baseclass
+ * different from java.lang.Object
+ * - toString method is added to case objects,
+ * unless they are defined in the class or a baseclass
+ * different from java.lang.Object
* - Calls to case factory methods are replaced by new's.
* - Type nodes are replaced by TypeTerm nodes.
* - Eliminate constant definitions
@@ -860,6 +863,11 @@ class RefCheck(globl: scalac.Global) extends Transformer(globl) {
ts.append(caseElementMethod(clazz));
ts.append(caseArityMethod(clazz));
ts.append(tagMethod(clazz));
+ } else if (clazz.isCaseObject()) {
+ if (!hasImplementation(clazz, Names.toString)) {
+ ts.append(toStringMethod(clazz));
+ }
+ ts.append(tagMethod(clazz));
} else if ((clazz.flags & ABSTRACT) == 0) {
ts.append(tagMethod(clazz));
}
diff --git a/sources/scala/util/grammar/ImmutableTreeHedgeGrammar.scala b/sources/scala/util/grammar/ImmutableTreeHedgeGrammar.scala
index 62132a2aef..85e1b779cc 100644
--- a/sources/scala/util/grammar/ImmutableTreeHedgeGrammar.scala
+++ b/sources/scala/util/grammar/ImmutableTreeHedgeGrammar.scala
@@ -21,7 +21,9 @@ abstract class ImmutableTreeHedgeGrammar[ A <: Alphabet ] extends TreeHedgeGramm
val hedgeInitials: immutable.BitSet;
/** inv: isNullable.length == nHedgeNT */
val isNullable: immutable.BitSet;
- val treeTransitions: Array[immutable.Set[TreeRHS]];
- val hedgeTransitions: Array[immutable.Set[HedgeRHS]];
+ /** inv: treeTransitions.length == nTreeNT */
+ val treeTransitions: Function1[Int,immutable.Set[TreeRHS]];
+ /** inv: hedgeTransitions.length == nHedgeNT */
+ val hedgeTransitions: Function1[Int,immutable.Set[HedgeRHS]];
}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 586daeff92..eab2fb7a3b 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -668,6 +668,12 @@ public abstract class Symbol implements Modifiers, Kinds {
return kind == CLASS && (flags & CASE) != 0;
}
+ /** Does this symbol denote a case object?
+ */
+ public final boolean isCaseObject() {
+ return isModuleClass() && (sourceModule().flags & CASE) != 0;
+ }
+
/** Does this symbol denote a uniform (i.e. parameterless) class? */
public final boolean isTrait() {
//preInitialize(); todo: enable, problem is that then we cannot print