This repository has been archived by the owner on Sep 22, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
117 lines (102 loc) · 2.99 KB
/
index.js
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env node
const fs = require("fs");
const { join } = require("path");
const lex = require("./lib/lexer.js");
const parse = require("./lib/parser.js");
const info = require("./package.json");
const argv = process.argv.slice(process.argv[0] == "node" ? 3 : 2);
switch (argv[0]) {
case "-v": case "--version":
console.log(info.name, "v" + info.version);
Object.keys(info.dependencies || {}).forEach(dependency =>
console.log("→", dependency, require("./node_modules/" + dependency + "/package.json").version));
break;
case "-h": case "--help": case undefined:
console.log("magenta <-v|-h> ...");
console.log();
console.log([
["-v", "prints the command version"],
["-h", "prints command help"],
["...", "files/directories to target"],
// todo: -o specify output for executable
].map(x => " " + x[0] + "\t" + x[1]).join("\n"));
break;
default: {
let targets = [];
let scanArg = (parent, filename = "") => {
let arg = join(parent.toString(), filename.toString());
try {
let r = fs.lstatSync(arg);
if (r.isFile()) {
targets.push(arg);
} else if (r.isDirectory() && filename != "node_modules" && (filename.charAt(0) != "." || filename.length == 1)) {
let d = fs.readdirSync(arg);
d.forEach((x) => scanArg(arg, x));
}
} catch (e) { return e; }
}
argv.forEach((x) => scanArg(process.cwd(), x));
// remove duplicates
targets = targets.filter((x, i) => i == targets.indexOf(x)).filter(x => x.endsWith(".m"));
console.log(targets);
if (targets.length == 0) return console.log("magenta: no .m files in target");
let files = [];
let errors = [];
// read all files
let readFiles = () => {
let x = 0;
targets.forEach((file, i) => {
fs.readFile(file, "utf8", (err, data) => {
if (err) return console.error(err);
files.push({ data,
filename: file,
namespace: null,
requires: null,
tokens: null,
});
if (++x == targets.length) {
getMeta();
}
});
});
}
// extract namespace + includes from files
let getMeta = () => {
files.forEach((file, i) => {
// extract namespace
// extract includes
// apply to file
if (i == files.length - 1) {
lexFiles();
}
});
}
// lex all files
let lexFiles = () => {
files.forEach((file, i) => {
let [ tokens, lexerErrors ] = lex(file.data);
file.tokens = tokens;
errors = errors.concat(lexerErrors);
console.log("lex →", file.tokens);
if (i == files.length - 1) {
parseAll();
}
});
}
// parse into ast
let parseAll = () => {
let [ ast, parserErrors ] = parse(files.map(x => x.tokens));
console.log("\nast →", ast);
let err = help(errors.concat(parserErrors));
if (err) return;
}
readFiles();
}
}
function help(errors) {
errors.sort((a, b) => a.row - b.row).forEach(e => {
console.log(`${e.fatal ? "\x1b[31;1m" : "\x1b[93;1m"}[${e.row}, ${e.col}] ${e.msg} \x1b[m`);
console.log("\t" + e.source.replace(/\n/g, "\n\t"));
})
return errors.length > 0;
}