@ugo-studio/jspp 0.1.8 → 0.2.0
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/README.md +1 -1
- package/dist/cli-utils/args.js +2 -0
- package/dist/cli.js +1 -1
- package/package.json +3 -2
- package/scripts/precompile-headers.ts +110 -0
- package/scripts/setup-compiler.ts +63 -0
- package/src/prelude/any_value.hpp +185 -391
- package/src/prelude/any_value_access.hpp +170 -190
- package/src/prelude/any_value_defines.hpp +12 -12
- package/src/prelude/any_value_helpers.hpp +208 -26
- package/src/prelude/exception.hpp +27 -31
- package/src/prelude/exception_helpers.hpp +53 -49
- package/src/prelude/index.hpp +9 -4
- package/src/prelude/library/array.hpp +4 -9
- package/src/prelude/library/console.hpp +112 -112
- package/src/prelude/library/error.hpp +8 -8
- package/src/prelude/library/math.hpp +3 -3
- package/src/prelude/library/object.hpp +12 -24
- package/src/prelude/library/promise.hpp +1 -1
- package/src/prelude/library/symbol.hpp +1 -1
- package/src/prelude/library/timer.hpp +3 -3
- package/src/prelude/types.hpp +178 -130
- package/src/prelude/utils/access.hpp +338 -378
- package/src/prelude/utils/log_any_value/function.hpp +39 -39
- package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
- package/src/prelude/utils/operators.hpp +20 -82
- package/src/prelude/utils/well_known_symbols.hpp +14 -15
- package/src/prelude/values/array.hpp +5 -3
- package/src/prelude/values/async_iterator.hpp +3 -1
- package/src/prelude/values/descriptors.hpp +15 -3
- package/src/prelude/values/function.hpp +5 -9
- package/src/prelude/values/helpers/array.hpp +208 -219
- package/src/prelude/values/helpers/async_iterator.hpp +7 -11
- package/src/prelude/values/helpers/function.hpp +12 -17
- package/src/prelude/values/helpers/iterator.hpp +108 -107
- package/src/prelude/values/helpers/object.hpp +104 -109
- package/src/prelude/values/helpers/promise.hpp +185 -119
- package/src/prelude/values/helpers/string.hpp +7 -10
- package/src/prelude/values/helpers/symbol.hpp +21 -23
- package/src/prelude/values/iterator.hpp +4 -1
- package/src/prelude/values/object.hpp +6 -4
- package/src/prelude/values/promise.hpp +5 -2
- package/src/prelude/values/prototypes/array.hpp +22 -22
- package/src/prelude/values/prototypes/async_iterator.hpp +3 -10
- package/src/prelude/values/prototypes/iterator.hpp +51 -58
- package/src/prelude/values/prototypes/promise.hpp +32 -28
- package/src/prelude/values/prototypes/string.hpp +5 -5
- package/src/prelude/values/prototypes/symbol.hpp +1 -1
- package/src/prelude/values/string.hpp +3 -1
- package/src/prelude/values/symbol.hpp +101 -102
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ This phase focuses on building a solid foundation that correctly models JavaScri
|
|
|
104
104
|
- [x] Dynamic Variables & Primitives (`let`, `const`, `var`, `undefined`, `null`, `string`, `number`, `boolean`, etc.)
|
|
105
105
|
- [x] Function Declarations & Arrow Functions
|
|
106
106
|
- [x] Correct Hoisting for Variables and Functions
|
|
107
|
-
- [x] Closures & Lexical Scoping
|
|
107
|
+
- [x] Closures & Lexical Scoping
|
|
108
108
|
- [x] `if-elseif-else` conditions
|
|
109
109
|
- [x] Basic `console` API
|
|
110
110
|
|
package/dist/cli-utils/args.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
+
import pkg from "../../package.json";
|
|
2
3
|
import { COLORS } from "./colors";
|
|
3
4
|
export function parseArgs(rawArgs) {
|
|
4
5
|
let jsFilePathArg = null;
|
|
@@ -42,6 +43,7 @@ export function parseArgs(rawArgs) {
|
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
if (!jsFilePathArg) {
|
|
46
|
+
console.log(`${COLORS.bold}JSPP Compiler${COLORS.reset} ${COLORS.dim}v${pkg.version}${COLORS.reset}`);
|
|
45
47
|
console.log(`${COLORS.bold}Usage:${COLORS.reset} jspp <path-to-js-file> [--release] [--keep-cpp] [-o <output-path>] [-- <args...>]`);
|
|
46
48
|
process.exit(1);
|
|
47
49
|
}
|
package/dist/cli.js
CHANGED
|
@@ -44,7 +44,7 @@ async function main() {
|
|
|
44
44
|
const { cppCode, preludePath } = interpreter.interpret(jsCode);
|
|
45
45
|
// Ensure directory for cpp file exists (should exist as it's source dir, but for safety if we change logic)
|
|
46
46
|
await fs.mkdir(path.dirname(cppFilePath), { recursive: true });
|
|
47
|
-
await fs.writeFile(cppFilePath, cppCode);
|
|
47
|
+
// await fs.writeFile(cppFilePath, cppCode);
|
|
48
48
|
spinner.succeed(`Generated cpp`);
|
|
49
49
|
// 2. Precompiled Header Check
|
|
50
50
|
spinner.text = "Checking precompiled headers...";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ugo-studio/jspp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A modern transpiler that converts JavaScript code into high-performance, standard C++23.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
|
-
"src/prelude"
|
|
13
|
+
"src/prelude",
|
|
14
|
+
"scripts"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
16
17
|
"postinstall": "bun run scripts/setup-compiler.ts",
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
const PRELUDE_DIR = path.resolve(process.cwd(), "src", "prelude");
|
|
5
|
+
const PRECOMPILED_HEADER_BASE_DIR = path.resolve(process.cwd(), "prelude-build");
|
|
6
|
+
|
|
7
|
+
const MODES = [
|
|
8
|
+
{
|
|
9
|
+
name: "debug",
|
|
10
|
+
flags: ["-O0"],
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
name: "release",
|
|
14
|
+
flags: ["-O3", "-DNDEBUG"],
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
if (process.platform === "win32") {
|
|
19
|
+
MODES[0].flags.push("-Wa,-mbig-obj");
|
|
20
|
+
MODES[1].flags.push("-Wa,-mbig-obj");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function getLatestMtime(dirPath: string): Promise<number> {
|
|
24
|
+
let maxMtime = 0;
|
|
25
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
28
|
+
if (entry.isDirectory()) {
|
|
29
|
+
const nestedMtime = await getLatestMtime(fullPath);
|
|
30
|
+
if (nestedMtime > maxMtime) maxMtime = nestedMtime;
|
|
31
|
+
} else {
|
|
32
|
+
const stats = await fs.stat(fullPath);
|
|
33
|
+
if (stats.mtimeMs > maxMtime) maxMtime = stats.mtimeMs;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return maxMtime;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function precompileHeaders() {
|
|
40
|
+
const force = process.argv.includes("--force");
|
|
41
|
+
try {
|
|
42
|
+
await fs.mkdir(PRECOMPILED_HEADER_BASE_DIR, { recursive: true });
|
|
43
|
+
const sourceMtime = await getLatestMtime(PRELUDE_DIR);
|
|
44
|
+
|
|
45
|
+
for (const mode of MODES) {
|
|
46
|
+
const modeDir = path.join(PRECOMPILED_HEADER_BASE_DIR, mode.name);
|
|
47
|
+
const headerPath = path.join(modeDir, "index.hpp");
|
|
48
|
+
const gchPath = path.join(modeDir, "index.hpp.gch");
|
|
49
|
+
|
|
50
|
+
if (!force) {
|
|
51
|
+
try {
|
|
52
|
+
const gchStats = await fs.stat(gchPath);
|
|
53
|
+
if (gchStats.mtimeMs >= sourceMtime) {
|
|
54
|
+
console.log(`[${mode.name.toUpperCase()}] Headers are up-to-date. Skipping.`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
// PCH doesn't exist, proceed to compile
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log(`\n[${mode.name.toUpperCase()}] Setting up...`);
|
|
63
|
+
await fs.mkdir(modeDir, { recursive: true });
|
|
64
|
+
|
|
65
|
+
// Copy index.hpp
|
|
66
|
+
await fs.copyFile(path.join(PRELUDE_DIR, "index.hpp"), headerPath);
|
|
67
|
+
|
|
68
|
+
// Remove existing gch if it exists
|
|
69
|
+
if (
|
|
70
|
+
await fs.stat(gchPath).then(
|
|
71
|
+
() => true,
|
|
72
|
+
() => false,
|
|
73
|
+
)
|
|
74
|
+
) {
|
|
75
|
+
await fs.unlink(gchPath);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.log(`[${mode.name.toUpperCase()}] Compiling header...`);
|
|
79
|
+
const compile = Bun.spawnSync({
|
|
80
|
+
cmd: [
|
|
81
|
+
"g++",
|
|
82
|
+
"-x",
|
|
83
|
+
"c++-header",
|
|
84
|
+
"-std=c++23",
|
|
85
|
+
...mode.flags,
|
|
86
|
+
headerPath,
|
|
87
|
+
"-o",
|
|
88
|
+
gchPath,
|
|
89
|
+
"-I",
|
|
90
|
+
PRELUDE_DIR,
|
|
91
|
+
],
|
|
92
|
+
stdout: "inherit",
|
|
93
|
+
stderr: "inherit",
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (compile.exitCode !== 0) {
|
|
97
|
+
console.error(
|
|
98
|
+
`[${mode.name.toUpperCase()}] Failed to precompile headers.`,
|
|
99
|
+
);
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
console.log(`[${mode.name.toUpperCase()}] Success.`);
|
|
103
|
+
}
|
|
104
|
+
} catch (error: any) {
|
|
105
|
+
console.error(`Error: ${error.message}`);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
precompileHeaders();
|
|
@@ -0,0 +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();
|