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 +45 -2
- package/README.md +55 -42
- package/docs/RIP-INTERNALS.md +576 -0
- package/docs/RIP-LANG.md +1126 -0
- package/docs/{TYPES.md → RIP-TYPES.md} +3 -3
- package/docs/dist/rip.browser.js +3278 -5474
- package/docs/dist/rip.browser.min.js +248 -332
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/package.json +1 -1
- package/src/browser.js +3 -20
- package/src/compiler.js +1683 -4550
- package/src/grammar/grammar.rip +529 -488
- package/src/lexer.js +1318 -3035
- package/src/parser.js +212 -220
- package/src/repl.js +16 -9
- package/docs/BROWSER.md +0 -990
- package/docs/GUIDE.md +0 -636
- package/docs/INTERNALS.md +0 -857
- package/docs/RATIONALE.md +0 -180
- package/docs/examples/README.md +0 -33
- package/docs/examples/arrows.rip +0 -74
- package/docs/examples/async-await.rip +0 -59
- package/docs/examples/existential.rip +0 -86
- package/docs/examples/fibonacci.rip +0 -12
- package/docs/examples/module.rip +0 -48
- package/docs/examples/ranges.rip +0 -45
- package/docs/examples/reactivity.rip +0 -48
- package/docs/examples/switch.rip +0 -50
- package/docs/examples/ternary.rip +0 -36
- /package/docs/{REACTIVITY.md → RIP-REACTIVITY.md} +0 -0
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/
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
##
|
|
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
|
-
| `?.`
|
|
129
|
-
|
|
|
130
|
-
|
|
|
131
|
-
|
|
|
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
|
|
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 '''
|
|
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 '''
|
|
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 |
|
|
212
|
-
| **Compiler** | 10,346 LOC |
|
|
213
|
-
| **Total** | 17,760 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
|
|
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
|
-
Source
|
|
240
|
-
|
|
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 #
|
|
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/
|
|
305
|
-
| [docs/REACTIVITY.md](docs/REACTIVITY.md) | Reactivity deep dive |
|
|
306
|
-
| [docs/INTERNALS.md](docs/INTERNALS.md) | Compiler
|
|
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
|
|
339
|
+
Simple IR (S-expressions), clear pipeline (lex -> parse -> generate), minimal code, comprehensive tests.
|
|
327
340
|
|
|
328
341
|
---
|
|
329
342
|
|