ranger-compiler 3.1.0 → 3.1.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/CHANGELOG.md CHANGED
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.1.1] - 2026-06-23
11
+
12
+ ### Changed
13
+
14
+ - Version bump for npm publish — recommended for cloud CI and projects that install `ranger-compiler` from npm (e.g. koodisampo) instead of a sibling `../agent/Ranger` checkout
15
+ - Default `npm test` / `prepublishOnly` skips `compiler-llvm.test.ts` (experimental LLVM/WAT backend); run `npm run test:llvm` when working on native/WASM codegen
16
+
17
+ ### Added
18
+
19
+ - **IsoDate stdlib** — `lib/IsoDate/` (`DateMath`, `IsoDateParse`, `IsoCalendar`) and `lib/IsoDateLib.rgr` for portable ISO calendar dates without host `Date`; see [ai/ISO_DATE.md](ai/ISO_DATE.md)
20
+ - **IsoDate compiler intrinsics** — `iso_add_days`, `iso_compare`, `iso_between` in `Lang.rgr` (Kotlin/Java `java.time.LocalDate`, ES6 UTC-safe helper)
21
+ - **IsoDate regression** — `tests/fixtures/iso_date_ops.rgr` in Kotlin compiler tests
22
+ - **Regex stdlib** — `lib/Regex/` (`RegexMatch`) and `lib/RegexLib.rgr` for string-pattern matching without `/literal/` syntax; see [ai/REGEX.md](ai/REGEX.md)
23
+ - **Regex compiler intrinsic** — `regex_test(pattern, haystack)` in `Lang.rgr` (Kotlin/Java `Regex`/`Pattern`, ES6 `RegExp`, Swift `range(of:options:)`)
24
+ - **Regex regression** — `tests/fixtures/regex_test_ops.rgr` in Kotlin compiler tests
25
+
26
+ - **JavaScript/TypeScript source maps (`-sourcemap`)** — `SourceMapBuilder` with VLQ encoding (`compiler/ng_SourceMap.rgr`); `CodeWriter` line/column tracking, `walkNodeStack`, and `outMapped()`; embedded `sourcesContent` for `.rgr` sources; `.js.map` + `//# sourceMappingURL=` on save; statement/expression mappings via `LiveCompiler.WalkNode` walk context; expression `names` from `node.vref` / parameter names; regression `tests/compiler-sourcemap.test.ts`; README section *JavaScript / TypeScript source maps*
27
+
28
+ ### Fixed
29
+
30
+ - **Source map VLQ line breaks** — `buildMappingsString` no longer resets source/original relative state on `;` (fixes DevTools breakpoints on `.rgr` sources)
31
+ - **Source map original line** — `addMappingFromNode` uses `node.getLine()` from `sp` instead of stale `node.row`
32
+ - **Kotlin `floor` / `int2double`** — `int2double` emits `.toDouble()`; reserved parameter names escaped (`val`, `object`, …)
33
+ - **`proc_send` dispatch wrapping** — turn boundaries around handler calls; `ProcessRuntime.beginDispatchTurn` / `endDispatchTurn`
34
+
10
35
  ## [3.1.0] - 2026-06-02
11
36
 
12
37
  ### Added
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ranger cross language compiler
2
2
 
3
- **Version 3.1.0** | Status: `experimental`
3
+ **Version 3.1.1** | Status: `experimental`
4
4
 
5
5
  Ranger is a self-hosting cross-language compiler for writing portable algorithms, parsers, generators, and small tools once and compiling them to multiple target languages.
6
6
 
@@ -56,7 +56,7 @@ const host = ProcessUiHost.__singleton();
56
56
  host.notifyPath = (path) => { /* sync view model + re-render */ };
57
57
  ```
58
58
 
59
- **Docs:** [PROCESS_MVP.md](PROCESS_MVP.md) (scope), [PROCESS_STATUS.md](PROCESS_STATUS.md) (compiler checklist), [PROCESS_UI_NOTIFY.md](PROCESS_UI_NOTIFY.md) (notify batching), [PROCESS_UI_VIEW_MODELS.md](PROCESS_UI_VIEW_MODELS.md) (view DTO assignment). **Gallery:** [process_counter_board](gallery/process_counter_board/README.md). **Pilot:** [realtrainer `app-ranger` Active Workout demo](https://github.com/terotests/realtrainer/tree/copilot/create-watch-ui-components/app-ranger/demo/active-workout-process).
59
+ **Docs:** [PROCESS_MVP.md](PROCESS_MVP.md) (scope), [PROCESS_STATUS.md](PROCESS_STATUS.md) (compiler checklist), [PROCESS_RUNTIME_INVARIANTS.md](PROCESS_RUNTIME_INVARIANTS.md) (dispatch turn / one notify), [PROCESS_UI_NOTIFY.md](PROCESS_UI_NOTIFY.md) (notify batching), [PROCESS_UI_VIEW_MODELS.md](PROCESS_UI_VIEW_MODELS.md) (view DTO assignment). **Gallery:** [process_counter_board](gallery/process_counter_board/README.md) (Vite + React host for `@process`).
60
60
 
61
61
  ## Where To Start
62
62
 
@@ -69,6 +69,7 @@ host.notifyPath = (path) => { /* sync view model + re-render */ };
69
69
  - `gallery/js_parser` - substantial parser example with benchmarks and README
70
70
  - `gallery/pdf_writer` - EVG / TSX document tooling and preview server
71
71
  - `gallery/invaders` - cross-target demo game
72
+ - `gallery/invaders/llvm/invaders.ll` - checked-in LLVM IR sample from the experimental `-l=llvm` backend
72
73
 
73
74
  ## Compatibility Snapshot
74
75
 
@@ -80,6 +81,7 @@ The project can target `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C#`,
80
81
  | Self-hosting | Actively used, but full compiler generation quality is strongest in JavaScript |
81
82
  | JavaScript / ES6 | Best baseline target and most reliable place to start |
82
83
  | Go / Swift / Rust / Kotlin / C++ | Useful and increasingly capable, but expect edge cases and target-specific gaps |
84
+ | **LLVM / WASM** (`-l=llvm`) | **Experimental.** Lowers to LLVM IR; optional WAT export for freestanding WASM. Native libc builds work for demos like Space Invaders; browser WASM is still rough. See `npm run test:llvm`, `npm run game:build:llvm`. |
83
85
  | Gallery examples | Good for understanding direction and capability, but some require manual setup or platform-specific tooling |
84
86
 
85
87
  ## What's New in Version 3.0
@@ -115,9 +117,9 @@ See [CHANGELOG.md](CHANGELOG.md) for full version history and [PLAN_3.md](PLAN_3
115
117
  The compiler is _self hosting_ which means that it has been written using the compiler itself and thus it can be hosted
116
118
  on several platforms. At the moment the official platform is node.js, because external plugins are only available as npm packages.
117
119
 
118
- The target languages supported are `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C#`, `Scala`, `Python`, and `Rust`. The quality
119
- of the target translation still varies and at the moment of this writing the compiler can only be compiled fully to JavaScript
120
- target. However, most targets already can compile reasonably good code.
120
+ The target languages supported are `JavaScript`, `Java`, `Go`, `Swift`, `PHP`, `C++`, `C#`, `Scala`, `Python`, and `Rust`. An **experimental LLVM backend** (`-l=llvm`) emits LLVM IR and optional freestanding WAT for WASM toolchains; it is not a separate surface language but another codegen path from the same Ranger sources.
121
+
122
+ The quality of the target translation still varies and at the moment of this writing the compiler can only be compiled fully to JavaScript target. However, most targets already can compile reasonably good code.
121
123
 
122
124
  ## Recent Updates (December 2025)
123
125
 
@@ -394,11 +396,12 @@ See `gallery/pdf_writer/examples/test_for_loop.tsx` for a complete demonstration
394
396
 
395
397
  ### Space Invaders Demo Game
396
398
 
397
- A complete terminal-based Space Invaders game demonstrating Ranger's cross-language capabilities. The same source code compiles to **4 different targets**:
399
+ A complete terminal-based Space Invaders game demonstrating Ranger's cross-language capabilities. The same source code compiles to **several targets**:
398
400
 
399
- | Target | Executable | Build Command |
401
+ | Target | Output | Build Command |
400
402
  | -------------- | ------------------- | --------------------------- |
401
403
  | ES6/JavaScript | `invaders.js` | `npm run game:compile` |
404
+ | **LLVM native**| `tmp/invaders-native/invaders` | `npm run game:build:llvm` |
402
405
  | Rust | `invaders_rust.exe` | `npm run game:build:rust` |
403
406
  | Go | `invaders_go.exe` | `npm run game:build:go` |
404
407
  | Kotlin | `invaders.jar` | `npm run game:build:kotlin` |
@@ -415,8 +418,24 @@ npm run game:build:all
415
418
  npm run game:run # JavaScript
416
419
  npm run game:run:rust # Rust
417
420
  npm run game:run:go # Go
421
+ ./tmp/invaders-native/invaders # LLVM native (after game:build:llvm)
422
+ ```
423
+
424
+ #### Experimental LLVM backend (Space Invaders)
425
+
426
+ Ranger can lower the same `invaders.rgr` through a **Low IR → LLVM IR** pipeline (`-l=llvm`), then link with `clang` and a small C runtime (`runtime/ranger_term.c`) for terminal I/O.
427
+
428
+ ```bash
429
+ npm run compile # refresh bin/output.js after compiler changes
430
+ npm run game:build:llvm # invaders.rgr → tmp/invaders-native/invaders.ll → native binary
431
+ npm run test:llvm # LLVM/WASM fixture tests (vitest)
432
+ npm run demo:wasm # smaller freestanding WASM demo (tests/fixtures/llvm_wasm_demo.rgr)
418
433
  ```
419
434
 
435
+ **Checked-in sample:** [`gallery/invaders/llvm/invaders.ll`](gallery/invaders/llvm/invaders.ll) is LLVM IR kept in the repo so you can inspect codegen without building. Regenerate with `cp tmp/invaders-native/invaders.ll gallery/invaders/llvm/invaders.ll` after `game:build:llvm` (see [`gallery/invaders/llvm/README.md`](gallery/invaders/llvm/README.md)).
436
+
437
+ Status: experimental — libc-linked native builds are the most reliable path; freestanding WAT/WASM for the full game is still incomplete (terminal imports, control-flow lowering). Smaller WASM demos under `npm run demo:wasm` are closer to working in the browser.
438
+
420
439
  #### Cross-Compiling the Game
421
440
 
422
441
  The Space Invaders game demonstrates cross-platform compilation from a single source file.
@@ -470,6 +489,15 @@ npm run game:compile:swift # Generates invaders.swift
470
489
  swiftc invaders.swift -o invaders_swift
471
490
  ```
472
491
 
492
+ **LLVM native (macOS / Linux, experimental)**
493
+
494
+ ```bash
495
+ npm run game:build:llvm
496
+ ./tmp/invaders-native/invaders
497
+ ```
498
+
499
+ Requires `clang` on `PATH`. On macOS the script picks `arm64-apple-macos` or `x86_64-apple-macos` automatically.
500
+
473
501
  #### Platform-Specific Keyboard Input
474
502
 
475
503
  The game uses `on_keypress` and `poll_keypress` operators with platform-specific implementations:
@@ -492,6 +520,7 @@ The Space Invaders game provides an interesting comparison of how the same Range
492
520
  | Target | Generated File | Size (bytes) | Lines | Notes |
493
521
  | ---------- | ---------------- | ------------ | ----- | ------------------------------- |
494
522
  | **Ranger** | `invaders.rgr` | 11,289 | ~400 | Original source |
523
+ | **LLVM IR**| `llvm/invaders.ll` | ~60,000 | ~1,700 | Low-level IR (sample in repo) |
495
524
  | Python | `invaders.py` | 9,271 | ~330 | Most compact generated code |
496
525
  | JavaScript | `invaders.js` | 10,301 | ~350 | Clean, readable output |
497
526
  | Swift | `invaders.swift` | 12,554 | ~470 | Verbose type annotations |
@@ -499,11 +528,12 @@ The Space Invaders game provides an interesting comparison of how the same Range
499
528
  | C++ | `invaders.cpp` | 14,148 | ~500 | Headers and type declarations |
500
529
  | Rust | `invaders.rs` | 17,918 | ~600 | Most verbose (ownership, types) |
501
530
 
502
- **Executable Sizes (Windows):**
531
+ **Executable Sizes (native binaries):**
503
532
 
504
533
  | Target | Executable | Size | Notes |
505
534
  | ------ | -------------------- | ------ | --------------------------------- |
506
- | Swift | `invaders_swift.exe` | 76 KB | Smallest native binary |
535
+ | **LLVM** | `tmp/invaders-native/invaders` | ~34 KB (arm64 macOS) | Smallest in recent local builds; libc + minimal runtime |
536
+ | Swift | `invaders_swift.exe` | 76 KB | Dynamic link to system libraries |
507
537
  | Rust | `invaders_rust.exe` | 291 KB | Optimized, statically linked |
508
538
  | Go | `invaders_go.exe` | 2.3 MB | Includes Go runtime |
509
539
  | C++ | `invaders_cpp.exe` | 3.0 MB | Static linking with MinGW/pthread |
@@ -766,6 +796,7 @@ Flags: -<flag>
766
796
  -nodecli Insert node.js command line header #!/usr/bin/env node to the beginning of the JavaScript file
767
797
  -nodemodule Export classes as CommonJS modules using module.exports (disables static main function)
768
798
  -esm Export classes as ES6/ESM modules using export keyword (disables static main function)
799
+ -sourcemap Emit .js.map / .ts.map with embedded .rgr sourcesContent (ES6/TypeScript only)
769
800
  -client the code is ment to be run in the client environment
770
801
  -scalafiddle scalafiddle.io compatible output
771
802
  -compiler recompile the compiler
@@ -800,6 +831,47 @@ node bin/output.js -es6 -esm myfile.rgr -o=myfile.mjs
800
831
  **File Extensions:**
801
832
  The compiler automatically detects JavaScript-related extensions (`.js`, `.ts`, `.mjs`, `.cjs`) and won't double-add them. You can safely specify the full filename with extension.
802
833
 
834
+ ### JavaScript / TypeScript source maps (`-sourcemap`)
835
+
836
+ Use `-sourcemap` with `-es6` or `-typescript` to emit a sibling `.js.map` / `.ts.map` file and append `//# sourceMappingURL=…` to the generated output. Kotlin, Swift, and other non-JS targets ignore this flag.
837
+
838
+ **What you get**
839
+
840
+ | Output | Purpose |
841
+ | --- | --- |
842
+ | `output.js.map` | Source map v3 (VLQ `mappings`, `names`, `sources`) |
843
+ | `sourcesContent` | Full `.rgr` source embedded in the map — Chrome DevTools can open `.rgr` files without a separate file server |
844
+ | Statement + expression mappings | `LiveCompiler.WalkNode` walk context plus `outMapped()` on identifiers, calls, literals |
845
+
846
+ **Compile example**
847
+
848
+ ```bash
849
+ # Standalone ES module + map
850
+ node bin/output.js -es6 -esm -nodemodule -sourcemap ./myapp/App.rgr -o=app.js
851
+
852
+ # Result: bin/app.js and bin/app.js.map
853
+ ```
854
+
855
+ **Debug in Chrome / Edge**
856
+
857
+ 1. Serve the generated `.js` (and `.map` beside it). Vite/webpack are optional when `sourcesContent` is embedded.
858
+ 2. Open DevTools → **Sources**. Original `.rgr` files appear under the map tree (from `sourcesContent`).
859
+ 3. Set breakpoints on **executable** lines (e.g. `def`, `if`, `return`) — not only blank lines or signatures.
860
+ 4. Breakpoints must be **solid red**. A hollow/grey breakpoint means no mapping for that line; rebuild with `-sourcemap` and hard-refresh (disable cache).
861
+
862
+ **Tests**
863
+
864
+ ```bash
865
+ npm run compile
866
+ npx vitest run tests/compiler-sourcemap.test.ts
867
+ ```
868
+
869
+ **Implementation notes** (for compiler hackers)
870
+
871
+ - `compiler/ng_SourceMap.rgr` — `SourceMapBuilder`, VLQ encoder, `addMappingFromNode()` uses `node.getLine()` + `node.code.getColumn(sp)` (not stale `node.row`).
872
+ - `compiler/ng_writer.rgr` — `lineNumber` / `columnNumber` on emit, `walkNodeStack`, `outMapped()`, `.map` write in `CodeFileSystem.saveTo`.
873
+ - Flag: `compiler/ng_Compiler.rgr` → `flag sourcemap`; enabled in `VirtualCompiler.rgr` via `fileSystem.enableSourceMaps()`.
874
+
803
875
  ## Getting started with Hello World
804
876
 
805
877
  Create file `hello.rgr`