summaryrefslogtreecommitdiff
path: root/js/repl.ts
diff options
context:
space:
mode:
authorAndy Hayden <andyhayden1@gmail.com>2018-11-05 09:55:59 -0800
committerRyan Dahl <ry@tinyclouds.org>2018-11-05 09:55:59 -0800
commit27ecfc1617c79d23255e025fcbd0257b3523906a (patch)
treee6b68b4a291372e0a479d7dff156d546ff965d30 /js/repl.ts
parent5e48a681c4d6d6cb3debb4024b5108780dbbad90 (diff)
Add repl (#998)
- Running repl from js side. - Add tests for repl behavior. - Handle ctrl-C and ctrl-D.
Diffstat (limited to 'js/repl.ts')
-rw-r--r--js/repl.ts89
1 files changed, 89 insertions, 0 deletions
diff --git a/js/repl.ts b/js/repl.ts
new file mode 100644
index 000000000..b7c516110
--- /dev/null
+++ b/js/repl.ts
@@ -0,0 +1,89 @@
+// Copyright 2018 the Deno authors. All rights reserved. MIT license.
+import * as msg from "gen/msg_generated";
+import * as flatbuffers from "./flatbuffers";
+import { assert } from "./util";
+import * as deno from "./deno";
+import { close } from "./files";
+import * as dispatch from "./dispatch";
+import { exit } from "./os";
+import { window } from "./globals";
+
+function startRepl(historyFile: string): number {
+ const builder = flatbuffers.createBuilder();
+ const historyFile_ = builder.createString(historyFile);
+
+ msg.ReplStart.startReplStart(builder);
+ msg.ReplStart.addHistoryFile(builder, historyFile_);
+ const inner = msg.ReplStart.endReplStart(builder);
+
+ const baseRes = dispatch.sendSync(builder, msg.Any.ReplStart, inner);
+ assert(baseRes != null);
+ assert(msg.Any.ReplStartRes === baseRes!.innerType());
+ const innerRes = new msg.ReplStartRes();
+ assert(baseRes!.inner(innerRes) != null);
+ const rid = innerRes.rid();
+ return rid;
+}
+
+// @internal
+export function readline(rid: number, prompt: string): string {
+ const builder = flatbuffers.createBuilder();
+ const prompt_ = builder.createString(prompt);
+ msg.ReplReadline.startReplReadline(builder);
+ msg.ReplReadline.addRid(builder, rid);
+ msg.ReplReadline.addPrompt(builder, prompt_);
+ const inner = msg.ReplReadline.endReplReadline(builder);
+
+ // TODO use async?
+ const baseRes = dispatch.sendSync(builder, msg.Any.ReplReadline, inner);
+
+ assert(baseRes != null);
+ assert(msg.Any.ReplReadlineRes === baseRes!.innerType());
+ const innerRes = new msg.ReplReadlineRes();
+ assert(baseRes!.inner(innerRes) != null);
+ const line = innerRes.line();
+ assert(line !== null);
+ return line || "";
+}
+
+// @internal
+export function replLoop(): void {
+ window.deno = deno; // FIXME use a new scope (rather than window).
+
+ const historyFile = "deno_history.txt";
+ const prompt = "> ";
+
+ const rid = startRepl(historyFile);
+
+ let line = "";
+ while (true) {
+ try {
+ line = readline(rid, prompt);
+ line = line.trim();
+ } catch (err) {
+ if (err.message === "EOF") {
+ break;
+ }
+ console.error(err);
+ exit(1);
+ }
+ if (!line) {
+ continue;
+ }
+ if (line === ".exit") {
+ break;
+ }
+ try {
+ const result = eval.call(window, line); // FIXME use a new scope.
+ console.log(result);
+ } catch (err) {
+ if (err instanceof Error) {
+ console.error(`${err.constructor.name}: ${err.message}`);
+ } else {
+ console.error("Thrown:", err);
+ }
+ }
+ }
+
+ close(rid);
+}