rip-lang 3.13.92 → 3.13.94

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +3 -3
  3. package/bin/rip +11 -1
  4. package/docs/AGENTS.md +43 -0
  5. package/docs/RIP-LANG.md +3 -3
  6. package/docs/RIP-TYPES.md +72 -91
  7. package/docs/charts.html +15 -15
  8. package/docs/dist/rip.js +142 -38
  9. package/docs/dist/rip.min.js +174 -174
  10. package/docs/dist/rip.min.js.br +0 -0
  11. package/docs/index.html +2 -2
  12. package/package.json +1 -1
  13. package/src/AGENTS.md +456 -0
  14. package/src/lexer.js +1 -2
  15. package/src/typecheck.js +188 -6
  16. package/src/types.js +63 -38
  17. package/src/ui.rip +65 -0
  18. package/docs/ui/accordion.rip +0 -113
  19. package/docs/ui/alert-dialog.rip +0 -96
  20. package/docs/ui/autocomplete.rip +0 -141
  21. package/docs/ui/avatar.rip +0 -37
  22. package/docs/ui/badge.rip +0 -15
  23. package/docs/ui/breadcrumb.rip +0 -46
  24. package/docs/ui/button-group.rip +0 -26
  25. package/docs/ui/button.rip +0 -23
  26. package/docs/ui/card.rip +0 -25
  27. package/docs/ui/carousel.rip +0 -110
  28. package/docs/ui/checkbox-group.rip +0 -65
  29. package/docs/ui/checkbox.rip +0 -33
  30. package/docs/ui/collapsible.rip +0 -50
  31. package/docs/ui/combobox.rip +0 -155
  32. package/docs/ui/context-menu.rip +0 -105
  33. package/docs/ui/date-picker.rip +0 -214
  34. package/docs/ui/dialog.rip +0 -107
  35. package/docs/ui/drawer.rip +0 -79
  36. package/docs/ui/editable-value.rip +0 -80
  37. package/docs/ui/field.rip +0 -53
  38. package/docs/ui/fieldset.rip +0 -22
  39. package/docs/ui/form.rip +0 -39
  40. package/docs/ui/grid.rip +0 -901
  41. package/docs/ui/hljs-rip.js +0 -209
  42. package/docs/ui/index.css +0 -1772
  43. package/docs/ui/index.html +0 -2433
  44. package/docs/ui/input-group.rip +0 -28
  45. package/docs/ui/input.rip +0 -36
  46. package/docs/ui/label.rip +0 -16
  47. package/docs/ui/menu.rip +0 -162
  48. package/docs/ui/menubar.rip +0 -155
  49. package/docs/ui/meter.rip +0 -36
  50. package/docs/ui/multi-select.rip +0 -158
  51. package/docs/ui/native-select.rip +0 -32
  52. package/docs/ui/nav-menu.rip +0 -129
  53. package/docs/ui/number-field.rip +0 -162
  54. package/docs/ui/otp-field.rip +0 -89
  55. package/docs/ui/pagination.rip +0 -123
  56. package/docs/ui/popover.rip +0 -143
  57. package/docs/ui/preview-card.rip +0 -73
  58. package/docs/ui/progress.rip +0 -25
  59. package/docs/ui/radio-group.rip +0 -67
  60. package/docs/ui/resizable.rip +0 -123
  61. package/docs/ui/scroll-area.rip +0 -145
  62. package/docs/ui/select.rip +0 -184
  63. package/docs/ui/separator.rip +0 -17
  64. package/docs/ui/skeleton.rip +0 -22
  65. package/docs/ui/slider.rip +0 -165
  66. package/docs/ui/spinner.rip +0 -17
  67. package/docs/ui/table.rip +0 -27
  68. package/docs/ui/tabs.rip +0 -124
  69. package/docs/ui/textarea.rip +0 -48
  70. package/docs/ui/toast.rip +0 -87
  71. package/docs/ui/toggle-group.rip +0 -78
  72. package/docs/ui/toggle.rip +0 -24
  73. package/docs/ui/toolbar.rip +0 -46
  74. package/docs/ui/tooltip.rip +0 -115
Binary file
package/docs/index.html CHANGED
@@ -634,7 +634,7 @@
634
634
  typeKeywords: ['number', 'string', 'boolean', 'void', 'any', 'never', 'unknown', 'object', 'symbol', 'bigint'],
635
635
 
636
636
  operators: [
637
- '|>', '::=', '::', ':=', '~=', '~>', '<=>', '=!', '!?', '=~', '??', '?.', '...',
637
+ '|>', '::', ':=', '~=', '~>', '<=>', '=!', '!?', '=~', '??', '?.', '...',
638
638
  '..', '**', '//', '%%', '++', '--', '&&', '||', '===', '!==', '==', '!=',
639
639
  '<=', '>=', '=>', '->', '+=', '-=', '*=', '/=', '%=', '**=', '&&=', '||=',
640
640
  '??=', '<<=', '>>=', '>>>=', '&=', '|=', '^=', '>>>', '>>', '<<',
@@ -695,7 +695,7 @@
695
695
  [/\d[\d_]*(?:\.[\d][\d_]*)?(?:[eE][+-]?\d+)?n?/, 'number'],
696
696
 
697
697
  // Operators (multi-char first)
698
- [/::=/, 'keyword.operator.type'],
698
+ [/\btype\b/, 'keyword'],
699
699
  [/::(?!=)/, 'keyword.operator.type'],
700
700
  [/~=|:=|~>|<=>/, 'keyword.operator.reactive'],
701
701
  [/=!/, 'keyword.operator.readonly'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rip-lang",
3
- "version": "3.13.92",
3
+ "version": "3.13.94",
4
4
  "description": "A modern language that compiles to JavaScript",
5
5
  "type": "module",
6
6
  "main": "src/compiler.js",
package/src/AGENTS.md ADDED
@@ -0,0 +1,456 @@
1
+ # Compiler Subsystem — Agent Guide
2
+
3
+ This covers `compiler.js`, `lexer.js`, `components.js`, `browser.js`, `types.js`, `typecheck.js`, and the `grammar/` directory.
4
+
5
+ ---
6
+
7
+ ## S-Expression Patterns
8
+
9
+ Common patterns:
10
+
11
+ ```javascript
12
+ ["=", "x", 42]
13
+ ["+", left, right]
14
+ ["def", "name", params, body]
15
+ ["->", params, body]
16
+ ["if", condition, then, else]
17
+ ["state", name, expr]
18
+ ["computed", name, expr]
19
+ ["enum", name, body]
20
+ ```
21
+
22
+ Complete node reference:
23
+
24
+ ```javascript
25
+ // Top Level
26
+ ['program', ...statements]
27
+
28
+ // Variables & Assignment
29
+ ['=', target, value]
30
+ ['+=', target, value] // Also: -=, *=, /=, %=, **=
31
+ ['&&=', target, value] ['||=', target, value]
32
+ ['?=', target, value] ['??=', target, value]
33
+
34
+ // Functions
35
+ ['def', name, params, body]
36
+ ['->', params, body] // Thin arrow
37
+ ['=>', params, body] // Fat arrow
38
+ // Params: 'name', ['rest', 'name'], ['default', 'name', expr],
39
+ // ['expansion'], ['object', ...], ['array', ...]
40
+
41
+ // Calls & Property Access
42
+ [callee, ...args] // Function call
43
+ ['await', expr]
44
+ ['.', obj, 'prop']
45
+ ['?.', obj, 'prop']
46
+ ['[]', arr, index]
47
+ ['optindex', arr, index] // arr?.[index]
48
+ ['optcall', fn, ...args] // fn?.(args)
49
+ ['new', constructorExpr]
50
+ ['super', ...args]
51
+ ['tagged-template', tag, str]
52
+
53
+ // Data Structures
54
+ ['array', ...elements]
55
+ ['object', ...pairs] // pairs: [key, value]
56
+ ['...', expr] // Spread (prefix only)
57
+
58
+ // Operators
59
+ ['+', left, right] ['-', left, right] ['*', left, right]
60
+ ['/', left, right] ['%', left, right] ['**', left, right]
61
+ ['==', left, right] ['!=', left, right] // == compiles to ===
62
+ ['<', left, right] ['<=', left, right]
63
+ ['>', left, right] ['>=', left, right]
64
+ ['&&', left, right] ['||', left, right] ['??', left, right]
65
+ ['!', expr] ['~', expr] ['typeof', expr]
66
+ ['delete', expr] ['instanceof', expr, type]
67
+ ['?', expr] // Existence check (x?)
68
+ ['defined', expr] // Defined check (x!?)
69
+ ['presence', expr] // Presence check (x?!) — Houdini operator
70
+ ['++', expr, isPostfix] ['--', expr, isPostfix]
71
+
72
+ // Control Flow
73
+ ['if', condition, thenBlock, elseBlock?]
74
+ ['unless', condition, body]
75
+ ['?:', condition, thenExpr, elseExpr]
76
+ ['switch', discriminant, cases, defaultCase?]
77
+
78
+ // Loops
79
+ ['for-in', vars, iterable, step?, guard?, body]
80
+ ['for-of', vars, object, guard?, body]
81
+ ['for-as', vars, iterable, async?, guard?, body] // for await
82
+ ['while', condition, body] ['until', condition, body] ['loop', body]
83
+ ['break'] ['continue'] ['break-if', condition] ['continue-if', condition]
84
+
85
+ // Comprehensions
86
+ ['comprehension', expr, iterators, guards]
87
+ ['object-comprehension', keyExpr, valueExpr, iterators, guards]
88
+
89
+ // Exceptions
90
+ ['try', tryBlock, [catchParam, catchBlock]?, finallyBlock?]
91
+ ['throw', expr]
92
+
93
+ // Classes & Types
94
+ ['class', name, parent?, ...members]
95
+ ['enum', name, body]
96
+
97
+ // Ranges
98
+ ['..', from, to] // Inclusive
99
+ ['...', from, to] // Exclusive
100
+
101
+ // Blocks & Modules
102
+ ['block', ...statements]
103
+ ['do-iife', expr]
104
+ ['import', specifiers, source]
105
+ ['export', statement] ['export-default', expr]
106
+ ['export-all', source] ['export-from', specifiers, source]
107
+
108
+ // Reactivity
109
+ ['state', name, expr] // :=
110
+ ['computed', name, expr] // ~=
111
+ ['effect', name, expr] // ~>
112
+ ['readonly', name, expr] // =!
113
+
114
+ // Components
115
+ ['component', null, body]
116
+ ['render', body]
117
+ ```
118
+
119
+ ## Lexer Token Format
120
+
121
+ Tokens are `[tag, val]` arrays with extra properties:
122
+
123
+ - `.pre` — whitespace count before token
124
+ - `.data` — metadata like `{ await, predicate, quote, invert, parsedValue }`
125
+ - `.loc` — `{ r, c, n }`
126
+ - `.spaced` — sugar for `.pre > 0`
127
+ - `.newLine` — whether preceded by newline
128
+
129
+ Identifier suffixes:
130
+
131
+ - `!` sets `.data.await = true`
132
+ - `?` sets `.data.predicate = true`
133
+ - `as!` in loops emits `FORASAWAIT` for `for await`
134
+
135
+ ## Context-Aware Generation
136
+
137
+ ```javascript
138
+ generate(sexpr, context = 'statement')
139
+ ```
140
+
141
+ - Value context: emit an expression result
142
+ - Statement context: emit statements without preserving a result
143
+
144
+ Comprehensions are the canonical example — value context becomes an IIFE with array building, statement context becomes a plain loop.
145
+
146
+ ## Dispatch Table
147
+
148
+ All node types dispatch through `GENERATORS` for O(1) lookup. To change a feature:
149
+
150
+ 1. Inspect the s-expression with `echo 'code' | ./bin/rip -s`
151
+ 2. Search `GENERATORS` in `src/compiler.js`
152
+ 3. Edit the matching generator method
153
+ 4. Run `bun run test`
154
+
155
+ For grammar work:
156
+
157
+ 1. edit `src/grammar/grammar.rip`
158
+ 2. run `bun run parser`
159
+ 3. verify the new parse shape with `./bin/rip -s`
160
+ 4. update codegen or lexer handling if the new node shape requires it
161
+
162
+ ## Heredocs
163
+
164
+ Heredocs (`'''` and `"""`) use a **closing-delimiter-as-left-margin** rule. The column position of the closing delimiter defines how much leading whitespace to strip from each content line:
165
+
166
+ ```coffee
167
+ # Closing delimiter at same indent as content — fully left-aligned output
168
+ contents = """
169
+ username=#{user}
170
+ password=#{pass}
171
+ """
172
+ # Result: "username=...\npassword=..."
173
+
174
+ # Closing delimiter 2 columns left of content — 2 spaces retained
175
+ html = '''
176
+ <div>
177
+ <p>Hello</p>
178
+ </div>
179
+ '''
180
+ # Result: " <div>\n <p>Hello</p>\n </div>"
181
+ ```
182
+
183
+ Raw heredocs (`'''\` and `"""\`) keep recognized escape sequences literal (`\n`, `\t`, `\u`, `\x`, `\\`). Non-JS escapes like `\s`, `\w`, and `\d` already pass through unchanged in both modes.
184
+
185
+ ## Block Unwrapping
186
+
187
+ Parser bodies are commonly wrapped in `['block', ...]`. Always unwrap before operating on statements:
188
+
189
+ ```javascript
190
+ if (Array.isArray(body) && body[0] === 'block') {
191
+ const statements = body.slice(1)
192
+ }
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Component Internals
198
+
199
+ The component system is a compiler sidecar. `installComponentSupport(CodeGenerator, Lexer)` adds methods to both prototypes.
200
+
201
+ ### Render Rewriter
202
+
203
+ `rewriteRender()` runs after `normalizeLines` and before `tagPostfixConditionals`.
204
+
205
+ Inside `render` blocks it rewrites template syntax into function-call syntax:
206
+
207
+ ```coffee
208
+ div
209
+ span "hello"
210
+ ```
211
+
212
+ becomes roughly:
213
+
214
+ ```coffee
215
+ div(->
216
+ span("hello"))
217
+ ```
218
+
219
+ Tag class patterns:
220
+
221
+ ```coffee
222
+ div.card
223
+ .card
224
+ div.card.active
225
+ .("flex-1 p-4")
226
+ .card.("flex-1 p-4")
227
+ .card.primary.("flex", x)
228
+ ```
229
+
230
+ Key mechanisms:
231
+
232
+ - `startsWithTag` — backward scan to decide whether a line starts a template tag
233
+ - `pendingCallEnds` — indent stack for injected `CALL_START` / `CALL_END`
234
+ - `fromThen` skip — inline postfix `if ... then ... else ...` expressions are never template nesting
235
+ - `$open: true` becomes `"data-open": true`
236
+
237
+ ### Component Codegen
238
+
239
+ Key entry points:
240
+
241
+ - `buildRender` — initializes counters and create/setup line arrays
242
+ - `generateNode` — dispatch for elements, text, conditionals, loops, components
243
+ - `generateConditional` — emits conditional block factories
244
+ - `generateTemplateLoop` — emits `__reconcile(...)`
245
+ - `emitBlockFactory` — shared factory emitter used by conditionals and loops
246
+
247
+ ### Factory Mode
248
+
249
+ Block factories need locals and `ctx.member` references instead of `this._elN` and `this.member`.
250
+
251
+ - `_factoryMode` — emit locals like `_el0` and `ctx.member`
252
+ - `_self` — returns `'this'` or `'ctx'`
253
+ - `_factoryVars` — variables that need local `let` declarations
254
+ - `_fragChildren` — fragment-to-children tracking for removals
255
+ - `_pushEffect(body)` — emits `__effect(...)` or `disposers.push(__effect(...))`
256
+ - `_loopVarStack` — threads loop variables through nested factories
257
+
258
+ Factory mode is entered in `generateConditionBranch` and `generateTemplateLoop` via save/restore of `[_createLines, _setupLines, _factoryMode, _factoryVars]`.
259
+
260
+ ### Auto-Wired Event Handlers
261
+
262
+ Methods named `onClick`, `onKeydown`, `onMouseenter`, etc. automatically bind to the root DOM element.
263
+
264
+ - detection: methods matching `/^on[A-Z]/` that are not lifecycle hooks
265
+ - root only: the first generated HTML tag can claim auto-wiring
266
+ - explicit override: `@click: handler` on the root suppresses auto-wire for that event
267
+ - lifecycle exclusion: `onError` is not auto-wired
268
+
269
+ ```coffee
270
+ export Checkbox = component
271
+ @checked := false
272
+ onClick: -> @checked = not @checked
273
+ onKeydown: (e) ->
274
+ @onClick() if e.key in ['Enter', ' ']
275
+ render
276
+ button role: 'checkbox', aria-checked: !!@checked
277
+ slot
278
+ ```
279
+
280
+ ### List Reconciliation
281
+
282
+ Loop rendering uses runtime `__reconcile` instead of inlined diff logic.
283
+
284
+ Phases:
285
+
286
+ 1. creation batch via `DocumentFragment`
287
+ 2. prefix scan
288
+ 3. suffix scan
289
+ 4. fast paths for pure insert/delete
290
+ 5. LIS for minimal moves on true reorders
291
+
292
+ Compile-time optimizations:
293
+
294
+ - static blocks: `_s: true` skips patch calls when possible
295
+ - array-based `state.blocks[]`
296
+ - `state.keys = items.slice()` for default item-as-key behavior
297
+
298
+ ### Error Boundaries
299
+
300
+ `onError` walks the `_parent` chain.
301
+
302
+ - constructor wraps `_init`
303
+ - mount wraps `_create`, `_setup`, and `mounted`
304
+ - child setup and mount calls are wrapped at codegen time
305
+ - `__handleComponentError(error, component)` finds the nearest handler or rethrows
306
+
307
+ ### Transitions
308
+
309
+ Syntax:
310
+
311
+ ```coffee
312
+ div ~fade
313
+ ```
314
+
315
+ Pipeline:
316
+
317
+ - rewriter converts the tilde form into `__transition__`
318
+ - `generateAttributes` emits `this._t = "fade"`
319
+ - conditionals check `_t` for async leave / enter
320
+ - runtime `__transition(el, name, dir, done)` performs the CSS class dance
321
+
322
+ Built-in presets: `fade`, `slide`, `scale`, `blur`, `fly`
323
+
324
+ Custom transitions follow the `{name}-enter-from`, `{name}-enter-active`, `{name}-leave-to` convention.
325
+
326
+ ### Component Testing
327
+
328
+ Component tests live in `test/rip/components.rip`.
329
+
330
+ - use `code` tests with `{ skipPreamble: true, skipRuntimes: true }` for codegen assertions
331
+ - use `test` tests for runtime behavior like state, methods, reconciliation, and error boundaries
332
+
333
+ ---
334
+
335
+ ## Browser Runtime (`browser.js`)
336
+
337
+ The browser bundle is an IIFE loaded with `<script defer>`, not `type="module"`, so `file://` demos still work without CORS issues.
338
+
339
+ ### Loading Flow
340
+
341
+ `processRipScripts()` runs on `DOMContentLoaded` and:
342
+
343
+ 1. collects `data-src` URLs from the runtime script
344
+ 2. collects all `<script type="text/rip">` tags
345
+ 3. fetches `.rip` sources and JSON bundles
346
+ 4. expands bundles and merges bundle data into `data-state`
347
+ 5. compiles each source with `{ skipRuntimes: true, skipExports: true }`
348
+ 6. appends `Component.mount(target)` when `data-mount` is present
349
+ 7. executes everything as one shared async IIFE
350
+
351
+ ### Compiler Options
352
+
353
+ - `skipExports` — suppresses `export` in codegen; `export` makes components visible across tags as plain `const` declarations in the shared scope
354
+ - `skipRuntimes` — skips re-emitting reactive/component runtimes and uses `var` helpers for safe concatenation
355
+
356
+ ### Browser Helpers
357
+
358
+ - `rip(code)` — browser REPL for Rip snippets
359
+ - `importRip(url)` — fetch, compile, and import a `.rip` file
360
+ - `compileToJS(code)` — compile Rip source to JS
361
+ - `__rip` — reactive runtime
362
+ - `__ripComponent` — component runtime
363
+
364
+ ### Variable Persistence in `rip()`
365
+
366
+ `let` declarations are stripped so values can persist in sloppy-mode eval, while `const` is hoisted to `globalThis`.
367
+
368
+ ---
369
+
370
+ ## Reactivity Implementation
371
+
372
+ The reactive runtime is embedded in `compiler.js` and only emitted when needed.
373
+
374
+ ### `offer` / `accept`
375
+
376
+ Context-sensitive keywords that only activate inside component bodies. Elsewhere they remain plain identifiers.
377
+
378
+ ```coffee
379
+ export Tabs = component
380
+ offer active := 'overview'
381
+
382
+ export TabContent = component
383
+ accept active
384
+ ```
385
+
386
+ `offer` can wrap `:=`, `~=`, `=`, or `=!`. The same reactive object flows through parent and child.
387
+
388
+ Implementation details:
389
+
390
+ - tokenized as `OFFER` / `ACCEPT` only inside component bodies
391
+ - handled via `classifyKeyword` override in `components.js`
392
+ - grammar lives in `ComponentLine`
393
+ - runtime uses existing `setContext`, `getContext`, and `_parent` chain
394
+
395
+ ### Component Signal Sharing
396
+
397
+ `<=>` on components is different from `<=>` on HTML elements.
398
+
399
+ The parent passes the signal via `__bind_propName__`. The child checks that prop first:
400
+
401
+ ```javascript
402
+ this.checked = __state(props.__bind_checked__ ?? props.checked ?? false)
403
+ ```
404
+
405
+ Because `__state()` passes through existing signals, parent and child share the same signal object. No event-based synchronization is needed.
406
+
407
+ ---
408
+
409
+ ## Type System
410
+
411
+ Rip types are erased from JavaScript and exist for `.d.ts` emission, IDE tooling, and documentation.
412
+
413
+ ### Syntax
414
+
415
+ ```coffee
416
+ def greet(name:: string):: string
417
+ "Hello, #{name}!"
418
+
419
+ type User =
420
+ id: number
421
+ name: string
422
+ email?: string
423
+
424
+ interface Animal
425
+ name: string
426
+ speak: => void
427
+
428
+ enum Status
429
+ Active
430
+ Inactive
431
+ ```
432
+
433
+ ### Architecture
434
+
435
+ Type emission logic lives in `types.js`. Type-checking integration and diagnostic filtering live in `typecheck.js`.
436
+
437
+ - `installTypeSupport(Lexer)` adds `rewriteTypes()`
438
+ - `emitTypes(tokens)` emits `.d.ts`
439
+ - `generateEnum()` emits runtime JS for enums
440
+ - `typecheck.js` drives `rip check` and mediates TypeScript diagnostics
441
+
442
+ Types are processed at the token layer before parsing.
443
+
444
+ ### Shadow TypeScript
445
+
446
+ `rip --shadow file.rip` dumps the virtual TypeScript file that `rip check` and the VS Code extension feed into the TypeScript language service.
447
+
448
+ Typical debugging sequence:
449
+
450
+ ```bash
451
+ rip --shadow file.rip
452
+ rip -d file.rip
453
+ rip -cd file.rip
454
+ rip -c file.rip
455
+ rip -s file.rip
456
+ ```
package/src/lexer.js CHANGED
@@ -214,7 +214,7 @@ let UNARY_MATH = new Set(['!', '~']);
214
214
  // The ! suffix is NOT captured when followed by ? to preserve !? as operator
215
215
  let IDENTIFIER_RE = /^(?!\d)((?:(?!\s)[$\w\x7f-\uffff])+(?:!(?!\?)|[?](?![.?![(]))?)([^\n\S]*:(?![=:]))?/;
216
216
  let NUMBER_RE = /^0b[01](?:_?[01])*n?|^0o[0-7](?:_?[0-7])*n?|^0x[\da-f](?:_?[\da-f])*n?|^\d+(?:_\d+)*n|^(?:\d+(?:_\d+)*)?\.?\d+(?:_\d+)*(?:e[+-]?\d+(?:_\d+)*)?/i;
217
- let OPERATOR_RE = /^(?:<=>|::=|::|[-=]>|~>|~=|:=|=!|===|!==|!\?|\?\!|\?\?|=~|\|>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?\.?|\.{2,3})/;
217
+ let OPERATOR_RE = /^(?:<=>|::|[-=]>|~>|~=|:=|=!|===|!==|!\?|\?\!|\?\?|=~|\|>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?\.?|\.{2,3})/;
218
218
  let WHITESPACE_RE = /^[^\n\S]+/;
219
219
  let NEWLINE_RE = /^(?:\n[^\n\S]*)+/;
220
220
  let COMMENT_RE = /^(\s*)###([^#][\s\S]*?)(?:###([^\n\S]*)|###$)|^((?:\s*#(?!##[^#]).*)+)/;
@@ -1211,7 +1211,6 @@ export class Lexer {
1211
1211
  // Pipe operator
1212
1212
  else if (val === '|>') tag = 'PIPE';
1213
1213
  // Type operators
1214
- else if (val === '::=') tag = 'TYPE_ALIAS';
1215
1214
  else if (val === '::' && /^[a-zA-Z_$]/.test(this.chunk[2] || '')) {
1216
1215
  // Prototype access: String::trim → String.prototype.trim
1217
1216
  this.emit('.', '.');