summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/MainInterpreter.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/MainInterpreter.scala')
-rw-r--r--src/compiler/scala/tools/nsc/MainInterpreter.scala166
1 files changed, 112 insertions, 54 deletions
diff --git a/src/compiler/scala/tools/nsc/MainInterpreter.scala b/src/compiler/scala/tools/nsc/MainInterpreter.scala
index b1ea38e065..4727cd8cc9 100644
--- a/src/compiler/scala/tools/nsc/MainInterpreter.scala
+++ b/src/compiler/scala/tools/nsc/MainInterpreter.scala
@@ -3,72 +3,130 @@
* @author emir
*/
// $Id$
-package scala.tools.nsc;
+package scala.tools.nsc
-import java.io._;
-import scala.tools.nsc.util.{Position};
-import scala.tools.nsc.reporters.{Reporter, ConsoleReporter};
+import java.io._
+import scala.tools.nsc.util.{Position}
+import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
/** The main class for the new scala interpreter.
*/
-object MainInterpreter extends Object with EvalLoop {
- // lots of stuff duplicated from Main
- val PRODUCT: String =
- System.getProperty("scala.product", "scalaint");
- val VERSION: String =
- System.getProperty("scala.version", "unknown version");
- val versionMsg = PRODUCT + " " + VERSION + " -- (c) 2002-05 LAMP/EPFL";
- val prompt = "\nnsc> ";
-
- private var reporter: ConsoleReporter = _;
-
- def error(msg: String): unit =
- reporter.error(new Position(PRODUCT),
- msg + "\n " + PRODUCT + " -help gives more information");
-
- def errors() = reporter.errors;
-
- def interpret(gCompiler: Global): unit = {
- val interpreter = new Interpreter {
- val compiler: gCompiler.type = gCompiler
- };
- loop(line => try {
- interpreter.interpret(line.trim(), reporter)
- } catch {
- case e: Exception => {
- reporter.info(null,e.getMessage(),true);
- //e.printStackTrace();
- }
+object MainInterpreter {
+ val reporter = new ConsoleReporter()
+
+ var interpreter: Interpreter = _
+
+ /** print a friendly help message */
+ def printHelp = {
+ Console.println("This is an interpreter for Scala.")
+ Console.println("Type in expressions to have them evaluated.")
+ Console.println("Type :quit to exit the interpreter.")
+ Console.println("Type :compile followed by a filename to compile a complete Scala file.")
+ Console.println("Type :load followed by a filename to load a sequence of interpreter commands.")
+ Console.println("Type :help to repeat this message later.")
+ }
+
+ /** A simple, generic read-eval-print loop with a pluggable eval-print function.
+ Loop reading lines of input and invoking the eval-print function.
+ Stop looping when eval-print returns false. */
+ def repl(evpr: String => Boolean): Unit = {
+ val in = new BufferedReader(new InputStreamReader(System.in))
+
+ while(true) {
+ Console.print("\nscala> ")
+ var line = in.readLine()
+ if(line == null)
+ return () // assumes null means EOF
+
+ val keepGoing = evpr(line)
+
+ if(!keepGoing)
+ return () // the evpr function said to stop
+ }
+ }
+
+ /** interpret one line of code submitted by the user */
+ def interpretOne(line: String): Unit = {
+ try {
+ interpreter.interpret(line)
+ } catch {
+ case e: Exception => {
+ reporter.info(null,"Exception occurred: " + e.getMessage(),true)
+ //e.printStackTrace()
+ }
+ }
+ }
+
+ /** interpret all lines from a specified file */
+ def interpretAllFrom(filename: String): Unit = {
+ val fileIn = try {
+ new FileReader(filename)
+ } catch {
+ case _:IOException =>
+ Console.println("Error opening file: " + filename)
+ null
+ }
+ if(fileIn == null) return ()
+ val in = new BufferedReader(fileIn)
+ while(true) {
+ val line = in.readLine
+ if(line == null) {
+ fileIn.close
+ return ()
}
- )
+ command(line)
+ }
}
- def process(args: Array[String]): unit = {
- reporter = new ConsoleReporter();
- val command = new CompilerCommand(List.fromArray(args), error, false);
- reporter.prompt = (command.settings.prompt.value);
- if (command.settings.version.value)
- reporter.info(null, versionMsg, true)
- else if (command.settings.help.value) // 2do replace with InterpCommand
- reporter.info(null, command.usageMsg, true)
+ /** run one command submitted by the user */
+ def command(line: String): Boolean = {
+ def withFile(command: String)(action: String=>Unit): Unit = {
+ val spaceIdx = command.indexOf(' ')
+ if(spaceIdx <= 0) {
+ Console.println("That command requires a filename to be specified.")
+ return ()
+ }
+ val filename = command.substring(spaceIdx).trim
+ action(filename)
+ }
- else {
- try {
- val compiler = new Global(command.settings, reporter);
- interpret(compiler);
- } catch {
- case ex @ FatalError(msg) =>
- if (command.settings.debug.value)
- ex.printStackTrace();
- reporter.error(null, "fatal error: " + msg);
+ if(line.startsWith(":"))
+ line match {
+ case ":help" => printHelp
+ case ":quit" => return false
+ case _ if line.startsWith(":compile") => withFile(line)(f => interpreter.compile(f))
+ case _ if line.startsWith(":load") => withFile(line)(f => interpretAllFrom(f))
+ case _ => Console.println("Unknown command. Type :help for help.")
}
- reporter.printSummary()
+ else
+ interpretOne(line)
+ true
+ }
+
+
+
+ /** the main interpreter loop */
+ def interpretLoop(compiler: Global): unit = {
+ interpreter = new Interpreter(compiler, str=>Console.print(str))
+ repl(command)
+ interpreter.close
+ }
+
+
+
+ /** process the command-line arguments and do as they request */
+ def process(args: Array[String]): unit = {
+ val command = new CompilerCommand(List.fromArray(args), error, false)
+ reporter.prompt = command.settings.prompt.value
+ if (command.settings.help.value) {
+ reporter.info(null, command.usageMsg, true)
+ } else {
+ printHelp
+ interpretLoop(new Global(command.settings, reporter))
}
}
def main(args: Array[String]): unit = {
- process(args);
- System.exit(if (reporter.errors > 0) 1 else 0);
+ process(args)
}
-
}