diff options
Diffstat (limited to 'js/repl.ts')
-rw-r--r-- | js/repl.ts | 89 |
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); +} |