-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathcli.js
More file actions
80 lines (68 loc) · 2.97 KB
/
Copy pathcli.js
File metadata and controls
80 lines (68 loc) · 2.97 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
80
#!/usr/bin/env node
const packageJson = require("./package.json");
const path = require("path");
const constants = require("./src/constants.js");
const commander = require("commander");
const printBanner = require("./src/banner.js");
// Mirror how PHP keeps its own internal (C) stack out of a script's error
// output: swap errors are already user-facing messages (see feedbackMessages.js
// and InputStream#throwError), so surface just that message here instead of
// letting Node's raw JS stack trace leak out of the interpreter. Set
// SWAP_DEBUG=1 to see the full stack while working on the interpreter itself.
process.on("uncaughtException", (error) => {
if (process.env.SWAP_DEBUG) throw error;
console.error(`Error: ${error.message}`);
process.exit(1);
});
// The art banner is an info/help affordance, not part of a running program's
// output - only show it when no file is being executed (bare invocation,
// -h/--help, -v/--version).
// -i/--interactive is deliberately excluded here: the REPL (src/repl.js)
// prints its own banner at startup, so including it here would double it up.
const cliArgs = process.argv.slice(2);
const isInfoRequest = cliArgs.length === 0 ||
[ "-h", "--help", "-v", "--version", ].some((flag) => cliArgs.includes(flag));
if (isInfoRequest) printBanner(packageJson.version);
commander.on("--help", function () {
console.log("author: Abdulbasit Sultan Rubeiyya");
console.log("Examples:");
console.log(" $ swap file.sw");
console.log(" $ swap -i");
console.log(" $ swap -h");
console.log(" $ swap -v");
});
commander.version(packageJson.version, "-v, --version");
commander.arguments("[file]")
.option("-l, --lang <lang>", "language for error messages (english|swahili)")
.option("-i, --interactive", "start an interactive REPL")
.action((file, options) => {
if (options.interactive) {
setGlobalVars(options);
startReplProcess();
} else if (!file) {
commander.help();
} else if (path.extname(file) === constants.SWAP_EXT) {
setGlobalVars(options);
startSwapProcess(file);
} else {
console.log("Invalid file extension used, only swap file can be used\n");
commander.help();
}
});
commander.parse(process.argv);
function setGlobalVars (options) {
const lang = [ "english", "swahili", ];
global.defaultLang = lang.includes(options.lang) ? options.lang : "english";
}
function startSwapProcess (file) {
const InputStream = require("./src/inputstream.js");
const Lexer = require("./src/lexer.js");
const Parser = require("./src/parsers/parser.js");
const Environment = require("./src/environment.js");
const MainInterpreter = require("./src/interpreters/maininterpreter.js");
const parser = new Parser(new Lexer(new InputStream(file)));
new MainInterpreter(new Environment(), parser).interpreteProgram();
}
function startReplProcess () {
require("./src/repl.js").start();
}