rip-lang 2.9.2 → 3.0.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/CHANGELOG.md CHANGED
@@ -7,6 +7,49 @@ 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.0.0] - 2026-02-07
11
+
12
+ ### Complete Rewrite
13
+
14
+ Rip 3.0 is a ground-up rewrite of the entire compiler pipeline. Every component is new:
15
+
16
+ - **Lexer + Rewriter** (`src/lexer.js`) — 1,542 LOC, down from 3,260
17
+ - **Compiler + Codegen** (`src/compiler.js`) — 3,148 LOC, down from 6,016
18
+ - **Grammar** (`src/grammar/grammar.rip`) — 887 LOC, updated for new syntax
19
+ - **Parser** (`src/parser.js`) — 352 LOC, regenerated from new grammar
20
+ - **REPL** (`src/repl.js`) — 654 LOC, rewritten for the new pipeline
21
+ - **Browser** (`src/browser.js`) — 79 LOC, rewritten for the new pipeline
22
+ - **CLI** (`bin/rip`) — 267 LOC, updated to use the new pipeline
23
+ - **Total**: ~7,700 LOC (down from ~10,100)
24
+
25
+ ### Language Changes
26
+
27
+ #### Removed
28
+ - Postfix spread/rest (`x...`) — use prefix `...x` (ES6)
29
+ - Prototype access (`x::y`, `x?::y`) — use `.prototype` or class syntax
30
+ - Soak call sugar (`fn?(arg)`) — use `fn?.(arg)` (ES6 optional call)
31
+ - Soak index sugar (`arr?[i]`) — use `arr?.[i]` (ES6 optional index)
32
+ - `is not` contraction — use `isnt`
33
+
34
+ #### Added
35
+ - JS-style ternary operator: `x ? a : b`
36
+ - `for...as` iteration: `for x as iterable` (replaces `for x from iterable`)
37
+ - `as!` async shorthand: `for x as! iterable` (shorthand for `for await x as iterable`)
38
+
39
+ #### Kept
40
+ - Existence check: `x?` compiles to `(x != null)`
41
+ - All reactive operators: `:=`, `~=`, `~>`, `=!`
42
+ - Dammit operator: `x!` compiles to `await x()`
43
+ - Optional chaining: `?.`, `?.[]`, `?.()` (ES6 dot-form only)
44
+ - Nullish coalescing: `??`
45
+ - All other CoffeeScript-compatible syntax
46
+
47
+ ### Tests
48
+ - 1,048 tests passing (100%)
49
+ - 25 test files across all language features
50
+
51
+ ---
52
+
10
53
  ## [2.9.0] - 2026-02-05
11
54
 
12
55
  ### Compiler Fix
@@ -220,8 +263,8 @@ Counter.new().mount("#app") # Selector string support
220
263
  ### 📚 Documentation Overhaul
221
264
 
222
265
  **Consolidated Documentation** - 13 files merged into 4 main docs:
223
- - `docs/GUIDE.md` - Language features, reactivity, templates, components
224
- - `docs/INTERNALS.md` - Compiler architecture, S-expressions, Solar
266
+ - `docs/RIP-LANG.md` - Language reference
267
+ - `docs/RIP-INTERNALS.md` - Compiler architecture, S-expressions, Solar
225
268
  - `docs/PHILOSOPHY.md` - Design principles, CoffeeScript comparison
226
269
  - `docs/BROWSER.md` - Browser usage, REPL, deployment
227
270
 
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-2.9.0-blue.svg" alt="Version"></a>
12
+ <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/version-3.0.0-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-1115%2F1115-brightgreen.svg" alt="Tests"></a>
14
+ <a href="#"><img src="https://img.shields.io/badge/tests-1048%2F1048-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 10,000 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 7,700 lines of code.
21
21
 
22
22
  > **No imports. No hooks. No dependency arrays. Just write code.**
23
23
 
@@ -28,6 +28,10 @@ squares = (x * x for x in [1..10]) # List comprehension
28
28
 
29
29
  str =~ /Hello, (\w+)/ # Regex match
30
30
  log "Found: #{_[1]}" # Captures in _[1], _[2], etc.
31
+
32
+ get '/users/:id' -> # RESTful API endpoint, comma-less
33
+ name = read 'name', 'string!' # Required string
34
+ age = read 'age' , [0, 105] # Simple numeric validation
31
35
  ```
32
36
 
33
37
  ---
@@ -103,6 +107,22 @@ user?.profile?.name # Optional chaining
103
107
  data = fetchData! # Await shorthand
104
108
  ```
105
109
 
110
+ ### Iteration
111
+
112
+ ```coffee
113
+ for item in [1, 2, 3] # Array iteration (for-in)
114
+ console.log item
115
+
116
+ for key, value of object # Object iteration (for-of)
117
+ console.log "#{key}: #{value}"
118
+
119
+ for x as iterable # ES6 for-of on any iterable
120
+ console.log x
121
+
122
+ for x as! asyncIterable # Async iteration shorthand
123
+ console.log x # Equivalent to: for await x as asyncIterable
124
+ ```
125
+
106
126
  ### Reactivity
107
127
 
108
128
  State, computed values, and effects as language operators:
@@ -117,32 +137,25 @@ State, computed values, and effects as language operators:
117
137
 
118
138
  ---
119
139
 
120
- ## New Operators
140
+ ## Operators
121
141
 
122
142
  | Operator | Example | What it does |
123
143
  |----------|---------|--------------|
124
144
  | `!` (dammit) | `fetchData!` | Calls AND awaits |
125
145
  | `!` (void) | `def process!` | Suppresses implicit return |
126
146
  | `!?` (otherwise) | `val !? 5` | Default only if `undefined` |
147
+ | `?` (existence) | `x?` | True if `x != null` |
127
148
  | `?:` (ternary) | `x > 0 ? 'yes' : 'no'` | JS-style ternary expression |
128
- | `?.` `?[]` | `a?.b` `a?[0]` | Optional chaining (both styles) |
129
- | `...` (spread) | `[...rest, last]` | Spread at start or end (JS: end only) |
130
- | `//` | `7 // 2` | Floor division 3 |
131
- | `%%` | `-1 %% 3` | True modulo → 2 |
149
+ | `?.` `?.[]` `?.()` | `a?.b` `a?.[0]` `a?.()` | Optional chaining (ES6) |
150
+ | `??` | `a ?? b` | Nullish coalescing |
151
+ | `...` (spread) | `[...items, last]` | Prefix spread (ES6) |
152
+ | `//` | `7 // 2` | Floor division |
153
+ | `%%` | `-1 %% 3` | True modulo |
132
154
  | `=~` | `str =~ /Hello, (\w+)/` | Match (captures in `_`) |
133
155
  | `[//, n]` | `str[/Hello, (\w+)/, 1]` | Extract capture n |
134
156
  | `.new()` | `Dog.new()` | Ruby-style constructor |
135
157
  | `or return` | `x = get() or return err` | Guard clause (Ruby-style) |
136
- | `?? throw` | `x = get() ?? throw err` | Nullish guard (null/undefined only) |
137
-
138
- **Optional chaining** — Both CoffeeScript and ES6 styles are supported:
139
-
140
- | Syntax | Style | Compiles to |
141
- |--------|-------|-------------|
142
- | `obj?[0]` | CoffeeScript | `(obj != null ? obj[0] : undefined)` |
143
- | `fn?(arg)` | CoffeeScript | `(typeof fn === 'function' ? fn(arg) : undefined)` |
144
- | `obj?.[0]` | ES6/JS | `obj?.[0]` |
145
- | `fn?.(arg)` | ES6/JS | `fn?.(arg)` |
158
+ | `?? throw` | `x = get() ?? throw err` | Nullish guard |
146
159
 
147
160
  ### Heredoc & Heregex
148
161
 
@@ -154,7 +167,7 @@ html = '''
154
167
  <p>Hello</p>
155
168
  </div>
156
169
  '''
157
- # Closing ''' is at column 4 (same as content) no leading whitespace
170
+ # Closing ''' at column 4 (same as content) no leading whitespace
158
171
  # Result: "<div>\n <p>Hello</p>\n</div>"
159
172
 
160
173
  html = '''
@@ -162,21 +175,10 @@ html = '''
162
175
  <p>Hello</p>
163
176
  </div>
164
177
  '''
165
- # Closing ''' is at column 2 (2 less than content) → 2 spaces of leading whitespace
178
+ # Closing ''' at column 2 2 spaces of leading whitespace preserved
166
179
  # Result: " <div>\n <p>Hello</p>\n </div>"
167
180
  ```
168
181
 
169
- Use `"""` for interpolation, `'''` for literal strings. The same margin rule applies to both:
170
-
171
- ```coffee
172
- name = "World"
173
- msg = """
174
- Hello, #{name}!
175
- Welcome to Rip.
176
- """
177
- # Result: "Hello, World!\nWelcome to Rip."
178
- ```
179
-
180
182
  **Heregex** — Extended regex with comments and whitespace:
181
183
 
182
184
  ```coffee
@@ -208,9 +210,9 @@ Rip's reactivity is framework-agnostic — use it with React, Vue, Svelte, or va
208
210
  | **Reactivity** | None | Built-in |
209
211
  | **Dependencies** | Multiple | Zero |
210
212
  | **Self-hosting** | No | Yes |
211
- | **Lexer** | 3,558 LOC | 3,250 LOC |
212
- | **Compiler** | 10,346 LOC | 5,878 LOC |
213
- | **Total** | 17,760 LOC | ~10,100 LOC |
213
+ | **Lexer** | 3,558 LOC | 1,542 LOC |
214
+ | **Compiler** | 10,346 LOC | 3,148 LOC |
215
+ | **Total** | 17,760 LOC | ~7,700 LOC |
214
216
 
215
217
  Smaller codebase, modern output, built-in reactivity.
216
218
 
@@ -218,7 +220,7 @@ Smaller codebase, modern output, built-in reactivity.
218
220
 
219
221
  ## Browser
220
222
 
221
- Run Rip directly in the browser (51KB compressed):
223
+ Run Rip directly in the browser:
222
224
 
223
225
  ```html
224
226
  <script src="https://shreeve.github.io/rip-lang/docs/dist/rip.browser.min.js"></script>
@@ -236,12 +238,23 @@ Run Rip directly in the browser (51KB compressed):
236
238
  ## Architecture
237
239
 
238
240
  ```
239
- SourceLexerParserS-ExpressionsCodegenJavaScript
240
- ["=", "x", 42]
241
+ Source -> Lexer -> Parser -> S-Expressions -> Codegen -> JavaScript
242
+ (1,542) (352) ["=", "x", 42] (3,148)
241
243
  ```
242
244
 
243
245
  Simple arrays instead of AST node classes. The compiler is self-hosting — `bun run parser` rebuilds from source.
244
246
 
247
+ | Component | File | Lines |
248
+ |-----------|------|-------|
249
+ | Lexer + Rewriter | `src/lexer.js` | 1,542 |
250
+ | Compiler + Codegen | `src/compiler.js` | 3,148 |
251
+ | Parser (generated) | `src/parser.js` | 352 |
252
+ | Grammar | `src/grammar/grammar.rip` | 887 |
253
+ | Parser Generator | `src/grammar/solar.rip` | 1,001 |
254
+ | REPL | `src/repl.js` | 654 |
255
+ | Browser Entry | `src/browser.js` | 79 |
256
+ | **Total** | | **7,663** |
257
+
245
258
  ---
246
259
 
247
260
  ## The Rip Stack
@@ -290,7 +303,7 @@ rip file.rip # Run
290
303
  rip -c file.rip # Compile
291
304
  rip -t file.rip # Tokens
292
305
  rip -s file.rip # S-expressions
293
- bun run test # 1115 tests
306
+ bun run test # 1048 tests
294
307
  bun run parser # Rebuild parser
295
308
  bun run browser # Build browser bundle
296
309
  ```
@@ -301,9 +314,9 @@ bun run browser # Build browser bundle
301
314
 
302
315
  | Guide | Description |
303
316
  |-------|-------------|
304
- | [docs/GUIDE.md](docs/GUIDE.md) | Language guide |
305
- | [docs/REACTIVITY.md](docs/REACTIVITY.md) | Reactivity deep dive |
306
- | [docs/INTERNALS.md](docs/INTERNALS.md) | Compiler architecture |
317
+ | [docs/RIP-LANG.md](docs/RIP-LANG.md) | Language reference |
318
+ | [docs/RIP-REACTIVITY.md](docs/RIP-REACTIVITY.md) | Reactivity deep dive |
319
+ | [docs/RIP-INTERNALS.md](docs/RIP-INTERNALS.md) | Compiler internals |
307
320
  | [packages/](packages/README.md) | Full-stack packages |
308
321
  | [CONTRIBUTING.md](CONTRIBUTING.md) | How to contribute |
309
322
 
@@ -323,7 +336,7 @@ Everything included: compiler, parser generator, REPL, browser bundle, test fram
323
336
 
324
337
  > *Simplicity scales.*
325
338
 
326
- Simple IR (S-expressions), clear pipeline (lex parse generate), minimal code, comprehensive tests.
339
+ Simple IR (S-expressions), clear pipeline (lex -> parse -> generate), minimal code, comprehensive tests.
327
340
 
328
341
  ---
329
342