mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
Support repl multiline input (#1165)
This commit is contained in:
parent
13e1eb2b87
commit
e9327be831
2 changed files with 63 additions and 18 deletions
75
js/repl.ts
75
js/repl.ts
|
@ -51,15 +51,12 @@ export function replLoop(): void {
|
||||||
window.deno = deno; // FIXME use a new scope (rather than window).
|
window.deno = deno; // FIXME use a new scope (rather than window).
|
||||||
|
|
||||||
const historyFile = "deno_history.txt";
|
const historyFile = "deno_history.txt";
|
||||||
const prompt = "> ";
|
|
||||||
|
|
||||||
const rid = startRepl(historyFile);
|
const rid = startRepl(historyFile);
|
||||||
|
|
||||||
let line = "";
|
let code = "";
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
line = readline(rid, prompt);
|
code = readBlock(rid, "> ", " ");
|
||||||
line = line.trim();
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.message === "EOF") {
|
if (err.message === "EOF") {
|
||||||
break;
|
break;
|
||||||
|
@ -67,23 +64,65 @@ export function replLoop(): void {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (!line) {
|
if (!code) {
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (code.trim() === ".exit") {
|
||||||
if (line === ".exit") {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
const result = eval.call(window, line); // FIXME use a new scope.
|
evaluate(code);
|
||||||
console.log(result);
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
console.error(`${err.constructor.name}: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
console.error("Thrown:", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(rid);
|
close(rid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function evaluate(code: string): void {
|
||||||
|
try {
|
||||||
|
const result = eval.call(window, code); // 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readBlock(
|
||||||
|
rid: number,
|
||||||
|
prompt: string,
|
||||||
|
continuedPrompt: string
|
||||||
|
): string {
|
||||||
|
let code = "";
|
||||||
|
do {
|
||||||
|
code += readline(rid, prompt);
|
||||||
|
prompt = continuedPrompt;
|
||||||
|
} while (parenthesesAreOpen(code));
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modified from
|
||||||
|
// https://codereview.stackexchange.com/a/46039/148556
|
||||||
|
function parenthesesAreOpen(code: string): boolean {
|
||||||
|
const parentheses = "[]{}()";
|
||||||
|
const stack = [];
|
||||||
|
|
||||||
|
for (const ch of code) {
|
||||||
|
const bracePosition = parentheses.indexOf(ch);
|
||||||
|
|
||||||
|
if (bracePosition === -1) {
|
||||||
|
// not a paren
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bracePosition % 2 === 0) {
|
||||||
|
stack.push(bracePosition + 1); // push next expected brace position
|
||||||
|
} else {
|
||||||
|
if (stack.length === 0 || stack.pop() !== bracePosition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stack.length > 0;
|
||||||
|
}
|
||||||
|
|
|
@ -80,6 +80,12 @@ class Repl(object):
|
||||||
assertEqual(err, 'TypeError: console is not a function\n')
|
assertEqual(err, 'TypeError: console is not a function\n')
|
||||||
assertEqual(code, 0)
|
assertEqual(code, 0)
|
||||||
|
|
||||||
|
def test_multiline(self):
|
||||||
|
out, err, code = self.input("(\n1 + 2\n)")
|
||||||
|
assertEqual(out, '3\n')
|
||||||
|
assertEqual(err, '')
|
||||||
|
assertEqual(code, 0)
|
||||||
|
|
||||||
def test_exit_command(self):
|
def test_exit_command(self):
|
||||||
out, err, code = self.input(".exit", "'ignored'", exit=False)
|
out, err, code = self.input(".exit", "'ignored'", exit=False)
|
||||||
assertEqual(out, '')
|
assertEqual(out, '')
|
||||||
|
|
Loading…
Add table
Reference in a new issue