Compute imports that allow definitions from previous requests to be visible in a new request.
Here is where we:
One line of code submitted by the user for interpretation
Parse the ScalaSig to find type aliases
Translate a repl-defined identifier into a Symbol.
Temporarily be quiet
Bind a specified name to a specified value.
Bind a specified name to a specified value. The name may later be used by expressions passed to interpret.
the variable name to bind
the type of the variable, as a string
the object value to bind to it
an indication of whether the binding succeeded
This instance is no longer needed, so release any resources it is using.
This instance is no longer needed, so release any resources it is using. The reporter's output gets flushed.
Compile an nsc SourceFile.
Compile an nsc SourceFile. Returns true if there are no compilation errors, or false otherwise.
Compile a string.
Compile a string. Returns true if there are no compilation errors, or false otherwise.
the compiler's classpath, as URL's
Create a line manager.
Create a line manager. Overridable.
Given a simple repl-defined name, returns the real name of the class representing it, e.
Given a simple repl-defined name, returns the real name of the class representing it, e.g. for "Bippy" it may return
$line19.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$Bippy
the public, go through the future compiler
Stubs for work in progress.
Tuples of (source, imported symbols) in the order they were imported.
Tuples of (source, imported symbols) in the order they were imported.
Interpret one line of input.
Interpret one line of input. All feedback, including parse errors and evaluation results, are printed via the supplied compiler's reporter. Values defined are available for future interpreted strings.
The return value is whether the line was interpreter successfully, e.g. that there were no parse errors.
interpreter settings
Symbols whose contents are language-defined to be imported.
Symbols whose contents are language-defined to be imported.
Returns the name of the most recent interpreter result.
Returns the name of the most recent interpreter result. Mostly this exists so you can conveniently invoke methods on the previous result.
Instantiate a compiler.
Instantiate a compiler. Overridable.
Parent classloader.
Parent classloader. Overridable.
Reset this interpreter, forgetting all user-specified requests.
Types which have been wildcard imported, such as: val x = "abc" ; import x.
Types which have been wildcard imported, such as: val x = "abc" ; import x._ // type java.lang.String import java.lang.String._ // object java.lang.String
Used by tab completion.
XXX right now this gets import x._ and import java.lang.String._, but doesn't figure out import String._. There's a lot of ad hoc scope twiddling which should be swept away in favor of digging into the compiler scopes.
Another entry point for tab-completion, ids in scope
directory to save .
directory to save .class files to
An interpreter for Scala code.
The main public entry points are compile(), interpret(), and bind(). The compile() method loads a complete Scala file. The interpret() method executes one line of Scala code at the request of the user. The bind() method binds an object to a variable that can then be used by later interpreted code.
The overall approach is based on compiling the requested code and then using a Java classloader and Java reflection to run the code and access its results.
In more detail, a single compiler instance is used to accumulate all successfully compiled or interpreted Scala code. To "interpret" a line of code, the compiler generates a fresh object that includes the line of code and which has public member(s) to export all variables defined by that code. To extract the result of an interpreted line to show the user, a second "result object" is created which imports the variables exported by the above object and then exports members called "$eval" and "$print". To accomodate user expressions that read from variables or methods defined in previous statements, "import" statements are used.
This interpreter shares the strengths and weaknesses of using the full compiler-to-Java. The main strength is that interpreted code behaves exactly as does compiled code, including running at full speed. The main weakness is that redefining classes and methods is not handled properly, because rebinding at the Java level is technically difficult.