diff options
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 <code>n</code> + * 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 <code>n</code> 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 <code>f</code>. + */ + 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 <code>that</code>. + */ + 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 <code>f</code> to each element of + * this iterator, then concatenates the results. + * + * @param f the function to apply on each element. + * @return an iterator over <code>f(a0), ... , f(an)</code> if this iterator + * yields the elements <code>a0, ..., an</code>. + */ + 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 <code>p</code>. The order of the elements + * is preserved. + * + * @param p the redicate used to filter the iterator. + * @return the elements of this iterator satisfying <code>p</code>. + */ + 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 + * <code>that</code> by associating each element of the former with + * the element at the same position in the latter. + * + * @param <code>that</code> must have the same number of elements as this + * iterator. + * @return an iterator yielding <code>(a0,b0), ..., (an,bn)</code> where + * <code>ai</code> are the elements from this iterator and + * <code>bi</code> are the elements from iterator <code>that</code>. + */ + 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 <code>f</code> 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 <code>p</code> 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 <code>p</code> to all elements of this + * iterable object and return true, iff there is at least one + * element for which <code>p</code> 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( i<i ) it.next; - it.next + /** Find and return the first element of the iterable object satisfying a + * predicate, if any. + * + * @param p the predicate + * @return the first element in the iterable object satisfying <code>p</code>, + * or <code>None</code> 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 <code>op</code>, from left to right, and starting with + * the value <code>z</code>. + * @return <code>op(... (op(op(z,a0),a1) ...), an)</code> if the list + * is <code>List(a0, a1, ..., an)</code>. + */ + 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 <code>op</code>, from rigth to left, and starting with + * the value <code>z</code>. + * @return <code>a0 op (... op (an op z)...)</code> if the list + * is <code>[a0, a1, ..., an]</code>. + */ + 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 <code>foldLeft</code> but can be used as + * an operator with the order of list and zero arguments reversed. + * That is, <code>z /: xs</code> is the same as <code>xs foldLeft z</code> + */ + def /:[B](z: B)(f: (B, A) => B): B = foldLeft(z)(f); + + /** An alias for <code>foldRight</code>. + * That is, <code>xs :\ z</code> is the same as <code>xs foldRight z</code> + */ + 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 <code>xs</code> with the elements of + * this sequence starting at position <code>start</code>. + * + * @param xs the array to fill. + * @param start starting index. + * @return the given array <code>xs</code> 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 <code>n</code> first elements of this list. * @throws <code>java.lang.RuntimeException</code> 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 <code>n</code> first elements. * @throws <code>java.lang.RuntimeException</code> 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 <code>Seq[A]</code> represents finite sequences of elements * of type <code>A</code>. * @@ -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 <code>n</code>. + */ + def take(n: Int): Seq[A] = subseq(0, n); + + /** Returns a new sub-sequence that drops the first <code>n</code> + * elements of this sequence. + */ + def drop(n: Int): Seq[A] = subseq(n, length - n); + /** Returns a subsequence starting from index <code>from</code> * consisting of <code>len</code> 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 <code>xs</code> with the elements of - * this list starting at position <code>start</code>. Does not - * work with empty lists. + * this sequence starting at position <code>start</code>. * * @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 <code>toString</code> 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 <code>n</code>. + * + * @return the element at index <code>n</code>. + */ + def apply(n: Int): A = x.apply(n); + /** Is this partial function defined for the index <code>x</code>? * * @return true, iff <code>x</code> 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 <code>n</code>. + */ + override def take(n: Int): Seq[A] = x.take(n); + + /** Returns a new sub-sequence that drops the first <code>n</code> + * elements of this sequence. + */ + override def drop(n: Int): Seq[A] = x.drop(n); /** Returns a subsequence starting from index <code>from</code> * consisting of <code>len</code> 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 <code>xs</code> with the elements of - * this list starting at position <code>start</code>. Does not - * work with empty lists. + * this sequence starting at position <code>start</code>. * * @param xs the array to fill. * @param start starting index. - * @return the given array <code>xs</code> filled with this list. + * @return the given array <code>xs</code> 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 <code>elements</code> 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 <code>elements</code> 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 <code>n</code> 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 <code>n</code> 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 <code>ArrayBuffer</code> 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 <code>Buffer</code> 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 <code>remove</code>. * * @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 <code>key</code> * to <code>value</code> 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 <code>key</code>. - * 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: * <pre> @@ -41,32 +35,45 @@ trait Map[A, B] with scala.collection.Map[A, B] { */ def +=(key: A): MapTo = new MapTo(key); - /** <code>incl</code> can be used to add many mappings at the same time - * to the map. The method assumes that a mapping is represented - * by a <code>Pair</code> 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 <code>map</code> 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 <code>map</code> 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. + /** <code>incl</code> can be used to add many mappings at the same time + * to the map. The method assumes that a mapping is represented + * by a <code>Pair</code> 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 <code>key</code>. + * 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 <code>keys</code> 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 <code>keys</code> 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 <code>n</code>th 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 <code>n</code>th element of this list or <code>None</code> + * 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 <code>scala.List</code> 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 <code>Map</code> class into which this abstract * class is mixed in. Class <code>ObservableMap</code> publishes - * events of the type <code>ObservableUpdate</code>. + * events of the type <code>Message</code>. * * @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 <code>Set</code> class into which this abstract * class is mixed in. Class <code>ObservableSet</code> publishes - * events of the type <code>ObservableUpdate</code>. + * events of the type <code>Message</code>. * * @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; * <code>remove</code>, and <code>clear</code>. * * @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 <code>elem</code> + * from this set depending on the value of parameter <code>included</code>. + * Typically, one would use the following syntax: + * <pre>set(elem) = true</pre> + */ + 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; - /** <code>incl</code> 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 <code>that</code> 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 <code>that</code> to the set. */ - def incl(that: Iterable[A]): Unit = - that.elements.foreach(elem => +=(elem)); + def ++=(it: Iterator[A]): Unit = it foreach +=; + + /** <code>incl</code> can be used to add many elements to the set + * at the same time. + */ + def incl(elems: A*): Unit = ++=(elems.elements); /** <code>-=</code> can be used to remove a single element from * a set. */ def -=(elem: A): Unit; - /** <code>excl</code> removes many elements from the set. + /** This method removes all the elements provided by the + * the iterable object <code>that</code> 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 <code>that</code> from the set. + * <code>it</code> from the set. + */ + def --=(it: Iterator[A]): Unit = it foreach -=; + + /** <code>excl</code> 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 <code>that</code>. * It removes all the elements that are not present in <code>that</code>. @@ -61,7 +74,7 @@ trait Set[A] with scala.collection.Set[A] { /** Method <code>filter</code> removes all elements from the set for * which the predicate <code>p</code> yields the value <code>false</code>. */ - 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 <code>ArrayBuffer</code> 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; |