You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
['function', 'name', ['a', 'b'], body] function name(a, b) { body }
210
-
['function', null, ['x'], body] function(x) { body }
211
+
['function', 'name', [',', 'a', 'b'], body] function name(a, b) { body }
212
+
['function', '', 'x', body] function(x) { body }
211
213
```
212
214
213
215
@@ -218,15 +220,25 @@ Template literals contain string parts (as literals) interleaved with expression
218
220
219
221
Following McCarthy's [original Lisp](http://www-formal.stanford.edu/jmc/recursive.pdf) (1960), the operator occupies position zero. This enables uniform traversal: every node is processed identically regardless of arity.
220
222
221
-
### 2. Strings are References
223
+
### 2. Strings are References or Tokens
222
224
223
-
An unwrapped string is always an identifier — a name to resolve from context. This prevents confusion between the *name*`"x"` and the *string value*`"x"`.
225
+
An unwrapped string in operand position is interpreted by the operator:
226
+
227
+
-**Identifier**: resolved from context (most operators)
228
+
-**Token**: used directly as name/data (operator-specific)
224
229
225
230
```
226
-
"x" → resolve x from context
227
-
[, "x"] → the literal string "x"
231
+
"x" → resolve x from context
232
+
[, "x"] → the literal string "x"
233
+
['.', a, 'b'] → 'b' is property name (token)
234
+
['//', 'abc', 'g']→ pattern/flags are tokens
235
+
['n', '123'] → bigint digits are token
236
+
['px', '100'] → unit value is token
237
+
['function', 'f', ...] → 'f' is function name (token)
228
238
```
229
239
240
+
Operators that use tokens: `.`, `?.`, `//`, `n`, `px`/units, `=>`, `function`, `let`, `const`, `try` (catch param).
241
+
230
242
### 3. Empty Slot for Literals
231
243
232
244
The pattern `[, value]` uses JavaScript's elision syntax. The empty first position signals: *this is data, not code*. No operator means no operation.
@@ -275,41 +287,74 @@ Custom operators are simply strings in position zero.
**Regex** uses `//` as constructor operator (distinct from `/` division):
293
-
- Division: `['/', a, b]`
294
-
- Regex: `['//', pattern]` or `['//', pattern, flags]`
304
+
**Regex** (`//`), **BigInt** (`n`), and **Units** (`px`, `em`, etc.) use tokens because they're syntactic parts of the primitive, like property names in `.` access.
295
305
296
306
**Template literals** must be operations — they contain sub-expressions to evaluate.
297
307
298
-
**Note**: For full JSON serialization portability, non-JSON primitives should use constructor form. JS-only values (`undefined`, `NaN`, `Infinity`) work in JS runtime but serialize to `null`.
299
308
309
+
### Examples
310
+
311
+
**Property access** — name is token:
312
+
```
313
+
a.b → ['.', 'a', 'b']
314
+
a?.b → ['?.', 'a', 'b']
315
+
```
316
+
317
+
**Primitives** — pattern/digits/unit are tokens:
318
+
```
319
+
/abc/gi → ['//', 'abc', 'gi']
320
+
10n → ['n', '10']
321
+
100px → ['px', '100']
322
+
```
323
+
324
+
**Variables** — wrap assignment expression:
325
+
```
326
+
let x → ['let', 'x']
327
+
let x = 1 → ['let', ['=', 'x', [, 1]]]
328
+
const y = 2 → ['const', ['=', 'y', [, 2]]]
329
+
```
300
330
301
-
### Operand Validity
331
+
**For loops** — head is an expression:
332
+
```
333
+
for (x of arr) {} → ['for', ['of', 'x', 'arr'], body]
334
+
for (const x of arr) {} → ['for', ['of', ['const', 'x'], 'arr'], body]
335
+
for (let x of arr) {} → ['for', ['of', ['let', 'x'], 'arr'], body]
336
+
for (x in obj) {} → ['for', ['in', 'x', 'obj'], body]
337
+
for (;;) {} → ['for', [';', null, null, null], body]
338
+
```
302
339
303
-
Operands must be valid tree nodes:
340
+
**Try/catch** — uses `catch`/`finally` as operators:
341
+
```
342
+
try { a } catch (e) { b } → ['catch', ['try', 'a'], 'e', 'b']
343
+
try { a } finally { c } → ['finally', ['try', 'a'], 'c']
344
+
try { a } catch (e) { b } finally { c } → ['finally', ['catch', ['try', 'a'], 'e', 'b'], 'c']
345
+
```
304
346
347
+
**Functions** — name and params are tokens:
305
348
```
306
-
['px', [, 100]] ✓ literal operand
307
-
['px', 'x'] ✓ identifier operand
308
-
['px', 100] ✗ raw number is not a tree node
349
+
function f(a, b) { c } → ['function', 'f', [',', 'a', 'b'], 'c']
350
+
function(x) { y } → ['function', '', 'x', 'y']
351
+
x => x → ['=>', 'x', 'x']
352
+
(a, b) => a + b → ['=>', ['()', [',', 'a', 'b']], ['+', 'a', 'b']]
309
353
```
310
354
311
355
312
356
357
+
313
358
## Serialization
314
359
315
360
The format is valid JSON when serialized with standard `JSON.stringify`. Elided array elements serialize as `null`:
0 commit comments