@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.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-utils/args.js +2 -0
  3. package/dist/cli.js +1 -1
  4. package/package.json +3 -2
  5. package/scripts/precompile-headers.ts +110 -0
  6. package/scripts/setup-compiler.ts +63 -0
  7. package/src/prelude/any_value.hpp +185 -391
  8. package/src/prelude/any_value_access.hpp +170 -190
  9. package/src/prelude/any_value_defines.hpp +12 -12
  10. package/src/prelude/any_value_helpers.hpp +208 -26
  11. package/src/prelude/exception.hpp +27 -31
  12. package/src/prelude/exception_helpers.hpp +53 -49
  13. package/src/prelude/index.hpp +9 -4
  14. package/src/prelude/library/array.hpp +4 -9
  15. package/src/prelude/library/console.hpp +112 -112
  16. package/src/prelude/library/error.hpp +8 -8
  17. package/src/prelude/library/math.hpp +3 -3
  18. package/src/prelude/library/object.hpp +12 -24
  19. package/src/prelude/library/promise.hpp +1 -1
  20. package/src/prelude/library/symbol.hpp +1 -1
  21. package/src/prelude/library/timer.hpp +3 -3
  22. package/src/prelude/types.hpp +178 -130
  23. package/src/prelude/utils/access.hpp +338 -378
  24. package/src/prelude/utils/log_any_value/function.hpp +39 -39
  25. package/src/prelude/utils/log_any_value/log_any_value.hpp +1 -1
  26. package/src/prelude/utils/operators.hpp +20 -82
  27. package/src/prelude/utils/well_known_symbols.hpp +14 -15
  28. package/src/prelude/values/array.hpp +5 -3
  29. package/src/prelude/values/async_iterator.hpp +3 -1
  30. package/src/prelude/values/descriptors.hpp +15 -3
  31. package/src/prelude/values/function.hpp +5 -9
  32. package/src/prelude/values/helpers/array.hpp +208 -219
  33. package/src/prelude/values/helpers/async_iterator.hpp +7 -11
  34. package/src/prelude/values/helpers/function.hpp +12 -17
  35. package/src/prelude/values/helpers/iterator.hpp +108 -107
  36. package/src/prelude/values/helpers/object.hpp +104 -109
  37. package/src/prelude/values/helpers/promise.hpp +185 -119
  38. package/src/prelude/values/helpers/string.hpp +7 -10
  39. package/src/prelude/values/helpers/symbol.hpp +21 -23
  40. package/src/prelude/values/iterator.hpp +4 -1
  41. package/src/prelude/values/object.hpp +6 -4
  42. package/src/prelude/values/promise.hpp +5 -2
  43. package/src/prelude/values/prototypes/array.hpp +22 -22
  44. package/src/prelude/values/prototypes/async_iterator.hpp +3 -10
  45. package/src/prelude/values/prototypes/iterator.hpp +51 -58
  46. package/src/prelude/values/prototypes/promise.hpp +32 -28
  47. package/src/prelude/values/prototypes/string.hpp +5 -5
  48. package/src/prelude/values/prototypes/symbol.hpp +1 -1
  49. package/src/prelude/values/string.hpp +3 -1
  50. 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 (via `std::shared_ptr` capture)
107
+ - [x] Closures & Lexical Scoping
108
108
  - [x] `if-elseif-else` conditions
109
109
  - [x] Basic `console` API
110
110
 
@@ -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.1.8",
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();