mslinn / cli-loop Goto Github PK
View Code? Open in Web Editor NEWCommand line loop with tab completion and polyglot JSR223-compatible subshells
Command line loop with tab completion and polyglot JSR223-compatible subshells
Oracle Nashorn can share data and code between the JVM and JavaScript, so JVM libraries can be called from JavaScript, and vice-versa. That gives a lot of flexibility.
Engine Name = Oracle Nashorn
Engine Version = 1.8.0_151
Language Name = ECMAScript
Language Version = ECMA - 262 Edition 5.1
Names = nashorn, Nashorn, js, JS, JavaScript, javascript, ECMAScript, ecmascript
Oracle's Nashorn docs are extensive, and the User Guide includes API docs.
It is possible that other scripting engines might be better than Nashorn, or might be good to have in addition to that JavaScript engine. It is easy to create shells that are similar to the JavaScriptShell
/JavaScriptEvaluator
that has already been created. Provided that a user-friendly way to specify which shell is desired, dozens or hundreds of shells and their interpreters could be run concurrently by the present design.
Even if there is only one process on the JVM that needs to communicate with one process on a scripting engine, there is the possibility that each process might attempt to alter the same value at the same time. Thus concurrent Maps must be used. Expressed in Scala, both sides conceptually need an interface something like:
import scala.collection.concurrent
case class beth(data: concurrent.Map) {
def status: concurrent.Map
}
Oracle Java's Nashorn JavaScript engine has been wrapped in an Evaluator
subclass called JavaScriptEvaluator
, which is mediated by a Shell
subclass called JavaScriptShell
. Other Shell
s, each with their own Evaluator
, exist.
From the point of view of a Java or Scala program running on the JVM, and a JavaScript program's point of view running on a JavaScript engine, the namespace provided by an Evaluator
should seem a little bit like a transparent mirror, with the same namespace names on both sides of the mirror. The mirror has some inherent distortion, in part because JavaScript only supports Double
; it lacks Int
and Float
. Other limitations will no doubt become apparent, and they should be documented in the this project's wiki as they are discovered.
The current version of the JavaScriptEvaluator
always returns results as type AnyRef
. There may be some way that we can provided some support of typed responses in the future.
With Java/JavaScript inter-operation, library code in one Shell
could be invoked from JavaScript, Java and Scala. Also, custom Java and Scala code could leverage existing JavaScript such as Node.js libraries. We need unit tests for all these scenarios.
It is important that the simplest possible implementation be developed. This often takes 3 quick iterations, with most of the original code replaced at least once.
This unit test demonstrates the problem.
js.isDefined("ten") shouldBe false // Does JavaScript have a variable defined called 'ten'?
js.put("ten", 10) shouldBe 10.0 // Store the value 10 into a new variable called 'ten'
js.get("ten") shouldBe 10.0 // fails, variable 'ten' not defined
js.isDefined("ten") shouldBe true // fails
Once the above is fixed, also verify that creating a JavaScript variable using eval
stores the newly created variable in the same binding space as used by put
, get
and isDefined
:
js.eval("var x = 'asdf'")
js.get("x") // should be 'asdf', returned as an `AnyRef` instance
Note:
js.eval
should always return AnyRef
for now.Int
or Float
, just Double
, so don't be surprised when you discover that Double
s are returned by a computation that should result in an Int
String
s and Double
s interact very oddly.Mike is currently reworking the JavaScript
class's external interface in the rework
branch of this git repository. He is not changing the internals, so hopefully the solution to this bug should mergeable with a minimum of fuss.
This project is a tangle of dependencies. The existing classes (CliBase
, CliLoop
, CommandShell
, Completers
) need radical surgery.
JavaScript
seems to have the right object model - it is merely a simple class and that is working fine so far.
Need Shell
and SubShell
classes. Not sure of the hierarchy or what traits might be appropriate.
Also need a Stack[Shell]
; when the shellStack
is empty the program exits. User input should always be directed to the shell on top of shellStack
. Prompts and results to user input are also issued to the shell on top of shellStack
.
$ bin/run
Micronautics Research Ethereum Shell v0.2.0
Commands are: account, bindkey, exit/^d, groovy, help/?, javascript, jython, password, scala, set, testkey and tput
cli-loop [master] shell> javascript
Entering the javascript sub-shell. Press Control-d to exit the sub-shell.
cli-loop [master] javascript> x=2
2
cli-loop [master] javascript>
Returning to javascript.
Commands are: account, bindkey, exit/^d, groovy, help/?, javascript, jython, password, scala, set, testkey and tput
cli-loop [master] shell> javascript
ERROR com.micronautics.evaluator.Evaluator - Error: ScriptEngine Java not found.
Use Monix?
The input log would only contain what the user typed, without the evaluated responses; it would be stored in a file called ${USER}_yyyy-mm-dd-HH-MM-ss.log
.
To see what ${USER}
expands to on your computer, type the following into a bash-compatible shell:
echo ${USER}
The directory to write the input log to defaults to ~/$productName/log
, but this can be overridden by using the --log-directory
command-line switch. For example:
bin/run --log-directory /path/to/directory
--replay
command-line switch to play back a use log.bin/run --log-directory /path/to/directory --replay "${USER}_2017-10-31-12-34-56.log"
The transcript would contain what the user typed and the evaluated responses; it would be stored in a file called $USER_yyyy-mm-dd-dd-HH-MM-ss.log
.
The directory to write the transcript to defaults to ~/$productName/transcript
, but this can be overridden by using the --transcript-directory
command-line switch. For example:
bin/run --transcript-directory /path/to/directory
Users can control logging with the following command-line switches, specified when the program is launched:
--log-directory /path/to/directory - default is to log in ~/$productName/log
--no-log - disable logging
--no-transcript - disable transcript
--replay user_yyyy-mm-dd-HH-MM-ss - log-directory can specify where to read from
--transcript-directory /path/to/directory - default is to log in ~/$productName/transcript
productName
is specified in src/main/resources/reference.conf
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.