summaryrefslogtreecommitdiff
path: root/js/repl.ts
diff options
context:
space:
mode:
Diffstat (limited to 'js/repl.ts')
-rw-r--r--js/repl.ts197
1 files changed, 0 insertions, 197 deletions
diff --git a/js/repl.ts b/js/repl.ts
deleted file mode 100644
index 966e809e8..000000000
--- a/js/repl.ts
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { close } from "./files.ts";
-import { exit } from "./os.ts";
-import { window } from "./window.ts";
-import { core } from "./core.ts";
-import { formatError } from "./format_error.ts";
-import { stringifyArgs } from "./console.ts";
-import * as dispatch from "./dispatch.ts";
-import { sendSync, sendAsync } from "./dispatch_json.ts";
-
-const { console } = window;
-
-/**
- * REPL logging.
- * In favor of console.log to avoid unwanted indentation
- */
-function replLog(...args: unknown[]): void {
- core.print(stringifyArgs(args) + "\n");
-}
-
-/**
- * REPL logging for errors.
- * In favor of console.error to avoid unwanted indentation
- */
-function replError(...args: unknown[]): void {
- core.print(stringifyArgs(args) + "\n", true);
-}
-
-const helpMsg = [
- "_ Get last evaluation result",
- "_error Get last thrown error",
- "exit Exit the REPL",
- "help Print this help message"
-].join("\n");
-
-const replCommands = {
- exit: {
- get(): void {
- exit(0);
- }
- },
- help: {
- get(): string {
- return helpMsg;
- }
- }
-};
-
-function startRepl(historyFile: string): number {
- return sendSync(dispatch.OP_REPL_START, { historyFile });
-}
-
-// @internal
-export async function readline(rid: number, prompt: string): Promise<string> {
- return sendAsync(dispatch.OP_REPL_READLINE, { rid, prompt });
-}
-
-// Error messages that allow users to continue input
-// instead of throwing an error to REPL
-// ref: https://github.com/v8/v8/blob/master/src/message-template.h
-// TODO(kevinkassimo): this list might not be comprehensive
-const recoverableErrorMessages = [
- "Unexpected end of input", // { or [ or (
- "Missing initializer in const declaration", // const a
- "Missing catch or finally after try", // try {}
- "missing ) after argument list", // console.log(1
- "Unterminated template literal" // `template
- // TODO(kevinkassimo): need a parser to handling errors such as:
- // "Missing } in template expression" // `${ or `${ a 123 }`
-];
-
-function isRecoverableError(e: Error): boolean {
- return recoverableErrorMessages.includes(e.message);
-}
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type Value = any;
-
-let lastEvalResult: Value = undefined;
-let lastThrownError: Value = undefined;
-
-// Evaluate code.
-// Returns true if code is consumed (no error/irrecoverable error).
-// Returns false if error is recoverable
-function evaluate(code: string): boolean {
- const [result, errInfo] = core.evalContext(code);
- if (!errInfo) {
- lastEvalResult = result;
- replLog(result);
- } else if (errInfo.isCompileError && isRecoverableError(errInfo.thrown)) {
- // Recoverable compiler error
- return false; // don't consume code.
- } else {
- lastThrownError = errInfo.thrown;
- if (errInfo.isNativeError) {
- const formattedError = formatError(
- core.errorToJSON(errInfo.thrown as Error)
- );
- replError(formattedError);
- } else {
- replError("Thrown:", errInfo.thrown);
- }
- }
- return true;
-}
-
-// @internal
-export async function replLoop(): Promise<void> {
- Object.defineProperties(window, replCommands);
-
- const historyFile = "deno_history.txt";
- const rid = startRepl(historyFile);
-
- const quitRepl = (exitCode: number): void => {
- // Special handling in case user calls deno.close(3).
- try {
- close(rid); // close signals Drop on REPL and saves history.
- } catch {}
- exit(exitCode);
- };
-
- // Configure window._ to give the last evaluation result.
- Object.defineProperty(window, "_", {
- configurable: true,
- get: (): Value => lastEvalResult,
- set: (value: Value): Value => {
- Object.defineProperty(window, "_", {
- value: value,
- writable: true,
- enumerable: true,
- configurable: true
- });
- console.log("Last evaluation result is no longer saved to _.");
- }
- });
-
- // Configure window._error to give the last thrown error.
- Object.defineProperty(window, "_error", {
- configurable: true,
- get: (): Value => lastThrownError,
- set: (value: Value): Value => {
- Object.defineProperty(window, "_error", {
- value: value,
- writable: true,
- enumerable: true,
- configurable: true
- });
- console.log("Last thrown error is no longer saved to _error.");
- }
- });
-
- while (true) {
- let code = "";
- // Top level read
- try {
- code = await readline(rid, "> ");
- if (code.trim() === "") {
- continue;
- }
- } catch (err) {
- if (err.message === "EOF") {
- quitRepl(0);
- } else {
- // If interrupted, don't print error.
- if (err.message !== "Interrupted") {
- // e.g. this happens when we have deno.close(3).
- // We want to display the problem.
- const formattedError = formatError(core.errorToJSON(err));
- replError(formattedError);
- }
- // Quit REPL anyways.
- quitRepl(1);
- }
- }
- // Start continued read
- while (!evaluate(code)) {
- code += "\n";
- try {
- code += await readline(rid, " ");
- } catch (err) {
- // If interrupted on continued read,
- // abort this read instead of quitting.
- if (err.message === "Interrupted") {
- break;
- } else if (err.message === "EOF") {
- quitRepl(0);
- } else {
- // e.g. this happens when we have deno.close(3).
- // We want to display the problem.
- const formattedError = formatError(core.errorToJSON(err));
- replError(formattedError);
- quitRepl(1);
- }
- }
- }
- }
-}