-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathptls.js
More file actions
executable file
·123 lines (103 loc) · 2.85 KB
/
ptls.js
File metadata and controls
executable file
·123 lines (103 loc) · 2.85 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
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
118
119
120
121
122
123
#!/usr/bin/env node
// This code is human written and reviewed with contributions from AI
// http://pointless.dev/articles/ai-and-pointless/
import { impl } from "./runtime/impl.js";
import { loader } from "./runtime/loader.js";
import { Runtime } from "./runtime/runtime.js";
import { Panic } from "./lang/panic.js";
import { runRepl } from "./tooling/repl.js";
import { format } from "./tooling/formatter.js";
import { Command } from "commander";
import path from "node:path";
import fs from "node:fs";
async function runFile(runtime, file, throwPanic) {
try {
await runtime.importer.get("./", file);
} catch (err) {
if (err instanceof Panic) {
console.log(String(err));
}
if (throwPanic || !(err instanceof Panic)) {
throw err;
}
}
}
const program = new Command();
program
.name("ptls")
.description("Pointless language")
.argument("[file]", "file to run")
.argument("[args...]", "arguments passed to the script")
.passThroughOptions()
.action(async (file) => {
const runtime = new Runtime(impl, loader);
if (file) {
await runFile(runtime, file, true);
} else {
await runRepl(runtime);
}
});
program
.command("run <file>")
.description("run a Pointless file")
.action(async (file) => {
const runtime = new Runtime(impl, loader);
await runFile(runtime, file, true);
});
program
.command("live <file>")
.description("run a Pointless file interactively (rerun on save)")
.action(async (file) => {
const runtime = new Runtime(impl, loader);
let timer;
const runChange = async () => {
console.clear();
runtime.importer.clearImports();
await runFile(runtime, file, false);
};
await runChange();
fs.watch(file, () => {
clearTimeout(timer);
timer = setTimeout(runChange, 100);
});
});
function* findPtls(filePath) {
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
for (const fileName of fs.readdirSync(filePath, { recursive: true })) {
if (fileName.endsWith(".ptls")) {
yield path.join(filePath, fileName);
}
}
} else {
yield filePath;
}
}
program
.command("fmt [paths...]")
.description("format Pointless files")
.action((paths) => {
if (!paths.length) {
paths = ["."];
}
for (const path of paths) {
for (const file of findPtls(path)) {
const src = fs.readFileSync(file, "utf8");
try {
const out = format(src, file);
if (out !== src) {
console.log("Formatted:", file);
fs.writeFileSync(file, out, "utf8");
}
} catch (err) {
if (err instanceof Panic) {
console.log("Syntax Error:", file);
console.log(String(err).replace(/^/gm, " "));
} else {
throw err;
}
}
}
}
});
program.parseAsync();