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 +25 -0
- package/README.md +81 -9
- package/dist/Lang.rgr +153 -1
- package/dist/lib/IsoDate/DateMath.rgr +219 -0
- package/dist/lib/IsoDate/IsoCalendar.rgr +137 -0
- package/dist/lib/IsoDate/IsoDateParse.rgr +57 -0
- package/dist/lib/IsoDateLib.rgr +15 -0
- package/dist/lib/RangerProcess.rgr +47 -0
- package/dist/lib/Regex/RegexMatch.rgr +134 -0
- package/dist/lib/RegexLib.rgr +10 -0
- package/dist/lib/Time.rgr +2 -1
- package/dist/rgrc.js +9715 -2229
- package/package.json +13 -4
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.
|
|
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)
|
|
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`.
|
|
119
|
-
|
|
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 **
|
|
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 |
|
|
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 (
|
|
531
|
+
**Executable Sizes (native binaries):**
|
|
503
532
|
|
|
504
533
|
| Target | Executable | Size | Notes |
|
|
505
534
|
| ------ | -------------------- | ------ | --------------------------------- |
|
|
506
|
-
|
|
|
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`
|