@ugo-studio/jspp 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +25 -25
- package/README.md +20 -12
- package/dist/analysis/scope.js +5 -3
- package/dist/analysis/typeAnalyzer.js +21 -25
- package/dist/cli/index.js +14 -4
- package/dist/cli/utils.js +61 -0
- package/dist/core/codegen/control-flow-handlers.js +10 -9
- package/dist/core/codegen/declaration-handlers.js +10 -3
- package/dist/core/codegen/destructuring-handlers.js +9 -4
- package/dist/core/codegen/expression-handlers.js +40 -29
- package/dist/core/codegen/function-handlers.js +78 -12
- package/dist/core/codegen/helpers.js +91 -14
- package/dist/core/codegen/index.js +4 -2
- package/dist/core/codegen/statement-handlers.js +8 -6
- package/package.json +2 -2
- package/scripts/precompile-headers.ts +249 -50
- package/scripts/setup-compiler.ts +63 -63
- package/src/prelude/any_value.cpp +636 -0
- package/src/prelude/any_value.hpp +23 -16
- package/src/prelude/{exception_helpers.hpp → exception.cpp} +53 -53
- package/src/prelude/exception.hpp +27 -27
- package/src/prelude/iterator_instantiations.hpp +10 -0
- package/src/prelude/{index.hpp → jspp.hpp} +10 -16
- package/src/prelude/library/array.cpp +191 -0
- package/src/prelude/library/array.hpp +5 -178
- package/src/prelude/library/console.cpp +125 -0
- package/src/prelude/library/console.hpp +9 -97
- package/src/prelude/library/error.cpp +100 -0
- package/src/prelude/library/error.hpp +8 -108
- package/src/prelude/library/function.cpp +69 -0
- package/src/prelude/library/function.hpp +6 -5
- package/src/prelude/library/global.cpp +96 -0
- package/src/prelude/library/global.hpp +12 -28
- package/src/prelude/library/global_usings.hpp +15 -0
- package/src/prelude/library/math.cpp +258 -0
- package/src/prelude/library/math.hpp +6 -288
- package/src/prelude/library/object.cpp +379 -0
- package/src/prelude/library/object.hpp +5 -267
- package/src/prelude/library/performance.cpp +21 -0
- package/src/prelude/library/performance.hpp +5 -20
- package/src/prelude/library/process.cpp +38 -0
- package/src/prelude/library/process.hpp +3 -31
- package/src/prelude/library/promise.cpp +131 -0
- package/src/prelude/library/promise.hpp +5 -116
- package/src/prelude/library/symbol.cpp +56 -0
- package/src/prelude/library/symbol.hpp +5 -46
- package/src/prelude/library/timer.cpp +88 -0
- package/src/prelude/library/timer.hpp +11 -87
- package/src/prelude/runtime.cpp +19 -0
- package/src/prelude/types.hpp +17 -12
- package/src/prelude/utils/access.hpp +122 -31
- package/src/prelude/utils/assignment_operators.hpp +99 -99
- package/src/prelude/utils/log_any_value/array.hpp +61 -40
- package/src/prelude/utils/log_any_value/function.hpp +39 -39
- package/src/prelude/utils/log_any_value/object.hpp +60 -3
- package/src/prelude/utils/operators.hpp +25 -10
- package/src/prelude/utils/operators_primitive.hpp +336 -336
- package/src/prelude/utils/well_known_symbols.hpp +24 -24
- package/src/prelude/values/array.cpp +1399 -0
- package/src/prelude/values/array.hpp +4 -0
- package/src/prelude/values/async_iterator.cpp +251 -0
- package/src/prelude/values/async_iterator.hpp +60 -32
- package/src/prelude/values/function.cpp +262 -0
- package/src/prelude/values/function.hpp +10 -30
- package/src/prelude/values/iterator.cpp +309 -0
- package/src/prelude/values/iterator.hpp +33 -64
- package/src/prelude/values/number.cpp +176 -0
- package/src/prelude/values/object.cpp +159 -0
- package/src/prelude/values/object.hpp +4 -0
- package/src/prelude/values/promise.cpp +479 -0
- package/src/prelude/values/promise.hpp +9 -2
- package/src/prelude/values/prototypes/array.hpp +46 -1348
- package/src/prelude/values/prototypes/async_iterator.hpp +19 -61
- package/src/prelude/values/prototypes/function.hpp +7 -46
- package/src/prelude/values/prototypes/iterator.hpp +15 -191
- package/src/prelude/values/prototypes/number.hpp +23 -210
- package/src/prelude/values/prototypes/object.hpp +7 -23
- package/src/prelude/values/prototypes/promise.hpp +8 -186
- package/src/prelude/values/prototypes/string.hpp +28 -553
- package/src/prelude/values/prototypes/symbol.hpp +9 -70
- package/src/prelude/values/shape.hpp +52 -52
- package/src/prelude/values/string.cpp +485 -0
- package/src/prelude/values/symbol.cpp +89 -0
- package/src/prelude/values/symbol.hpp +101 -101
- package/src/prelude/any_value_access.hpp +0 -170
- package/src/prelude/any_value_defines.hpp +0 -190
- package/src/prelude/any_value_helpers.hpp +0 -374
- package/src/prelude/values/helpers/array.hpp +0 -199
- package/src/prelude/values/helpers/async_iterator.hpp +0 -275
- package/src/prelude/values/helpers/function.hpp +0 -109
- package/src/prelude/values/helpers/iterator.hpp +0 -145
- package/src/prelude/values/helpers/object.hpp +0 -104
- package/src/prelude/values/helpers/promise.hpp +0 -254
- package/src/prelude/values/helpers/string.hpp +0 -37
- package/src/prelude/values/helpers/symbol.hpp +0 -21
|
@@ -1,7 +1,82 @@
|
|
|
1
|
-
import { spawnSync } from "child_process";
|
|
1
|
+
import { spawn, spawnSync } from "child_process";
|
|
2
2
|
import fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
4
|
|
|
5
|
+
const COLORS = {
|
|
6
|
+
reset: "\x1b[0m",
|
|
7
|
+
cyan: "\x1b[36m",
|
|
8
|
+
green: "\x1b[32m",
|
|
9
|
+
yellow: "\x1b[33m",
|
|
10
|
+
red: "\x1b[31m",
|
|
11
|
+
dim: "\x1b[2m",
|
|
12
|
+
bold: "\x1b[1m",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export class Spinner {
|
|
16
|
+
private frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
17
|
+
private interval: any = null;
|
|
18
|
+
private frameIndex = 0;
|
|
19
|
+
public text: string;
|
|
20
|
+
|
|
21
|
+
constructor(text: string) {
|
|
22
|
+
this.text = text;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
start() {
|
|
26
|
+
process.stdout.write("\x1b[?25l"); // Hide cursor
|
|
27
|
+
this.frameIndex = 0;
|
|
28
|
+
this.render();
|
|
29
|
+
this.interval = setInterval(() => {
|
|
30
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
31
|
+
this.render();
|
|
32
|
+
}, 80);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
update(text: string) {
|
|
36
|
+
this.text = text;
|
|
37
|
+
this.render();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
stop(symbol: string = "", color: string = COLORS.reset) {
|
|
41
|
+
if (this.interval) {
|
|
42
|
+
clearInterval(this.interval);
|
|
43
|
+
this.interval = null;
|
|
44
|
+
}
|
|
45
|
+
this.clearLine();
|
|
46
|
+
process.stdout.write(
|
|
47
|
+
`${color}${symbol} ${COLORS.reset} ${this.text}\n`,
|
|
48
|
+
);
|
|
49
|
+
process.stdout.write("\x1b[?25h"); // Show cursor
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
succeed(text?: string) {
|
|
53
|
+
if (text) this.text = text;
|
|
54
|
+
this.stop("✔", COLORS.green);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fail(text?: string) {
|
|
58
|
+
if (text) this.text = text;
|
|
59
|
+
this.stop("✖", COLORS.red);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
info(text?: string) {
|
|
63
|
+
if (text) this.text = text;
|
|
64
|
+
this.stop("ℹ", COLORS.cyan);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private render() {
|
|
68
|
+
this.clearLine();
|
|
69
|
+
const frame = this.frames[this.frameIndex];
|
|
70
|
+
process.stdout.write(
|
|
71
|
+
`${COLORS.cyan}${frame} ${COLORS.reset} ${this.text}`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private clearLine() {
|
|
76
|
+
process.stdout.write("\r\x1b[K");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
5
80
|
const PRELUDE_DIR = path.resolve(process.cwd(), "src", "prelude");
|
|
6
81
|
const PRECOMPILED_HEADER_BASE_DIR = path.resolve(
|
|
7
82
|
process.cwd(),
|
|
@@ -11,7 +86,7 @@ const PRECOMPILED_HEADER_BASE_DIR = path.resolve(
|
|
|
11
86
|
const MODES = [
|
|
12
87
|
{
|
|
13
88
|
name: "debug",
|
|
14
|
-
flags: ["-
|
|
89
|
+
flags: ["-Og"],
|
|
15
90
|
},
|
|
16
91
|
{
|
|
17
92
|
name: "release",
|
|
@@ -24,15 +99,19 @@ if (process.platform === "win32") {
|
|
|
24
99
|
MODES[1].flags.push("-Wa,-mbig-obj");
|
|
25
100
|
}
|
|
26
101
|
|
|
27
|
-
async function getLatestMtime(
|
|
102
|
+
async function getLatestMtime(
|
|
103
|
+
dirPath: string,
|
|
104
|
+
filter?: (name: string) => boolean,
|
|
105
|
+
): Promise<number> {
|
|
28
106
|
let maxMtime = 0;
|
|
29
107
|
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
30
108
|
for (const entry of entries) {
|
|
31
109
|
const fullPath = path.join(dirPath, entry.name);
|
|
32
110
|
if (entry.isDirectory()) {
|
|
33
|
-
const nestedMtime = await getLatestMtime(fullPath);
|
|
111
|
+
const nestedMtime = await getLatestMtime(fullPath, filter);
|
|
34
112
|
if (nestedMtime > maxMtime) maxMtime = nestedMtime;
|
|
35
113
|
} else {
|
|
114
|
+
if (filter && !filter(entry.name)) continue;
|
|
36
115
|
const stats = await fs.stat(fullPath);
|
|
37
116
|
if (stats.mtimeMs > maxMtime) maxMtime = stats.mtimeMs;
|
|
38
117
|
}
|
|
@@ -40,53 +119,74 @@ async function getLatestMtime(dirPath: string): Promise<number> {
|
|
|
40
119
|
return maxMtime;
|
|
41
120
|
}
|
|
42
121
|
|
|
122
|
+
async function findCppFiles(dir: string): Promise<string[]> {
|
|
123
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
124
|
+
const files = await Promise.all(entries.map((entry) => {
|
|
125
|
+
const res = path.resolve(dir, entry.name);
|
|
126
|
+
if (entry.isDirectory()) {
|
|
127
|
+
return findCppFiles(res);
|
|
128
|
+
} else {
|
|
129
|
+
return res.endsWith(".cpp") ? [res] : [];
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
return Array.prototype.concat(...files);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function runCommand(cmd: string, args: string[]): Promise<boolean> {
|
|
136
|
+
return new Promise((resolve) => {
|
|
137
|
+
const proc = spawn(cmd, args, { stdio: "ignore" });
|
|
138
|
+
proc.on("close", (code) => resolve(code === 0));
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
43
142
|
async function precompileHeaders() {
|
|
143
|
+
console.log(
|
|
144
|
+
`${COLORS.bold}${COLORS.cyan}JSPP: Precompiling headers and runtime...${COLORS.reset}\n`,
|
|
145
|
+
);
|
|
146
|
+
|
|
44
147
|
const force = process.argv.includes("--force");
|
|
45
148
|
try {
|
|
46
149
|
await fs.mkdir(PRECOMPILED_HEADER_BASE_DIR, { recursive: true });
|
|
47
|
-
|
|
150
|
+
|
|
151
|
+
const latestHeaderMtime = await getLatestMtime(
|
|
152
|
+
PRELUDE_DIR,
|
|
153
|
+
(name) => name.endsWith(".hpp") || name.endsWith(".h"),
|
|
154
|
+
);
|
|
48
155
|
|
|
49
156
|
for (const mode of MODES) {
|
|
50
157
|
const modeDir = path.join(PRECOMPILED_HEADER_BASE_DIR, mode.name);
|
|
51
|
-
const headerPath = path.join(modeDir, "
|
|
52
|
-
const gchPath = path.join(modeDir, "
|
|
158
|
+
const headerPath = path.join(modeDir, "jspp.hpp");
|
|
159
|
+
const gchPath = path.join(modeDir, "jspp.hpp.gch");
|
|
160
|
+
|
|
161
|
+
const modeLabel = `[${mode.name.toUpperCase()}]`;
|
|
162
|
+
const spinner = new Spinner(`${modeLabel} Checking headers...`);
|
|
163
|
+
spinner.start();
|
|
164
|
+
|
|
165
|
+
await fs.mkdir(modeDir, { recursive: true });
|
|
53
166
|
|
|
54
|
-
|
|
167
|
+
let gchRebuilt = false;
|
|
168
|
+
let shouldBuildGch = force;
|
|
169
|
+
|
|
170
|
+
if (!shouldBuildGch) {
|
|
55
171
|
try {
|
|
56
172
|
const gchStats = await fs.stat(gchPath);
|
|
57
|
-
if (gchStats.mtimeMs
|
|
58
|
-
|
|
59
|
-
`[${mode.name.toUpperCase()}] Headers are up-to-date. Skipping.`,
|
|
60
|
-
);
|
|
61
|
-
continue;
|
|
173
|
+
if (latestHeaderMtime > gchStats.mtimeMs) {
|
|
174
|
+
shouldBuildGch = true;
|
|
62
175
|
}
|
|
63
176
|
} catch (e) {
|
|
64
|
-
|
|
177
|
+
shouldBuildGch = true;
|
|
65
178
|
}
|
|
66
179
|
}
|
|
67
180
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// Remove existing gch if it exists
|
|
75
|
-
if (
|
|
76
|
-
await fs.stat(gchPath).then(
|
|
77
|
-
() => true,
|
|
78
|
-
() => false,
|
|
79
|
-
)
|
|
80
|
-
) {
|
|
81
|
-
await fs.unlink(gchPath);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
console.log(`[${mode.name.toUpperCase()}] Compiling header...`);
|
|
85
|
-
const tempGchPath = `${gchPath}.tmp`;
|
|
181
|
+
if (shouldBuildGch) {
|
|
182
|
+
spinner.update(`${modeLabel} Compiling header...`);
|
|
183
|
+
await fs.copyFile(
|
|
184
|
+
path.join(PRELUDE_DIR, "jspp.hpp"),
|
|
185
|
+
headerPath,
|
|
186
|
+
);
|
|
86
187
|
|
|
87
|
-
|
|
88
|
-
"g++",
|
|
89
|
-
[
|
|
188
|
+
const tempGchPath = `${gchPath}.tmp`;
|
|
189
|
+
const success = await runCommand("g++", [
|
|
90
190
|
"-x",
|
|
91
191
|
"c++-header",
|
|
92
192
|
"-std=c++23",
|
|
@@ -95,31 +195,130 @@ async function precompileHeaders() {
|
|
|
95
195
|
"-o",
|
|
96
196
|
tempGchPath,
|
|
97
197
|
"-I",
|
|
198
|
+
modeDir,
|
|
199
|
+
"-I",
|
|
98
200
|
PRELUDE_DIR,
|
|
99
|
-
]
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
if (!success) {
|
|
204
|
+
spinner.fail(`${modeLabel} Failed to precompile headers.`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
await fs.rename(tempGchPath, gchPath);
|
|
209
|
+
gchRebuilt = true;
|
|
210
|
+
spinner.succeed(`${modeLabel} PCH Success.`);
|
|
211
|
+
} else {
|
|
212
|
+
spinner.succeed(`${modeLabel} Headers are up-to-date.`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// --- Incremental Compilation of .cpp files ---
|
|
216
|
+
const cppFiles = await findCppFiles(PRELUDE_DIR);
|
|
217
|
+
const objFiles: string[] = [];
|
|
218
|
+
let anyObjRebuilt = false;
|
|
219
|
+
|
|
220
|
+
const gchMtime = (await fs.stat(gchPath)).mtimeMs;
|
|
221
|
+
|
|
222
|
+
const libSpinner = new Spinner(
|
|
223
|
+
`${modeLabel} Checking runtime library...`,
|
|
103
224
|
);
|
|
225
|
+
libSpinner.start();
|
|
226
|
+
|
|
227
|
+
for (let idx = 0; idx < cppFiles.length; idx++) {
|
|
228
|
+
const cppFile = cppFiles[idx];
|
|
229
|
+
const relativePath = path.relative(PRELUDE_DIR, cppFile);
|
|
230
|
+
const objFile = path.join(
|
|
231
|
+
modeDir,
|
|
232
|
+
relativePath.replace(/\.cpp$/, ".o"),
|
|
233
|
+
);
|
|
234
|
+
await fs.mkdir(path.dirname(objFile), { recursive: true });
|
|
235
|
+
objFiles.push(objFile);
|
|
236
|
+
|
|
237
|
+
let shouldCompile = force || gchRebuilt;
|
|
238
|
+
if (!shouldCompile) {
|
|
239
|
+
try {
|
|
240
|
+
const objStats = await fs.stat(objFile);
|
|
241
|
+
const cppStats = await fs.stat(cppFile);
|
|
242
|
+
if (
|
|
243
|
+
cppStats.mtimeMs > objStats.mtimeMs ||
|
|
244
|
+
gchMtime > objStats.mtimeMs
|
|
245
|
+
) {
|
|
246
|
+
shouldCompile = true;
|
|
247
|
+
}
|
|
248
|
+
} catch (e) {
|
|
249
|
+
shouldCompile = true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (shouldCompile) {
|
|
254
|
+
libSpinner.update(
|
|
255
|
+
`${modeLabel} Compiling ${relativePath} ${COLORS.dim}[${
|
|
256
|
+
idx + 1
|
|
257
|
+
}/${cppFiles.length}]${COLORS.reset}`,
|
|
258
|
+
);
|
|
259
|
+
const success = await runCommand("g++", [
|
|
260
|
+
"-c",
|
|
261
|
+
"-std=c++23",
|
|
262
|
+
...mode.flags,
|
|
263
|
+
cppFile,
|
|
264
|
+
"-o",
|
|
265
|
+
objFile,
|
|
266
|
+
"-I",
|
|
267
|
+
modeDir,
|
|
268
|
+
"-I",
|
|
269
|
+
PRELUDE_DIR,
|
|
270
|
+
]);
|
|
104
271
|
|
|
105
|
-
|
|
272
|
+
if (!success) {
|
|
273
|
+
libSpinner.fail(
|
|
274
|
+
`${modeLabel} Failed to compile ${relativePath}`,
|
|
275
|
+
);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
}
|
|
278
|
+
anyObjRebuilt = true;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const libPath = path.join(modeDir, "libjspp.a");
|
|
283
|
+
let shouldArchive = anyObjRebuilt;
|
|
284
|
+
if (!shouldArchive) {
|
|
106
285
|
try {
|
|
107
|
-
await fs.
|
|
286
|
+
await fs.access(libPath);
|
|
108
287
|
} catch (e) {
|
|
109
|
-
|
|
288
|
+
shouldArchive = true;
|
|
110
289
|
}
|
|
111
|
-
console.error(
|
|
112
|
-
`[${mode.name.toUpperCase()}] Failed to precompile headers.`,
|
|
113
|
-
);
|
|
114
|
-
process.exit(1);
|
|
115
290
|
}
|
|
116
291
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
292
|
+
if (shouldArchive) {
|
|
293
|
+
libSpinner.update(`${modeLabel} Updating runtime library...`);
|
|
294
|
+
const tempLibPath = `${libPath}.tmp`;
|
|
295
|
+
|
|
296
|
+
const success = await runCommand("ar", [
|
|
297
|
+
"rcs",
|
|
298
|
+
tempLibPath,
|
|
299
|
+
...objFiles,
|
|
300
|
+
]);
|
|
301
|
+
|
|
302
|
+
if (!success) {
|
|
303
|
+
libSpinner.fail(
|
|
304
|
+
`${modeLabel} Failed to create static library.`,
|
|
305
|
+
);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
await fs.rename(tempLibPath, libPath);
|
|
310
|
+
libSpinner.succeed(`${modeLabel} Runtime Library Success.`);
|
|
311
|
+
} else {
|
|
312
|
+
libSpinner.succeed(
|
|
313
|
+
`${modeLabel} Runtime library is up-to-date.`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
120
316
|
}
|
|
317
|
+
console.log(
|
|
318
|
+
`\n${COLORS.bold}${COLORS.green}JSPP: Environment ready.${COLORS.reset}\n`,
|
|
319
|
+
);
|
|
121
320
|
} catch (error: any) {
|
|
122
|
-
console.error(
|
|
321
|
+
console.error(`${COLORS.red}Error: ${error.message}${COLORS.reset}`);
|
|
123
322
|
process.exit(1);
|
|
124
323
|
}
|
|
125
324
|
}
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
import { spawnSync } from "child_process";
|
|
2
|
-
import { platform } from "os";
|
|
3
|
-
|
|
4
|
-
const COLORS = {
|
|
5
|
-
reset: "\x1b[0m",
|
|
6
|
-
green: "\x1b[32m",
|
|
7
|
-
yellow: "\x1b[33m",
|
|
8
|
-
red: "\x1b[31m",
|
|
9
|
-
cyan: "\x1b[36m",
|
|
10
|
-
bold: "\x1b[1m",
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
function checkGpp(): boolean {
|
|
14
|
-
try {
|
|
15
|
-
const result = spawnSync("g++", ["--version"], { encoding: "utf8" });
|
|
16
|
-
return result.status === 0;
|
|
17
|
-
} catch (e) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function setup() {
|
|
23
|
-
console.log(`${COLORS.bold}${COLORS.cyan}JSPP: Checking for C++ compiler...${COLORS.reset}`);
|
|
24
|
-
|
|
25
|
-
if (checkGpp()) {
|
|
26
|
-
console.log(`${COLORS.green}✔ g++ found.${COLORS.reset}`);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
console.log(`${COLORS.yellow}⚠ g++ (GCC) not found in PATH. JSPP requires a C++23 compatible compiler.${COLORS.reset}`);
|
|
31
|
-
|
|
32
|
-
const os = platform();
|
|
33
|
-
|
|
34
|
-
if (os === "win32") {
|
|
35
|
-
console.log(`\n${COLORS.bold}To install GCC on Windows:${COLORS.reset}`);
|
|
36
|
-
console.log(`1. Install MinGW-w64 via MSYS2: ${COLORS.cyan}https://www.msys2.org/${COLORS.reset}`);
|
|
37
|
-
console.log(`2. Or use winget: ${COLORS.cyan}winget install MSYS2.MSYS2${COLORS.reset}`);
|
|
38
|
-
console.log(` Then run: ${COLORS.bold}pacman -S mingw-w64-x86_64-gcc${COLORS.reset}`);
|
|
39
|
-
} else if (os === "linux") {
|
|
40
|
-
console.log(`\n${COLORS.bold}To install GCC on Linux (Ubuntu/Debian):${COLORS.reset}`);
|
|
41
|
-
console.log(`${COLORS.cyan}sudo apt update && sudo apt install g++-14 -y${COLORS.reset}`);
|
|
42
|
-
console.log(`\nAttempting to install now (may require password)...`);
|
|
43
|
-
|
|
44
|
-
// Try to install automatically on Linux if apt is found
|
|
45
|
-
try {
|
|
46
|
-
const install = spawnSync("sudo", ["apt-get", "install", "-y", "g++-14"], { stdio: "inherit" });
|
|
47
|
-
if (install.status === 0) {
|
|
48
|
-
console.log(`${COLORS.green}✔ g++-14 installed successfully.${COLORS.reset}`);
|
|
49
|
-
// Try to set up symlink if needed or just inform user
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
} catch (e) {
|
|
53
|
-
console.error(`${COLORS.red}Automatic installation failed. Please install manually.${COLORS.reset}`);
|
|
54
|
-
}
|
|
55
|
-
} else if (os === "darwin") {
|
|
56
|
-
console.log(`\n${COLORS.bold}To install GCC on macOS:${COLORS.reset}`);
|
|
57
|
-
console.log(`${COLORS.cyan}brew install gcc${COLORS.reset}`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
console.log(`\n${COLORS.bold}After installation, please ensure 'g++' is in your PATH and restart your terminal.${COLORS.reset}\n`);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
setup();
|
|
1
|
+
import { spawnSync } from "child_process";
|
|
2
|
+
import { platform } from "os";
|
|
3
|
+
|
|
4
|
+
const COLORS = {
|
|
5
|
+
reset: "\x1b[0m",
|
|
6
|
+
green: "\x1b[32m",
|
|
7
|
+
yellow: "\x1b[33m",
|
|
8
|
+
red: "\x1b[31m",
|
|
9
|
+
cyan: "\x1b[36m",
|
|
10
|
+
bold: "\x1b[1m",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function checkGpp(): boolean {
|
|
14
|
+
try {
|
|
15
|
+
const result = spawnSync("g++", ["--version"], { encoding: "utf8" });
|
|
16
|
+
return result.status === 0;
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function setup() {
|
|
23
|
+
console.log(`${COLORS.bold}${COLORS.cyan}JSPP: Checking for C++ compiler...${COLORS.reset}`);
|
|
24
|
+
|
|
25
|
+
if (checkGpp()) {
|
|
26
|
+
console.log(`${COLORS.green}✔ g++ found.${COLORS.reset}`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`${COLORS.yellow}⚠ g++ (GCC) not found in PATH. JSPP requires a C++23 compatible compiler.${COLORS.reset}`);
|
|
31
|
+
|
|
32
|
+
const os = platform();
|
|
33
|
+
|
|
34
|
+
if (os === "win32") {
|
|
35
|
+
console.log(`\n${COLORS.bold}To install GCC on Windows:${COLORS.reset}`);
|
|
36
|
+
console.log(`1. Install MinGW-w64 via MSYS2: ${COLORS.cyan}https://www.msys2.org/${COLORS.reset}`);
|
|
37
|
+
console.log(`2. Or use winget: ${COLORS.cyan}winget install MSYS2.MSYS2${COLORS.reset}`);
|
|
38
|
+
console.log(` Then run: ${COLORS.bold}pacman -S mingw-w64-x86_64-gcc${COLORS.reset}`);
|
|
39
|
+
} else if (os === "linux") {
|
|
40
|
+
console.log(`\n${COLORS.bold}To install GCC on Linux (Ubuntu/Debian):${COLORS.reset}`);
|
|
41
|
+
console.log(`${COLORS.cyan}sudo apt update && sudo apt install g++-14 -y${COLORS.reset}`);
|
|
42
|
+
console.log(`\nAttempting to install now (may require password)...`);
|
|
43
|
+
|
|
44
|
+
// Try to install automatically on Linux if apt is found
|
|
45
|
+
try {
|
|
46
|
+
const install = spawnSync("sudo", ["apt-get", "install", "-y", "g++-14"], { stdio: "inherit" });
|
|
47
|
+
if (install.status === 0) {
|
|
48
|
+
console.log(`${COLORS.green}✔ g++-14 installed successfully.${COLORS.reset}`);
|
|
49
|
+
// Try to set up symlink if needed or just inform user
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error(`${COLORS.red}Automatic installation failed. Please install manually.${COLORS.reset}`);
|
|
54
|
+
}
|
|
55
|
+
} else if (os === "darwin") {
|
|
56
|
+
console.log(`\n${COLORS.bold}To install GCC on macOS:${COLORS.reset}`);
|
|
57
|
+
console.log(`${COLORS.cyan}brew install gcc${COLORS.reset}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
console.log(`\n${COLORS.bold}After installation, please ensure 'g++' is in your PATH and restart your terminal.${COLORS.reset}\n`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
setup();
|