rip-lang 2.9.1 → 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.
@@ -1,47 +1,72 @@
1
1
  # ==============================================================================
2
- # Solar Syntax - S-Expression Grammar for Rip
2
+ # Solar Syntax S-Expression Grammar for Rip (2026)
3
+ # ==============================================================================
4
+ #
5
+ # Defines the grammar rules that Solar uses to generate an SLR(1) parser.
6
+ # Each rule maps a pattern of tokens/types to an s-expression action.
7
+ #
8
+ # Action format:
9
+ # - Numbers (1, 2, 3...) reference matched symbols by position
10
+ # - ...N spreads the array at position N
11
+ # - String literals become s-expression nodes: '["if", 2, 3]'
12
+ # - Default action (no action given) returns position 1
13
+ #
14
+ # Changes from old grammar:
15
+ # - Removed :: and ?:: (prototype access) — reserved for future type annotations
16
+ # - Removed INDEX_SOAK — use ES6 optional indexing (?.[i]) instead
17
+ # - Removed FUNC_EXIST / OptFuncExist — use ES6 optional call (?.(args)) instead
18
+ # - Removed Expression ? (existence check) — use ?? instead
19
+ # - Renamed FORFROM → FORAS, for-from → for-as (for x as iterable)
20
+ # - Simplified Invocation (no soak variants)
21
+ #
3
22
  # ==============================================================================
4
23
 
5
24
  o = (pattern, action, options) ->
6
25
  pattern = pattern.trim().replace /\s{2,}/g, ' '
7
- [pattern, action ? 1, options]
26
+ [pattern, action ?? 1, options]
8
27
 
9
28
  mode = 'sexp'
10
29
 
11
30
  grammar =
12
31
 
13
- # The **Root** is the top-level node in the syntax tree. All parsing ends here.
32
+ # ============================================================================
33
+ # Program Structure
34
+ # ============================================================================
35
+
36
+ # The top-level node — all parsing ends here.
14
37
  Root: [
15
38
  o '' , '["program"]'
16
39
  o 'Body', '["program", ...1]'
17
40
  ]
18
41
 
19
- # Any list of statements and expressions, separated by line breaks or semicolons.
42
+ # A list of statements/expressions, separated by line breaks or semicolons.
20
43
  Body: [
21
44
  o 'Line' , '[1]'
22
45
  o 'Body TERMINATOR Line', '[...1, 3]'
23
46
  o 'Body TERMINATOR'
24
47
  ]
25
48
 
26
- # Line is just a pass-through (default action returns the first token)
49
+ # A single line pass-through to expression or statement.
27
50
  Line: [
28
51
  o 'Expression'
29
52
  o 'ExpressionLine'
30
53
  o 'Statement'
31
54
  ]
32
55
 
33
- # Pure statements which cannot be expressions.
56
+ # Pure statements that cannot be used as expressions.
34
57
  Statement: [
35
58
  o 'Return'
36
- o 'STATEMENT' # Statements like break, continue, debugger
59
+ o 'STATEMENT' # break, continue, debugger
37
60
  o 'Import'
38
61
  o 'Export'
39
62
  ]
40
63
 
41
- # All the different types of expressions in our language. The basic unit of
42
- # CoffeeScript is the **Expression** -- everything that can be an expression
43
- # is one. Blocks serve as the building blocks of many other rules, making
44
- # them somewhat circular.
64
+ # ============================================================================
65
+ # Expressions
66
+ # ============================================================================
67
+
68
+ # All expression types. The fundamental unit of Rip — everything that can
69
+ # produce a value is an expression.
45
70
  Expression: [
46
71
  o 'Value'
47
72
  o 'Code'
@@ -62,98 +87,72 @@ grammar =
62
87
  o 'Def'
63
88
  ]
64
89
 
65
- # Def functions (Rip-specific syntax)
66
- Def: [
67
- o 'DEF Identifier CALL_START ParamList CALL_END Block', '["def", 2, 4, 6]'
68
- o 'DEF Identifier Block' , '["def", 2, [], 3]' # No params
69
- ]
70
-
71
- # Reactive: State assignment (:=) - mutable reactive values
72
- ReactiveAssign: [
73
- o 'Assignable REACTIVE_ASSIGN Expression' , '["state", 1, 3]'
74
- o 'Assignable REACTIVE_ASSIGN TERMINATOR Expression' , '["state", 1, 4]'
75
- o 'Assignable REACTIVE_ASSIGN INDENT Expression OUTDENT', '["state", 1, 4]'
76
- ]
77
-
78
- # Reactive: Computed assignment (~=) - computed values that auto-update
79
- ComputedAssign: [
80
- o 'Assignable COMPUTED_ASSIGN Expression' , '["computed", 1, 3]'
81
- o 'Assignable COMPUTED_ASSIGN TERMINATOR Expression' , '["computed", 1, 4]'
82
- o 'Assignable COMPUTED_ASSIGN INDENT Expression OUTDENT', '["computed", 1, 4]'
90
+ # Single-line expressions (for postfix forms and inline arrows).
91
+ ExpressionLine: [
92
+ o 'CodeLine'
93
+ o 'OperationLine'
83
94
  ]
84
95
 
85
- # Reactive: Readonly assignment (=!) - constants that cannot be reassigned
86
- ReadonlyAssign: [
87
- o 'Assignable READONLY_ASSIGN Expression' , '["readonly", 1, 3]'
88
- o 'Assignable READONLY_ASSIGN TERMINATOR Expression' , '["readonly", 1, 4]'
89
- o 'Assignable READONLY_ASSIGN INDENT Expression OUTDENT', '["readonly", 1, 4]'
90
- ]
96
+ # ============================================================================
97
+ # Values
98
+ # ============================================================================
91
99
 
92
- # Reactive: Effect assignment (~>) - side effects that run when dependencies change
93
- # x ~> body -> ["effect", x, body] (controllable - x gets the effect controller)
94
- # ~> body -> ["effect", null, body] (fire and forget)
95
- ReactAssign: [
96
- o 'Assignable REACT_ASSIGN Expression' , '["effect", 1, 3]'
97
- o 'Assignable REACT_ASSIGN TERMINATOR Expression' , '["effect", 1, 4]'
98
- o 'Assignable REACT_ASSIGN INDENT Expression OUTDENT', '["effect", 1, 4]'
99
- o 'REACT_ASSIGN Expression' , '["effect", null, 2]'
100
- o 'REACT_ASSIGN TERMINATOR Expression' , '["effect", null, 3]'
101
- o 'REACT_ASSIGN INDENT Expression OUTDENT' , '["effect", null, 3]'
100
+ # Expressions that produce values the building blocks.
101
+ Value: [
102
+ o 'Assignable'
103
+ o 'Literal'
104
+ o 'Parenthetical'
105
+ o 'Range'
106
+ o 'Invocation'
107
+ o 'DoIife'
108
+ o 'This'
109
+ o 'Super'
110
+ o 'MetaProperty'
102
111
  ]
103
112
 
104
- # Expressions which are written in single line and would otherwise require being
105
- # wrapped in braces: E.g `a = b if do -> f a is 1`, `if f (a) -> a*2 then ...`,
106
- # `for x in do (obj) -> f obj when x > 8 then f x`
107
- ExpressionLine: [
108
- o 'CodeLine'
109
- o 'OperationLine'
113
+ # Immediate values numbers, strings, booleans, etc.
114
+ Literal: [
115
+ o 'AlphaNumeric'
116
+ o 'JS' # Embedded JavaScript (backticks)
117
+ o 'Regex'
118
+ o 'UNDEFINED' , '"undefined"'
119
+ o 'NULL' , '"null"'
120
+ o 'BOOL' # true/false
121
+ o 'INFINITY' # Infinity
122
+ o 'NAN' # NaN
110
123
  ]
111
124
 
112
- # Yield expressions (for generators)
113
- Yield: [
114
- o 'YIELD' , '["yield"]'
115
- o 'YIELD Expression' , '["yield", 2]'
116
- o 'YIELD INDENT Object OUTDENT', '["yield", 3]'
117
- o 'YIELD FROM Expression' , '["yield-from", 3]'
125
+ AlphaNumeric: [
126
+ o 'NUMBER'
127
+ o 'String'
118
128
  ]
119
129
 
120
- # An indented block of expressions. Note that the rewriter
121
- # will convert some postfix forms into blocks for us, by adjusting the
122
- # token stream.
123
- Block: [
124
- o 'INDENT OUTDENT' , '["block"]'
125
- o 'INDENT Body OUTDENT', '["block", ...2]'
126
- ]
130
+ # ============================================================================
131
+ # Identifiers and Properties
132
+ # ============================================================================
127
133
 
128
- # Identifier - just return the token value (e.g., "console", "x")
129
134
  Identifier: [
130
135
  o 'IDENTIFIER'
131
136
  ]
132
137
 
133
- # Property - return the property name (e.g., "log", "name")
134
138
  Property: [
135
139
  o 'PROPERTY'
136
140
  ]
137
141
 
138
- # Alphanumerics - numbers and strings (pass through)
139
- AlphaNumeric: [
140
- o 'NUMBER'
141
- o 'String'
142
- ]
142
+ # ============================================================================
143
+ # Strings and Interpolation
144
+ # ============================================================================
143
145
 
144
- # String literals
145
146
  String: [
146
147
  o 'STRING'
147
148
  o 'STRING_START Interpolations STRING_END', '["str", ...2]'
148
149
  ]
149
150
 
150
- # Interpolations accumulate parts of template strings
151
151
  Interpolations: [
152
- o 'InterpolationChunk' , '[1]'
152
+ o 'InterpolationChunk' , '[1]'
153
153
  o 'Interpolations InterpolationChunk', '[...1, 2]'
154
154
  ]
155
155
 
156
- # Each chunk is either a string part or an interpolated expression
157
156
  InterpolationChunk: [
158
157
  o 'INTERPOLATION_START Body INTERPOLATION_END' , 2
159
158
  o 'INTERPOLATION_START INDENT Body OUTDENT INTERPOLATION_END', 3
@@ -161,231 +160,103 @@ grammar =
161
160
  o 'String'
162
161
  ]
163
162
 
164
- # Regular expressions
163
+ # ============================================================================
164
+ # Regular Expressions
165
+ # ============================================================================
166
+
165
167
  Regex: [
166
- o 'REGEX' # Pass through regex literal
168
+ o 'REGEX'
167
169
  o 'REGEX_START Invocation REGEX_END', '["regex", 2]'
168
170
  ]
169
171
 
170
- # Regex with optional capture index (for regex indexing feature)
172
+ # Regex with optional capture index: x[/pattern/, n]
171
173
  RegexWithIndex: [
172
- o 'Regex , Expression', '["regex-index", 1, 3]' # x[/pattern/, n] - with capture
173
- o 'Regex' , '["regex-index", 1, null]' # x[/pattern/] - no capture
174
+ o 'Regex , Expression', '["regex-index", 1, 3]'
175
+ o 'Regex' , '["regex-index", 1, null]'
174
176
  ]
175
177
 
176
- # All immediate values - numbers, strings, booleans, etc.
177
- Literal: [
178
- o 'AlphaNumeric'
179
- o 'JS' # Embedded JavaScript (backticks)
180
- o 'Regex'
181
- o 'UNDEFINED' , '"undefined"'
182
- o 'NULL' , '"null"'
183
- o 'BOOL' # true/false pass through
184
- o 'INFINITY' # Infinity passes through
185
- o 'NAN' # NaN passes through
186
- ]
178
+ # ============================================================================
179
+ # Assignment
180
+ # ============================================================================
187
181
 
188
- # Assignment: variable = value
189
182
  Assign: [
190
183
  o 'Assignable = Expression' , '["=", 1, 3]'
191
184
  o 'Assignable = TERMINATOR Expression' , '["=", 1, 4]'
192
185
  o 'Assignable = INDENT Expression OUTDENT', '["=", 1, 4]'
193
186
  ]
194
187
 
195
- # Assignment when it happens within an object literal. The difference from
196
- # the ordinary **Assign** is that these allow numbers and strings as keys.
197
- # Returns [key, value] pairs for building object literals
198
- AssignObj: [
199
- o 'ObjAssignable' , '[1, 1, null]' # Property shorthand: {x} → [x, x, null]
200
- o 'ObjRestValue' # Rest properties: {...rest}
201
- o 'ObjAssignable : Expression' , '[1, 3, ":"]' # Property: {a: 5}
202
- o 'ObjAssignable : INDENT Expression OUTDENT' , '[1, 4, ":"]' # Property (indented)
203
- o 'SimpleObjAssignable = Expression' , '[1, 3, "="]' # Default: {a = 5}
204
- o 'SimpleObjAssignable = INDENT Expression OUTDENT', '[1, 4, "="]' # Default (indented)
205
- ]
206
-
207
- SimpleObjAssignable: [
208
- o 'Identifier'
209
- o 'Property'
210
- o 'ThisProperty'
211
- ]
212
-
213
- ObjAssignable: [
214
- o 'SimpleObjAssignable'
215
- o '[ Expression ]' , '["dynamicKey", 2]' # Dynamic property key
216
- o '@ [ Expression ]', '["[]", "this", 3]'
217
- o 'AlphaNumeric'
218
- ]
219
-
220
- # Object literal spread/rest properties - ES6 prefix only
221
- ObjRestValue: [
222
- o '... SimpleObjAssignable', '["...", 2]' # ES6: {...rest}
223
- o '... ObjSpreadExpr' , '["...", 2]' # ES6: {...obj}
224
- ]
225
-
226
- # Object spread expressions with accessors
227
- # Merged ObjSpreadIdentifier into ObjSpreadExpr to eliminate duplication
228
- ObjSpreadExpr: [
229
- # Base cases
230
- o 'SimpleObjAssignable'
231
- o 'Object'
232
- o 'Parenthetical'
233
- o 'Super'
234
- o 'This'
235
- o 'SUPER OptFuncExist Arguments' , '["super", ...3]'
236
- o 'DYNAMIC_IMPORT Arguments' , '[1, ...2]'
237
- o 'SimpleObjAssignable OptFuncExist Arguments', '[1, ...3]'
238
- o 'ObjSpreadExpr OptFuncExist Arguments' , '[1, ...3]'
239
- # Recursive accessors (handles both base and chained cases)
240
- o 'ObjSpreadExpr . Property' , '[".", 1, 3]'
241
- o 'ObjSpreadExpr ?. Property' , '["?.", 1, 3]'
242
- o 'ObjSpreadExpr :: Property' , '["::", 1, 3]'
243
- o 'ObjSpreadExpr ?:: Property' , '["?::", 1, 3]'
244
- o 'ObjSpreadExpr ::' , '["::", 1, "prototype"]'
245
- o 'ObjSpreadExpr ?::' , '["?::", 1, "prototype"]'
246
- o 'ObjSpreadExpr INDEX_START Expression INDEX_END' , '["[]", 1, 3]'
247
- o 'ObjSpreadExpr INDEX_START INDENT Expression OUTDENT INDEX_END' , '["[]", 1, 4]'
248
- o 'ObjSpreadExpr INDEX_SOAK INDEX_START Expression INDEX_END' , '["?[]", 1, 4]'
249
- o 'ObjSpreadExpr INDEX_SOAK INDEX_START INDENT Expression OUTDENT INDEX_END', '["?[]", 1, 5]'
250
- ]
251
-
252
- # Return statement
253
- Return: [
254
- o 'RETURN Expression' , '["return", 2]'
255
- o 'RETURN INDENT Object OUTDENT', '["return", 3]'
256
- o 'RETURN' , '["return"]'
257
- ]
258
-
259
- # Arrow functions: (params) -> body or (params) => body
260
- Code: [
261
- o 'PARAM_START ParamList PARAM_END FuncGlyph Block', '[4, 2, 5]' # [arrow, params, body]
262
- o 'FuncGlyph Block' , '[1, [], 2]'
263
- ]
264
-
265
- # Single-line arrow functions
266
- CodeLine: [
267
- o 'PARAM_START ParamList PARAM_END FuncGlyph Line', '[4, 2, 5]'
268
- o 'FuncGlyph Line' , '[1, [], 2]'
188
+ # Reactive state (:=) mutable reactive values
189
+ ReactiveAssign: [
190
+ o 'Assignable REACTIVE_ASSIGN Expression' , '["state", 1, 3]'
191
+ o 'Assignable REACTIVE_ASSIGN TERMINATOR Expression' , '["state", 1, 4]'
192
+ o 'Assignable REACTIVE_ASSIGN INDENT Expression OUTDENT', '["state", 1, 4]'
269
193
  ]
270
194
 
271
- # Function arrow type: -> or =>
272
- FuncGlyph: [
273
- o '->'
274
- o '=>'
195
+ # Reactive computed (~=) auto-updating derived values
196
+ ComputedAssign: [
197
+ o 'Assignable COMPUTED_ASSIGN Expression' , '["computed", 1, 3]'
198
+ o 'Assignable COMPUTED_ASSIGN TERMINATOR Expression' , '["computed", 1, 4]'
199
+ o 'Assignable COMPUTED_ASSIGN INDENT Expression OUTDENT', '["computed", 1, 4]'
275
200
  ]
276
201
 
277
- # An optional, trailing comma.
278
- OptComma: [
279
- o ''
280
- o ','
202
+ # Reactive readonly (=!) — constants that cannot be reassigned
203
+ ReadonlyAssign: [
204
+ o 'Assignable READONLY_ASSIGN Expression' , '["readonly", 1, 3]'
205
+ o 'Assignable READONLY_ASSIGN TERMINATOR Expression' , '["readonly", 1, 4]'
206
+ o 'Assignable READONLY_ASSIGN INDENT Expression OUTDENT', '["readonly", 1, 4]'
281
207
  ]
282
208
 
283
- # Parameter list accumulation
284
- ParamList: [
285
- o '' , '[]'
286
- o 'Param' , '[1]'
287
- o 'ParamList , Param' , '[...1, 3]'
288
- o 'ParamList OptComma TERMINATOR Param' , '[...1, 4]'
289
- o 'ParamList OptComma INDENT ParamList OptComma OUTDENT', '[...1, ...4]'
209
+ # Reactive effect (~>) — side effects that run when dependencies change
210
+ ReactAssign: [
211
+ o 'Assignable REACT_ASSIGN Expression' , '["effect", 1, 3]'
212
+ o 'Assignable REACT_ASSIGN TERMINATOR Expression' , '["effect", 1, 4]'
213
+ o 'Assignable REACT_ASSIGN INDENT Expression OUTDENT', '["effect", 1, 4]'
214
+ o 'REACT_ASSIGN Expression' , '["effect", null, 2]'
215
+ o 'REACT_ASSIGN TERMINATOR Expression' , '["effect", null, 3]'
216
+ o 'REACT_ASSIGN INDENT Expression OUTDENT' , '["effect", null, 3]'
290
217
  ]
291
218
 
292
- # Individual parameters (can be identifier, destructuring, rest, or default)
293
- Param: [
294
- o 'ParamVar' # Simple param
295
- o 'ParamVar = Expression', '["default", 1, 3]' # Default param
296
- o '... ParamVar' , '["rest", 2]' # ES6 prefix rest only: ...name
297
- o '...' , '["expansion"]' # Expansion
298
- ]
219
+ # ============================================================================
220
+ # Assignable Targets
221
+ # ============================================================================
299
222
 
300
- # Function Parameters
301
- ParamVar: [
302
- o 'Identifier'
303
- o 'ThisProperty'
223
+ # Things that can appear on the left side of =
224
+ Assignable: [
225
+ o 'SimpleAssignable'
304
226
  o 'Array' # Array destructuring
305
227
  o 'Object' # Object destructuring
306
228
  ]
307
229
 
308
- # Spread operator (in calls and arrays) - ES6 prefix only
309
- Splat: [
310
- o '... Expression', '["...", 2]' # ES6 prefix: ...expr
311
- ]
312
-
313
- # SimpleAssignable: things that can be assigned to
314
- # Inlined accessor patterns for s-expression building
230
+ # Simple assignable targets identifiers, properties, and indexed values.
315
231
  SimpleAssignable: [
316
232
  o 'Identifier'
317
233
  o 'ThisProperty'
318
- # Value with property access
319
- o 'Value . Property' , '[".", 1, 3]'
320
- o 'Value ?. Property' , '["?.", 1, 3]'
321
- o 'Value :: Property' , '["::", 1, 3]'
322
- o 'Value ?:: Property', '["?::", 1, 3]'
323
- o 'Value ::' , '["::", 1, "prototype"]'
324
- o 'Value ?::' , '["?::", 1, "prototype"]'
325
- # Regular indexing
234
+ # Property access
235
+ o 'Value . Property' , '[".", 1, 3]'
236
+ o 'Value ?. Property', '["?.", 1, 3]'
237
+ # Indexing
326
238
  o 'Value INDEX_START Expression INDEX_END' , '["[]", 1, 3]'
327
239
  o 'Value INDEX_START INDENT Expression OUTDENT INDEX_END' , '["[]", 1, 4]'
328
240
  o 'Value INDEX_START Slice INDEX_END' , '["[]", 1, 3]'
329
241
  o 'Value INDEX_START INDENT Slice OUTDENT INDEX_END' , '["[]", 1, 4]'
330
242
  # Regex indexing with capture group
331
243
  o 'Value INDEX_START RegexWithIndex INDEX_END' , '[$3[0], $1, ...$3.slice(1)]'
332
- # CoffeeScript soak indexing (?[)
333
- o 'Value INDEX_SOAK INDEX_START Expression INDEX_END' , '["?[]", 1, 4]'
334
- o 'Value INDEX_SOAK INDEX_START INDENT Expression OUTDENT INDEX_END' , '["?[]", 1, 5]'
335
- o 'Value INDEX_SOAK INDEX_START Slice INDEX_END' , '["?[]", 1, 4]'
336
- o 'Value INDEX_SOAK INDEX_START INDENT Slice OUTDENT INDEX_END' , '["?[]", 1, 5]'
337
- # ES6 optional indexing (?.[)
244
+ # ES6 optional indexing (?.[ )
338
245
  o 'Value ES6_OPTIONAL_INDEX INDEX_START Expression INDEX_END' , '["optindex", 1, 4]'
339
246
  o 'Value ES6_OPTIONAL_INDEX INDEX_START INDENT Expression OUTDENT INDEX_END', '["optindex", 1, 5]'
340
- # Code (arrow function) with accessor
247
+ # Arrow function with accessor
341
248
  o 'Code . Property' , '[".", 1, 3]'
342
249
  o 'Code ?. Property' , '["?.", 1, 3]'
343
- o 'Code :: Property' , '["::", 1, 3]'
344
- o 'Code ?:: Property' , '["?::", 1, 3]'
345
- o 'Code ::' , '["::", 1, "prototype"]'
346
- o 'Code ?::' , '["?::", 1, "prototype"]'
347
250
  o 'Code INDEX_START Expression INDEX_END' , '["[]", 1, 3]'
348
251
  o 'Code INDEX_START INDENT Expression OUTDENT INDEX_END' , '["[]", 1, 4]'
349
- o 'Code INDEX_SOAK INDEX_START Expression INDEX_END' , '["?[]", 1, 4]'
350
- o 'Code INDEX_SOAK INDEX_START INDENT Expression OUTDENT INDEX_END' , '["?[]", 1, 5]'
351
- ]
352
-
353
- # Assignable: can be identifier, array pattern, or object pattern
354
- Assignable: [
355
- o 'SimpleAssignable'
356
- o 'Array' # Array destructuring pattern
357
- o 'Object' # Object destructuring pattern
358
- ]
359
-
360
- # Value: expressions that produce values (all pass through)
361
- Value: [
362
- o 'Assignable'
363
- o 'Literal'
364
- o 'Parenthetical'
365
- o 'Range'
366
- o 'Invocation'
367
- o 'DoIife'
368
- o 'This'
369
- o 'Super'
370
- o 'MetaProperty'
371
252
  ]
372
253
 
373
- # Super property access and calls
374
- Super: [
375
- o 'SUPER . Property' , '[".", "super", 3]'
376
- o 'SUPER INDEX_START Expression INDEX_END' , '["[]", "super", 3]'
377
- o 'SUPER INDEX_START INDENT Expression OUTDENT INDEX_END', '["[]", "super", 4]'
378
- ]
379
-
380
- # Meta-properties: new.target or import.meta
381
- MetaProperty: [
382
- o 'NEW_TARGET . Property' , '[".", "new", 3]'
383
- o 'IMPORT_META . Property', '[".", "import", 3]'
384
- ]
254
+ # ============================================================================
255
+ # Object Literals
256
+ # ============================================================================
385
257
 
386
- # Object literals
387
258
  Object: [
388
- # Object comprehensions - must come before regular objects
259
+ # Object comprehensions
389
260
  o '{ ObjAssignable : Expression FOR ForVariables FOROF Expression OptComma }' , '["object-comprehension", 2, 4, [["for-of", 6, 8, false]], []]'
390
261
  o '{ ObjAssignable : Expression FOR ForVariables FOROF Expression WHEN Expression OptComma }' , '["object-comprehension", 2, 4, [["for-of", 6, 8, false]], [10]]'
391
262
  o '{ ObjAssignable : Expression FOR OWN ForVariables FOROF Expression OptComma }' , '["object-comprehension", 2, 4, [["for-of", 7, 9, true]], []]'
@@ -394,7 +265,6 @@ grammar =
394
265
  o '{ AssignList OptComma }', '["object", ...2]'
395
266
  ]
396
267
 
397
- # Object property list accumulation
398
268
  AssignList: [
399
269
  o '' , '[]'
400
270
  o 'AssignObj' , '[1]'
@@ -403,222 +273,337 @@ grammar =
403
273
  o 'AssignList OptComma INDENT AssignList OptComma OUTDENT', '[...1, ...4]'
404
274
  ]
405
275
 
406
- # Class definitions
407
- Class: [
408
- o 'CLASS' , '["class", null, null]'
409
- o 'CLASS Block' , '["class", null, null, 2]'
410
- o 'CLASS EXTENDS Expression' , '["class", null, 3]'
411
- o 'CLASS EXTENDS Expression Block' , '["class", null, 3, 4]'
412
- o 'CLASS SimpleAssignable' , '["class", 2, null]'
413
- o 'CLASS SimpleAssignable Block' , '["class", 2, null, 3]'
414
- o 'CLASS SimpleAssignable EXTENDS Expression' , '["class", 2, 4]'
415
- o 'CLASS SimpleAssignable EXTENDS Expression Block', '["class", 2, 4, 5]'
276
+ AssignObj: [
277
+ o 'ObjAssignable' , '[1, 1, null]' # Shorthand: {x}
278
+ o 'ObjRestValue' # Rest: {...rest}
279
+ o 'ObjAssignable : Expression' , '[1, 3, ":"]' # Property: {a: 5}
280
+ o 'ObjAssignable : INDENT Expression OUTDENT' , '[1, 4, ":"]'
281
+ o 'SimpleObjAssignable = Expression' , '[1, 3, "="]' # Default: {a = 5}
282
+ o 'SimpleObjAssignable = INDENT Expression OUTDENT', '[1, 4, "="]'
416
283
  ]
417
284
 
418
- # Import statements - simplified for Rip
419
- Import: [
420
- o 'IMPORT String' , '["import", "{}", 2]'
421
- o 'IMPORT ImportDefaultSpecifier FROM String' , '["import", 2, 4]'
422
- o 'IMPORT ImportNamespaceSpecifier FROM String' , '["import", 2, 4]'
423
- o 'IMPORT { } FROM String' , '["import", "{}", 5]'
424
- o 'IMPORT { ImportSpecifierList OptComma } FROM String' , '["import", 3, 7]'
425
- o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String' , '["import", [2, 4], 6]'
426
- o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', '["import", [2, 5], 9]'
285
+ SimpleObjAssignable: [
286
+ o 'Identifier'
287
+ o 'Property'
288
+ o 'ThisProperty'
427
289
  ]
428
290
 
429
- ImportSpecifierList: [
430
- o 'ImportSpecifier' , '[1]'
431
- o 'ImportSpecifierList , ImportSpecifier' , '[...1, 3]'
432
- o 'ImportSpecifierList OptComma TERMINATOR ImportSpecifier' , '[...1, 4]'
433
- o 'INDENT ImportSpecifierList OptComma OUTDENT' , 2
434
- o 'ImportSpecifierList OptComma INDENT ImportSpecifierList OptComma OUTDENT', '[...1, ...4]'
291
+ ObjAssignable: [
292
+ o 'SimpleObjAssignable'
293
+ o '[ Expression ]' , '["dynamicKey", 2]'
294
+ o '@ [ Expression ]', '["[]", "this", 3]'
295
+ o 'AlphaNumeric'
435
296
  ]
436
297
 
437
- ImportSpecifier: [
438
- o 'Identifier' # Simple import
439
- o 'Identifier AS Identifier' , '[1, 3]' # Aliased import
440
- o 'DEFAULT' # Default import
441
- o 'DEFAULT AS Identifier' , '[1, 3]' # Aliased default
298
+ # Object spread/rest — ES6 prefix only
299
+ ObjRestValue: [
300
+ o '... SimpleObjAssignable', '["...", 2]'
301
+ o '... ObjSpreadExpr' , '["...", 2]'
302
+ ]
303
+
304
+ # Object spread expressions with chained accessors
305
+ ObjSpreadExpr: [
306
+ # Base cases
307
+ o 'SimpleObjAssignable'
308
+ o 'Object'
309
+ o 'Parenthetical'
310
+ o 'Super'
311
+ o 'This'
312
+ o 'SUPER Arguments' , '["super", ...2]'
313
+ o 'DYNAMIC_IMPORT Arguments' , '[1, ...2]'
314
+ o 'SimpleObjAssignable Arguments' , '[1, ...2]'
315
+ o 'ObjSpreadExpr Arguments' , '[1, ...2]'
316
+ # Property access
317
+ o 'ObjSpreadExpr . Property' , '[".", 1, 3]'
318
+ o 'ObjSpreadExpr ?. Property' , '["?.", 1, 3]'
319
+ # Indexing
320
+ o 'ObjSpreadExpr INDEX_START Expression INDEX_END' , '["[]", 1, 3]'
321
+ o 'ObjSpreadExpr INDEX_START INDENT Expression OUTDENT INDEX_END', '["[]", 1, 4]'
322
+ ]
323
+
324
+ # ============================================================================
325
+ # Array Literals
326
+ # ============================================================================
327
+
328
+ Array: [
329
+ o '[ ]' , '["array"]'
330
+ o '[ Elisions ]' , '["array", ...2]'
331
+ o '[ ArgElisionList OptElisions ]', '["array", ...2, ...3]'
332
+ ]
333
+
334
+ # Elision handling (sparse arrays: [1,,2])
335
+ ArgElisionList: [
336
+ o 'ArgElision'
337
+ o 'ArgElisionList , ArgElision' , '[...1, ...3]'
338
+ o 'ArgElisionList OptComma TERMINATOR ArgElision' , '[...1, ...4]'
339
+ o 'INDENT ArgElisionList OptElisions OUTDENT' , '[...2, ...3]'
340
+ o 'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT', '[...1, ...2, ...4, ...5]'
341
+ ]
342
+
343
+ ArgElision: [
344
+ o 'Arg' , '[1]'
345
+ o 'Elisions Arg', '[...1, 2]'
346
+ ]
347
+
348
+ OptElisions: [
349
+ o 'OptComma' , '[]'
350
+ o ', Elisions', '[...2]'
351
+ ]
352
+
353
+ Elisions: [
354
+ o 'Elision' , '[1]'
355
+ o 'Elisions Elision', '[...1, 2]'
356
+ ]
357
+
358
+ Elision: [
359
+ o ',' , 'null'
360
+ o 'Elision TERMINATOR'
361
+ ]
362
+
363
+ # ============================================================================
364
+ # Ranges and Slices
365
+ # ============================================================================
366
+
367
+ RangeDots: [
368
+ o '..' , '".."' # Inclusive
369
+ o '...', '"..."' # Exclusive
370
+ ]
371
+
372
+ Range: [
373
+ o '[ Expression RangeDots Expression ]', '[3, 2, 4]'
374
+ ]
375
+
376
+ Slice: [
377
+ o 'Expression RangeDots Expression', '[2, 1, 3]'
378
+ o 'Expression RangeDots' , '[2, 1, null]'
379
+ o 'RangeDots Expression' , '[1, null, 2]'
380
+ o 'RangeDots' , '[1, null, null]'
381
+ ]
382
+
383
+ # ============================================================================
384
+ # Functions and Parameters
385
+ # ============================================================================
386
+
387
+ # Named function definitions (Rip-specific)
388
+ Def: [
389
+ o 'DEF Identifier CALL_START ParamList CALL_END Block', '["def", 2, 4, 6]'
390
+ o 'DEF Identifier Block' , '["def", 2, [], 3]'
391
+ ]
392
+
393
+ # Arrow functions: (params) -> body or (params) => body
394
+ Code: [
395
+ o 'PARAM_START ParamList PARAM_END FuncGlyph Block', '[4, 2, 5]'
396
+ o 'FuncGlyph Block' , '[1, [], 2]'
397
+ ]
398
+
399
+ # Single-line arrow functions
400
+ CodeLine: [
401
+ o 'PARAM_START ParamList PARAM_END FuncGlyph Line', '[4, 2, 5]'
402
+ o 'FuncGlyph Line' , '[1, [], 2]'
442
403
  ]
443
404
 
444
- ImportDefaultSpecifier: [
445
- o 'Identifier'
405
+ FuncGlyph: [
406
+ o '->'
407
+ o '=>'
446
408
  ]
447
409
 
448
- ImportNamespaceSpecifier: [
449
- o 'IMPORT_ALL AS Identifier', '["*", 3]'
410
+ # Parameter list
411
+ ParamList: [
412
+ o '' , '[]'
413
+ o 'Param' , '[1]'
414
+ o 'ParamList , Param' , '[...1, 3]'
415
+ o 'ParamList OptComma TERMINATOR Param' , '[...1, 4]'
416
+ o 'ParamList OptComma INDENT ParamList OptComma OUTDENT', '[...1, ...4]'
450
417
  ]
451
418
 
452
- # Export statements
453
- Export: [
454
- o 'EXPORT { }' , '["export", "{}"]'
455
- o 'EXPORT { ExportSpecifierList OptComma }' , '["export", 3]'
456
- o 'EXPORT Class' , '["export", 2]'
457
- o 'EXPORT Def' , '["export", 2]'
458
- o 'EXPORT Identifier = Expression' , '["export", ["=", 2, 4]]'
459
- o 'EXPORT Identifier = TERMINATOR Expression' , '["export", ["=", 2, 5]]'
460
- o 'EXPORT Identifier = INDENT Expression OUTDENT' , '["export", ["=", 2, 5]]'
461
- o 'EXPORT DEFAULT Expression' , '["export-default", 3]'
462
- o 'EXPORT DEFAULT INDENT Object OUTDENT' , '["export-default", 4]'
463
- o 'EXPORT EXPORT_ALL FROM String' , '["export-all", 4]'
464
- o 'EXPORT { } FROM String' , '["export-from", "{}", 5]'
465
- o 'EXPORT { ExportSpecifierList OptComma } FROM String', '["export-from", 3, 7]'
419
+ Param: [
420
+ o 'ParamVar'
421
+ o 'ParamVar = Expression', '["default", 1, 3]'
422
+ o '... ParamVar' , '["rest", 2]' # ES6 prefix rest: ...name
423
+ o '...' , '["expansion"]'
466
424
  ]
467
425
 
468
- ExportSpecifierList: [
469
- o 'ExportSpecifier' , '[1]'
470
- o 'ExportSpecifierList , ExportSpecifier' , '[...1, 3]'
471
- o 'ExportSpecifierList OptComma TERMINATOR ExportSpecifier' , '[...1, 4]'
472
- o 'INDENT ExportSpecifierList OptComma OUTDENT' , 2
473
- o 'ExportSpecifierList OptComma INDENT ExportSpecifierList OptComma OUTDENT', '[...1, ...4]'
426
+ ParamVar: [
427
+ o 'Identifier'
428
+ o 'ThisProperty'
429
+ o 'Array'
430
+ o 'Object'
474
431
  ]
475
432
 
476
- ExportSpecifier: [
477
- o 'Identifier' # Simple export
478
- o 'Identifier AS Identifier', '[1, 3]' # Aliased export
479
- o 'Identifier AS DEFAULT' , '[1, 3]' # Export as default
480
- o 'DEFAULT' # Export default keyword
481
- o 'DEFAULT AS Identifier' , '[1, 3]'
433
+ # Spread in calls and arrays — ES6 prefix only
434
+ Splat: [
435
+ o '... Expression', '["...", 2]'
482
436
  ]
483
437
 
484
- # Function calls and invocations
485
- Invocation: [
486
- o 'Value OptFuncExist String' , '["tagged-template", 1, 3]' # Tagged template literal
487
- o 'Value OptFuncExist Arguments' , '2 ? ["?call", 1, ...3] : [1, ...3]' # Regular/soak call
488
- o 'Value ES6_OPTIONAL_CALL Arguments', '["optcall", 1, ...3]' # ES6 optional call
489
- o 'SUPER Arguments' , '["super", ...2]' # Super call (no soak support)
490
- o 'DYNAMIC_IMPORT Arguments' , '[1, ...2]' # Dynamic import
491
- ]
438
+ # ============================================================================
439
+ # Function Calls
440
+ # ============================================================================
492
441
 
493
- # Optional existence check (? operator for function calls)
494
- OptFuncExist: [
495
- o '' , 'null' # No soak
496
- o 'FUNC_EXIST' , 'true' # Has soak - mark as soak call
442
+ Invocation: [
443
+ o 'Value String' , '["tagged-template", 1, 2]' # Tagged template
444
+ o 'Value Arguments' , '[1, ...2]' # Regular call
445
+ o 'Value ES6_OPTIONAL_CALL Arguments' , '["optcall", 1, ...3]' # Optional call: x?.(args)
446
+ o 'SUPER Arguments' , '["super", ...2]' # Super call
447
+ o 'DYNAMIC_IMPORT Arguments' , '[1, ...2]' # Dynamic import()
497
448
  ]
498
449
 
499
- # Function arguments
500
450
  Arguments: [
501
451
  o 'CALL_START CALL_END' , '[]'
502
452
  o 'CALL_START ArgList OptComma CALL_END', 2
503
453
  ]
504
454
 
505
- # Reference to 'this'
455
+ ArgList: [
456
+ o 'Arg' , '[1]'
457
+ o 'ArgList , Arg' , '[...1, 3]'
458
+ o 'ArgList OptComma TERMINATOR Arg' , '[...1, 4]'
459
+ o 'INDENT ArgList OptComma OUTDENT' , 2
460
+ o 'ArgList OptComma INDENT ArgList OptComma OUTDENT', '[...1, ...4]'
461
+ ]
462
+
463
+ Arg: [
464
+ o 'Expression'
465
+ o 'ExpressionLine'
466
+ o 'Splat'
467
+ o '...', '"..."' # Expansion marker
468
+ ]
469
+
470
+ # Simple argument list for switch/when (always produces array)
471
+ SimpleArgs: [
472
+ o 'Expression' , '[$1]'
473
+ o 'SimpleArgs , Expression', '[...$1, $3]'
474
+ ]
475
+
476
+ # ============================================================================
477
+ # This and Super
478
+ # ============================================================================
479
+
506
480
  This: [
507
481
  o 'THIS', '"this"'
508
482
  o '@' , '"this"'
509
483
  ]
510
484
 
511
- # Reference to this.property
512
485
  ThisProperty: [
513
486
  o '@ Property', '[".", "this", 2]'
514
487
  ]
515
488
 
516
- # Array literals
517
- Array: [
518
- o '[ ]' , '["array"]'
519
- o '[ Elisions ]' , '["array", ...2]'
520
- o '[ ArgElisionList OptElisions ]', '["array", ...2, ...3]'
489
+ Super: [
490
+ o 'SUPER . Property' , '[".", "super", 3]'
491
+ o 'SUPER INDEX_START Expression INDEX_END' , '["[]", "super", 3]'
492
+ o 'SUPER INDEX_START INDENT Expression OUTDENT INDEX_END', '["[]", "super", 4]'
521
493
  ]
522
494
 
523
- # Range operators
524
- RangeDots: [
525
- o '..' , '".."' # Inclusive
526
- o '...', '"..."' # Exclusive
495
+ MetaProperty: [
496
+ o 'NEW_TARGET . Property' , '[".", "new", 3]'
497
+ o 'IMPORT_META . Property', '[".", "import", 3]'
527
498
  ]
528
499
 
529
- # Range literals (CoffeeScript-style in arrays)
530
- Range: [
531
- o '[ Expression RangeDots Expression ]', '[3, 2, 4]' # [from..to]
532
- ]
500
+ # ============================================================================
501
+ # Blocks and Parentheses
502
+ # ============================================================================
533
503
 
534
- # Array slices
535
- Slice: [
536
- o 'Expression RangeDots Expression', '[2, 1, 3]' # expr..expr
537
- o 'Expression RangeDots' , '[2, 1, null]' # expr..
538
- o 'RangeDots Expression' , '[1, null, 2]' # ..expr
539
- o 'RangeDots' , '[1, null, null]' # ..
504
+ Block: [
505
+ o 'INDENT OUTDENT' , '["block"]'
506
+ o 'INDENT Body OUTDENT', '["block", ...2]'
540
507
  ]
541
508
 
542
- # Argument list for function calls
543
- ArgList: [
544
- o 'Arg' , '[1]'
545
- o 'ArgList , Arg' , '[...1, 3]'
546
- o 'ArgList OptComma TERMINATOR Arg' , '[...1, 4]'
547
- o 'INDENT ArgList OptComma OUTDENT' , 2
548
- o 'ArgList OptComma INDENT ArgList OptComma OUTDENT', '[...1, ...4]'
509
+ Parenthetical: [
510
+ o '( Body )' , '$2.length === 1 ? $2[0] : ["block", ...$2]'
511
+ o '( INDENT Body OUTDENT )', '$3.length === 1 ? $3[0] : ["block", ...$3]'
549
512
  ]
550
513
 
551
- # Individual argument
552
- Arg: [
553
- o 'Expression'
554
- o 'ExpressionLine'
555
- o 'Splat'
556
- o '...', '"..."' # Expansion marker
514
+ OptComma: [
515
+ o ''
516
+ o ','
557
517
  ]
558
518
 
559
- # Array elision lists (for sparse arrays with holes)
560
- ArgElisionList: [
561
- o 'ArgElision'
562
- o 'ArgElisionList , ArgElision' , '[...1, ...3]'
563
- o 'ArgElisionList OptComma TERMINATOR ArgElision' , '[...1, ...4]'
564
- o 'INDENT ArgElisionList OptElisions OUTDENT' , '[...2, ...3]'
565
- o 'ArgElisionList OptElisions INDENT ArgElisionList OptElisions OUTDENT', '[...1, ...2, ...4, ...5]'
519
+ # ============================================================================
520
+ # Return and Throw
521
+ # ============================================================================
522
+
523
+ Return: [
524
+ o 'RETURN Expression' , '["return", 2]'
525
+ o 'RETURN INDENT Object OUTDENT', '["return", 3]'
526
+ o 'RETURN' , '["return"]'
566
527
  ]
567
528
 
568
- ArgElision: [
569
- o 'Arg' , '[1]'
570
- o 'Elisions Arg', '[...1, 2]'
529
+ Throw: [
530
+ o 'THROW Expression' , '["throw", 2]'
531
+ o 'THROW INDENT Object OUTDENT', '["throw", 3]'
571
532
  ]
572
533
 
573
- OptElisions: [
574
- o 'OptComma' , '[]'
575
- o ', Elisions', '[...2]'
534
+ # ============================================================================
535
+ # Yield (Generators)
536
+ # ============================================================================
537
+
538
+ Yield: [
539
+ o 'YIELD' , '["yield"]'
540
+ o 'YIELD Expression' , '["yield", 2]'
541
+ o 'YIELD INDENT Object OUTDENT', '["yield", 3]'
542
+ o 'YIELD FROM Expression' , '["yield-from", 3]'
576
543
  ]
577
544
 
578
- Elisions: [
579
- o 'Elision' , '[1]'
580
- o 'Elisions Elision', '[...1, 2]'
545
+ # ============================================================================
546
+ # Control Flow
547
+ # ============================================================================
548
+
549
+ # If/Unless
550
+ IfBlock: [
551
+ o 'IF Expression Block' , '["if", 2, 3]'
552
+ o 'IfBlock ELSE IF Expression Block' , '$1.length === 3 ? ["if", $1[1], $1[2], ["if", $4, $5]] : [...$1, ["if", $4, $5]]'
581
553
  ]
582
554
 
583
- Elision: [
584
- o ',' , 'null' # Hole in array
585
- o 'Elision TERMINATOR'
555
+ UnlessBlock: [
556
+ o 'UNLESS Expression Block' , '["unless", 2, 3]'
557
+ o 'UNLESS Expression Block ELSE Block' , '["if", ["!", 2], 3, 5]'
586
558
  ]
587
559
 
588
- # Simple argument lists for switch statements (always produces array)
589
- SimpleArgs: [
590
- o 'Expression' , '[$1]' # Single: wrap in array
591
- o 'SimpleArgs , Expression', '[...$1, $3]' # Multiple: spread + add
560
+ If: [
561
+ o 'IfBlock'
562
+ o 'IfBlock ELSE Block' , '$1.length === 3 ? ["if", $1[1], $1[2], $3] : [...$1, $3]'
563
+ o 'UnlessBlock'
564
+ o 'Statement POST_IF Expression' , '["if", 3, [1]]'
565
+ o 'Expression POST_IF Expression' , '["if", 3, [1]]'
566
+ o 'Statement POST_UNLESS Expression' , '["unless", 3, [1]]'
567
+ o 'Expression POST_UNLESS Expression', '["unless", 3, [1]]'
592
568
  ]
593
569
 
594
- # Try/catch/finally exception handling
570
+ # Try/Catch/Finally
595
571
  Try: [
596
572
  o 'TRY Block' , '["try", 2]'
597
- o 'TRY Block Catch' , '["try", 2, 3]' # Will expand Catch
573
+ o 'TRY Block Catch' , '["try", 2, 3]'
598
574
  o 'TRY Block FINALLY Block' , '["try", 2, 4]'
599
- o 'TRY Block Catch FINALLY Block', '["try", 2, 3, 5]' # Will expand Catch
575
+ o 'TRY Block Catch FINALLY Block', '["try", 2, 3, 5]'
600
576
  ]
601
577
 
602
- # Catch clause
603
578
  Catch: [
604
- o 'CATCH Identifier Block', '[2, 3]' # [param, block]
605
- o 'CATCH Object Block' , '[2, 3]' # [pattern, block]
606
- o 'CATCH Block' , '[null, 2]' # [null, block] - no param
579
+ o 'CATCH Identifier Block', '[2, 3]'
580
+ o 'CATCH Object Block' , '[2, 3]'
581
+ o 'CATCH Block' , '[null, 2]'
607
582
  ]
608
583
 
609
- # Throw statement
610
- Throw: [
611
- o 'THROW Expression' , '["throw", 2]'
612
- o 'THROW INDENT Object OUTDENT', '["throw", 3]'
584
+ # Switch/When
585
+ Switch: [
586
+ o 'SWITCH Expression INDENT Whens OUTDENT' , '["switch", 2, 4, null]'
587
+ o 'SWITCH Expression INDENT Whens ELSE Block OUTDENT' , '["switch", 2, 4, 6]'
588
+ o 'SWITCH INDENT Whens OUTDENT' , '["switch", null, 3, null]'
589
+ o 'SWITCH INDENT Whens ELSE Block OUTDENT' , '["switch", null, 3, 5]'
613
590
  ]
614
591
 
615
- # Parenthesized expressions - unwrap single-element Bodies, wrap multiple in block
616
- Parenthetical: [
617
- o '( Body )' , '$2.length === 1 ? $2[0] : ["block", ...$2]'
618
- o '( INDENT Body OUTDENT )', '$3.length === 1 ? $3[0] : ["block", ...$3]'
592
+ Whens: [
593
+ o 'When' , '[1]'
594
+ o 'Whens When', '[...1, 2]'
595
+ ]
596
+
597
+ When: [
598
+ o 'LEADING_WHEN SimpleArgs Block' , '["when", 2, 3]'
599
+ o 'LEADING_WHEN SimpleArgs Block TERMINATOR', '["when", 2, 3]'
619
600
  ]
620
601
 
621
- # While loop conditions (consolidated)
602
+ # ============================================================================
603
+ # Loops
604
+ # ============================================================================
605
+
606
+ # While/Until
622
607
  WhileSource: [
623
608
  o 'WHILE Expression' , '["while", 2]'
624
609
  o 'WHILE Expression WHEN Expression', '["while", 2, 4]'
@@ -626,7 +611,6 @@ grammar =
626
611
  o 'UNTIL Expression WHEN Expression', '["until", 2, 4]'
627
612
  ]
628
613
 
629
- # While loops - combine source + block
630
614
  While: [
631
615
  o 'WhileSource Block' , '$1.length === 2 ? [$1[0], $1[1], $2] : [$1[0], $1[1], $1[2], $2]'
632
616
  o 'Statement WhileSource' , '$2.length === 2 ? [$2[0], $2[1], [$1]] : [$2[0], $2[1], $2[2], [$1]]'
@@ -634,58 +618,74 @@ grammar =
634
618
  o 'Loop'
635
619
  ]
636
620
 
637
- # Infinite loop
638
621
  Loop: [
639
622
  o 'LOOP Block' , '["loop", 2]'
640
623
  o 'LOOP Expression', '["loop", [2]]'
641
624
  ]
642
625
 
643
- # For loops - build complete s-expressions directly
626
+ # For loops
644
627
  # Structure: ["for-in", vars, iterable, step, guard, body]
645
- # Structure: ["for-of", vars, object, guard, body]
628
+ # Structure: ["for-of", vars, object, own, guard, body]
629
+ # Structure: ["for-as", vars, iterable, async, guard, body]
646
630
  For: [
647
- # Block form (prefix - FOR comes first)
631
+ # --- Block form (prefix: FOR comes first) ---
632
+
633
+ # for x in array
648
634
  o 'FOR ForVariables FORIN Expression Block' , '["for-in" , 2, 4, null, null, 5]'
649
635
  o 'FOR ForVariables FORIN Expression WHEN Expression Block' , '["for-in" , 2, 4, null, 6, 7]'
650
636
  o 'FOR ForVariables FORIN Expression BY Expression Block' , '["for-in" , 2, 4, 6, null, 7]'
651
637
  o 'FOR ForVariables FORIN Expression WHEN Expression BY Expression Block', '["for-in" , 2, 4, 8, 6, 9]'
652
638
  o 'FOR ForVariables FORIN Expression BY Expression WHEN Expression Block', '["for-in" , 2, 4, 6, 8, 9]'
639
+
640
+ # for k of object
653
641
  o 'FOR ForVariables FOROF Expression Block' , '["for-of" , 2, 4, false, null, 5]'
654
642
  o 'FOR ForVariables FOROF Expression WHEN Expression Block' , '["for-of" , 2, 4, false, 6, 7]'
655
643
  o 'FOR OWN ForVariables FOROF Expression Block' , '["for-of" , 3, 5, true, null, 6]'
656
644
  o 'FOR OWN ForVariables FOROF Expression WHEN Expression Block' , '["for-of" , 3, 5, true, 7, 8]'
657
- o 'FOR ForVariables FORFROM Expression Block' , '["for-from", 2, 4, false, null, 5]'
658
- o 'FOR ForVariables FORFROM Expression WHEN Expression Block' , '["for-from", 2, 4, false, 6, 7]'
659
- o 'FOR AWAIT ForVariables FORFROM Expression Block' , '["for-from", 3, 5, true, null, 6]'
660
- o 'FOR AWAIT ForVariables FORFROM Expression WHEN Expression Block' , '["for-from", 3, 5, true, 7, 8]'
645
+
646
+ # for x as iterable (ES6 for-of on iterables, supports async)
647
+ o 'FOR ForVariables FORAS Expression Block' , '["for-as" , 2, 4, false, null, 5]'
648
+ o 'FOR ForVariables FORAS Expression WHEN Expression Block' , '["for-as" , 2, 4, false, 6, 7]'
649
+ o 'FOR AWAIT ForVariables FORAS Expression Block' , '["for-as" , 3, 5, true, null, 6]'
650
+ o 'FOR AWAIT ForVariables FORAS Expression WHEN Expression Block' , '["for-as" , 3, 5, true, 7, 8]'
651
+ o 'FOR ForVariables FORASAWAIT Expression Block' , '["for-as" , 2, 4, true, null, 5]'
652
+ o 'FOR ForVariables FORASAWAIT Expression WHEN Expression Block' , '["for-as" , 2, 4, true, 6, 7]'
653
+
654
+ # for [range]
661
655
  o 'FOR Range Block' , '["for-in" , [], 2, null, null, 3]'
662
656
  o 'FOR Range BY Expression Block' , '["for-in" , [], 2, 4, null, 5]'
663
657
 
664
- # Postfix form / Comprehensions (expression comes BEFORE for)
665
- # Note: These generate comprehensions (collect results into array)
666
- # CoffeeScript handles this contextually, but for s-expressions we always collect
667
- # The overhead is minimal and results can be discarded if unused
658
+ # --- Postfix form / Comprehensions (expression comes BEFORE for) ---
659
+
660
+ # x for y in array
668
661
  o 'Expression FOR ForVariables FORIN Expression' , '["comprehension", 1, [["for-in" , 3, 5, null]], []]'
669
662
  o 'Expression FOR ForVariables FORIN Expression WHEN Expression' , '["comprehension", 1, [["for-in" , 3, 5, null]], [7]]'
670
663
  o 'Expression FOR ForVariables FORIN Expression BY Expression' , '["comprehension", 1, [["for-in" , 3, 5, 7]], []]'
671
664
  o 'Expression FOR ForVariables FORIN Expression WHEN Expression BY Expression' , '["comprehension", 1, [["for-in" , 3, 5, 9]], [7]]'
672
665
  o 'Expression FOR ForVariables FORIN Expression BY Expression WHEN Expression' , '["comprehension", 1, [["for-in" , 3, 5, 7]], [9]]'
666
+
667
+ # x for k of object
673
668
  o 'Expression FOR ForVariables FOROF Expression' , '["comprehension", 1, [["for-of" , 3, 5, false]], []]'
674
669
  o 'Expression FOR ForVariables FOROF Expression WHEN Expression' , '["comprehension", 1, [["for-of" , 3, 5, false]], [7]]'
675
670
  o 'Expression FOR OWN ForVariables FOROF Expression' , '["comprehension", 1, [["for-of" , 4, 6, true]], []]'
676
671
  o 'Expression FOR OWN ForVariables FOROF Expression WHEN Expression' , '["comprehension", 1, [["for-of" , 4, 6, true]], [8]]'
677
- o 'Expression FOR ForVariables FORFROM Expression' , '["comprehension", 1, [["for-from", 3, 5, false, null]], []]'
678
- o 'Expression FOR ForVariables FORFROM Expression WHEN Expression' , '["comprehension", 1, [["for-from", 3, 5, false, null]], [7]]'
679
- o 'Expression FOR AWAIT ForVariables FORFROM Expression' , '["comprehension", 1, [["for-from", 4, 6, true, null]], []]'
680
- o 'Expression FOR AWAIT ForVariables FORFROM Expression WHEN Expression' , '["comprehension", 1, [["for-from", 4, 6, true, null]], [8]]'
681
- # Postfix range (without loop variable) - for N-time repetition
672
+
673
+ # x for y as iterable
674
+ o 'Expression FOR ForVariables FORAS Expression' , '["comprehension", 1, [["for-as" , 3, 5, false, null]], []]'
675
+ o 'Expression FOR ForVariables FORAS Expression WHEN Expression' , '["comprehension", 1, [["for-as" , 3, 5, false, null]], [7]]'
676
+ o 'Expression FOR AWAIT ForVariables FORAS Expression' , '["comprehension", 1, [["for-as" , 4, 6, true, null]], []]'
677
+ o 'Expression FOR AWAIT ForVariables FORAS Expression WHEN Expression' , '["comprehension", 1, [["for-as" , 4, 6, true, null]], [8]]'
678
+ o 'Expression FOR ForVariables FORASAWAIT Expression' , '["comprehension", 1, [["for-as" , 3, 5, true, null]], []]'
679
+ o 'Expression FOR ForVariables FORASAWAIT Expression WHEN Expression' , '["comprehension", 1, [["for-as" , 3, 5, true, null]], [7]]'
680
+
681
+ # x for [range]
682
682
  o 'Expression FOR Range' , '["comprehension", 1, [["for-in", [], 3, null]], []]'
683
683
  o 'Expression FOR Range BY Expression' , '["comprehension", 1, [["for-in", [], 3, 5]], []]'
684
684
  ]
685
685
 
686
686
  ForValue: [
687
- o 'ParamVar' # Simple variable (reuses ParamVar - same structure)
688
- o 'ParamVar = Expression', '["default", 1, 3]' # With default value (like params)
687
+ o 'ParamVar'
688
+ o 'ParamVar = Expression', '["default", 1, 3]'
689
689
  ]
690
690
 
691
691
  ForVariables: [
@@ -693,93 +693,131 @@ grammar =
693
693
  o 'ForValue , ForValue', '[1, 3]'
694
694
  ]
695
695
 
696
- # Switch statements
697
- Switch: [
698
- o 'SWITCH Expression INDENT Whens OUTDENT' , '["switch", 2, 4, null]'
699
- o 'SWITCH Expression INDENT Whens ELSE Block OUTDENT' , '["switch", 2, 4, 6]'
700
- o 'SWITCH INDENT Whens OUTDENT' , '["switch", null, 3, null]'
701
- o 'SWITCH INDENT Whens ELSE Block OUTDENT' , '["switch", null, 3, 5]'
696
+ # ============================================================================
697
+ # Classes
698
+ # ============================================================================
699
+
700
+ Class: [
701
+ o 'CLASS' , '["class", null, null]'
702
+ o 'CLASS Block' , '["class", null, null, 2]'
703
+ o 'CLASS EXTENDS Expression' , '["class", null, 3]'
704
+ o 'CLASS EXTENDS Expression Block' , '["class", null, 3, 4]'
705
+ o 'CLASS SimpleAssignable' , '["class", 2, null]'
706
+ o 'CLASS SimpleAssignable Block' , '["class", 2, null, 3]'
707
+ o 'CLASS SimpleAssignable EXTENDS Expression' , '["class", 2, 4]'
708
+ o 'CLASS SimpleAssignable EXTENDS Expression Block', '["class", 2, 4, 5]'
702
709
  ]
703
710
 
704
- # When clauses for switch (accumulate into array)
705
- Whens: [
706
- o 'When' , '[1]'
707
- o 'Whens When', '[...1, 2]'
711
+ # ============================================================================
712
+ # Import / Export
713
+ # ============================================================================
714
+
715
+ Import: [
716
+ o 'IMPORT String' , '["import", "{}", 2]'
717
+ o 'IMPORT ImportDefaultSpecifier FROM String' , '["import", 2, 4]'
718
+ o 'IMPORT ImportNamespaceSpecifier FROM String' , '["import", 2, 4]'
719
+ o 'IMPORT { } FROM String' , '["import", "{}", 5]'
720
+ o 'IMPORT { ImportSpecifierList OptComma } FROM String' , '["import", 3, 7]'
721
+ o 'IMPORT ImportDefaultSpecifier , ImportNamespaceSpecifier FROM String' , '["import", [2, 4], 6]'
722
+ o 'IMPORT ImportDefaultSpecifier , { ImportSpecifierList OptComma } FROM String', '["import", [2, 5], 9]'
708
723
  ]
709
724
 
710
- # Individual when clause
711
- When: [
712
- o 'LEADING_WHEN SimpleArgs Block' , '["when", 2, 3]'
713
- o 'LEADING_WHEN SimpleArgs Block TERMINATOR', '["when", 2, 3]'
725
+ ImportSpecifierList: [
726
+ o 'ImportSpecifier' , '[1]'
727
+ o 'ImportSpecifierList , ImportSpecifier' , '[...1, 3]'
728
+ o 'ImportSpecifierList OptComma TERMINATOR ImportSpecifier' , '[...1, 4]'
729
+ o 'INDENT ImportSpecifierList OptComma OUTDENT' , 2
730
+ o 'ImportSpecifierList OptComma INDENT ImportSpecifierList OptComma OUTDENT', '[...1, ...4]'
714
731
  ]
715
732
 
716
- # If statements - combine condition, then, and else branches
717
- IfBlock: [
718
- o 'IF Expression Block' , '["if", 2, 3]'
719
- o 'IfBlock ELSE IF Expression Block' , '$1.length === 3 ? ["if", $1[1], $1[2], ["if", $4, $5]] : [...$1, ["if", $4, $5]]'
733
+ ImportSpecifier: [
734
+ o 'Identifier'
735
+ o 'Identifier AS Identifier' , '[1, 3]'
736
+ o 'DEFAULT'
737
+ o 'DEFAULT AS Identifier' , '[1, 3]'
720
738
  ]
721
739
 
722
- UnlessBlock: [
723
- o 'UNLESS Expression Block' , '["unless", 2, 3]'
724
- o 'UNLESS Expression Block ELSE Block' , '["if", ["!", 2], 3, 5]' # unless with else = if not
740
+ ImportDefaultSpecifier: [
741
+ o 'Identifier'
725
742
  ]
726
743
 
727
- If: [
728
- o 'IfBlock'
729
- o 'IfBlock ELSE Block' , '$1.length === 3 ? ["if", $1[1], $1[2], $3] : [...$1, $3]'
730
- o 'UnlessBlock'
731
- o 'Statement POST_IF Expression' , '["if", 3, [1]]' # Postfix
732
- o 'Expression POST_IF Expression' , '["if", 3, [1]]' # Postfix
733
- o 'Statement POST_UNLESS Expression' , '["unless", 3, [1]]' # Postfix unless
734
- o 'Expression POST_UNLESS Expression', '["unless", 3, [1]]' # Postfix unless
735
- ]
736
-
737
- # Arithmetic and logical operators, working on one or more operands.
738
- # Here they are grouped by order of precedence. The actual precedence rules
739
- # are defined at the bottom of the page. It would be shorter if we could
740
- # combine most of these rules into a single generic *Operand OpSymbol Operand*
741
- # -type rule, but in order to make the precedence binding possible, separate
742
- # rules are necessary.
744
+ ImportNamespaceSpecifier: [
745
+ o 'IMPORT_ALL AS Identifier', '["*", 3]'
746
+ ]
747
+
748
+ Export: [
749
+ o 'EXPORT { }' , '["export", "{}"]'
750
+ o 'EXPORT { ExportSpecifierList OptComma }' , '["export", 3]'
751
+ o 'EXPORT Class' , '["export", 2]'
752
+ o 'EXPORT Def' , '["export", 2]'
753
+ o 'EXPORT Identifier = Expression' , '["export", ["=", 2, 4]]'
754
+ o 'EXPORT Identifier = TERMINATOR Expression' , '["export", ["=", 2, 5]]'
755
+ o 'EXPORT Identifier = INDENT Expression OUTDENT' , '["export", ["=", 2, 5]]'
756
+ o 'EXPORT DEFAULT Expression' , '["export-default", 3]'
757
+ o 'EXPORT DEFAULT INDENT Object OUTDENT' , '["export-default", 4]'
758
+ o 'EXPORT EXPORT_ALL FROM String' , '["export-all", 4]'
759
+ o 'EXPORT { } FROM String' , '["export-from", "{}", 5]'
760
+ o 'EXPORT { ExportSpecifierList OptComma } FROM String', '["export-from", 3, 7]'
761
+ ]
762
+
763
+ ExportSpecifierList: [
764
+ o 'ExportSpecifier' , '[1]'
765
+ o 'ExportSpecifierList , ExportSpecifier' , '[...1, 3]'
766
+ o 'ExportSpecifierList OptComma TERMINATOR ExportSpecifier' , '[...1, 4]'
767
+ o 'INDENT ExportSpecifierList OptComma OUTDENT' , 2
768
+ o 'ExportSpecifierList OptComma INDENT ExportSpecifierList OptComma OUTDENT', '[...1, ...4]'
769
+ ]
770
+
771
+ ExportSpecifier: [
772
+ o 'Identifier'
773
+ o 'Identifier AS Identifier', '[1, 3]'
774
+ o 'Identifier AS DEFAULT' , '[1, 3]'
775
+ o 'DEFAULT'
776
+ o 'DEFAULT AS Identifier' , '[1, 3]'
777
+ ]
778
+
779
+ # ============================================================================
780
+ # Operations
781
+ # ============================================================================
782
+
783
+ # Single-line operation forms
743
784
  OperationLine: [
744
785
  o 'UNARY ExpressionLine', '[1, 2]'
745
786
  o 'DO ExpressionLine' , '["do-iife", 2]'
746
787
  o 'DO_IIFE CodeLine' , '["do-iife", 2]'
747
788
  ]
748
789
 
749
- # All operations - unary and binary
790
+ # All operations unary and binary
750
791
  Operation: [
751
- # Unary operators
752
- o 'UNARY Expression' , '[1, 2]' # not, typeof, delete, new
792
+ # Unary
793
+ o 'UNARY Expression' , '[1, 2]' # not, typeof, delete, new
753
794
  o 'DO Expression' , '["do-iife", 2]'
754
- o 'UNARY_MATH Expression' , '[1, 2]' # !, ~
755
- o '- Expression' , '["-", 2]', prec: 'UNARY_MATH' # Unary minus
756
- o '+ Expression' , '["+", 2]', prec: 'UNARY_MATH' # Unary plus
795
+ o 'UNARY_MATH Expression' , '[1, 2]' # !, ~
796
+ o '- Expression' , '["-", 2]', prec: 'UNARY_MATH'
797
+ o '+ Expression' , '["+", 2]', prec: 'UNARY_MATH'
757
798
 
758
799
  # Await
759
800
  o 'AWAIT Expression' , '["await", 2]'
760
801
  o 'AWAIT INDENT Object OUTDENT' , '["await", 3]'
761
802
 
762
- # Increment/decrement (with prefix/postfix flag)
763
- o '-- SimpleAssignable', '["--", 2, false]' # Prefix: --x
764
- o '++ SimpleAssignable', '["++", 2, false]' # Prefix: ++x
765
- o 'SimpleAssignable --', '["--", 1, true]' # Postfix: x--
766
- o 'SimpleAssignable ++', '["++", 1, true]' # Postfix: x++
767
-
768
- # Existence check
769
- o 'Expression ?', '["?", 1]'
803
+ # Increment/Decrement
804
+ o '-- SimpleAssignable', '["--", 2, false]' # Prefix
805
+ o '++ SimpleAssignable', '["++", 2, false]'
806
+ o 'SimpleAssignable --', '["--", 1, true]' # Postfix
807
+ o 'SimpleAssignable ++', '["++", 1, true]'
770
808
 
771
- # Binary operators
809
+ # Binary arithmetic
772
810
  o 'Expression + Expression' , '["+", 1, 3]'
773
811
  o 'Expression - Expression' , '["-", 1, 3]'
774
812
  o 'Expression MATH Expression' , '[2, 1, 3]' # *, /, %, //, %%
775
813
  o 'Expression ** Expression' , '["**", 1, 3]'
776
814
  o 'Expression SHIFT Expression' , '[2, 1, 3]' # <<, >>, >>>
777
- o 'Expression COMPARE Expression' , '[2, 1, 3]' # ==, !=, <, >, <=, >= (== and != convert to === and !== in codegen)
815
+ o 'Expression COMPARE Expression' , '[2, 1, 3]' # ==, !=, <, >, <=, >=
778
816
  o 'Expression & Expression' , '["&", 1, 3]'
779
817
  o 'Expression ^ Expression' , '["^", 1, 3]'
780
818
  o 'Expression | Expression' , '["|", 1, 3]'
781
819
 
782
- # Control flow short-circuits (must be before generic && || ?? to take precedence)
820
+ # Control flow short-circuits
783
821
  o 'Expression || Return' , '["control", 2, 1, 3]'
784
822
  o 'Expression || Throw' , '["control", 2, 1, 3]'
785
823
  o 'Expression ?? Return' , '["control", 2, 1, 3]'
@@ -787,17 +825,20 @@ grammar =
787
825
  o 'Expression && Return' , '["control", 2, 1, 3]'
788
826
  o 'Expression && Throw' , '["control", 2, 1, 3]'
789
827
 
828
+ # Logical / Nullish
790
829
  o 'Expression && Expression' , '["&&", 1, 3]'
791
830
  o 'Expression || Expression' , '["||", 1, 3]'
792
- o 'Expression ?? Expression' , '["??", 1, 3]' # Nullish coalescing
793
- o 'Expression !? Expression' , '["!?", 1, 3]' # Otherwise operator (undefined-only coalescing)
831
+ o 'Expression ?? Expression' , '["??", 1, 3]'
832
+ o 'Expression !? Expression' , '["!?", 1, 3]' # Otherwise (undefined-only coalescing)
833
+
834
+ # Relational
794
835
  o 'Expression RELATION Expression', '[2, 1, 3]' # in, of, instanceof
795
836
 
796
- # Ternary operator (uses SPACE? token = ? with space before it)
837
+ # Ternary
797
838
  o 'Expression SPACE? Expression : Expression', '["?:", 1, 3, 5]'
798
839
 
799
- # Compound assignment operators
800
- o 'SimpleAssignable COMPOUND_ASSIGN Expression' , '[2, 1, 3]' # +=, -=, ||=, etc.
840
+ # Compound assignment
841
+ o 'SimpleAssignable COMPOUND_ASSIGN Expression' , '[2, 1, 3]'
801
842
  o 'SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT', '[2, 1, 4]'
802
843
  o 'SimpleAssignable COMPOUND_ASSIGN TERMINATOR Expression' , '[2, 1, 4]'
803
844
  ]
@@ -807,13 +848,15 @@ grammar =
807
848
  o 'DO_IIFE Code', '["do-iife", 2]'
808
849
  ]
809
850
 
810
- # Precedence here is high to low
851
+ # ==============================================================================
852
+ # Operator Precedence (high to low)
853
+ # ==============================================================================
854
+
811
855
  operators = """
812
856
  right DO_IIFE
813
- left . ?. :: ?::
857
+ left . ?.
814
858
  left CALL_START CALL_END
815
859
  nonassoc ++ --
816
- left ?
817
860
  right UNARY DO
818
861
  right AWAIT
819
862
  right **
@@ -832,15 +875,13 @@ operators = """
832
875
  nonassoc INDENT OUTDENT
833
876
  right YIELD
834
877
  right = : COMPOUND_ASSIGN RETURN THROW EXTENDS
835
- right FORIN FOROF FORFROM BY WHEN
878
+ right FORIN FOROF FORAS FORASAWAIT BY WHEN
836
879
  right IF ELSE FOR WHILE UNTIL LOOP SUPER CLASS IMPORT EXPORT DYNAMIC_IMPORT
837
880
  left POST_IF
838
881
  """.trim().split('\n').reverse().map (line) -> line.trim().split /\s+/
839
882
 
840
- # Wrapping Up
841
- # -----------
883
+ # ==============================================================================
884
+ # Export
885
+ # ==============================================================================
842
886
 
843
- # Export the processed grammar and operators for the parser generator. Unlike
844
- # the original implementation, we no longer extract and pass tokens separately,
845
- # the parser generator can derive them automatically from the BNF grammar.
846
887
  export default {mode, grammar, operators}