rip-lang 3.4.2 → 3.4.4

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,45 @@ All notable changes to Rip will be documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [3.4.3] - 2026-02-09
11
+
12
+ ### Source Maps & IDE Intelligence
13
+
14
+ - **Source Map V3 support** — New `src/sourcemaps.js` implements ECMA-426 source maps with zero dependencies. VLQ encoder + SourceMapGenerator class in ~120 lines.
15
+ - **Inline source maps** — `-m` flag embeds source maps as base64 data URLs in compiled output. One file for everything — debuggers read them natively.
16
+ - **Reverse source maps** — `toReverseMap()` provides O(1) source→generated position lookup for IDE type intelligence.
17
+ - **S-expression locations** — Parser now attaches `.loc = {r, c}` on every S-expression node. Locations flow from lexer through parser to code generator using consistent `{r, c}` naming.
18
+ - **Parser cleanup** — Removed legacy Jison location format (`first_line`/`first_column`), dead `ranges` variable, and `locFirst`/`locLast` extraction. Parser uses `{r, c}` natively.
19
+ - **VS Code Extension v0.3.1** — Level 2 type intelligence: autocomplete, hover, and go-to-definition from third-party `.d.ts` files inside `.rip` files. Shadow `.ts` compilation with 300ms debounce. Configurable via `rip.types.intellisense` setting.
20
+
21
+ ## [3.3.1] - 2026-02-09
22
+
23
+ ### Playground & Extension
24
+
25
+ - **Playground cleanup** — Eliminated dead CSS rules, extracted shared Monaco config, DRYed up toggle handlers, fixed flicker by restoring button states before page reveal, added smooth fade-in transition, defaulted light/dark mode to system `prefers-color-scheme`.
26
+ - **VS Code Extension v0.2.0** — Auto-generate `.d.ts` files on save, commands for single-file and workspace-wide type generation, auto-detect compiler binary, configurable settings.
27
+ - **Extension published** to VS Code Marketplace as `rip-lang.rip`.
28
+
29
+ ## [3.2.1] - 2026-02-08
30
+
31
+ ### Test Suite & Solar Cleanup
32
+
33
+ - **Test suite overhaul** — Redistributed tests from `stabilization.rip` and `compatibility.rip` into proper files, removed duplicates, added `reactivity.rip` and `types.rip` test files, added `for-as` guard tests. Now 1,140 tests.
34
+ - **Solar parser generator cleanup** — Removed ~79 lines of dead Jison compatibility code, optimized runtime parser with `.call` instead of `.apply`, modernized variable naming from `yy` prefixes.
35
+
36
+ ## [3.2.0] - 2026-02-08
37
+
38
+ ### Rip Types — Optional Type System
39
+
40
+ - **Type annotations** (`::`) on variables, parameters, and return types — compile-time only, stripped from JS output.
41
+ - **Type aliases** (`::=`) for named types, structural types, union types.
42
+ - **Interfaces** with `extends` support.
43
+ - **Enums** with runtime JS generation and `.d.ts` emission.
44
+ - **Generics** (`<T>`) for reusable type definitions.
45
+ - **`.d.ts` emission** — `emitTypes()` generates TypeScript declaration files directly from annotated token stream.
46
+ - **CLI flag** — `-d`/`--dts` generates `.d.ts` files alongside compiled JS.
47
+ - **Architecture** — All type logic consolidated in `src/types.js` (lexer sidecar), minimal changes to lexer and compiler. Added `::` and `::=` operators to lexer.
48
+
10
49
  ## [3.1.0] - 2026-02-08
11
50
 
12
51
  ### Rip UI — Zero-Build Reactive Web Framework
package/README.md CHANGED
@@ -9,15 +9,15 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.1.0-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.4.3-blue.svg" alt="Version"></a>
13
13
  <a href="#zero-dependencies"><img src="https://img.shields.io/badge/dependencies-ZERO-brightgreen.svg" alt="Dependencies"></a>
14
- <a href="#"><img src="https://img.shields.io/badge/tests-1130%2F1130-brightgreen.svg" alt="Tests"></a>
14
+ <a href="#"><img src="https://img.shields.io/badge/tests-1140%2F1140-brightgreen.svg" alt="Tests"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
16
16
  </p>
17
17
 
18
18
  ---
19
19
 
20
- Rip is a modern language inspired by CoffeeScript. It compiles to **ES2022** (classes, `?.`, `??`, modules), adds about a **dozen new operators**, includes **built-in reactivity**, and sports a self-hosting compiler with **zero dependencies** — all in about 7,700 lines of code.
20
+ Rip is a modern language inspired by CoffeeScript. It compiles to **ES2022** (classes, `?.`, `??`, modules), adds about a **dozen new operators**, includes **built-in reactivity**, and sports a self-hosting compiler with **zero dependencies** — all in about 10,300 lines of code.
21
21
 
22
22
  > **No imports. No hooks. No dependency arrays. Just write code.**
23
23
 
@@ -254,9 +254,9 @@ See [@rip-lang/ui](packages/ui/) for the full framework: Virtual File System, fi
254
254
  | **Reactivity** | None | Built-in |
255
255
  | **Dependencies** | Multiple | Zero |
256
256
  | **Self-hosting** | No | Yes |
257
- | **Lexer** | 3,558 LOC | 1,542 LOC |
258
- | **Compiler** | 10,346 LOC | 3,148 LOC |
259
- | **Total** | 17,760 LOC | ~7,700 LOC |
257
+ | **Lexer** | 3,558 LOC | 1,867 LOC |
258
+ | **Compiler** | 10,346 LOC | 3,292 LOC |
259
+ | **Total** | 17,760 LOC | ~10,300 LOC |
260
260
 
261
261
  Smaller codebase, modern output, built-in reactivity.
262
262
 
@@ -282,22 +282,26 @@ Run Rip directly in the browser:
282
282
  ## Architecture
283
283
 
284
284
  ```
285
- Source -> Lexer -> Parser -> S-Expressions -> Codegen -> JavaScript
286
- (1,542) (352) ["=", "x", 42] (3,148)
285
+ Source -> Lexer -> emitTypes -> Parser -> S-Expressions -> Codegen -> JavaScript
286
+ (1,867) (types.js) (357) ["=", "x", 42] (3,292) + source map
287
287
  ```
288
288
 
289
- Simple arrays instead of AST node classes. The compiler is self-hosting — `bun run parser` rebuilds from source.
289
+ Simple arrays (with `.loc`) instead of AST node classes. The compiler is self-hosting — `bun run parser` rebuilds from source.
290
290
 
291
291
  | Component | File | Lines |
292
292
  |-----------|------|-------|
293
- | Lexer + Rewriter | `src/lexer.js` | 1,542 |
294
- | Compiler + Codegen | `src/compiler.js` | 3,148 |
295
- | Parser (generated) | `src/parser.js` | 352 |
296
- | Grammar | `src/grammar/grammar.rip` | 887 |
297
- | Parser Generator | `src/grammar/solar.rip` | 1,001 |
298
- | REPL | `src/repl.js` | 654 |
299
- | Browser Entry | `src/browser.js` | 79 |
300
- | **Total** | | **7,663** |
293
+ | Lexer + Rewriter | `src/lexer.js` | 1,867 |
294
+ | Compiler + Codegen | `src/compiler.js` | 3,292 |
295
+ | Type System | `src/types.js` | 719 |
296
+ | Component System | `src/components.js` | 1,240 |
297
+ | Source Maps | `src/sourcemaps.js` | 122 |
298
+ | Parser (generated) | `src/parser.js` | 357 |
299
+ | Grammar | `src/grammar/grammar.rip` | 935 |
300
+ | Parser Generator | `src/grammar/solar.rip` | 916 |
301
+ | REPL | `src/repl.js` | 707 |
302
+ | Browser Entry | `src/browser.js` | 80 |
303
+ | Tags | `src/tags.js` | 63 |
304
+ | **Total** | | **10,298** |
301
305
 
302
306
  ---
303
307
 
@@ -305,12 +309,16 @@ Simple arrays instead of AST node classes. The compiler is self-hosting — `bun
305
309
 
306
310
  Rip includes optional packages for full-stack development:
307
311
 
308
- | Package | Purpose | Lines |
309
- |---------|---------|-------|
310
- | [@rip-lang/ui](packages/ui/) | Zero-build reactive web framework (VFS, router, components) | ~1,300 |
311
- | [@rip-lang/api](packages/api/) | HTTP framework (Sinatra-style routing, 37 validators) | ~1,050 |
312
- | [@rip-lang/server](packages/server/) | Multi-worker app server (hot reload, HTTPS, mDNS) | ~1,210 |
313
- | [@rip-lang/db](packages/db/) | DuckDB server with official UI (pure Bun FFI) | ~1,740 |
312
+ | Package | Purpose |
313
+ |---------|---------|
314
+ | [@rip-lang/ui](packages/ui/) | Zero-build reactive web framework (VFS, router, components) |
315
+ | [@rip-lang/api](packages/api/) | HTTP framework (Sinatra-style routing, 37 validators) |
316
+ | [@rip-lang/server](packages/server/) | Multi-worker app server (hot reload, HTTPS, mDNS) |
317
+ | [@rip-lang/db](packages/db/) | DuckDB server with official UI (pure Bun FFI) |
318
+ | [@rip-lang/swarm](packages/swarm/) | Parallel job runner with worker pool |
319
+ | [@rip-lang/csv](packages/csv/) | CSV parser + writer |
320
+ | [@rip-lang/schema](packages/schema/) | ORM + validation |
321
+ | [VS Code Extension](packages/vscode/) | Syntax highlighting, type intelligence, source maps |
314
322
 
315
323
  ```bash
316
324
  bun add -g @rip-lang/db # Installs everything (rip-lang + api + db)
@@ -348,7 +356,7 @@ rip file.rip # Run
348
356
  rip -c file.rip # Compile
349
357
  rip -t file.rip # Tokens
350
358
  rip -s file.rip # S-expressions
351
- bun run test # 1073 tests
359
+ bun run test # 1140 tests
352
360
  bun run parser # Rebuild parser
353
361
  bun run browser # Build browser bundle
354
362
  ```
package/bin/rip CHANGED
@@ -26,7 +26,7 @@ Usage:
26
26
  Options:
27
27
  -c, --compile Show compiled JavaScript output
28
28
  -d, --dts Generate .d.ts type declaration file
29
- -m, --map Generate .js.map source map file
29
+ -m, --map Embed inline source map in compiled output
30
30
  -h, --help Show this help message
31
31
  -o, --output <file> Write JavaScript to file
32
32
  -q, --quiet Suppress headers
@@ -47,7 +47,7 @@ Examples:
47
47
  rip -s -c example.rip # Show s-expressions AND JavaScript
48
48
  rip -s -t -c example.rip # Show everything (full debug mode)
49
49
  rip -d example.rip # Generate example.d.ts
50
- rip -m example.rip # Generate example.js.map
50
+ rip -m example.rip # Compile with inline source map
51
51
  rip -cd example.rip # Compile JS and generate .d.ts
52
52
  rip -q -c example.rip # Just the JS, no headers (for piping)
53
53
  rip -w # Launch browser REPL (auto-opens)
@@ -156,8 +156,7 @@ async function main() {
156
156
  showSExpr,
157
157
  quiet,
158
158
  types: generateDts ? 'emit' : undefined,
159
- sourceMap: generateMap ? true : undefined,
160
- filename: null, // set below after determining input file
159
+ sourceMap: generateMap ? 'inline' : undefined,
161
160
  };
162
161
 
163
162
  // Find input file and output file from ripOptions only
@@ -243,11 +242,6 @@ async function main() {
243
242
  source = readFileSync(inputFile, 'utf-8');
244
243
  }
245
244
 
246
- // Set filename for source map generation
247
- if (inputFile) {
248
- options.filename = inputFile.replace(/\.rip$/, '');
249
- }
250
-
251
245
  // Compile
252
246
  const compiler = new Compiler(options);
253
247
  const result = compiler.compile(source);
@@ -288,22 +282,6 @@ async function main() {
288
282
  }
289
283
  }
290
284
 
291
- // Write .js.map file
292
- if (generateMap && result.map) {
293
- if (inputFile) {
294
- let mapFile = inputFile.replace(/\.rip$/, '.js.map');
295
- writeFileSync(mapFile, result.map, 'utf-8');
296
- if (!options.quiet) {
297
- console.log(`Generated ${mapFile}`);
298
- }
299
- } else {
300
- // stdin — print source map to stdout
301
- if (!options.quiet) {
302
- console.log(`// == Source map == //\n`);
303
- }
304
- console.log(result.map);
305
- }
306
- }
307
285
  } catch (error) {
308
286
  console.error('Compilation Error:', error.message);
309
287
  if (error.stack) {
@@ -43,7 +43,7 @@ class BinaryOp {
43
43
  ["+", left, right] // That's it!
44
44
  ```
45
45
 
46
- **Result:** CoffeeScript's compiler is 17,760 LOC. Rip's is ~7,700 LOC — smaller, yet includes a complete reactive runtime.
46
+ **Result:** CoffeeScript's compiler is 17,760 LOC. Rip's is ~10,300 LOC — smaller, yet includes a complete reactive runtime, type system, component system, and source maps.
47
47
 
48
48
  > **Transform the IR (s-expressions), not the output (strings).**
49
49
 
@@ -75,7 +75,7 @@ console.log(code);
75
75
  | Dependencies | Multiple | **Zero** |
76
76
  | Parser generator | External (Jison) | **Built-in (Solar)** |
77
77
  | Self-hosting | No | **Yes** |
78
- | Total LOC | 17,760 | ~7,700 |
78
+ | Total LOC | 17,760 | ~10,300 |
79
79
 
80
80
  ## Design Principles
81
81
 
@@ -91,7 +91,7 @@ console.log(code);
91
91
 
92
92
  ```
93
93
  Source Code → Lexer → emitTypes → Parser → S-Expressions → Codegen → JavaScript
94
- (1,866) (types.js) (356) (simple arrays) (3,219) (ES2022)
94
+ (1,867) (types.js) (357) (arrays + .loc) (3,292) + source map
95
95
 
96
96
  file.d.ts (when types: "emit")
97
97
  ```
@@ -100,13 +100,15 @@ Source Code → Lexer → emitTypes → Parser → S-Expressions → C
100
100
 
101
101
  | File | Purpose | Lines | Modify? |
102
102
  |------|---------|-------|---------|
103
- | `src/lexer.js` | Lexer + Rewriter | 1,866 | Yes |
104
- | `src/compiler.js` | Compiler + Code Generator | 3,219 | Yes |
105
- | `src/types.js` | Type System (lexer sidecar) | 718 | Yes |
106
- | `src/components.js` | Component System (compiler sidecar) | ~1,240 | Yes |
107
- | `src/parser.js` | Generated parser | 356 | No (auto-gen) |
108
- | `src/grammar/grammar.rip` | Grammar specification | 934 | Yes (carefully) |
109
- | `src/grammar/solar.rip` | Parser generator | 1,001 | No |
103
+ | `src/lexer.js` | Lexer + Rewriter | 1,867 | Yes |
104
+ | `src/compiler.js` | Compiler + Code Generator | 3,292 | Yes |
105
+ | `src/types.js` | Type System (lexer sidecar) | 719 | Yes |
106
+ | `src/components.js` | Component System (compiler sidecar) | 1,240 | Yes |
107
+ | `src/sourcemaps.js` | Source Map V3 Generator | 122 | Yes |
108
+ | `src/tags.js` | HTML Tag Classification | 63 | Yes |
109
+ | `src/parser.js` | Generated parser | 357 | No (auto-gen) |
110
+ | `src/grammar/grammar.rip` | Grammar specification | 935 | Yes (carefully) |
111
+ | `src/grammar/solar.rip` | Parser generator | 916 | No |
110
112
 
111
113
  ## Example Flow
112
114
 
@@ -271,7 +273,7 @@ S-expressions are simple arrays that serve as Rip's intermediate representation
271
273
 
272
274
  # 4. Lexer & Rewriter
273
275
 
274
- The lexer (`src/lexer.js`) is a clean reimplementation that replaces the old lexer (3,260 lines) with ~1,550 lines producing the same token vocabulary the parser expects.
276
+ The lexer (`src/lexer.js`) is a clean reimplementation that replaces the old lexer (3,260 lines) with ~1,870 lines producing the same token vocabulary the parser expects.
275
277
 
276
278
  ## Architecture
277
279
 
@@ -435,7 +437,7 @@ REGEX tokens store `delimiter` and optional `heregex` flags in `token.data`.
435
437
 
436
438
  # 6. Compiler
437
439
 
438
- The compiler (`src/compiler.js`) is a clean reimplementation replacing the old compiler (6,016 lines) with ~3,150 lines producing identical JavaScript output.
440
+ The compiler (`src/compiler.js`) is a clean reimplementation replacing the old compiler (6,016 lines) with ~3,290 lines producing identical JavaScript output.
439
441
 
440
442
  ## Structure
441
443
 
@@ -479,7 +481,7 @@ The `Compiler` class's lexer adapter reconstructs `new String()` wrapping from t
479
481
 
480
482
  | Area | Old lines | New lines | Reduction |
481
483
  |------|-----------|-----------|-----------|
482
- | Total file | 6,016 | ~3,150 | **48%** |
484
+ | Total file | 6,016 | ~3,290 | **45%** |
483
485
  | Body generation | ~500 | ~200 | 60% |
484
486
  | Variable collection | ~230 | ~100 | 57% |
485
487
  | Helper methods | ~600 | ~250 | 58% |
@@ -490,7 +492,7 @@ The `Compiler` class's lexer adapter reconstructs `new String()` wrapping from t
490
492
 
491
493
  **Solar** is a complete SLR(1) parser generator included with Rip — written in Rip, compiled by Rip, zero external dependencies.
492
494
 
493
- **Location:** `src/grammar/solar.rip` (1,001 lines)
495
+ **Location:** `src/grammar/solar.rip` (916 lines)
494
496
 
495
497
  ## Grammar Syntax
496
498
 
@@ -529,7 +531,7 @@ Parenthetical: [
529
531
  | Parse time | 12,500ms | ~50ms |
530
532
  | Dependencies | Many | Zero |
531
533
  | Self-hosting | No | Yes |
532
- | Code size | 2,285 LOC | 1,001 LOC |
534
+ | Code size | 2,285 LOC | 916 LOC |
533
535
 
534
536
  After modifying `src/grammar/grammar.rip`:
535
537
 
@@ -558,17 +560,10 @@ rip> .sexp # Toggle s-expression display
558
560
  rip> .js # Toggle JS display
559
561
  ```
560
562
 
561
- Compare old and new compilers across all test suites:
562
-
563
- ```bash
564
- bun src/compare-compilers.js
565
- ```
566
-
567
563
  ---
568
564
 
569
565
  # 9. Future Work
570
566
 
571
- - Comment preservation for source maps
572
567
  - Parser update to read `.data` directly instead of `new String()` properties
573
568
  - Once parser supports `.data`, the `meta()`/`str()` helpers become trivial to update
574
569
 
@@ -581,4 +576,4 @@ bun src/compare-compilers.js
581
576
 
582
577
  ---
583
578
 
584
- *Rip 3.0 — 1,130 tests passing — Zero dependencies — Self-hosting — ~8,800 LOC*
579
+ *Rip 3.4 — 1,140 tests passing — Zero dependencies — Self-hosting — ~10,300 LOC*
package/docs/RIP-LANG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rip 3.0 Language Reference
2
2
 
3
- Rip is a modern reactive language that compiles to ES2022 JavaScript. It combines CoffeeScript's elegant syntax with built-in reactivity primitives. Zero dependencies, self-hosting, ~7,700 LOC.
3
+ Rip is a modern reactive language that compiles to ES2022 JavaScript. It combines CoffeeScript's elegant syntax with built-in reactivity primitives. Zero dependencies, self-hosting, ~10,300 LOC.
4
4
 
5
5
  ---
6
6
 
@@ -1163,4 +1163,4 @@ count = 10 # Logs: "Count: 10, Doubled: 20"
1163
1163
 
1164
1164
  ---
1165
1165
 
1166
- *Rip 3.0 — 1,073 tests passing — Zero dependencies — Self-hosting — ~7,700 LOC*
1166
+ *Rip 3.4 — 1,140 tests passing — Zero dependencies — Self-hosting — ~10,300 LOC*
@@ -3983,7 +3983,7 @@ if (typeof globalThis !== 'undefined') {
3983
3983
  };
3984
3984
  }
3985
3985
 
3986
- // src/sourcemap.js
3986
+ // src/sourcemaps.js
3987
3987
  var B64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3988
3988
  function vlqEncode(value) {
3989
3989
  let result = "";
@@ -7505,8 +7505,9 @@ class Compiler {
7505
7505
  let map = sourceMap ? sourceMap.toJSON() : null;
7506
7506
  let reverseMap = sourceMap ? sourceMap.toReverseMap() : null;
7507
7507
  if (map && this.options.sourceMap === "inline") {
7508
+ let b64 = typeof Buffer !== "undefined" ? Buffer.from(map).toString("base64") : btoa(map);
7508
7509
  code += `
7509
- //# sourceMappingURL=data:application/json;base64,${btoa(map)}`;
7510
+ //# sourceMappingURL=data:application/json;base64,${b64}`;
7510
7511
  } else if (map && this.options.filename) {
7511
7512
  code += `
7512
7513
  //# sourceMappingURL=${this.options.filename}.js.map`;
@@ -7535,8 +7536,8 @@ function getComponentRuntime() {
7535
7536
  return new CodeGenerator({}).getComponentRuntime();
7536
7537
  }
7537
7538
  // src/browser.js
7538
- var VERSION = "3.4.2";
7539
- var BUILD_DATE = "2026-02-09@07:09:22GMT";
7539
+ var VERSION = "3.4.4";
7540
+ var BUILD_DATE = "2026-02-09@07:32:49GMT";
7540
7541
  var dedent = (s) => {
7541
7542
  const m = s.match(/^[ \t]*(?=\S)/gm);
7542
7543
  const i = Math.min(...(m || []).map((x) => x.length));
@@ -523,6 +523,6 @@ if (typeof globalThis !== 'undefined') {
523
523
  `),W=U.findIndex((R)=>R==="__DATA__");if(W!==-1){let R=U.slice(W+1);F=R.length>0?R.join(`
524
524
  `)+`
525
525
  `:"",Y=U.slice(0,W).join(`
526
- `)}let $=new v().tokenize(Y);if(this.options.showTokens)$.forEach((R)=>console.log(`${R[0].padEnd(12)} ${JSON.stringify(R[1])}`)),console.log();let Q=null;if(this.options.types==="emit"||this.options.types==="check"||this.options.types===!0)Q=Q1($);$=$.filter((R)=>R[0]!=="TYPE_DECL");while($.length>0&&$[0][0]==="TERMINATOR")$.shift();if($.every((R)=>R[0]==="TERMINATOR"))return{tokens:$,sexpr:["program"],code:"",dts:Q,data:F,reactiveVars:{}};g.lexer={tokens:$,pos:0,setInput:function(){},lex:function(){if(this.pos>=this.tokens.length)return 1;let R=this.tokens[this.pos++],M=R[1];if(R.data)M=new String(M),Object.assign(M,R.data);return this.text=M,this.loc=R.loc,R[0]}};let D;try{D=g.parse(Y)}catch(R){if(/\?\s*\([^)]*\?[^)]*:[^)]*\)\s*:/.test(Y)||/\?\s+\w+\s+\?\s+/.test(Y))throw Error("Nested ternary operators are not supported. Use if/else statements instead.");throw R}if(this.options.showSExpr)console.log(y(D,0,!0)),console.log();let Z=null;if(this.options.sourceMap){let R=(this.options.filename||"output")+".js",M=this.options.filename||"input.rip";Z=new Y1(R,M,Y)}let X=new V({dataSection:F,skipReactiveRuntime:this.options.skipReactiveRuntime,skipComponentRuntime:this.options.skipComponentRuntime,reactiveVars:this.options.reactiveVars,sourceMap:Z}),J=X.compile(D),K=Z?Z.toJSON():null,z=Z?Z.toReverseMap():null;if(K&&this.options.sourceMap==="inline")J+=`
527
- //# sourceMappingURL=data:application/json;base64,${btoa(K)}`;else if(K&&this.options.filename)J+=`
528
- //# sourceMappingURL=${this.options.filename}.js.map`;return{tokens:$,sexpr:D,code:J,dts:Q,map:K,reverseMap:z,data:F,reactiveVars:X.reactiveVars}}compileToJS(Y){return this.compile(Y).code}compileToSExpr(Y){return this.compile(Y).sexpr}}E1(V);V.prototype.generateEnum=Z1;function H2(Y,F={}){return new r(F).compile(Y)}function t(Y,F={}){return new r(F).compileToJS(Y)}function O2(){return new V({}).getReactiveRuntime()}function q2(){return new V({}).getComponentRuntime()}var v2="3.4.2",g2="2026-02-09@07:09:22GMT",P2=(Y)=>{let F=Y.match(/^[ \t]*(?=\S)/gm),U=Math.min(...(F||[]).map((W)=>W.length));return Y.replace(RegExp(`^[ ]{${U}}`,"gm"),"").trim()};async function T1(){let Y=document.querySelectorAll('script[type="text/rip"]');for(let F of Y){if(F.hasAttribute("data-rip-processed"))continue;try{let U=P2(F.textContent),W=t(U);(0,eval)(W),F.setAttribute("data-rip-processed","true")}catch(U){console.error("Error compiling Rip script:",U),console.error("Script content:",F.textContent)}}}if(typeof document<"u")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",T1);else T1();function _2(Y){try{let U=t(Y).replace(/^let\s+[^;]+;\s*\n\s*/m,"");U=U.replace(/^const\s+/gm,"var ");let W=(0,eval)(U);if(W!==void 0)globalThis._=W;return W}catch(F){console.error("Rip compilation error:",F.message);return}}if(typeof globalThis<"u")globalThis.rip=_2;export{_2 as rip,T1 as processRipScripts,g as parser,O2 as getReactiveRuntime,q2 as getComponentRuntime,y as formatSExpr,t as compileToJS,H2 as compile,v2 as VERSION,v as Lexer,r as Compiler,V as CodeGenerator,g2 as BUILD_DATE};
526
+ `)}let $=new v().tokenize(Y);if(this.options.showTokens)$.forEach((R)=>console.log(`${R[0].padEnd(12)} ${JSON.stringify(R[1])}`)),console.log();let Q=null;if(this.options.types==="emit"||this.options.types==="check"||this.options.types===!0)Q=Q1($);$=$.filter((R)=>R[0]!=="TYPE_DECL");while($.length>0&&$[0][0]==="TERMINATOR")$.shift();if($.every((R)=>R[0]==="TERMINATOR"))return{tokens:$,sexpr:["program"],code:"",dts:Q,data:F,reactiveVars:{}};g.lexer={tokens:$,pos:0,setInput:function(){},lex:function(){if(this.pos>=this.tokens.length)return 1;let R=this.tokens[this.pos++],M=R[1];if(R.data)M=new String(M),Object.assign(M,R.data);return this.text=M,this.loc=R.loc,R[0]}};let D;try{D=g.parse(Y)}catch(R){if(/\?\s*\([^)]*\?[^)]*:[^)]*\)\s*:/.test(Y)||/\?\s+\w+\s+\?\s+/.test(Y))throw Error("Nested ternary operators are not supported. Use if/else statements instead.");throw R}if(this.options.showSExpr)console.log(y(D,0,!0)),console.log();let Z=null;if(this.options.sourceMap){let R=(this.options.filename||"output")+".js",M=this.options.filename||"input.rip";Z=new Y1(R,M,Y)}let X=new V({dataSection:F,skipReactiveRuntime:this.options.skipReactiveRuntime,skipComponentRuntime:this.options.skipComponentRuntime,reactiveVars:this.options.reactiveVars,sourceMap:Z}),J=X.compile(D),K=Z?Z.toJSON():null,z=Z?Z.toReverseMap():null;if(K&&this.options.sourceMap==="inline"){let R=typeof Buffer<"u"?Buffer.from(K).toString("base64"):btoa(K);J+=`
527
+ //# sourceMappingURL=data:application/json;base64,${R}`}else if(K&&this.options.filename)J+=`
528
+ //# sourceMappingURL=${this.options.filename}.js.map`;return{tokens:$,sexpr:D,code:J,dts:Q,map:K,reverseMap:z,data:F,reactiveVars:X.reactiveVars}}compileToJS(Y){return this.compile(Y).code}compileToSExpr(Y){return this.compile(Y).sexpr}}E1(V);V.prototype.generateEnum=Z1;function H2(Y,F={}){return new r(F).compile(Y)}function t(Y,F={}){return new r(F).compileToJS(Y)}function O2(){return new V({}).getReactiveRuntime()}function q2(){return new V({}).getComponentRuntime()}var v2="3.4.4",g2="2026-02-09@07:32:49GMT",P2=(Y)=>{let F=Y.match(/^[ \t]*(?=\S)/gm),U=Math.min(...(F||[]).map((W)=>W.length));return Y.replace(RegExp(`^[ ]{${U}}`,"gm"),"").trim()};async function T1(){let Y=document.querySelectorAll('script[type="text/rip"]');for(let F of Y){if(F.hasAttribute("data-rip-processed"))continue;try{let U=P2(F.textContent),W=t(U);(0,eval)(W),F.setAttribute("data-rip-processed","true")}catch(U){console.error("Error compiling Rip script:",U),console.error("Script content:",F.textContent)}}}if(typeof document<"u")if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",T1);else T1();function _2(Y){try{let U=t(Y).replace(/^let\s+[^;]+;\s*\n\s*/m,"");U=U.replace(/^const\s+/gm,"var ");let W=(0,eval)(U);if(W!==void 0)globalThis._=W;return W}catch(F){console.error("Rip compilation error:",F.message);return}}if(typeof globalThis<"u")globalThis.rip=_2;export{_2 as rip,T1 as processRipScripts,g as parser,O2 as getReactiveRuntime,q2 as getComponentRuntime,y as formatSExpr,t as compileToJS,H2 as compile,v2 as VERSION,v as Lexer,r as Compiler,V as CodeGenerator,g2 as BUILD_DATE};
Binary file
package/docs/index.html CHANGED
@@ -191,7 +191,7 @@
191
191
  display: flex;
192
192
  align-items: flex-start;
193
193
  gap: 4px;
194
- background: #1e1e1e;
194
+ background: #2d2d30;
195
195
  padding: 8px 10px;
196
196
  border: 1px solid #3e3e42;
197
197
  border-radius: 4px;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rip-lang",
3
- "version": "3.4.2",
3
+ "version": "3.4.4",
4
4
  "description": "A modern language that compiles to JavaScript",
5
5
  "type": "module",
6
6
  "main": "src/compiler.js",
package/src/compiler.js CHANGED
@@ -12,7 +12,7 @@ import { Lexer } from './lexer.js';
12
12
  import { parser } from './parser.js';
13
13
  import { installComponentSupport } from './components.js';
14
14
  import { emitTypes, generateEnum } from './types.js';
15
- import { SourceMapGenerator } from './sourcemap.js';
15
+ import { SourceMapGenerator } from './sourcemaps.js';
16
16
 
17
17
  // =============================================================================
18
18
  // Metadata helpers — isolate all new String() awareness here
@@ -3239,7 +3239,8 @@ export class Compiler {
3239
3239
  let map = sourceMap ? sourceMap.toJSON() : null;
3240
3240
  let reverseMap = sourceMap ? sourceMap.toReverseMap() : null;
3241
3241
  if (map && this.options.sourceMap === 'inline') {
3242
- code += `\n//# sourceMappingURL=data:application/json;base64,${btoa(map)}`;
3242
+ let b64 = typeof Buffer !== 'undefined' ? Buffer.from(map).toString('base64') : btoa(map);
3243
+ code += `\n//# sourceMappingURL=data:application/json;base64,${b64}`;
3243
3244
  } else if (map && this.options.filename) {
3244
3245
  code += `\n//# sourceMappingURL=${this.options.filename}.js.map`;
3245
3246
  }
File without changes