summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-06-20 16:34:51 +0000
committerMartin Odersky <odersky@gmail.com>2006-06-20 16:34:51 +0000
commit4d929158efa9a6e95df14c399091a0f213aebf2d (patch)
tree488270edb1eed025a96c1655e8cc139951d84839
parent640ea6fc45b860e85b588d3217df61d087d674ba (diff)
downloadscala-4d929158efa9a6e95df14c399091a0f213aebf2d.tar.gz
scala-4d929158efa9a6e95df14c399091a0f213aebf2d.tar.bz2
scala-4d929158efa9a6e95df14c399091a0f213aebf2d.zip
Fixed parsing problem for closures
-rw-r--r--src/compiler/scala/tools/ant/Scalac.scala6
-rw-r--r--src/compiler/scala/tools/ant/Scaladoc.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala21
-rw-r--r--src/compiler/scala/tools/nsc/io/PlainFile.scala2
-rw-r--r--src/library/scala/PartialFunction.scala26
-rw-r--r--src/library/scala/Responder.scala36
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/concurrent/Process.scala2
9 files changed, 67 insertions, 32 deletions
diff --git a/src/compiler/scala/tools/ant/Scalac.scala b/src/compiler/scala/tools/ant/Scalac.scala
index 9632094102..0db460b084 100644
--- a/src/compiler/scala/tools/ant/Scalac.scala
+++ b/src/compiler/scala/tools/ant/Scalac.scala
@@ -255,7 +255,7 @@ package scala.tools.ant {
/** Sets the log attribute. Used by Ant.
* @param input The value for <code>logPhase</code>. */
def setLogPhase(input: String) = {
- logPhase = List.fromArray(input.split(",")).flatMap(s: String => {
+ logPhase = List.fromArray(input.split(",")).flatMap { s: String =>
val st = s.trim()
if (CompilerPhase.isPermissible(st))
(if (input != "") List(st) else Nil)
@@ -263,7 +263,7 @@ package scala.tools.ant {
error("Phase " + st + " in log does not exist.")
Nil
}
- })
+ }
}
/** Sets the use predefs attribute. Used by Ant.
@@ -479,7 +479,7 @@ package scala.tools.ant {
// Compiles the actual code
val compiler = new Global(settings, reporter)
try {
- (new compiler.Run).compile(sourceFiles.map(f:File=>f.toString()))
+ (new compiler.Run).compile(sourceFiles.map { f:File=>f.toString() })
} catch {
case exception: Throwable if (exception.getMessage != null) =>
exception.printStackTrace()
diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala
index 4e7581c6f4..08ddbfb320 100644
--- a/src/compiler/scala/tools/ant/Scaladoc.scala
+++ b/src/compiler/scala/tools/ant/Scaladoc.scala
@@ -390,7 +390,7 @@ package scala.tools.ant {
object compiler extends Global(settings, reporter)
try {
val run = new compiler.Run
- run.compile(sourceFiles.map(f: File => f.toString()))
+ run.compile(sourceFiles.map { f: File => f.toString() })
object generator extends DocGenerator {
val global = compiler
def outdir = settings.outdir.value
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index 207df561bf..32683d9029 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -14,7 +14,7 @@ object CompileSocket {
private val dirName = "scalac-compile-server-port"
/** The vm-part of the command to start a new scala compile server */
- private val vmCommand = "scala"
+ private val vmCommand = "java"
/** The class name of the scala compile server */
private val serverClass = "scala.tools.nsc.CompileServer"
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 5107db14ee..ce885459a9 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -608,9 +608,9 @@ trait Parsers requires SyntaxAnalyzer {
ts.toList
}
- /** Expr ::= Bindings `=>' Expr
+ /** Expr ::= (Bindings | Id) `=>' Expr
* | Expr1
- * ResultExpr ::= Bindings `=>' Block
+ * ResultExpr ::= (Bindings | Id `:' Type1) `=>' Block
* | Expr1
* Expr1 ::= if (' Expr `)' [NewLine] Expr [[`;'] else Expr]
* | try `{' block `}' [catch `{' caseClauses `}'] [finally Expr]
@@ -625,8 +625,7 @@ trait Parsers requires SyntaxAnalyzer {
* | PostfixExpr [`:' Type1]
* | PostfixExpr match `{' CaseClauses `}'
* | MethodClosure
- * Bindings ::= Id [`:' Type1]
- * | `(' [Binding {`,' Binding}] `)'
+ * Bindings ::= `(' [Binding {`,' Binding}] `)'
* Binding ::= Id [`:' Type]
*/
def expr(): Tree =
@@ -726,7 +725,19 @@ trait Parsers requires SyntaxAnalyzer {
syntaxError(in.currentPos, "`*' expected", true);
}
} else {
- t = atPos(pos) { Typed(t, type1()) }
+ t = atPos(pos) { Typed(t, if (isInBlock) type1() else typ()) }
+ if (isInBlock && in.token == COMMA) {
+ val vdefs = new ListBuffer[ValDef];
+ while (in.token == COMMA) {
+ in.nextToken();
+ vdefs += ValDef(Modifiers(Flags.PARAM), ident(), typedOpt(), EmptyTree)
+ }
+ if (in.token == ARROW) {
+ t = atPos(in.skipToken()) {
+ Function(convertToParams(t) ::: vdefs.toList, block())
+ }
+ } else syntaxError(in.currentPos, "`=>' expected", true)
+ }
}
} else if (in.token == MATCH) {
t = atPos(in.skipToken()) {
diff --git a/src/compiler/scala/tools/nsc/io/PlainFile.scala b/src/compiler/scala/tools/nsc/io/PlainFile.scala
index 5ab83c447f..60f8ad4f7f 100644
--- a/src/compiler/scala/tools/nsc/io/PlainFile.scala
+++ b/src/compiler/scala/tools/nsc/io/PlainFile.scala
@@ -83,7 +83,7 @@ class PlainFile(val file: File) extends AbstractFile {
assert(isDirectory, "not a directory '" + this + "'");
val names: Array[String] = file.list();
if (names == null || names.length == 0) Iterator.empty;
- else Iterator.fromArray(names).map(name: String => new File(file, name))
+ else Iterator.fromArray(names).map { name: String => new File(file, name) }
.filter(.exists()).map(file => new PlainFile(file))
}
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index 8af05728f1..316b62dea0 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -22,10 +22,24 @@ package scala;
*/
trait PartialFunction[-A, +B] extends AnyRef with (A => B) {
- /** Checks if a value is contained in the functions domain.
- *
- * @param x the value to test
- * @return true, iff <code>x</code> is in the domain of this function.
- */
- def isDefinedAt(x: A): Boolean;
+ /** Checks if a value is contained in the functions domain.
+ *
+ * @param x the value to test
+ * @return true, iff <code>x</code> is in the domain of this function.
+ */
+ def isDefinedAt(x: A): Boolean;
+
+ def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) = new PartialFunction[A1, B1] {
+ def isDefinedAt(x: A1): Boolean =
+ PartialFunction.this.isDefinedAt(x) || that.isDefinedAt(x)
+ def apply(x: A1): B1 =
+ if (PartialFunction.this.isDefinedAt(x)) PartialFunction.this.apply(x)
+ else that.apply(x)
+ }
+
+ def andThen[C](k: B => C) = new PartialFunction[A, C] {
+ def isDefinedAt(x: A): Boolean = PartialFunction.this.isDefinedAt(x)
+ def apply(x: A): C = k(PartialFunction.this.apply(x))
+ }
}
+
diff --git a/src/library/scala/Responder.scala b/src/library/scala/Responder.scala
index a86f1d30b8..8d294e95ea 100644
--- a/src/library/scala/Responder.scala
+++ b/src/library/scala/Responder.scala
@@ -8,46 +8,56 @@ object Responder {
/** creates a responder that answer continuations with the constant a */
def constant[a](x: a) = new Responder[a] {
- def answer(k: a => unit) = k(x)
+ def foreach(k: a => unit) = k(x)
}
/** executes x and returns true, useful as syntactic convenience in
- * for comprehensions
- */
+ * for comprehensions
+ */
def exec[a](x: => unit): boolean = { x; true }
/** runs a responder, returning an optional result
*/
def run[a](r: Responder[a]): Option[a] = {
var result: Option[a] = None
- r.answer(x => result = Some(x))
+ r.foreach(x => result = Some(x))
result
}
+
+ def loop[a](r: Responder[unit]): Responder[Nothing] =
+ for (val _ <- r; val y <- loop(r)) yield y
+
+ def loopWhile[a](cond: => boolean)(r: Responder[unit]): Responder[unit] =
+ if (cond) for (val _ <- r; val y <- loopWhile(cond)(r)) yield y
+ else constant(())
+
}
-/** instances of responder are the building blocks of small programs
+/** Instances of responder are the building blocks of small programs
* written in continuation passing style. By using responder classes
* in for comprehensions, one can embed domain-specific languages in
* Scala while giving the impression that programs in these DSLs are
* written in direct style.
* @since revision 6897 (will be 2.1.1)
*/
-abstract class Responder[a] {
+abstract class Responder[+a] {
- def answer(k: a => unit): unit
+ def foreach(k: a => unit): unit
def map[b](f: a => b) = new Responder[b] {
- def answer(k: b => unit): unit =
- Responder.this.answer(x => k(f(x)))
+ def foreach(k: b => unit): unit =
+ Responder.this.foreach(x => k(f(x)))
}
def flatMap[b](f: a => Responder[b]) = new Responder[b] {
- def answer(k: b => unit): unit =
- Responder.this.answer(x => f(x).answer(k))
+ def foreach(k: b => unit): unit =
+ Responder.this.foreach(x => f(x).foreach(k))
}
def filter(p: a => boolean) = new Responder[a] {
- def answer(k: a => unit): unit =
- Responder.this.answer(x => if (p(x)) k(x) else ())
+ def foreach(k: a => unit): unit =
+ Responder.this.foreach(x => if (p(x)) k(x) else ())
}
+
}
+
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index 6654340fa0..81eb283fe0 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -106,7 +106,7 @@ trait HashTable[A] extends AnyRef {
}
}
- private def entryFor(key: A) = (e: Entry => elemEquals(entryKey(e), key));
+ private def entryFor(key: A) = { e: Entry => elemEquals(entryKey(e), key) }
protected def initTable(tb: Array[List[Entry]]): Unit = {
var i = tb.length - 1;
diff --git a/src/library/scala/concurrent/Process.scala b/src/library/scala/concurrent/Process.scala
index 24e1185353..537b6c120c 100644
--- a/src/library/scala/concurrent/Process.scala
+++ b/src/library/scala/concurrent/Process.scala
@@ -59,7 +59,7 @@ class Process(body: => Unit) extends Actor() {
};
private def signal(s: MailBox#Message) =
- links.foreach(p: Process => p.send(Triple('EXIT, this, s)));
+ links.foreach { p: Process => p.send(Triple('EXIT, this, s)) }
def !(msg: MailBox#Message) =
send(msg);