-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun.js
More file actions
executable file
·80 lines (63 loc) · 1.51 KB
/
run.js
File metadata and controls
executable file
·80 lines (63 loc) · 1.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env node
import { lexer } from './lexer.js';
import { parser } from './parse.js';
import { evalAst } from './eval.js';
import fs from 'node:fs';
import readline from 'node:readline';
let code = `
(print
"Welcome to" (last (split \"${process.argv[1]}\" "/")))
`;
let verbosity = 0;
async function main() {
let mode = undefined;
for (const opt of process.argv.slice(2)) {
if (mode === 'eval') {
code = opt;
mode = undefined;
}
else if (['-e', '--eval'].includes(opt))
mode = 'eval';
else if (['-r', '--repl'].includes(opt))
await readEvalPrintLoop();
else if (['-v', '--verbose'].includes(opt))
verbosity += 1;
else if (['-vv'].includes(opt))
verbosity += 2;
else {
code = fs.readFileSync(opt, 'utf8');
await runCode(code);
}
}
}
async function readEvalPrintLoop() {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
historySize: 100,
removeHistoryDuplicates: true,
});
rl.setPrompt("> ");
await rl;
rl.prompt(true);
for await (const line of rl) {
if (line === 'q')
process.exit(0);
if (line.trim() === "") {
rl.prompt(true);
continue;
}
await runCode(line);
rl.prompt(true);
}
}
function runCode(codeString) {
const tokens = lexer(codeString);
verbosity >= 2 && console.log(tokens);
const ast = parser(tokens);
verbosity >= 1 && console.log(ast);
const ret = evalAst(ast);
console.log(ret);
}
main();