diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/main.ts | 13 | ||||
-rw-r--r-- | js/repl.ts | 89 |
2 files changed, 96 insertions, 6 deletions
diff --git a/js/main.ts b/js/main.ts index 50de2c26c..0ed45aaec 100644 --- a/js/main.ts +++ b/js/main.ts @@ -8,6 +8,7 @@ import { libdeno } from "./libdeno"; import { args } from "./deno"; import { sendSync, handleAsyncMsgFromRust } from "./dispatch"; import { promiseErrorExaminer, promiseRejectHandler } from "./promise_util"; +import { replLoop } from "./repl"; import { version } from "typescript"; function sendStart(): msg.StartRes { @@ -77,13 +78,13 @@ export default function denoMain() { } log("args", args); Object.freeze(args); - const inputFn = args[0]; - if (!inputFn) { - console.log("No input script specified."); - os.exit(1); - } compiler.recompile = startResMsg.recompileFlag(); - compiler.run(inputFn, `${cwd}/`); + + if (inputFn) { + compiler.run(inputFn, `${cwd}/`); + } else { + replLoop(); + } } 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); +} |