summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/ReferencePart.tex2
-rw-r--r--sources/examples/Parsers.scala64
-rw-r--r--sources/examples/parsers1.scala16
-rw-r--r--sources/scala/Predef.scala6
-rw-r--r--sources/scala/Stream.scala3
-rw-r--r--sources/scala/tools/scalac/typechecker/Analyzer.scala6
-rw-r--r--sources/scalac/transformer/LambdaLift.java4
7 files changed, 83 insertions, 18 deletions
diff --git a/doc/reference/ReferencePart.tex b/doc/reference/ReferencePart.tex
index 5c5c0bc505..13b3504208 100644
--- a/doc/reference/ReferencePart.tex
+++ b/doc/reference/ReferencePart.tex
@@ -4462,6 +4462,8 @@ class AnyRef extends Any {
trait ScalaObject extends AnyRef;
\end{lstlisting}
+\todo{isinstanceof not permitted on numeric types}
+
The type cast operation \verb@asInstanceOf@ has a special meaning (not
expressed in the code above) when its type parameter is a numeric
type. For any type \lstinline@T <: Double@, and any numeric value
diff --git a/sources/examples/Parsers.scala b/sources/examples/Parsers.scala
index d99c3628ec..5697868d76 100644
--- a/sources/examples/Parsers.scala
+++ b/sources/examples/Parsers.scala
@@ -2,37 +2,37 @@ package examples;
abstract class Parsers {
- type intype;
+ type inputType;
trait Parser[a] {
- type Result = Option[Pair[a, intype]];
+ type Result = Option[Pair[a, inputType]];
- def apply(in: intype): Result;
+ def apply(in: inputType): Result;
def filter(pred: a => boolean) = new Parser[a] {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => None
case Some(Pair(x, in1)) => if (pred(x)) Some(Pair(x, in1)) else None
}
}
def map[b](f: a => b) = new Parser[b] {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => None
case Some(Pair(x, in1)) => Some(Pair(f(x), in1))
}
}
def flatMap[b](f: a => Parser[b]) = new Parser[b] {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => None
case Some(Pair(x, in1)) => f(x).apply(in1)
}
}
def ||| (def p: Parser[a]) = new Parser[a] {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => p(in)
case s => s
}
@@ -43,7 +43,7 @@ abstract class Parsers {
}
def succeed[a](x: a) = new Parser[a] {
- def apply(in: intype): Result = Some(Pair(x, in))
+ def apply(in: inputType): Result = Some(Pair(x, in))
}
def rep[a](p: Parser[a]): Parser[List[a]] =
@@ -56,6 +56,53 @@ abstract class Parsers {
(for (val x <- p) yield List(x)) ||| succeed(List());
}
+class Tokenizer(in: Iterator[char], delimiters: String) extends Iterator[String] {
+
+ val EOI = 0;
+
+ def nextChar() =
+ if (in.hasNext()) in.next() else EOI;
+
+ private var ch = nextChar();
+
+ def isDelimiter(ch: Char) = {
+ var i = 0;
+ while (i < delimiters.length() && delimiters.charAt(i) != ch) { i = i + 1 }
+ i < delimiters.length()
+ }
+
+ def hasNext: boolean = ch != EOI;
+
+ private val buf = new StringBuffer;
+
+ def next: String =
+ while (ch <= ' ' && ch != EOI) nextChar();
+ if (ch == EOI) ""
+ else {
+ if (isDelimiter(ch)) ch.toString()
+ else {
+ buf.setLength(0); buf append ch;
+ while (ch > ' ' && ch != EOI && !isDelimiter(ch)) {
+ buf append ch; nextChar();
+ }
+ buf.toString()
+ }
+ }
+}
+
+abstract class TokenParsers extends Parsers {
+ type inputType = Stream[String];
+ def nextToken() = new Parser[String] {
+ def apply(in: inputType): Result =
+ if (in.isEmpty) None else Some(Pair(in.head, in.tail));
+ }
+}
+
+
+
+
+
+
abstract class CharParsers extends Parsers {
def any: Parser[char];
def chr(ch: char) =
@@ -63,3 +110,4 @@ abstract class CharParsers extends Parsers {
def chr(p: char => boolean) =
for (val c <- any; p(c)) yield c;
}
+abstract class
diff --git a/sources/examples/parsers1.scala b/sources/examples/parsers1.scala
index 09de0343ab..2ed0f4be4b 100644
--- a/sources/examples/parsers1.scala
+++ b/sources/examples/parsers1.scala
@@ -4,18 +4,18 @@ object parsers1 {
abstract class Parsers {
- type intype;
+ type inputType;
abstract class Parser {
- type Result = Option[intype];
+ type Result = Option[inputType];
- def apply(in: intype): Result;
+ def apply(in: inputType): Result;
/*** p &&& q applies first p, and if that succeeds, then q
*/
def &&& (def q: Parser) = new Parser {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => None
case Some(in1) => q(in1)
}
@@ -24,7 +24,7 @@ object parsers1 {
/*** p ||| q applies first p, and, if that fails, then q.
*/
def ||| (def q: Parser) = new Parser {
- def apply(in: intype): Result = Parser.this.apply(in) match {
+ def apply(in: inputType): Result = Parser.this.apply(in) match {
case None => q(in)
case s => s
}
@@ -32,11 +32,11 @@ object parsers1 {
}
val empty = new Parser {
- def apply(in: intype): Result = Some(in)
+ def apply(in: inputType): Result = Some(in)
}
val fail = new Parser {
- def apply(in: intype): Result = None
+ def apply(in: inputType): Result = None
}
def opt(p: Parser): Parser = p ||| empty; // p? = (p | <empty>)
@@ -69,7 +69,7 @@ object parsers1 {
}
class ParseString(s: String) extends Parsers {
- type intype = int;
+ type inputType = int;
val input = 0;
def chr(p: char => boolean) = new Parser {
def apply(in: int): Parser#Result =
diff --git a/sources/scala/Predef.scala b/sources/scala/Predef.scala
index 94d50234d7..a260a97d21 100644
--- a/sources/scala/Predef.scala
+++ b/sources/scala/Predef.scala
@@ -60,6 +60,12 @@ object Predef {
array;
}
/*
+ def Array[A <: AnyRef](xs: A*): Array[A] = {
+ val array = new Array[A](xs.length);
+ var i = 0;
+ for (val x <- xs.elements) { array(i) = x; i = i + 1; }
+ array;
+ }
def Array(x: boolean, xs: boolean*): Array[boolean] = {
val array = new Array[boolean](xs.length + 1);
array(0) = x;
diff --git a/sources/scala/Stream.scala b/sources/scala/Stream.scala
index 444b4aae3a..3256b647a3 100644
--- a/sources/scala/Stream.scala
+++ b/sources/scala/Stream.scala
@@ -40,6 +40,9 @@ object Stream {
}
}
+ def fromIterator[a](it: Iterator[a]): Stream[a] =
+ if (it.hasNext) cons(it.next, fromIterator(it)) else empty;
+
def concat[a](xs: Seq[Stream[a]]): Stream[a] = concat(xs.elements);
def concat[a](xs: Iterator[Stream[a]]): Stream[a] = {
diff --git a/sources/scala/tools/scalac/typechecker/Analyzer.scala b/sources/scala/tools/scalac/typechecker/Analyzer.scala
index fdb292bc5f..86f0654849 100644
--- a/sources/scala/tools/scalac/typechecker/Analyzer.scala
+++ b/sources/scala/tools/scalac/typechecker/Analyzer.scala
@@ -83,13 +83,15 @@ class Analyzer(global: scalac_Global, descr: AnalyzerPhase) extends Transformer(
def loadMixinCode(pos: Int, clasz: Symbol): unit = {
assert(clasz.isClass() && !clasz.isModuleClass(), Debug.show(clasz));
if (clasz.isExternal()) {
+ var c: Symbol = clasz;
try {
- global.compileLate(global.getSourceFile(clasz), true);
+ while (!c.owner().isPackageClass()) c = c.owner();
+ global.compileLate(global.getSourceFile(c), true);
} catch {
case exception: java.io.IOException =>
if (global.debug) exception.printStackTrace();
unit.error(pos, exception.getMessage() + "; source file for "
- + clasz + " is needed because it is used as a mixin");
+ + c + " is needed because it is used as a mixin");
}
}
}
diff --git a/sources/scalac/transformer/LambdaLift.java b/sources/scalac/transformer/LambdaLift.java
index 169fa67690..18af31ac55 100644
--- a/sources/scalac/transformer/LambdaLift.java
+++ b/sources/scalac/transformer/LambdaLift.java
@@ -209,6 +209,10 @@ public class LambdaLift extends OwnerTransformer
!excluded.contains(sym))
markFree(sym, currentOwner);
break;
+ case SingleType(NoPrefix, Symbol sym):
+ if (isLocal(sym, currentOwner))
+ markFree(sym, currentOwner);
+ break;
case PolyType(Symbol[] tparams, Type restp):
for (int i = 0; i < tparams.length; i++)
excluded = excluded.incl(tparams[i]);