From bd07456f926c31bb47f0009c54002b2b0e8379f5 Mon Sep 17 00:00:00 2001 From: Matthias Zenger Date: Mon, 10 May 2004 13:07:01 +0000 Subject: Refactored class library. --- sources/scala/Iterable.scala | 14 +- sources/scala/IterableProxy.scala | 6 - sources/scala/Iterator.scala | 351 ++++++++++++++------- sources/scala/List.scala | 4 +- sources/scala/Option.scala | 2 +- sources/scala/Predef.scala | 82 ++++- sources/scala/Seq.scala | 51 ++- sources/scala/SeqProxy.scala | 39 ++- sources/scala/Stream.scala | 76 ++--- sources/scala/collection/Map.scala | 9 +- sources/scala/collection/Set.scala | 6 + sources/scala/collection/mutable/Buffer.scala | 75 ++++- sources/scala/collection/mutable/BufferProxy.scala | 8 +- sources/scala/collection/mutable/HashMap.scala | 6 + sources/scala/collection/mutable/HashSet.scala | 6 + sources/scala/collection/mutable/History.scala | 12 +- .../scala/collection/mutable/JavaMapAdaptor.scala | 6 + .../scala/collection/mutable/JavaSetAdaptor.scala | 6 + sources/scala/collection/mutable/Map.scala | 68 ++-- sources/scala/collection/mutable/MapProxy.scala | 18 +- sources/scala/collection/mutable/MutableList.scala | 13 + .../scala/collection/mutable/ObservableMap.scala | 14 +- .../scala/collection/mutable/ObservableSet.scala | 11 +- .../scala/collection/mutable/PriorityQueue.scala | 32 +- sources/scala/collection/mutable/Publisher.scala | 2 +- sources/scala/collection/mutable/Queue.scala | 22 +- .../collection/mutable/RevertableHistory.scala | 6 +- sources/scala/collection/mutable/Set.scala | 63 +++- sources/scala/collection/mutable/SetProxy.scala | 24 +- sources/scala/collection/mutable/Stack.scala | 24 +- sources/scala/collection/mutable/Subscriber.scala | 2 +- .../collection/mutable/SynchronizedBuffer.scala | 4 + .../scala/collection/mutable/SynchronizedMap.scala | 34 +- .../mutable/SynchronizedPriorityQueue.scala | 6 + .../collection/mutable/SynchronizedQueue.scala | 8 + .../scala/collection/mutable/SynchronizedSet.scala | 36 ++- .../collection/mutable/SynchronizedStack.scala | 8 + sources/scala/tools/dtd2scala/DeclToScala.scala | 4 +- sources/scala/tools/scalac/icode/ICode.scala | 2 +- 39 files changed, 855 insertions(+), 305 deletions(-) diff --git a/sources/scala/Iterable.scala b/sources/scala/Iterable.scala index 87f2d33636..84e7a9daa8 100644 --- a/sources/scala/Iterable.scala +++ b/sources/scala/Iterable.scala @@ -9,6 +9,7 @@ package scala; + object Iterable { def view[A <% Ordered[A]](x: Iterable[A]): Ordered[Iterable[A]] = new Ordered[Iterable[A]] { def compareTo[B >: Iterable[A] <% Ordered[B]](that: B): Int = that match { @@ -139,19 +140,6 @@ trait Iterable[+A] { */ def :\[B](z: B)(f: (A, B) => B): B = foldRight(z)(f); - /** Transform this iterable object into a list of all elements. - * - * @return a list which enumerates all elements of this set. - */ - def toList: List[A] = { - val it = elements; - var res: List[A] = Nil; - while (it.hasNext) { - res = it.next :: res; - } - res.reverse - } - /** Checks if the other iterable object contains the same elements. * * @param that the other iterable object diff --git a/sources/scala/IterableProxy.scala b/sources/scala/IterableProxy.scala index 13dfebb4fc..537b2dcb10 100644 --- a/sources/scala/IterableProxy.scala +++ b/sources/scala/IterableProxy.scala @@ -86,12 +86,6 @@ class IterableProxy[+A](x: Iterable[A]) extends Iterable[A] with Proxy(x) { */ override def :\[B](z: B)(f: (A, B) => B): B = x.:\(z)(f); - /** Transform this iterable object into a list of all elements. - * - * @return a list which enumerates all elements of this set. - */ - override def toList: List[A] = x.toList; - /** Checks if the other iterable object contains the same elements. * * @param that the other iterable object diff --git a/sources/scala/Iterator.scala b/sources/scala/Iterator.scala index 3472f1f436..c05a010665 100644 --- a/sources/scala/Iterator.scala +++ b/sources/scala/Iterator.scala @@ -20,8 +20,8 @@ package scala; object Iterator { def empty[a] = new Iterator[a] { - def hasNext = false; - def next: a = error("next on empty iterator"); + def hasNext = false; + def next: a = error("next on empty iterator"); } def fromValues[a](xs: a*) = xs.elements; @@ -140,127 +140,264 @@ object Iterator { * @author Matthias Zenger * @version 1.2, 15/03/2004 */ -trait Iterator[+a] with Iterable[a] { +trait Iterator[+A] { - def hasNext: Boolean; + /** Does this iterator provide another element? + */ + def hasNext: Boolean; - def next: a; + /** Returns the next element. + */ + def next: A; - def elements: Iterator[a] = this; + /** Returns a new iterator that iterates only over the first n + * elements. + */ + def take(n: Int) = new Iterator[A] { + var remaining = n; + def hasNext = remaining > 0 && Iterator.this.hasNext; + def next: A = + if (hasNext) { remaining = remaining - 1; Iterator.this.next } + else error("next on empty iterator"); + } - def take(n: Int) = new Iterator[a] { - var remaining = n; - def hasNext = remaining > 0 && Iterator.this.hasNext; - def next: a = - if (hasNext) { remaining = remaining - 1; Iterator.this.next } - else error("next on empty iterator"); - } + /** Removes the first n elements from this iterator. + */ + def drop(n: Int): Iterator[A] = + if (n > 0) { next; drop(n - 1) } else this; - def drop(n: Int): Iterator[a] = - if (n > 0) { next; drop(n - 1) } else this; + /** Returns a new iterator that maps all elements of this iterator + * to new elements using function f. + */ + def map[B](f: A => B): Iterator[B] = new Iterator[B] { + def hasNext = Iterator.this.hasNext; + def next = f(Iterator.this.next) + } - def map[b](f: a => b): Iterator[b] = new Iterator[b] { - def hasNext = Iterator.this.hasNext; - def next = f(Iterator.this.next) - } + /** Returns a new iterator that first yields the elements of this + * iterator followed by the elements provided by iterator that. + */ + def append[B >: A](that: Iterator[B]) = new Iterator[B] { + def hasNext = Iterator.this.hasNext || that.hasNext; + def next = if (Iterator.this.hasNext) Iterator.this.next else that.next; + } - def append[b >: a](that: Iterator[b]) = new Iterator[b] { - def hasNext = Iterator.this.hasNext || that.hasNext; - def next = if (Iterator.this.hasNext) Iterator.this.next else that.next; - } + /** Applies the given function f to each element of + * this iterator, then concatenates the results. + * + * @param f the function to apply on each element. + * @return an iterator over f(a0), ... , f(an) if this iterator + * yields the elements a0, ..., an. + */ + def flatMap[B](f: A => Iterator[B]): Iterator[B] = new Iterator[B] { + private var cur: Iterator[B] = Iterator.empty; + def hasNext: Boolean = + if (cur.hasNext) true + else if (Iterator.this.hasNext) { + cur = f(Iterator.this.next); + hasNext + } else false; + def next: B = + if (cur.hasNext) cur.next + else if (Iterator.this.hasNext) { + cur = f(Iterator.this.next); + next + } else error("next on empty iterator"); + } - def flatMap[b](f: a => Iterator[b]): Iterator[b] = new Iterator[b] { - private var cur: Iterator[b] = Iterator.empty; - def hasNext: Boolean = - if (cur.hasNext) true - else if (Iterator.this.hasNext) { - cur = f(Iterator.this.next); - hasNext - } else false; - def next: b = - if (cur.hasNext) cur.next - else if (Iterator.this.hasNext) { - cur = f(Iterator.this.next); - next - } else error("next on empty iterator"); - } + /** Returns an iterator over all the elements of this iterator that + * satisfy the predicate p. The order of the elements + * is preserved. + * + * @param p the redicate used to filter the iterator. + * @return the elements of this iterator satisfying p. + */ + def filter(p: A => Boolean): Iterator[A] = new BufferedIterator[A] { + private val source = Iterator.this.buffered; + private def skip: Unit = + while (source.hasNext && !p(source.head)) { source.next; () } + def hasNext: Boolean = { skip; source.hasNext } + def next: A = { skip; source.next } + def head: A = { skip; source.head; } + } - def filter(p: a => Boolean): Iterator[a] = new BufferedIterator[a] { - private val source = - Iterator.this.buffered; - private def skip: Unit = - while (source.hasNext && !p(source.head)) { source.next; () } - def hasNext: Boolean = { skip; source.hasNext } - def next: a = { skip; source.next } - def head: a = { skip; source.head; } - } + /** Return an iterator formed from this iterator and the specified iterator + * that by associating each element of the former with + * the element at the same position in the latter. + * + * @param that must have the same number of elements as this + * iterator. + * @return an iterator yielding (a0,b0), ..., (an,bn) where + * ai are the elements from this iterator and + * bi are the elements from iterator that. + */ + def zip[B](that: Iterator[B]) = new Iterator[Pair[A, B]] { + def hasNext = Iterator.this.hasNext && that.hasNext; + def next = Pair(Iterator.this.next, that.next); + } - def zip[b](that: Iterator[b]) = new Iterator[Pair[a, b]] { - def hasNext = Iterator.this.hasNext && that.hasNext; - def next = Pair(Iterator.this.next, that.next); - } + /** Apply a function f to all elements of this + * iterable object. + * + * @param f a function that is applied to every element. + */ + def foreach(f: A => Unit): Unit = while (hasNext) { f(next) }; - def buffered: BufferedIterator[a] = new BufferedIterator[a] { - private var hd: a = _; - private var ahead: Boolean = false; - def head: a = { - if (!ahead) { - hd = Iterator.this.next; - ahead = true - } - hd + /** Apply a predicate p to all elements of this + * iterable object and return true, iff the predicate yields + * true for all elements. + * + * @param p the predicate + * @returns true, iff the predicate yields true for all elements. + */ + def forall(p: A => Boolean): Boolean = { + var res = true; + while (res && hasNext) { res = p(next) } + res } - def next: a = - if (ahead) { ahead = false; hd } else head; - def hasNext: Boolean = ahead || Iterator.this.hasNext; - override def buffered: BufferedIterator[a] = this; - } - def duplicate: Pair[Iterator[a], Iterator[a]] = { - var xs: List[a] = Nil; - var ahead: Iterator[a] = null; - class Partner extends Iterator[a] { - var ys: List[a] = Nil; - def hasNext: Boolean = Iterator.this.synchronized { - ((this == ahead) && Iterator.this.hasNext) || - ((this != ahead) && (!xs.isEmpty || !ys.isEmpty || Iterator.this.hasNext)); - } - def next: a = Iterator.this.synchronized { - if (this == ahead) { - val e = Iterator.this.next; - xs = e :: xs; e - } else { - if (ys.isEmpty) { - ys = xs.reverse; - xs = Nil; - } - ys match { - case Nil => - val e = Iterator.this.next; - ahead = this; - xs = e :: xs; e - case z :: zs => - ys = zs; z - } - } - } + /** Apply a predicate p to all elements of this + * iterable object and return true, iff there is at least one + * element for which p yields true. + * + * @param p the predicate + * @returns true, iff the predicate yields true for at least one element. + */ + def exists(p: A => Boolean): Boolean = { + var res = false; + while (!res && hasNext) { res = p(next) } + res } - ahead = new Partner; - Pair(ahead, new Partner) - } - /** converts a prefix of this iterator to a sequence - def toSeq( len:int ):Seq[a] = new Seq[a] { - def length: Int = len; - def elements = Iterator.this; - def apply( i:int ) = { - val it = Iterator.this; - var j = 0; while( ip, + * or None if none exists. + */ + def find(p: A => Boolean): Option[A] = { + var res: Option[A] = None; + while (res.isEmpty && hasNext) { + val e = next; + if (p(e)) res = Some(e); + } + res } - } - def toSeq:Seq[a] = toList; - */ + /** Combines the elements of this list together using the binary + * operator op, from left to right, and starting with + * the value z. + * @return op(... (op(op(z,a0),a1) ...), an) if the list + * is List(a0, a1, ..., an). + */ + def foldLeft[B](z: B)(op: (B, A) => B): B = { + var acc = z; + while (hasNext) { acc = op(acc, next) } + acc + } + + /** Combines the elements of this list together using the binary + * operator op, from rigth to left, and starting with + * the value z. + * @return a0 op (... op (an op z)...) if the list + * is [a0, a1, ..., an]. + */ + def foldRight[B](z: B)(op: (A, B) => B): B = { + def fold(z: B): B = + if (hasNext) op(next, fold(z)) else z; + fold(z) + } + + /** Similar to foldLeft but can be used as + * an operator with the order of list and zero arguments reversed. + * That is, z /: xs is the same as xs foldLeft z + */ + def /:[B](z: B)(f: (B, A) => B): B = foldLeft(z)(f); + + /** An alias for foldRight. + * That is, xs :\ z is the same as xs foldRight z + */ + def :\[B](z: B)(f: (A, B) => B): B = foldRight(z)(f); + + /** Returns a buffered iterator from this iterator. + */ + def buffered: BufferedIterator[A] = new BufferedIterator[A] { + private var hd: A = _; + private var ahead: Boolean = false; + def head: A = { + if (!ahead) { + hd = Iterator.this.next; + ahead = true + } + hd + } + def next: A = + if (ahead) { ahead = false; hd } else head; + def hasNext: Boolean = ahead || Iterator.this.hasNext; + override def buffered: BufferedIterator[A] = this; + } + + /** Creates two new iterators that both iterate over the same elements + * than this iterator (in the same order). + */ + def duplicate: Pair[Iterator[A], Iterator[A]] = { + var xs: List[A] = Nil; + var ahead: Iterator[A] = null; + class Partner extends Iterator[A] { + var ys: List[A] = Nil; + def hasNext: Boolean = Iterator.this.synchronized { + ((this == ahead) && Iterator.this.hasNext) || + ((this != ahead) && (!xs.isEmpty || !ys.isEmpty || Iterator.this.hasNext)); + } + def next: A = Iterator.this.synchronized { + if (this == ahead) { + val e = Iterator.this.next; + xs = e :: xs; e + } else { + if (ys.isEmpty) { + ys = xs.reverse; + xs = Nil; + } + ys match { + case Nil => val e = Iterator.this.next; + ahead = this; + xs = e :: xs; e + case z :: zs => ys = zs; z + } + } + } + } + ahead = new Partner; + Pair(ahead, new Partner) + } + + /** Fills the given array xs with the elements of + * this sequence starting at position start. + * + * @param xs the array to fill. + * @param start starting index. + * @return the given array xs filled with this list. + */ + def copyToArray[B >: A](xs: Array[B], start: Int): Array[B] = { + var i = start; + while (hasNext) { + xs(i) = next; + i = i + 1; + } + xs + } + + /** Transform this iterator into a list of all elements. + * + * @return a list which enumerates all elements of this iterator. + */ + def toList: List[A] = { + var res: List[A] = Nil; + while (hasNext) { + res = next :: res; + } + res.reverse + } } diff --git a/sources/scala/List.scala b/sources/scala/List.scala index bc8936e2c0..0ba4b74102 100644 --- a/sources/scala/List.scala +++ b/sources/scala/List.scala @@ -308,7 +308,7 @@ sealed trait List[+a] extends Seq[a] { * @return the n first elements of this list. * @throws java.lang.RuntimeException if the list is too short. */ - def take(n: Int): List[a] = + override def take(n: Int): List[a] = if (n == 0) Nil else head :: (tail take (n-1)); @@ -318,7 +318,7 @@ sealed trait List[+a] extends Seq[a] { * @return the list without its n first elements. * @throws java.lang.RuntimeException if the list is too short. */ - def drop(n: Int): List[a] = + override def drop(n: Int): List[a] = if (n == 0) this else (tail drop (n-1)); diff --git a/sources/scala/Option.scala b/sources/scala/Option.scala index e0a5e2d999..bc997cc317 100644 --- a/sources/scala/Option.scala +++ b/sources/scala/Option.scala @@ -60,7 +60,7 @@ trait Option[+A] extends Iterable[A] { case Some(x) => Iterator.fromValues(x) } - override def toList: List[A] = match { + def toList: List[A] = match { case None => List() case Some(x) => List(x) } diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala index 1b31e3464d..66fcafbdef 100644 --- a/sources/scala/Predef.scala +++ b/sources/scala/Predef.scala @@ -68,6 +68,7 @@ object Predef { if (!assertion) throw new Error("assertion failed"); } + def assert(assertion: Boolean, message: Any): Unit = { if (!assertion) throw new Error("assertion failed: " + message); @@ -135,15 +136,6 @@ object Predef { } } - def view[A](xs: Array[A]): Seq[A] = new Seq[A] { - def length = xs.length; - def elements = Iterator.fromArray(xs); - def apply(n: Int) = xs(n); - override def hashCode(): Int = xs.hashCode(); - override def equals(y: Any): Boolean = xs.equals(y); - override protected def stringPrefix: String = "Array"; - } - def view[A <% Ordered[A]](xs: Array[A]): Ordered[Array[A]] = new Ordered[Array[A]] with Proxy(xs) { def compareTo[B >: Array[A] <% Ordered[B]](that: B): Int = that match { case ys: Array[A] => @@ -160,10 +152,82 @@ object Predef { } } + private def first(xs: Int*): Int = xs.elements.find(x => x != 0) match { + case Some(r) => r + case _ => 0 + } + + /** We can't bootstrap currently with the following views included. We have to + * wait for the next release... + * + def view[A <% Ordered[A], B <% Ordered[B]](x: Tuple2[A, B]): Ordered[Tuple2[A, B]] = + new Ordered[Tuple2[A, B]] with Proxy(x) { + def compareTo[T >: Tuple2[A, B] <% Ordered[T]](y: T): Int = y match { + case y1: Tuple2[A, B] => first(x._1.compareTo(y1._1), + x._2.compareTo(y1._2)); + case _ => -(y compareTo x) + } + } + + def view[A <% Ordered[A], B <% Ordered[B], C <% Ordered[C]] + (x: Tuple3[A, B, C]): Ordered[Tuple3[A, B, C]] = + new Ordered[Tuple3[A, B, C]] with Proxy(x) { + def compareTo[T >: Tuple3[A, B, C] <% Ordered[T]](y: T): Int = y match { + case y1: Tuple3[A, B, C] => first(x._1.compareTo(y1._1), + x._2.compareTo(y1._2), + x._3.compareTo(y1._3)); + case _ => -(y compareTo x) + } + } + + def view[A <% Ordered[A], B <% Ordered[B], C <% Ordered[C], D <% Ordered[D]] + (x: Tuple4[A, B, C, D]): Ordered[Tuple4[A, B, C, D]] = + new Ordered[Tuple4[A, B, C, D]] with Proxy(x) { + def compareTo[T >: Tuple4[A, B, C, D] <% Ordered[T]](y: T): Int = y match { + case y1: Tuple4[A, B, C, D] => first(x._1.compareTo(y1._1), + x._2.compareTo(y1._2), + x._3.compareTo(y1._3), + x._4.compareTo(y1._4)); + case _ => -(y compareTo x) + } + } + + def view[A <% Ordered[A], B <% Ordered[B], C <% Ordered[C], D <% Ordered[D], E <% Ordered[E]] + (x: Tuple5[A, B, C, D, E]): Ordered[Tuple5[A, B, C, D, E]] = + new Ordered[Tuple5[A, B, C, D, E]] with Proxy(x) { + def compareTo[T >: Tuple5[A, B, C, D, E] <% Ordered[T]](y: T): Int = y match { + case y1: Tuple5[A, B, C, D, E] => first(x._1.compareTo(y1._1), + x._2.compareTo(y1._2), + x._3.compareTo(y1._3), + x._4.compareTo(y1._4), + x._5.compareTo(y1._5)); + case _ => -(y compareTo x) + } + } + */ + def view(x: String): Ordered[String] = new Ordered[String] with Proxy(x) { def compareTo [b >: String <% Ordered[b]](y: b): int = y match { case y1: String => x compareTo y1; case _ => -(y compareTo x) } } + + def view[A](xs: Array[A]): Seq[A] = new Seq[A] { + def length = xs.length; + def elements = Iterator.fromArray(xs); + def apply(n: Int) = xs(n); + override def hashCode(): Int = xs.hashCode(); + override def equals(y: Any): Boolean = xs.equals(y); + override protected def stringPrefix: String = "Array"; + } + + def view(str: String): Seq[Char] = new Seq[Char] { + def length = str.length(); + def elements = Iterator.fromString(str); + def apply(n: Int) = str.charAt(n); + override def hashCode(): Int = str.hashCode(); + override def equals(y: Any): Boolean = str.equals(y); + override protected def stringPrefix: String = "String"; + } } diff --git a/sources/scala/Seq.scala b/sources/scala/Seq.scala index e9b157b696..502ef546bc 100644 --- a/sources/scala/Seq.scala +++ b/sources/scala/Seq.scala @@ -10,6 +10,24 @@ package scala; +object Seq { + def view[A <% Ordered[A]](xs: Seq[A]): Ordered[Seq[A]] = new Ordered[Seq[A]] with Proxy(xs) { + def compareTo[B >: Seq[A] <% Ordered[B]](that: B): Int = that match { + case ys: Seq[A] => + var res = 0; + val xsit = xs.elements; + val ysit = ys.elements; + while (xsit.hasNext && ysit.hasNext && (res == 0)) { + res = xsit.next compareTo ysit.next; + } + if (res != 0) res else if (xsit.hasNext) 1 else -1 + case _ => + -(that compareTo xs) + } + } +} + + /** Class Seq[A] represents finite sequences of elements * of type A. * @@ -73,10 +91,19 @@ trait Seq[+A] with PartialFunction[Int, A] with Iterable[A] { if (found) i else -1; } + /** Returns the sub-sequence starting from index n. + */ + def take(n: Int): Seq[A] = subseq(0, n); + + /** Returns a new sub-sequence that drops the first n + * elements of this sequence. + */ + def drop(n: Int): Seq[A] = subseq(n, length - n); + /** Returns a subsequence starting from index from * consisting of len elements. */ - def subSequence(from: Int, len: Int): Seq[A] = + def subseq(from: Int, len: Int): Seq[A] = if ((from + len) <= length) new Seq[A] { def apply(n: Int): A = Seq.this.apply(n - from); def length: Int = len; @@ -93,8 +120,7 @@ trait Seq[+A] with PartialFunction[Int, A] with Iterable[A] { error("cannot create subsequence"); /** Fills the given array xs with the elements of - * this list starting at position start. Does not - * work with empty lists. + * this sequence starting at position start. * * @param xs the array to fill. * @param start starting index. @@ -110,17 +136,18 @@ trait Seq[+A] with PartialFunction[Int, A] with Iterable[A] { xs } - /** Returns true if the elements in this sequence are equal - * to the elements in another sequence - def similar(x: Any): Boolean = { // WEG - x.match { - case that: Seq[A] => - (that.length == this.length) && sameElements(that) - case _ => - false + /** Transform this sequence into a list of all elements. + * + * @return a list which enumerates all elements of this sequence. + */ + def toList: List[A] = { + val it = elements; + var res: List[A] = Nil; + while (it.hasNext) { + res = it.next :: res; } + res.reverse } - */ /** Customizes the toString method. * diff --git a/sources/scala/SeqProxy.scala b/sources/scala/SeqProxy.scala index e8bd68781f..3c5b506647 100644 --- a/sources/scala/SeqProxy.scala +++ b/sources/scala/SeqProxy.scala @@ -17,7 +17,7 @@ package scala; * @author Matthias Zenger * @version 1.0, 16/07/2003 */ -class SeqProxy[+A](x: Seq[A]) extends IterableProxy(x) { +class SeqProxy[+A](x: Seq[A]) extends Seq[A] with IterableProxy(x) { /** Returns the length of the sequence. * @@ -25,11 +25,17 @@ class SeqProxy[+A](x: Seq[A]) extends IterableProxy(x) { */ def length: Int = x.length; + /** Access element number n. + * + * @return the element at index n. + */ + def apply(n: Int): A = x.apply(n); + /** Is this partial function defined for the index x? * * @return true, iff x is a legal sequence index. */ - def isDefinedAt(y: Int): Boolean = x.isDefinedAt(y); + override def isDefinedAt(y: Int): Boolean = x.isDefinedAt(y); /** Returns the index of the first occurence of the specified * object in this sequence. @@ -38,7 +44,7 @@ class SeqProxy[+A](x: Seq[A]) extends IterableProxy(x) { * @return the index in this sequence of the first occurence of the specified * element, or -1 if the sequence does not contain this element. */ - def indexOf[B >: A](elem: B): Int = x.indexOf(elem); + override def indexOf[B >: A](elem: B): Int = x.indexOf(elem); /** Returns the index of the last occurence of the specified * element in this sequence, or -1 if the sequence does not @@ -49,20 +55,35 @@ class SeqProxy[+A](x: Seq[A]) extends IterableProxy(x) { * specified element, or -1 if the sequence does not contain * this element. */ - def lastIndexOf[B >: A](elem: B): Int = x.lastIndexOf(elem); + override def lastIndexOf[B >: A](elem: B): Int = x.lastIndexOf(elem); + + /** Returns the sub-sequence starting from index n. + */ + override def take(n: Int): Seq[A] = x.take(n); + + /** Returns a new sub-sequence that drops the first n + * elements of this sequence. + */ + override def drop(n: Int): Seq[A] = x.drop(n); /** Returns a subsequence starting from index from * consisting of len elements. */ - def subSequence(from: Int, len: Int): Seq[A] = x.subSequence(from, len); + override def subseq(from: Int, len: Int): Seq[A] = x.subseq(from, len); /** Fills the given array xs with the elements of - * this list starting at position start. Does not - * work with empty lists. + * this sequence starting at position start. * * @param xs the array to fill. * @param start starting index. - * @return the given array xs filled with this list. + * @return the given array xs filled with the elements + * of this sequence. + */ + override def copyToArray[B >: A](xs: Array[B], start: Int): Array[B] = x.copyToArray(xs, start); + + /** Transform this sequence into a list of all elements. + * + * @return a list which enumerates all elements of this sequence. */ - def copyToArray[B >: A](xs: Array[B], start: Int): Array[B] = x.copyToArray(xs, start); + override def toList: List[A] = x.toList; } diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala index a87b5187fd..f0c1415f9f 100644 --- a/sources/scala/Stream.scala +++ b/sources/scala/Stream.scala @@ -10,6 +10,42 @@ package scala; +object Stream { + + val empty: Stream[All] = new Stream[All] { + def isEmpty = true; + def head: All = error("head of empty stream"); + def tail: Stream[All] = error("tail of empty stream"); + def printElems(buf: StringBuffer, prefix: String): StringBuffer = buf; + } + + def cons[a](hd: a, def tl: Stream[a]) = new Stream[a] { + def isEmpty = false; + def head = hd; + private var tlVal: Stream[a] = _; + private var tlDefined = false; + def tail: Stream[a] = { + if (!tlDefined) { tlVal = tl; tlDefined = true; } + tlVal + } + def printElems(buf: StringBuffer, prefix: String): StringBuffer = { + val buf1 = buf.append(prefix).append(hd.asInstanceOf[java.lang.Object]); + if (tlDefined) printElems(buf1, ", ") else buf1 append ", ?"; + } + } + + def concat[a](xs: Seq[Stream[a]]): Stream[a] = concat(xs.elements); + + def concat[a](xs: Iterator[Stream[a]]): Stream[a] = { + if (xs.hasNext) xs.next append concat(xs) + else empty; + } + + def range(start: int, end: int): Stream[int] = + if (start >= end) empty + else cons(start, range(start + 1, end)); +} + trait Stream[+a] extends Seq[a] { def isEmpty: Boolean; @@ -38,11 +74,11 @@ trait Stream[+a] extends Seq[a] { else if (tail.isEmpty) head else tail.last; - def take(n: int): Stream[a] = + override def take(n: int): Stream[a] = if (n == 0) Stream.empty else Stream.cons(head, tail.take(n-1)); - def drop(n: int): Stream[a] = + override def drop(n: int): Stream[a] = if (n == 0) this else tail.drop(n-1); @@ -130,39 +166,3 @@ trait Stream[+a] extends Seq[a] { def printElems(buf: StringBuffer, prefix: String): StringBuffer; } - -object Stream { - - val empty: Stream[All] = new Stream[All] { - def isEmpty = true; - def head: All = error("head of empty stream"); - def tail: Stream[All] = error("tail of empty stream"); - def printElems(buf: StringBuffer, prefix: String): StringBuffer = buf; - } - - def cons[a](hd: a, def tl: Stream[a]) = new Stream[a] { - def isEmpty = false; - def head = hd; - private var tlVal: Stream[a] = _; - private var tlDefined = false; - def tail: Stream[a] = { - if (!tlDefined) { tlVal = tl; tlDefined = true; } - tlVal - } - def printElems(buf: StringBuffer, prefix: String): StringBuffer = { - val buf1 = buf.append(prefix).append(hd.asInstanceOf[java.lang.Object]); - if (tlDefined) printElems(buf1, ", ") else buf1 append ", ?"; - } - } - - def concat[a](xs: Seq[Stream[a]]): Stream[a] = concat(xs.elements); - - def concat[a](xs: Iterator[Stream[a]]): Stream[a] = { - if (xs.hasNext) xs.next append concat(xs) - else empty; - } - - def range(start: int, end: int): Stream[int] = - if (start >= end) empty - else cons(start, range(start + 1, end)); -} diff --git a/sources/scala/collection/Map.scala b/sources/scala/collection/Map.scala index b0accaeb50..e623380eb1 100644 --- a/sources/scala/collection/Map.scala +++ b/sources/scala/collection/Map.scala @@ -24,8 +24,7 @@ package scala.collection; * @author Matthias Zenger * @version 1.1, 02/05/2004 */ -trait Map[A, +B] with PartialFunction[A, B] - with Iterable[Pair[A, B]] { +trait Map[A, +B] with PartialFunction[A, B] with Iterable[Pair[A, B]] { /** Compute the number of key-to-value mappings. * @@ -149,6 +148,12 @@ trait Map[A, +B] with PartialFunction[A, B] } }}; + /** Returns the mappings of this map as a list. + * + * @return a list containing all mappings + */ + def toList: List[Pair[A, B]] = elements.toList; + /** Creates a string representation for this map. * * @return a string showing all mappings diff --git a/sources/scala/collection/Set.scala b/sources/scala/collection/Set.scala index 59b8eed07b..f57f6a3961 100644 --- a/sources/scala/collection/Set.scala +++ b/sources/scala/collection/Set.scala @@ -73,6 +73,12 @@ trait Set[A] with Function1[A, Boolean] with Iterable[A] { this.size == other.size && this.elements.forall(other.contains) }; + /** Returns the elements of this set as a list. + * + * @return a list containing all set elements. + */ + def toList: List[A] = elements.toList; + /** Returns a string representation of this set. * * @return a string showing all elements of this set. diff --git a/sources/scala/collection/mutable/Buffer.scala b/sources/scala/collection/mutable/Buffer.scala index 65da4983d1..3d99e11f73 100644 --- a/sources/scala/collection/mutable/Buffer.scala +++ b/sources/scala/collection/mutable/Buffer.scala @@ -18,7 +18,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 02/03/2004 */ -trait Buffer[A] with Seq[A] with Cloneable { +trait Buffer[A] with Seq[A] with Scriptable[Message[Pair[Location, A]]] with Cloneable { /** Append a single element to this buffer and return * the identity of the buffer. @@ -39,8 +39,16 @@ trait Buffer[A] with Seq[A] with Cloneable { * * @param iter the iterable object. */ - def ++(iter: Iterable[A]): Buffer[A] = { - iter.elements.foreach(e => this += e); + def ++(elems: Iterable[A]): Buffer[A] = this ++ elems.elements; + + /** Appends a number of elements provided by an iterable object + * via its elements method. The identity of the + * buffer is returned. + * + * @param iter the iterable object. + */ + def ++(iter: Iterator[A]): Buffer[A] = { + iter.foreach(e => this += e); this } @@ -49,7 +57,14 @@ trait Buffer[A] with Seq[A] with Cloneable { * * @param iter the iterable object. */ - def ++=(iter: Iterable[A]): Unit = this ++ iter; + def ++=(elems: Iterable[A]): Unit = this ++ elems.elements; + + /** Appends a number of elements provided by an iterable object + * via its elements method. + * + * @param iter the iterable object. + */ + def ++=(it: Iterator[A]): Unit = this ++ it; /** Appends a sequence of elements to this buffer. * @@ -78,7 +93,7 @@ trait Buffer[A] with Seq[A] with Cloneable { * @param iter the iterable object. */ def ++:(iter: Iterable[A]): Buffer[A] = { - iter.toList.reverse.foreach(e => e +: this); + iter.elements.toList.reverse.foreach(e => e +: this); this } @@ -128,13 +143,61 @@ trait Buffer[A] with Seq[A] with Cloneable { */ def remove(n: Int): A; + /** Removes the first n elements. + * + * @param n the number of elements to remove from the beginning + * of this buffer. + */ + def trimStart(n: Int): Unit = { + var i = n; + while (i > 0) { remove(0); i = i - 1; } + } + + /** Removes the last n elements. + * + * @param n the number of elements to remove from the end + * of this buffer. + */ + def trimEnd(n: Int): Unit = { + var i = n; + while (i > 0) { remove(length - 1); i = i - 1; } + } + /** Clears the buffer contents. */ def clear: Unit; + /** Send a message to this scriptable object. + * + * @param cmd the message to send. + */ + def <<(cmd: Message[Pair[Location, A]]): Unit = cmd match { + case Include(Pair(l, elem)) => l match { + case Start => prepend(elem); + case End => append(elem); + case Index(n) => insert(n, elem); + case _ => error("message " + cmd + " not understood"); + } + case Update(Pair(l, elem)) => l match { + case Start => update(0, elem); + case End => update(length - 1, elem); + case Index(n) => update(n, elem); + case _ => error("message " + cmd + " not understood"); + } + case Remove(Pair(l, _)) => l match { + case Start => remove(0); + case End => remove(length - 1); + case Index(n) => remove(n); + case _ => error("message " + cmd + " not understood"); + } + case Reset() => clear; + case s: Script[Pair[Location, A]] => s.elements foreach <<; + case _ => error("message " + cmd + " not understood"); + } + /** Return a clone of this buffer. * - * @return an ArrayBuffer with the same elements. + * @return a buffer with the same elements. */ override def clone(): Buffer[A] = super.clone().asInstanceOf[Buffer[A]]; diff --git a/sources/scala/collection/mutable/BufferProxy.scala b/sources/scala/collection/mutable/BufferProxy.scala index 1365c0362f..1c4be09a3c 100644 --- a/sources/scala/collection/mutable/BufferProxy.scala +++ b/sources/scala/collection/mutable/BufferProxy.scala @@ -131,9 +131,15 @@ class BufferProxy[A](buf: Buffer[A]) extends Buffer[A] with Proxy(buf) { */ def clear: Unit = buf.clear; + /** Send a message to this scriptable object. + * + * @param cmd the message to send. + */ + override def <<(cmd: Message[Pair[Location, A]]): Unit = buf << cmd; + /** Return a clone of this buffer. * * @return a Buffer with the same elements. */ - override def clone(): Buffer[A] = buf.clone(); + override def clone(): Buffer[A] = new BufferProxy(buf.clone()); } diff --git a/sources/scala/collection/mutable/HashMap.scala b/sources/scala/collection/mutable/HashMap.scala index 9e545a7281..3771a54fee 100644 --- a/sources/scala/collection/mutable/HashMap.scala +++ b/sources/scala/collection/mutable/HashMap.scala @@ -26,4 +26,10 @@ class HashMap[A, B] extends scala.collection.mutable.Map[A, B] initTable(table); tableSize = 0; } + + override def clone(): HashMap[A, B] = { + val res = new HashMap[A, B]; + res ++= this; + res + } } diff --git a/sources/scala/collection/mutable/HashSet.scala b/sources/scala/collection/mutable/HashSet.scala index 07cc6726c6..6a7b895791 100644 --- a/sources/scala/collection/mutable/HashSet.scala +++ b/sources/scala/collection/mutable/HashSet.scala @@ -39,4 +39,10 @@ class HashSet[A] extends scala.collection.mutable.Set[A] with HashTable[A] { protected type Entry = A; protected def entryKey(e: Entry) = e; + + override def clone(): HashSet[A] = { + val res = new HashSet[A]; + res ++= this; + res + } } diff --git a/sources/scala/collection/mutable/History.scala b/sources/scala/collection/mutable/History.scala index b56f231862..0587349806 100644 --- a/sources/scala/collection/mutable/History.scala +++ b/sources/scala/collection/mutable/History.scala @@ -18,22 +18,24 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.0, 08/07/2003 */ -class History[A, B] with Subscriber[A, B] { +class History[A, B] with Subscriber[A, B] with Iterable[Pair[B, A]] { protected val log: Queue[Pair[B, A]] = new Queue[Pair[B, A]]; - val maxHistory: Int = 32000; + val maxHistory: Int = 1000; - def update(pub: B, event: A): Unit = { + def notify(pub: B, event: A): Unit = { if (log.length >= maxHistory) { val old = log.dequeue; } log.enqueue(Pair(pub, event)); } - def getHistory: Iterator[Pair[B, A]] = log.toList.elements; + def elements: Iterator[Pair[B, A]] = log.elements; - def historySize: Int = log.length; + def events: Iterator[A] = log.elements.map { case Pair(_, e) => e } + + def size: Int = log.length; def clear: Unit = log.clear; } diff --git a/sources/scala/collection/mutable/JavaMapAdaptor.scala b/sources/scala/collection/mutable/JavaMapAdaptor.scala index b575d172c0..f84562d4cb 100644 --- a/sources/scala/collection/mutable/JavaMapAdaptor.scala +++ b/sources/scala/collection/mutable/JavaMapAdaptor.scala @@ -57,4 +57,10 @@ class JavaMapAdaptor[A, B](jmap: java.util.Map) extends Map[A, B] { def -=(key: A): Unit = { val x = jmap.remove(key); } override def clear: Unit = jmap.clear(); + + override def clone(): Map[A, B] = { + val res = new HashMap[A, B]; + res ++= this; + res + } } diff --git a/sources/scala/collection/mutable/JavaSetAdaptor.scala b/sources/scala/collection/mutable/JavaSetAdaptor.scala index 172c056c21..a07ef614c7 100644 --- a/sources/scala/collection/mutable/JavaSetAdaptor.scala +++ b/sources/scala/collection/mutable/JavaSetAdaptor.scala @@ -35,4 +35,10 @@ class JavaSetAdaptor[A](jset: java.util.Set) extends Set[A] { def -=(elem: A): Unit = { val x = jset.remove(elem); } def clear: Unit = jset.clear(); + + override def clone(): Set[A] = { + val res = new HashSet[A]; + res ++= this; + res; + } } diff --git a/sources/scala/collection/mutable/Map.scala b/sources/scala/collection/mutable/Map.scala index b2a8a94f99..053e90de43 100644 --- a/sources/scala/collection/mutable/Map.scala +++ b/sources/scala/collection/mutable/Map.scala @@ -16,9 +16,9 @@ package scala.collection.mutable; * and remove. * * @author Matthias Zenger - * @version 1.0, 08/07/2003 + * @version 1.1, 09/05/2004 */ -trait Map[A, B] with scala.collection.Map[A, B] { +trait Map[A, B] with scala.collection.Map[A, B] with Scriptable[Message[Pair[A, B]]] with Cloneable { /** This method allows one to add a new mapping from key * to value to the map. If the map already contains a @@ -27,12 +27,6 @@ trait Map[A, B] with scala.collection.Map[A, B] { */ def update(key: A, value: B): Unit; - /** This method removes a mapping from the given key. - * If the map does not contain a mapping for the given key, the - * method does nothing. - */ - def -=(key: A): Unit; - /** This method defines syntactic sugar for adding or modifying * mappings. It is typically used in the following way: *
@@ -41,32 +35,45 @@ trait Map[A, B] with scala.collection.Map[A, B] {
      */
     def +=(key: A): MapTo = new MapTo(key);
 
-    /** incl can be used to add many mappings at the same time
-     *  to the map. The method assumes that a mapping is represented
-     *  by a Pair object who's first component denotes the
-     *  key, and who's second component refers to the value.
+    /** This method adds all the mappings provided by an iterator of
+     *  parameter map to the map.
      */
-    def incl(mappings: Pair[A, B]*): Unit = {
-        val ys = mappings.asInstanceOf[List[Pair[A, B]]];
-        ys foreach { case Pair(key, value) => update(key, value); };
-    }
+    def ++=(map: Iterable[Pair[A, B]]): Unit = ++=(map.elements);
 
     /** This method adds all the mappings provided by an iterator of
      *  parameter map to the map.
      */
-    def incl(map: Iterable[Pair[A, B]]): Unit = map.elements foreach {
+    def ++=(it: Iterator[Pair[A, B]]): Unit = it foreach {
         case Pair(key, value) => update(key, value);
     }
 
-    /** This method will remove all the mappings for the given sequence
-     *  of keys from the map.
+    /** incl can be used to add many mappings at the same time
+     *  to the map. The method assumes that a mapping is represented
+     *  by a Pair object who's first component denotes the
+     *  key, and who's second component refers to the value.
+     */
+    def incl(mappings: Pair[A, B]*): Unit = ++=(mappings.elements);
+
+    /** This method removes a mapping from the given key.
+     *  If the map does not contain a mapping for the given key, the
+     *  method does nothing.
+     */
+    def -=(key: A): Unit;
+
+    /** This method removes all the mappings for keys provided by an
+     *  iterator over the elements of the keys object.
      */
-    def excl(keys: A*): Unit = excl(keys);
+    def --=(keys: Iterable[A]): Unit = --=(keys.elements);
 
     /** This method removes all the mappings for keys provided by an
      *  iterator over the elements of the keys object.
      */
-    def excl(keys: Iterable[A]): Unit = keys.elements foreach -=;
+    def --=(it: Iterator[A]): Unit = it foreach -=;
+
+    /** This method will remove all the mappings for the given sequence
+     *  of keys from the map.
+     */
+    def excl(keys: A*): Unit = --=(keys.elements);
 
     /** Removes all mappings from the map. After this operation is
      *  completed, the map is empty.
@@ -87,6 +94,25 @@ trait Map[A, B] with scala.collection.Map[A, B] {
         case Pair(key, value) => if (!p(key, value)) -=(key);
     }
 
+    /** Send a message to this scriptable object.
+     *
+     *  @param cmd  the message to send.
+     */
+    def <<(cmd: Message[Pair[A, B]]): Unit = cmd match {
+    	case Include(Pair(k, v)) => update(k, v);
+    	case Update(Pair(k, v)) => update(k, v);
+    	case Remove(Pair(k, _)) => this -= k;
+    	case Reset() => clear;
+    	case s: Script[Pair[A, B]] => s.elements foreach <<;
+    	case _ => error("message " + cmd + " not understood");
+    }
+
+    /** Return a clone of this map.
+     *
+     *  @return an map with the same elements.
+     */
+    override def clone(): Map[A, B] = super.clone().asInstanceOf[Map[A, B]];
+
     /** The hashCode method always yields an error, since it is not
      *  safe to use mutable maps as keys in hash tables.
      *
diff --git a/sources/scala/collection/mutable/MapProxy.scala b/sources/scala/collection/mutable/MapProxy.scala
index a4e65d65f6..75493aad86 100644
--- a/sources/scala/collection/mutable/MapProxy.scala
+++ b/sources/scala/collection/mutable/MapProxy.scala
@@ -22,15 +22,19 @@ class MapProxy[A, B](m: Map[A, B]) extends Map[A, B]
 
     def update(key: A, value: B): Unit = m.update(key, value);
 
-    def -=(key: A): Unit = m.-=(key);
+    override def ++=(map: Iterable[Pair[A, B]]): Unit = m ++= map;
 
-    override def incl(mappings: Pair[A, B]*): Unit = m.incl(mappings);
+    override def ++=(it: Iterator[Pair[A, B]]): Unit = m ++= it;
 
-    override def incl(map: Iterable[Pair[A, B]]): Unit = m.incl(map);
+    override def incl(mappings: Pair[A, B]*): Unit = m ++= mappings;
 
-    override def excl(keys: A*): Unit = m.excl(keys);
+    def -=(key: A): Unit = m -= key;
 
-    override def excl(keys: Iterable[A]): Unit = m.excl(keys);
+    override def --=(keys: Iterable[A]): Unit = m --= keys;
+
+    override def --=(it: Iterator[A]): Unit = m --= it;
+
+    override def excl(keys: A*): Unit = m --= keys;
 
     override def clear: Unit = m.clear;
 
@@ -41,4 +45,8 @@ class MapProxy[A, B](m: Map[A, B]) extends Map[A, B]
     override def toString() = m.toString();
 
     override def mappingToString(p: Pair[A, B]) = m.mappingToString(p);
+
+    override def <<(cmd: Message[Pair[A, B]]): Unit = m << cmd;
+
+    override def clone(): Map[A, B] = new MapProxy(m.clone());
 }
diff --git a/sources/scala/collection/mutable/MutableList.scala b/sources/scala/collection/mutable/MutableList.scala
index c8a694804f..b17b161e5d 100644
--- a/sources/scala/collection/mutable/MutableList.scala
+++ b/sources/scala/collection/mutable/MutableList.scala
@@ -23,13 +23,21 @@ abstract class MutableList[A] extends Seq[A] with PartialFunction[Int, A] {
     protected var last: LinkedList[A] = null;
     protected var len: Int = 0;
 
+    /** Returns the length of this list.
+     */
     def length: Int = len;
 
+    /** Returns the nth element of this list. This method
+     *  yields an error if the element does not exist.
+     */
     def apply(n: Int): A = get(n) match {
         case None => error("element not found")
         case Some(value) => value
     }
 
+    /** Returns the nth element of this list or None
+     *  if this element does not exist.
+     */
     def get(n: Int): Option[A] = first.get(n);
 
     protected def prependElem(elem: A): Unit = {
@@ -55,9 +63,14 @@ abstract class MutableList[A] extends Seq[A] with PartialFunction[Int, A] {
         len = 0;
     }
 
+    /** Returns an iterator over all elements of this list.
+     */
     def elements: Iterator[A] =
         if (first == null) Nil.elements else first.elements;
 
+    /** Returns an instance of scala.List containing the same
+     *  sequence of elements.
+     */
     override def toList: List[A] = if (first == null) Nil else first.toList;
 
 	override protected def stringPrefix: String = "MutableList";
diff --git a/sources/scala/collection/mutable/ObservableMap.scala b/sources/scala/collection/mutable/ObservableMap.scala
index 40aeddca77..1b682573ae 100644
--- a/sources/scala/collection/mutable/ObservableMap.scala
+++ b/sources/scala/collection/mutable/ObservableMap.scala
@@ -13,36 +13,36 @@ package scala.collection.mutable;
 /** This class is typically used as a mixin. It adds a subscription
  *  mechanism to the Map class into which this abstract
  *  class is mixed in. Class ObservableMap publishes
- *  events of the type ObservableUpdate.
+ *  events of the type Message.
  *
  *  @author  Matthias Zenger
  *  @version 1.0, 08/07/2003
  */
 abstract class ObservableMap[A, B, This <: ObservableMap[A, B, This]]: This
                     extends scala.collection.mutable.Map[A, B]
-                    with Publisher[ObservableUpdate[Pair[A, B]] with Undo, This] {
+                    with Publisher[Message[Pair[A, B]] with Undoable, This] {
 
     abstract override def update(key: A, value: B): Unit = get(key) match {
         case None => super.update(key, value);
-                     publish(new Inclusion(Pair(key, value)) with Undo {
+                     publish(new Include(Pair(key, value)) with Undoable {
                                  def undo = -=(key);
                              });
         case Some(old) => super.update(key, value);
-                          publish(new Modification(Pair(key, old), Pair(key, value)) with Undo {
-                                      def undo = update(key, old._2);
+                          publish(new Update(Pair(key, value)) with Undoable {
+                                      def undo = update(key, old);
                                   });
     }
 
     abstract override def -=(key: A): Unit = get(key) match {
         case None =>
         case Some(old) => super.-=(key);
-                          publish(new Removal(Pair(key, old)) with Undo {
+                          publish(new Remove(Pair(key, old)) with Undoable {
                                       def undo = update(key, old);
                                   });
     }
 
     abstract override def clear: Unit = {
         super.clear;
-        publish(new Reset() with Undo { def undo: Unit = error("cannot undo"); });
+        publish(new Reset with Undoable { def undo: Unit = error("cannot undo"); });
     }
 }
diff --git a/sources/scala/collection/mutable/ObservableSet.scala b/sources/scala/collection/mutable/ObservableSet.scala
index 0bd4cef331..2d0437f8c9 100644
--- a/sources/scala/collection/mutable/ObservableSet.scala
+++ b/sources/scala/collection/mutable/ObservableSet.scala
@@ -9,30 +9,31 @@
 
 package scala.collection.mutable;
 
+
 /** This class is typically used as a mixin. It adds a subscription
  *  mechanism to the Set class into which this abstract
  *  class is mixed in. Class ObservableSet publishes
- *  events of the type ObservableUpdate.
+ *  events of the type Message.
  *
  *  @author  Matthias Zenger
  *  @version 1.0, 08/07/2003
  */
 abstract class ObservableSet[A, This <: ObservableSet[A, This]]: This
                     extends scala.collection.mutable.Set[A]
-                    with Publisher[ObservableUpdate[A] with Undo, This] {
+                    with Publisher[Message[A] with Undoable, This] {
 
     abstract override def +=(elem: A): Unit = if (!contains(elem)) {
         super.+=(elem);
-        publish(new Inclusion(elem) with Undo { def undo = -=(elem); });
+        publish(new Include(elem) with Undoable { def undo = -=(elem); });
     }
 
     abstract override def -=(elem: A): Unit = if (contains(elem)) {
         super.-=(elem);
-        publish(new Removal(elem) with Undo { def undo = +=(elem); });
+        publish(new Remove(elem) with Undoable { def undo = +=(elem); });
     }
 
     abstract override def clear: Unit = {
         super.clear;
-        publish(new Reset() with Undo { def undo: Unit = error("cannot undo"); });
+        publish(new Reset with Undoable { def undo: Unit = error("cannot undo"); });
     }
 }
diff --git a/sources/scala/collection/mutable/PriorityQueue.scala b/sources/scala/collection/mutable/PriorityQueue.scala
index 848069a918..c639b29b60 100644
--- a/sources/scala/collection/mutable/PriorityQueue.scala
+++ b/sources/scala/collection/mutable/PriorityQueue.scala
@@ -17,7 +17,7 @@ package scala.collection.mutable;
  *  @author  Matthias Zenger
  *  @version 1.0, 03/05/2004
  */
-class PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] {
+class PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] with Cloneable {
   	size = size + 1; // we do not use array(0)
 
   	protected def fixUp(as: Array[A], m: Int): Unit = {
@@ -68,7 +68,13 @@ class PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] {
      *
      *  @param  iter        an iterable object
      */
-    def ++=(iter: Iterable[A]): Unit = iter.elements.foreach(e => this += e);
+    def ++=(iter: Iterable[A]): Unit = this ++= iter.elements;
+
+    /** Adds all elements provided by an iterator into the priority queue.
+     *
+     *  @param  it        an iterator
+     */
+    def ++=(it: Iterator[A]): Unit = it foreach { e => this += e };
 
     /** Adds all elements to the queue.
      *
@@ -142,9 +148,31 @@ class PriorityQueue[A <% Ordered[A]] extends ResizableArray[A] {
      */
     override def hashCode(): Int = error("unsuitable as hash key");
 
+    /** Returns a regular queue containing the same elements.
+     */
+    def toQueue: Queue[A] = {
+    	val res = new Queue[A];
+    	res ++= this;
+    	res
+    }
+
+    /** Returns a list of all elements.
+     */
+    def toList: List[A] = elements.toList;
+
     /** Returns a textual representation of a queue as a string.
      *
      *  @return the string representation of this queue.
      */
     override def toString() = toList.mkString("PriorityQueue(", ", ", ")");
+
+    /** This method clones the priority queue.
+     *
+     *  @return  a priority queue with the same elements.
+     */
+    override def clone(): PriorityQueue[A] = {
+    	val res = new PriorityQueue[A];
+    	res ++= this;
+    	res
+    }
 }
diff --git a/sources/scala/collection/mutable/Publisher.scala b/sources/scala/collection/mutable/Publisher.scala
index 3deb748e2b..1426bf7639 100644
--- a/sources/scala/collection/mutable/Publisher.scala
+++ b/sources/scala/collection/mutable/Publisher.scala
@@ -41,5 +41,5 @@ class Publisher[A, This <: Publisher[A, This]]: This {
 
     protected def publish(event: A): Unit =
         filters.keys.foreach(sub =>
-            if (filters.entryExists(sub, (p => p(event)))) sub.update(this, event));
+            if (filters.entryExists(sub, (p => p(event)))) sub.notify(this, event));
 }
diff --git a/sources/scala/collection/mutable/Queue.scala b/sources/scala/collection/mutable/Queue.scala
index 8bd6a0da4c..441aafec44 100644
--- a/sources/scala/collection/mutable/Queue.scala
+++ b/sources/scala/collection/mutable/Queue.scala
@@ -16,7 +16,7 @@ package scala.collection.mutable;
  *  @author  Matthias Zenger
  *  @version 1.1, 03/05/2004
  */
-class Queue[A] extends MutableList[A] {
+class Queue[A] extends MutableList[A] with Cloneable {
 
     /** Checks if the queue is empty.
      *
@@ -36,7 +36,15 @@ class Queue[A] extends MutableList[A] {
      *
      *  @param  iter        an iterable object
      */
-    def ++=(iter: Iterable[A]): Unit = iter.elements.foreach(e => appendElem(e));
+    def ++=(iter: Iterable[A]): Unit = this ++= iter.elements;
+
+	/** Adds all elements provided by an iterator
+     *  at the end of the queue. The elements are prepended in the order they
+     *  are given out by the iterator.
+     *
+     *  @param  it        an iterator
+     */
+    def ++=(it: Iterator[A]): Unit = it foreach appendElem;
 
     /** Adds all elements to the queue.
      *
@@ -95,4 +103,14 @@ class Queue[A] extends MutableList[A] {
      *  @return the string representation of this queue.
      */
     override def toString() = toList.mkString("Queue(", ", ", ")");
+
+    /** This method clones the queue.
+     *
+     *  @return  a queue with the same elements.
+     */
+    override def clone(): Queue[A] = {
+    	val res = new Queue[A];
+    	res ++= this;
+    	res
+    }
 }
diff --git a/sources/scala/collection/mutable/RevertableHistory.scala b/sources/scala/collection/mutable/RevertableHistory.scala
index 8430dfb96c..3bfc7cd2ed 100644
--- a/sources/scala/collection/mutable/RevertableHistory.scala
+++ b/sources/scala/collection/mutable/RevertableHistory.scala
@@ -18,15 +18,13 @@ package scala.collection.mutable;
  *  @author  Matthias Zenger
  *  @version 1.0, 08/07/2003
  */
-class RevertableHistory[A <: Undo, B] extends History[A, B] with Undo {
+class RevertableHistory[A <: Undoable, B] extends History[A, B] with Undoable {
 
     /** Rollback the full history.
      */
     def undo: Unit = {
         val old = log.toList.reverse;
         clear;
-        old.foreach {
-            case Pair(sub, event) => event.undo;
-        }
+        old.foreach { case Pair(sub, event) => event.undo; }
     }
 }
diff --git a/sources/scala/collection/mutable/Set.scala b/sources/scala/collection/mutable/Set.scala
index 47f1d6424a..b9f4e20b75 100644
--- a/sources/scala/collection/mutable/Set.scala
+++ b/sources/scala/collection/mutable/Set.scala
@@ -16,42 +16,55 @@ package scala.collection.mutable;
  *  remove, and clear.
  *
  *  @author  Matthias Zenger
- *  @version 1.0, 08/07/2003
+ *  @version 1.1, 09/05/2004
  */
-trait Set[A] with scala.collection.Set[A] {
+trait Set[A] with scala.collection.Set[A] with Scriptable[Message[A]] with Cloneable {
+
+    /** This method allows one to add or remove an element elem
+     *  from this set depending on the value of parameter included.
+     *  Typically, one would use the following syntax:
+     *  
set(elem) = true
+ */ + def update(elem: A, included: Boolean): Unit = + if (included) +=(elem) else -=(elem); /** This method adds a new element to the set. */ def +=(elem: A): Unit; - /** incl can be used to add many elements to the set - * at the same time. + /** This method will add all the elements provided by an iterator + * of the iterable object that to the set. */ - def incl(elems: A*): Unit = { - val ys = elems.asInstanceOf[List[A]]; - ys foreach { y => +=(y); }; - } + def ++=(that: Iterable[A]): Unit = ++=(that.elements); /** This method will add all the elements provided by an iterator * of the iterable object that to the set. */ - def incl(that: Iterable[A]): Unit = - that.elements.foreach(elem => +=(elem)); + def ++=(it: Iterator[A]): Unit = it foreach +=; + + /** incl can be used to add many elements to the set + * at the same time. + */ + def incl(elems: A*): Unit = ++=(elems.elements); /** -= can be used to remove a single element from * a set. */ def -=(elem: A): Unit; - /** excl removes many elements from the set. + /** This method removes all the elements provided by the + * the iterable object that from the set. */ - def excl(elems: A*): Unit = excl(elems); + def --=(that: Iterable[A]): Unit = --=(that.elements); /** This method removes all the elements provided by an iterator - * of the iterable object that from the set. + * it from the set. + */ + def --=(it: Iterator[A]): Unit = it foreach -=; + + /** excl removes many elements from the set. */ - def excl(that: Iterable[A]): Unit = - that.elements.foreach(elem => -=(elem)); + def excl(elems: A*): Unit = --=(elems.elements); /** This method computes an intersection with set that. * It removes all the elements that are not present in that. @@ -61,7 +74,7 @@ trait Set[A] with scala.collection.Set[A] { /** Method filter removes all elements from the set for * which the predicate p yields the value false. */ - def filter(p: A => Boolean): Unit = toList foreach { + def filter(p: A => Boolean): Unit = toList.foreach { elem => if (!p(elem)) -=(elem); } @@ -70,6 +83,24 @@ trait Set[A] with scala.collection.Set[A] { */ def clear: Unit; + /** Send a message to this scriptable object. + * + * @param cmd the message to send. + */ + def <<(cmd: Message[A]): Unit = cmd match { + case Include(elem) => this += elem; + case Remove(elem) => this -= elem; + case Reset() => clear; + case s: Script[A] => s.elements foreach <<; + case _ => error("message " + cmd + " not understood"); + } + + /** Return a clone of this set. + * + * @return a set with the same elements. + */ + override def clone(): Set[A] = super.clone().asInstanceOf[Set[A]]; + /** The hashCode method always yields an error, since it is not * safe to use mutable stacks as keys in hash tables. * diff --git a/sources/scala/collection/mutable/SetProxy.scala b/sources/scala/collection/mutable/SetProxy.scala index 88726b2b7e..af7521d733 100644 --- a/sources/scala/collection/mutable/SetProxy.scala +++ b/sources/scala/collection/mutable/SetProxy.scala @@ -15,26 +15,36 @@ package scala.collection.mutable; * dynamically using object composition and forwarding. * * @author Matthias Zenger - * @version 1.0, 21/07/2003 + * @version 1.1, 09/05/2004 */ class SetProxy[A](set: Set[A]) extends Set[A] with scala.collection.SetProxy[A](set) { - def +=(elem: A): Unit = set.+=(elem); + override def update(elem: A, included: Boolean): Unit = set(elem) = included; - override def incl(elems: A*): Unit = set.incl(elems); + def +=(elem: A): Unit = set += elem; - override def incl(that: Iterable[A]): Unit = set.incl(that); + override def ++=(that: Iterable[A]): Unit = set ++= that; - def -=(elem: A): Unit = set.-=(elem); + override def ++=(it: Iterator[A]): Unit = set ++= it; - override def excl(elems: A*): Unit = set.excl(elems); + override def incl(elems: A*): Unit = set ++= elems; - override def excl(that: Iterable[A]): Unit = set.excl(that); + def -=(elem: A): Unit = set -= elem; + + override def --=(that: Iterable[A]): Unit = set --= that; + + override def --=(it: Iterator[A]): Unit = set --= it; + + override def excl(elems: A*): Unit = set --= elems; override def intersect(that: Set[A]): Unit = set.intersect(that); def clear: Unit = set.clear; override def filter(p: A => Boolean): Unit = set.filter(p); + + override def <<(cmd: Message[A]): Unit = set << cmd; + + override def clone(): Set[A] = new SetProxy(set.clone()); } diff --git a/sources/scala/collection/mutable/Stack.scala b/sources/scala/collection/mutable/Stack.scala index d401d35144..7da0b6a6f6 100644 --- a/sources/scala/collection/mutable/Stack.scala +++ b/sources/scala/collection/mutable/Stack.scala @@ -16,7 +16,7 @@ package scala.collection.mutable; * @author Matthias Zenger * @version 1.1, 03/05/2004 */ -class Stack[A] extends MutableList[A] { +class Stack[A] extends MutableList[A] with Cloneable { /** Checks if the stack is empty. * @@ -36,7 +36,15 @@ class Stack[A] extends MutableList[A] { * * @param iter an iterable object */ - def ++=(iter: Iterable[A]): Unit = iter.elements.foreach(e => prependElem(e)); + def ++=(iter: Iterable[A]): Unit = this ++= iter.elements; + + /** Pushes all elements provided by an iterator + * on top of the stack. The elements are pushed in the order they + * are given out by the iterator. + * + * @param iter an iterator + */ + def ++=(it: Iterator[A]): Unit = it foreach { e => prependElem(e) }; /** Pushes a sequence of elements on top of the stack. The first element * is pushed first, etc. @@ -107,5 +115,15 @@ class Stack[A] extends MutableList[A] { * * @return the string representation of this stack. */ - override def toString() = toList.mkString("Stack(", ", ", ")"); + override def toString(): String = toList.mkString("Stack(", ", ", ")"); + + /** This method clones the stack. + * + * @return a stack with the same elements. + */ + override def clone(): Stack[A] = { + val res = new Stack[A]; + res ++= this; + res + } } diff --git a/sources/scala/collection/mutable/Subscriber.scala b/sources/scala/collection/mutable/Subscriber.scala index c62c09fb49..30ca2d03e2 100644 --- a/sources/scala/collection/mutable/Subscriber.scala +++ b/sources/scala/collection/mutable/Subscriber.scala @@ -18,5 +18,5 @@ package scala.collection.mutable; * @version 1.0, 08/07/2003 */ trait Subscriber[-A, -B] { - def update(pub: B, event: A): Unit; + def notify(pub: B, event: A): Unit; } diff --git a/sources/scala/collection/mutable/SynchronizedBuffer.scala b/sources/scala/collection/mutable/SynchronizedBuffer.scala index a64d864872..f4250d22a5 100644 --- a/sources/scala/collection/mutable/SynchronizedBuffer.scala +++ b/sources/scala/collection/mutable/SynchronizedBuffer.scala @@ -166,6 +166,10 @@ trait SynchronizedBuffer[A] extends Buffer[A] { super.clear; } + override def <<(cmd: Message[Pair[Location, A]]): Unit = synchronized { + super.<<(cmd); + } + /** Return a clone of this buffer. * * @return an ArrayBuffer with the same elements. diff --git a/sources/scala/collection/mutable/SynchronizedMap.scala b/sources/scala/collection/mutable/SynchronizedMap.scala index 09d3f1e8df..8e10b51068 100644 --- a/sources/scala/collection/mutable/SynchronizedMap.scala +++ b/sources/scala/collection/mutable/SynchronizedMap.scala @@ -62,24 +62,32 @@ trait SynchronizedMap[A, B] extends scala.collection.mutable.Map[A, B] { super.update(key, value); } - abstract override def -=(key: A): Unit = synchronized { - super.-=(key); + override def ++=(map: Iterable[Pair[A, B]]): Unit = synchronized { + super.++=(map); + } + + override def ++=(it: Iterator[Pair[A, B]]): Unit = synchronized { + super.++=(it); } override def incl(mappings: Pair[A, B]*): Unit = synchronized { - super.incl(mappings); + super.++=(mappings); } - override def incl(map: Iterable[Pair[A, B]]): Unit = synchronized { - super.incl(map); + abstract override def -=(key: A): Unit = synchronized { + super.-=(key); } - override def excl(keys: A*): Unit = synchronized { - super.excl(keys); + override def --=(keys: Iterable[A]): Unit = synchronized { + super.--=(keys); } - override def excl(keys: Iterable[A]): Unit = synchronized { - super.excl(keys); + override def --=(it: Iterator[A]): Unit = synchronized { + super.--=(it); + } + + override def excl(keys: A*): Unit = synchronized { + super.--=(keys); } override def clear: Unit = synchronized { @@ -97,4 +105,12 @@ trait SynchronizedMap[A, B] extends scala.collection.mutable.Map[A, B] { override def toString() = synchronized { super.toString(); } + + override def <<(cmd: Message[Pair[A, B]]): Unit = synchronized { + super.<<(cmd); + } + + override def clone(): Map[A, B] = synchronized { + super.clone(); + } } diff --git a/sources/scala/collection/mutable/SynchronizedPriorityQueue.scala b/sources/scala/collection/mutable/SynchronizedPriorityQueue.scala index 1afcb8171a..aa41070763 100644 --- a/sources/scala/collection/mutable/SynchronizedPriorityQueue.scala +++ b/sources/scala/collection/mutable/SynchronizedPriorityQueue.scala @@ -38,6 +38,12 @@ class SynchronizedPriorityQueue[A <% Ordered[A]] extends PriorityQueue[A] { */ override def ++=(iter: Iterable[A]): Unit = synchronized { super.++=(iter); } + /** Adds all elements provided by an iterator into the priority queue. + * + * @param it an iterator + */ + override def ++=(it: Iterator[A]): Unit = synchronized { super.++=(it); } + /** Adds all elements to the queue. * * @param elems the elements to add. diff --git a/sources/scala/collection/mutable/SynchronizedQueue.scala b/sources/scala/collection/mutable/SynchronizedQueue.scala index caf17d91d2..74fb9782b5 100644 --- a/sources/scala/collection/mutable/SynchronizedQueue.scala +++ b/sources/scala/collection/mutable/SynchronizedQueue.scala @@ -39,6 +39,14 @@ class SynchronizedQueue[A] extends Queue[A] { */ override def ++=(iter: Iterable[A]): Unit = synchronized { super.++=(iter); } + /** Adds all elements provided by an iterator + * at the end of the queue. The elements are prepended in the order they + * are given out by the iterator. + * + * @param it an iterator + */ + override def ++=(it: Iterator[A]): Unit = synchronized { super.++=(it); } + /** Adds all elements to the queue. * * @param elems the elements to add. diff --git a/sources/scala/collection/mutable/SynchronizedSet.scala b/sources/scala/collection/mutable/SynchronizedSet.scala index 7f5f764387..2d4c2d5767 100644 --- a/sources/scala/collection/mutable/SynchronizedSet.scala +++ b/sources/scala/collection/mutable/SynchronizedSet.scala @@ -30,28 +30,40 @@ trait SynchronizedSet[A] extends scala.collection.mutable.Set[A] { super.contains(elem); } + abstract override def update(elem: A, included: Boolean): Unit = synchronized { + super.update(elem, included); + } + abstract override def +=(elem: A): Unit = synchronized { super.+=(elem); } - override def incl(elems: A*): Unit = synchronized { - super.incl(elems); + override def ++=(that: Iterable[A]) = synchronized { + super.++=(that); } - override def incl(that: Iterable[A]) = synchronized { - super.incl(that); + override def ++=(it: Iterator[A]) = synchronized { + super.++=(it); + } + + override def incl(elems: A*): Unit = synchronized { + super.++=(elems); } abstract override def -=(elem: A): Unit = synchronized { super.-=(elem); } - override def excl(elems: A*): Unit = synchronized { - super.excl(elems); + override def --=(that: Iterable[A]) = synchronized { + super.--=(that); } - override def excl(that: Iterable[A]) = synchronized { - super.excl(that); + override def --=(it: Iterator[A]) = synchronized { + super.--=(it); + } + + override def excl(elems: A*): Unit = synchronized { + super.--=(elems); } override def intersect(that: Set[A]) = synchronized { @@ -81,4 +93,12 @@ trait SynchronizedSet[A] extends scala.collection.mutable.Set[A] { override def toString() = synchronized { super.toString(); } + + override def <<(cmd: Message[A]): Unit = synchronized { + super.<<(cmd); + } + + override def clone(): Set[A] = synchronized { + super.clone(); + } } diff --git a/sources/scala/collection/mutable/SynchronizedStack.scala b/sources/scala/collection/mutable/SynchronizedStack.scala index 2469b20d67..c21a17b22d 100644 --- a/sources/scala/collection/mutable/SynchronizedStack.scala +++ b/sources/scala/collection/mutable/SynchronizedStack.scala @@ -39,6 +39,14 @@ class SynchronizedStack[A] extends Stack[A] { */ override def ++=(iter: Iterable[A]): Unit = synchronized { super.++=(iter); } + /** Pushes all elements provided by an iterator + * on top of the stack. The elements are pushed in the order they + * are given out by the iterator. + * + * @param iter an iterator + */ + override def ++=(it: Iterator[A]): Unit = synchronized { super.++=(it); } + /** Pushes a sequence of elements on top of the stack. The first element * is pushed first, etc. * diff --git a/sources/scala/tools/dtd2scala/DeclToScala.scala b/sources/scala/tools/dtd2scala/DeclToScala.scala index 4283fbba46..152b255822 100644 --- a/sources/scala/tools/dtd2scala/DeclToScala.scala +++ b/sources/scala/tools/dtd2scala/DeclToScala.scala @@ -43,7 +43,7 @@ class DeclToScala(fOut:PrintWriter, n.child.elements.foreach { n => writeNode(n) } } case "elementBinding" => { - for( val decl <- elemMap.values.elements ) { + for( val decl <- elemMap.values ) { lookup += "elementName" -> decl.name; lookup += "elementContainsText" -> decl.containsText.toString(); lookup += "elementContentModel" -> decl.contentModel; @@ -64,7 +64,7 @@ class DeclToScala(fOut:PrintWriter, } */ case "attributeBinding" => { - for( val aDecl <- curAttribs.keys.elements ) { + for( val aDecl <- curAttribs.keys ) { lookup += "attributeName" -> aDecl; n.child.elements.foreach{ n => writeNode( n ) } } diff --git a/sources/scala/tools/scalac/icode/ICode.scala b/sources/scala/tools/scalac/icode/ICode.scala index 249768b537..629a15add6 100644 --- a/sources/scala/tools/scalac/icode/ICode.scala +++ b/sources/scala/tools/scalac/icode/ICode.scala @@ -64,7 +64,7 @@ class ICode(label: String, global: scalac_Global) { def icTraverseFeedBack(f: (IBasicBlock, HashMap[IBasicBlock, boolean]) => unit) = { // ?? Define order (actually preorder) val visited : HashMap[IBasicBlock, boolean] = new HashMap; - visited.incl(blocks.elements.map((x: IBasicBlock) => Pair(x, false))); + visited ++= blocks.elements.map(x => Pair(x, false)); var blockToVisit : List[IBasicBlock] = startBlock::Nil; -- cgit v1.2.3