@danielx/civet 0.7.0 → 0.7.1

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 (4) hide show
  1. package/dist/browser.js +2028 -1982
  2. package/dist/main.js +2028 -1982
  3. package/dist/main.mjs +2028 -1982
  4. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -31,1061 +31,629 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  mod
32
32
  ));
33
33
 
34
- // source/parser/op.civet
35
- function getPrecedence(op) {
36
- if (typeof op === "string") {
37
- return precedenceMap.get(op) ?? (() => {
38
- throw new Error(`Unknown operator: ${op}`);
39
- })();
40
- } else if (typeof op.prec === "number") {
41
- return op.prec;
42
- } else {
43
- return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
44
- }
45
- }
46
- function processBinaryOpExpression($0) {
47
- return recurse(expandChainedComparisons($0));
48
- function recurse(expandedOps) {
49
- let i = 2;
50
- while (i < expandedOps.length) {
51
- let op = expandedOps[i];
52
- if (op.special) {
53
- let advanceLeft2 = function(allowEqual) {
54
- while (start >= 4) {
55
- const prevPrec = getPrecedence(expandedOps[start - 2]);
56
- if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
57
- return prevPrec === prec;
58
- }
59
- start -= 4;
60
- }
61
- return false;
62
- }, advanceRight2 = function(allowEqual) {
63
- while (end + 4 < expandedOps.length) {
64
- const nextPrec = getPrecedence(expandedOps[end + 2]);
65
- if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
66
- return nextPrec === prec;
67
- }
68
- end += 4;
69
- }
70
- return false;
71
- };
72
- var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
73
- let start = i - 2, end = i + 2;
74
- const prec = getPrecedence(op);
75
- let error;
76
- switch (op.assoc) {
77
- case "left":
78
- case void 0: {
79
- advanceLeft2(true);
80
- advanceRight2(false);
81
- break;
82
- }
83
- case "right": {
84
- advanceLeft2(false);
85
- advanceRight2(true);
86
- break;
87
- }
88
- case "non": {
89
- if (advanceLeft2(false) || advanceRight2(false)) {
90
- error = {
91
- type: "Error",
92
- message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
93
- };
94
- }
95
- ;
96
- break;
97
- }
98
- case "arguments": {
99
- if (advanceLeft2(false)) {
100
- error = {
101
- type: "Error",
102
- message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
103
- };
104
- }
105
- advanceRight2(true);
106
- break;
107
- }
108
- default: {
109
- throw new Error(`Unsupported associativity: ${op.assoc}`);
110
- }
111
- }
112
- let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
113
- let wsOp = expandedOps[i - 1];
114
- let wsB = expandedOps[i + 1];
115
- let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
116
- if (op.assoc === "arguments") {
117
- let i2 = 2;
118
- while (i2 < b.length) {
119
- if (prec === getPrecedence(b[i2])) {
120
- if (!(b[i2].token === op.token)) {
121
- error ??= {
122
- type: "Error",
123
- message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
124
- };
125
- }
126
- b[i2] = ",";
127
- }
128
- i2 += 4;
129
- }
130
- } else {
131
- b = recurse(b);
132
- }
133
- if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
134
- a = ["typeof ", makeLeftHandSideExpression(a)];
135
- if (op.negated) {
136
- op = { ...op, token: "!==", negated: false };
137
- } else {
138
- op = { ...op, token: "===" };
139
- }
140
- }
141
- if (op.asConst) {
142
- a = makeAsConst(a);
143
- b = makeAsConst(b);
144
- }
145
- let children;
146
- if (op.call) {
147
- wsOp = insertTrimmingSpace(wsOp, "");
148
- if (op.reversed) {
149
- wsB = insertTrimmingSpace(wsB, "");
150
- children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
151
- } else {
152
- children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
153
- }
154
- } else if (op.method) {
155
- wsOp = insertTrimmingSpace(wsOp, "");
156
- wsB = insertTrimmingSpace(wsB, "");
157
- if (op.reversed) {
158
- if (end !== i + 2)
159
- b = makeLeftHandSideExpression(b);
160
- b = dotNumericLiteral(b);
161
- children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
162
- } else {
163
- if (start !== i - 2 || a.type === "NumericLiteral") {
164
- a = makeLeftHandSideExpression(a);
165
- }
166
- a = dotNumericLiteral(a);
167
- children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
168
- }
169
- } else if (op.token) {
170
- children = [a, wsOp, op, wsB, b];
171
- if (op.negated)
172
- children = ["(", ...children, ")"];
173
- } else {
174
- throw new Error("Unknown operator: " + JSON.stringify(op));
175
- }
176
- if (op.negated)
177
- children.unshift("!");
178
- if (error != null) {
179
- children.push(error);
180
- }
181
- expandedOps.splice(start, end - start + 1, {
182
- children
183
- });
184
- i = start + 2;
185
- } else {
186
- i += 4;
187
- }
188
- }
189
- return expandedOps;
190
- }
191
- ;
192
- return recurse;
193
- }
194
- function dotNumericLiteral(literal) {
195
- if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
196
- literal.children.push(".");
197
- literal.raw += ".";
198
- }
199
- return literal;
200
- }
201
- function makeAsConst(node) {
202
- if (Array.isArray(node) && node.length === 1) {
203
- node = node[0];
204
- }
205
- if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
206
- return { ...node, children: [...node.children, asConst] };
207
- } else {
208
- return node;
209
- }
210
- }
211
- function isExistence(exp) {
212
- if (exp?.type === "ParenthesizedExpression" && exp.implicit) {
213
- exp = exp.expression;
214
- }
215
- if (exp?.type === "Existence") {
216
- return exp;
217
- }
218
- ;
219
- return;
220
- }
221
- function isRelationalOp(op) {
222
- return op.relational || getPrecedence(op) === precedenceRelational;
223
- }
224
- function expandChainedComparisons([first, binops]) {
225
- if (!binops.length) {
226
- return [first];
227
- }
228
- const results = [];
229
- let start = 0;
230
- const chains = [];
231
- var i = 0;
232
- for (let i3 = 0, len2 = binops.length; i3 < len2; i3++) {
233
- var i = i3;
234
- var [, op] = binops[i3];
235
- if (isRelationalOp(op)) {
236
- chains.push(i);
237
- } else if (getPrecedence(op) < precedenceRelational) {
238
- processChains();
239
- first = results.pop();
240
- }
241
- }
242
- processChains();
243
- return results;
244
- function processChains() {
245
- if (chains.length > 0) {
246
- first = expandExistence(first);
247
- for (let i4 = 0, len3 = chains.length; i4 < len3; i4++) {
248
- const k = i4;
249
- const index = chains[i4];
250
- if (k > 0) {
251
- results.push(" ", "&&", " ");
252
- }
253
- const binop = binops[index];
254
- const exp = binop[3] = expandExistence(binop[3]);
255
- results.push(first);
256
- const endIndex = chains[k + 1] ?? i + 1;
257
- results.push(...binops.slice(start, endIndex).flat());
258
- first = [exp].concat(binops.slice(index + 1, endIndex));
259
- start = endIndex;
260
- }
261
- } else {
262
- results.push(first);
263
- results.push(...binops.slice(start, i + 1).flat());
264
- start = i + 1;
265
- }
266
- chains.length = 0;
267
- }
268
- function expandExistence(exp) {
269
- let ref;
270
- if (ref = isExistence(exp)) {
271
- const existence = ref;
272
- results.push(existence, " ", "&&", " ");
273
- return existence.expression;
274
- } else {
275
- return exp;
276
- }
277
- }
278
- ;
279
- }
280
- var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
281
- var init_op = __esm({
282
- "source/parser/op.civet"() {
283
- "use strict";
284
- init_util();
285
- precedenceOrder = [
286
- ["||", "??"],
287
- ["^^"],
288
- ["&&"],
289
- ["|"],
290
- ["^"],
291
- ["&"],
292
- // NOTE: Equality and inequality merged because of relational chaining
293
- [
294
- "==",
295
- "!=",
296
- "===",
297
- "!==",
298
- "<",
299
- "<=",
300
- ">",
301
- ">=",
302
- "in",
303
- "instanceof"
304
- ],
305
- // NOTE: Extra in-between level for default custom operators
306
- ["custom"],
307
- ["<<", ">>", ">>>"],
308
- ["+", "-"],
309
- ["*", "/", "%"],
310
- ["**"]
311
- ];
312
- precedenceMap = /* @__PURE__ */ new Map();
313
- for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
314
- const prec = i1;
315
- const ops = precedenceOrder[i1];
316
- for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
317
- const op = ops[i2];
318
- precedenceMap.set(op, prec);
319
- }
320
- }
321
- precedenceStep = 1 / 64;
322
- precedenceRelational = precedenceMap.get("==");
323
- precedenceCustomDefault = precedenceMap.get("custom");
324
- asConst = {
325
- ts: true,
326
- children: [" as const"]
327
- };
328
- }
329
- });
330
-
331
- // source/parser/unary.civet
332
- function processUnaryExpression(pre, exp, post) {
333
- if (!(pre.length || post))
334
- return exp;
335
- if (post?.token === "?") {
336
- post = {
337
- $loc: post.$loc,
338
- token: " != null"
339
- };
340
- if (pre.length) {
341
- const lastPre = pre.at(-1);
342
- if (lastPre.token === "!") {
343
- post.token = " == null";
344
- pre = pre.slice(0, -1);
345
- } else if (lastPre.length === 2 && lastPre[0].token === "!") {
346
- post.token = " == null";
347
- pre = pre.slice(0, -1);
348
- }
349
- }
350
- const existence = {
351
- type: "Existence",
352
- expression: exp,
353
- children: [exp, post],
354
- parent: void 0
355
- };
356
- exp = makeLeftHandSideExpression(existence);
357
- if (pre.length) {
358
- return {
359
- type: "UnaryExpression",
360
- children: [...pre, exp]
361
- };
362
- }
363
- return exp;
364
- }
365
- if (exp.type === "Literal") {
366
- if (pre.length === 1) {
367
- const { token } = pre[0];
368
- if (token === "-" || token === "+") {
369
- const children = [pre[0], ...exp.children];
370
- const literal = {
371
- type: "Literal",
372
- children,
373
- raw: `${token}${exp.raw}`
374
- };
375
- if (post) {
376
- return {
377
- type: "UnaryExpression",
378
- children: [literal, post]
379
- };
380
- }
381
- return literal;
382
- }
383
- }
384
- }
385
- let ref;
386
- while (ref = pre.length) {
387
- const l = ref;
388
- const last = pre[l - 1];
389
- if (last.type === "Await") {
390
- if (last.op) {
391
- if (exp.type !== "ParenthesizedExpression") {
392
- exp = ["(", exp, ")"];
393
- }
394
- exp = {
395
- type: "CallExpression",
396
- children: [...last.children, "Promise", last.op, exp]
397
- };
398
- pre = pre.slice(0, -1);
399
- } else {
400
- exp = {
401
- type: "AwaitExpression",
402
- children: [...last.children, exp]
403
- };
404
- pre = pre.slice(0, -1);
405
- }
406
- } else {
407
- break;
408
- }
409
- }
410
- return {
411
- type: "UnaryExpression",
412
- children: [...pre, exp, post]
413
- };
414
- }
415
- var init_unary = __esm({
416
- "source/parser/unary.civet"() {
417
- "use strict";
418
- init_util();
419
- }
420
- });
421
-
422
- // source/parser/util.civet
423
- function addParentPointers(node, parent) {
424
- if (node == null)
425
- return;
426
- if (typeof node !== "object")
427
- return;
428
- if (Array.isArray(node)) {
429
- for (const child of node) {
430
- addParentPointers(child, parent);
431
- }
432
- return;
433
- }
434
- node = node;
435
- node.parent = parent;
436
- if (node.children) {
437
- for (const child of node.children) {
438
- addParentPointers(child, node);
439
- }
440
- }
441
- }
442
- function clone(node) {
443
- removeParentPointers(node);
444
- return deepCopy(node);
445
- }
446
- function removeParentPointers(node) {
447
- if (node == null)
448
- return;
449
- if (typeof node !== "object")
450
- return;
451
- if (Array.isArray(node)) {
452
- for (const child of node) {
453
- removeParentPointers(child);
454
- }
455
- return;
456
- }
457
- node.parent = null;
458
- if (node.children) {
459
- for (const child of node.children) {
460
- removeParentPointers(child);
461
- }
462
- }
463
- }
464
- function maybeWrap(node, parent) {
465
- if (!isASTNodeObject(node)) {
466
- updateParentPointers(node = {
467
- type: "Wrapper",
468
- children: [node],
469
- parent
470
- });
471
- }
472
- return node;
473
- }
474
- function maybeUnwrap(node) {
475
- if (node?.type === "Wrapper") {
476
- return node.children[0];
477
- } else {
478
- return node;
479
- }
480
- }
481
- function isASTNodeObject(node) {
482
- return typeof node === "object" && node != null && !Array.isArray(node);
483
- }
484
- function isParent(node) {
485
- return node != null && node.children != null;
486
- }
487
- function isToken(node) {
488
- return node != null && node.token != null;
489
- }
490
- function isEmptyBareBlock(node) {
491
- if (node?.type !== "BlockStatement")
492
- return false;
493
- const { bare, expressions } = node;
494
- return bare && (expressions.length === 0 || expressions.length === 1 && expressions[0][1]?.type === "EmptyStatement");
495
- }
496
- function isFunction(node) {
497
- const { type } = node;
498
- return type === "FunctionExpression" || type === "ArrowFunction" || type === "MethodDefinition" || !!node.async;
499
- }
500
- function isWhitespaceOrEmpty(node) {
501
- if (!node)
502
- return true;
503
- if (node.type === "Ref")
504
- return false;
505
- if (node.token)
506
- return node.token.match(/^\s*$/);
507
- if (node.children)
508
- node = node.children;
509
- if (!node.length)
510
- return true;
511
- if (typeof node === "string")
512
- return node.match(/^\s*$/);
513
- if (Array.isArray(node))
514
- return node.every(isWhitespaceOrEmpty);
515
- return;
516
- }
517
- function isExit(node) {
518
- if (!(node != null)) {
519
- return false;
520
- }
521
- switch (node.type) {
522
- case "ReturnStatement":
523
- case "ThrowStatement":
524
- case "BreakStatement":
525
- case "ContinueStatement": {
526
- return true;
527
- }
528
- case "IfStatement": {
529
- return isExit(node.then) && isExit(node.else?.at(-1));
530
- }
531
- case "BlockStatement": {
532
- return isExit(node.expressions.at(-1)?.[1]);
533
- }
534
- case "IterationStatement": {
535
- return node.condition?.type === "ParenthesizedExpression" && node.condition.expression?.type === "Literal" && node.condition.expression?.raw === "true" && gatherRecursiveWithinFunction(
536
- node.block,
537
- ({ type }) => type === "BreakStatement"
538
- ).length === 0;
34
+ // source/parser/binding.civet
35
+ function adjustAtBindings(statements, asThis = false) {
36
+ gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
37
+ const { ref } = binding;
38
+ if (asThis) {
39
+ const atBinding = binding.binding;
40
+ atBinding.children.pop();
41
+ atBinding.type = void 0;
42
+ binding.children.unshift(ref.id, ": this.", ref.base);
43
+ binding.type = "Property";
44
+ binding.ref = void 0;
45
+ return;
539
46
  }
540
- default: {
541
- return false;
47
+ if (ref.names[0] !== ref.base) {
48
+ return binding.children.unshift(ref.base, ": ");
542
49
  }
543
- }
544
- }
545
- function isComma(node) {
546
- if (node?.token === ",") {
547
- return node;
548
- } else if (Array.isArray(node) && node.at(-1)?.token === ",") {
549
- return node.at(-1);
550
- }
551
- ;
552
- return;
50
+ ;
51
+ return;
52
+ });
553
53
  }
554
- function insertTrimmingSpace(target, c) {
555
- if (!(target != null)) {
556
- return target;
557
- }
558
- if (Array.isArray(target)) {
559
- if (target.length === 0) {
560
- return c;
54
+ function adjustBindingElements(elements) {
55
+ const names = elements.flatMap((p) => p.names || []), { length } = elements;
56
+ let blockPrefix, restIndex = -1, restCount = 0;
57
+ elements.forEach(({ type }, i) => {
58
+ if (type === "BindingRestElement") {
59
+ if (restIndex < 0)
60
+ restIndex = i;
61
+ return restCount++;
561
62
  }
562
- return target.map((e, i) => {
563
- if (i === 0) {
564
- return insertTrimmingSpace(e, c);
565
- } else {
566
- return e;
567
- }
568
- });
569
- } else if (isParent(target)) {
570
- return {
571
- ...target,
572
- children: insertTrimmingSpace(target.children, c)
573
- };
574
- } else if (isToken(target)) {
63
+ ;
64
+ return;
65
+ });
66
+ if (restCount === 0) {
575
67
  return {
576
- ...target,
577
- token: target.token.replace(/^ ?/, c)
68
+ children: elements,
69
+ names,
70
+ blockPrefix,
71
+ length
578
72
  };
579
- } else {
580
- return target;
581
- }
582
- }
583
- function inplaceInsertTrimmingSpace(target, c) {
584
- if (!(target != null)) {
585
- return target;
586
- }
587
- if (Array.isArray(target)) {
588
- inplaceInsertTrimmingSpace(target[0], c);
589
- } else if (isParent(target)) {
590
- inplaceInsertTrimmingSpace(target.children, c);
591
- } else if (isToken(target)) {
592
- target.token = target.token.replace(/^ ?/, c);
593
- }
594
- }
595
- function getTrimmingSpace(target) {
596
- if (!(target != null)) {
597
- return;
598
- }
599
- if (Array.isArray(target)) {
600
- return getTrimmingSpace(target[0]);
601
- } else if (isParent(target)) {
602
- return getTrimmingSpace(target.children[0]);
603
- } else if (isToken(target)) {
604
- return target.token.match(/^ ?/)[0];
605
- }
606
- ;
607
- return;
608
- }
609
- function prepend(prefix, node) {
610
- if (!(prefix && prefix.length)) {
611
- return node;
612
- }
613
- if (Array.isArray(node)) {
614
- return [prefix, ...node];
615
- } else if (isParent(node)) {
73
+ } else if (restCount === 1) {
74
+ const rest = elements[restIndex];
75
+ const after = elements.slice(restIndex + 1);
76
+ const restIdentifier = rest.binding.ref || rest.binding;
77
+ names.push(...rest.names || []);
78
+ let l = after.length;
79
+ if (l) {
80
+ if (arrayElementHasTrailingComma(after[l - 1]))
81
+ l++;
82
+ blockPrefix = {
83
+ type: "PostRestBindingElements",
84
+ children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
85
+ names: after.flatMap((p) => p.names)
86
+ };
87
+ }
616
88
  return {
617
- ...node,
618
- children: [prefix, ...node.children]
89
+ names,
90
+ children: [...elements.slice(0, restIndex), {
91
+ ...rest,
92
+ children: rest.children.slice(0, -1)
93
+ // remove trailing comma
94
+ }],
95
+ blockPrefix,
96
+ length
619
97
  };
620
- } else {
621
- return [prefix, node];
622
- }
623
- }
624
- function inplacePrepend(prefix, node) {
625
- if (!prefix) {
626
- return;
627
- }
628
- if (Array.isArray(prefix) && !prefix.length) {
629
- return;
630
- }
631
- if (Array.isArray(node)) {
632
- node.unshift(prefix);
633
- } else if (isParent(node)) {
634
- node.children.unshift(prefix);
635
- } else {
636
- throw new Error("Can't prepend to a leaf node");
637
98
  }
99
+ const err = {
100
+ type: "Error",
101
+ children: ["Multiple rest elements in array pattern"]
102
+ };
103
+ return {
104
+ names,
105
+ children: [...elements, err],
106
+ blockPrefix,
107
+ length
108
+ };
638
109
  }
639
- function literalValue(literal) {
640
- let { raw } = literal;
641
- switch (raw) {
642
- case "null":
643
- return null;
644
- case "true":
645
- return true;
646
- case "false":
647
- return false;
648
- }
649
- if (raw.startsWith('"') && raw.endsWith('"') || raw.startsWith("'") && raw.endsWith("'")) {
650
- return raw.slice(1, -1);
651
- }
652
- const numeric = literal.children.find(
653
- (child) => child.type === "NumericLiteral"
654
- );
655
- if (numeric) {
656
- raw = raw.replace(/_/g, "");
657
- const { token } = numeric;
658
- if (token.endsWith("n")) {
659
- return BigInt(raw.slice(0, -1));
660
- } else if (token.match(/[\.eE]/)) {
661
- return parseFloat(raw);
662
- } else if (token.startsWith("0")) {
663
- switch (token.charAt(1).toLowerCase()) {
664
- case "x":
665
- return parseInt(raw.replace(/0[xX]/, ""), 16);
666
- case "b":
667
- return parseInt(raw.replace(/0[bB]/, ""), 2);
668
- case "o":
669
- return parseInt(raw.replace(/0[oO]/, ""), 8);
110
+ function gatherBindingCode(statements, opts) {
111
+ const thisAssignments = [];
112
+ const splices = [];
113
+ function insertRestSplices(s, p, thisAssignments2) {
114
+ gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
115
+ if (n.type === "AtBinding") {
116
+ const { ref } = n;
117
+ const { id } = ref;
118
+ thisAssignments2.push([`this.${id} = `, ref]);
119
+ return;
670
120
  }
671
- }
672
- return parseInt(raw, 10);
673
- }
674
- throw new Error("Unrecognized literal " + JSON.stringify(literal));
675
- }
676
- function startsWith(target, value) {
677
- if (!target)
678
- return;
679
- if (Array.isArray(target)) {
680
- let i = 0;
681
- let l = target.length;
682
- while (i < l) {
683
- const t = target[i];
684
- if (t && (t.length || t.token || t.children)) {
685
- break;
121
+ if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
122
+ n.names.forEach((id) => ({
123
+ push: thisAssignments2.push({
124
+ type: "AssignmentExpression",
125
+ children: [`this.${id} = `, id],
126
+ js: true
127
+ })
128
+ }));
129
+ return;
686
130
  }
687
- i++;
688
- }
689
- if (i < l) {
690
- return startsWith(target[i], value);
691
- }
131
+ const { blockPrefix } = n;
132
+ p.push(blockPrefix);
133
+ return insertRestSplices(blockPrefix, p, thisAssignments2);
134
+ });
692
135
  }
693
- if (typeof target === "string")
694
- return value.test(target);
695
- if (target.children)
696
- return startsWith(target.children, value);
697
- if (target.token)
698
- return value.test(target.token);
699
- return;
136
+ insertRestSplices(statements, splices, thisAssignments);
137
+ return [splices, thisAssignments];
700
138
  }
701
- function hasAwait(exp) {
702
- return gatherRecursiveWithinFunction(exp, ({ type }) => type === "Await").length > 0;
139
+ function arrayElementHasTrailingComma(elementNode) {
140
+ const lastChild = elementNode.children.at(-1);
141
+ return lastChild && lastChild[lastChild.length - 1]?.token === ",";
703
142
  }
704
- function hasYield(exp) {
705
- return gatherRecursiveWithinFunction(exp, ({ type }) => type === "Yield").length > 0;
143
+ var init_binding = __esm({
144
+ "source/parser/binding.civet"() {
145
+ "use strict";
146
+ init_traversal();
147
+ init_util();
148
+ }
149
+ });
150
+
151
+ // source/parser/function.civet
152
+ function isVoidType(t) {
153
+ return t?.type === "LiteralType" && t.t.type === "VoidType";
706
154
  }
707
- function hasImportDeclaration(exp) {
708
- return gatherRecursiveWithinFunction(exp, ({ type }) => type === "ImportDeclaration").length > 0;
155
+ function isPromiseVoidType(t) {
156
+ return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
157
+ }
158
+ function isGeneratorVoidType(t) {
159
+ return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
709
160
  }
710
- function deepCopy(node) {
711
- if (node == null)
712
- return node;
713
- if (typeof node !== "object")
714
- return node;
715
- if (Array.isArray(node)) {
716
- return node.map(deepCopy);
717
- }
718
- if (node?.type === "Ref")
719
- return node;
720
- return Object.fromEntries(
721
- Object.entries(node).map(([key, value]) => {
722
- return [key, deepCopy(value)];
723
- })
724
- );
161
+ function isAsyncGeneratorVoidType(t) {
162
+ return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
725
163
  }
726
- function removeHoistDecs(node) {
727
- if (node == null)
164
+ function implicitFunctionBlock(f) {
165
+ if (f.abstract || f.block || f.signature?.optional)
728
166
  return;
729
- if (typeof node !== "object")
167
+ const { name, parent } = f;
168
+ if (parent?.type === "ExportDeclaration")
730
169
  return;
731
- if ("hoistDec" in node) {
732
- node.hoistDec = void 0;
170
+ const expressions = parent?.expressions ?? parent?.elements;
171
+ const currentIndex = expressions?.findIndex(([, def]) => def === f);
172
+ const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
173
+ if (f.type === following?.type && name && name === following.name) {
174
+ f.ts = true;
175
+ } else {
176
+ const block = makeEmptyBlock();
177
+ block.parent = f;
178
+ f.block = block;
179
+ f.children.push(block);
180
+ f.ts = false;
733
181
  }
734
- if (Array.isArray(node)) {
735
- for (const child of node) {
736
- removeHoistDecs(child);
737
- }
738
- return;
182
+ }
183
+ function processReturn(f, implicitReturns) {
184
+ let { returnType } = f.signature;
185
+ if (returnType && returnType.optional) {
186
+ convertOptionalType(returnType);
739
187
  }
740
- if (node.children) {
741
- for (const child of node.children) {
742
- removeHoistDecs(child);
188
+ if (!processReturnValue(f) && implicitReturns) {
189
+ const { signature, block } = f;
190
+ const { modifier, name, returnType: returnType2 } = signature;
191
+ const { async, generator, set } = modifier;
192
+ const isMethod = f.type === "MethodDefinition";
193
+ const isConstructor = isMethod && name === "constructor";
194
+ const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
195
+ if (block?.type === "BlockStatement") {
196
+ if (isVoid || set || isConstructor) {
197
+ if (block.bare && block.implicitlyReturned) {
198
+ braceBlock(block);
199
+ }
200
+ } else {
201
+ if (!block.implicitlyReturned) {
202
+ insertReturn(block);
203
+ }
204
+ }
743
205
  }
744
206
  }
745
207
  }
746
- function makeAmpersandFunction(rhs) {
747
- let { ref, typeSuffix, body } = rhs;
748
- if (!(ref != null)) {
749
- ref = makeRef("$");
750
- inplacePrepend(ref, body);
751
- }
752
- if (body?.type === "ObjectExpression") {
753
- body = makeLeftHandSideExpression(body);
208
+ function processReturnValue(func) {
209
+ const { block } = func;
210
+ const values = gatherRecursiveWithinFunction(
211
+ block,
212
+ ({ type }) => type === "ReturnValue"
213
+ );
214
+ if (!values.length) {
215
+ return false;
754
216
  }
755
- const parameters = makeNode({
756
- type: "Parameters",
757
- children: typeSuffix ? ["(", ref, typeSuffix, ")"] : [ref],
758
- names: []
759
- });
760
- const expressions = [body];
761
- const block = makeNode({
762
- bare: true,
763
- expressions,
764
- children: [expressions]
217
+ const ref = makeRef("ret");
218
+ let declaration;
219
+ values.forEach((value) => {
220
+ value.children = [ref];
221
+ const { ancestor, child } = findAncestor(
222
+ value,
223
+ ({ type }) => type === "Declaration",
224
+ isFunction
225
+ );
226
+ if (ancestor) {
227
+ return declaration ??= child;
228
+ }
229
+ ;
230
+ return;
765
231
  });
766
- const children = [parameters, " => ", block];
767
- const async = hasAwait(body);
768
- if (async) {
769
- children.unshift("async ");
232
+ let returnType = func.returnType ?? func.signature?.returnType;
233
+ if (returnType) {
234
+ const { t } = returnType;
235
+ let m;
236
+ if (m = t.type, m === "TypePredicate") {
237
+ returnType = ": boolean";
238
+ } else if (m === "AssertsType") {
239
+ returnType = void 0;
240
+ }
770
241
  }
771
- return makeNode({
772
- type: "ArrowFunction",
773
- signature: {
774
- modifier: {
775
- async
776
- }
777
- },
778
- children,
779
- ref,
780
- body,
781
- ampersandBlock: true,
242
+ if (declaration) {
243
+ if (!(declaration.suffix != null)) {
244
+ declaration.children[1] = declaration.suffix = returnType;
245
+ }
246
+ } else {
247
+ block.expressions.unshift([
248
+ getIndent(block.expressions[0]),
249
+ {
250
+ type: "Declaration",
251
+ children: ["let ", ref, returnType],
252
+ names: []
253
+ },
254
+ ";"
255
+ ]);
256
+ }
257
+ gatherRecursiveWithinFunction(
782
258
  block,
783
- parameters
259
+ (r) => r.type === "ReturnStatement" && !r.expression
260
+ ).forEach((r) => {
261
+ r.expression = ref;
262
+ return r.children.splice(-1, 1, " ", ref);
784
263
  });
785
- }
786
- function makeLeftHandSideExpression(expression) {
787
- if (expression.parenthesized) {
788
- return expression;
264
+ if (!(block.children.at(-2)?.type === "ReturnStatement")) {
265
+ const indent = getIndent(block.expressions.at(-1)) || ";";
266
+ block.expressions.push([
267
+ [indent],
268
+ {
269
+ type: "ReturnStatement",
270
+ expression: ref,
271
+ children: ["return ", ref]
272
+ }
273
+ ]);
789
274
  }
790
- switch (expression.type) {
791
- case "AmpersandRef":
792
- case "CallExpression":
275
+ return true;
276
+ }
277
+ function patternAsValue(pattern) {
278
+ switch (pattern.type) {
279
+ case "ArrayBindingPattern": {
280
+ const children = [...pattern.children];
281
+ const index = children.indexOf(pattern.elements);
282
+ if (index < 0)
283
+ throw new Error("failed to find elements in ArrayBindingPattern");
284
+ children[index] = pattern.elements.map((el) => {
285
+ const [ws, e, delim] = el.children;
286
+ return { ...el, children: [ws, patternAsValue(e), delim] };
287
+ });
288
+ return { ...pattern, children };
289
+ }
290
+ case "ObjectBindingPattern": {
291
+ const children = [...pattern.children];
292
+ const index = children.indexOf(pattern.properties);
293
+ if (index < 0)
294
+ throw new Error("failed to find properties in ArrayBindingPattern");
295
+ children[index] = pattern.properties.map(patternAsValue);
296
+ return { ...pattern, children };
297
+ }
793
298
  case "Identifier":
794
- case "JSXElement":
795
- case "JSXFragment":
796
- case "Literal":
797
- case "MemberExpression":
798
- case "NewExpression":
799
- case "ParenthesizedExpression":
800
- case "Ref":
801
- case "Placeholder":
802
- case "StatementExpression":
803
- return expression;
299
+ case "BindingProperty": {
300
+ const children = [
301
+ // { name: value } = ... declares value, not name
302
+ pattern.value ?? pattern.name,
303
+ pattern.delim
304
+ ];
305
+ if (isWhitespaceOrEmpty(pattern.children[0])) {
306
+ children.unshift(pattern.children[0]);
307
+ }
308
+ return { ...pattern, children };
309
+ }
310
+ default:
311
+ return pattern;
804
312
  }
805
- return makeNode({
806
- type: "ParenthesizedExpression",
807
- children: ["(", expression, ")"],
808
- expression,
809
- implicit: true,
810
- parent: void 0
811
- });
812
313
  }
813
- function updateParentPointers(node, parent, depth = 1) {
814
- if (!(node != null)) {
314
+ function assignResults(node, collect) {
315
+ if (!node)
316
+ return;
317
+ switch (node.type) {
318
+ case "BlockStatement":
319
+ if (node.expressions.length) {
320
+ assignResults(node.expressions.at(-1), collect);
321
+ } else {
322
+ node.expressions.push(["", collect("void 0"), ";"]);
323
+ }
324
+ return;
325
+ case "CaseBlock":
326
+ node.clauses.forEach((clause) => {
327
+ return assignResults(clause, collect);
328
+ });
329
+ return;
330
+ case "WhenClause":
331
+ case "DefaultClause":
332
+ case "PatternClause": {
333
+ assignResults(node.block, collect);
334
+ return;
335
+ }
336
+ }
337
+ if (!Array.isArray(node)) {
815
338
  return;
816
339
  }
817
- if (!(typeof node === "object")) {
340
+ let [, exp, semi] = node;
341
+ if (semi?.type === "SemicolonDelimiter") {
818
342
  return;
819
343
  }
820
- if (Array.isArray(node)) {
821
- for (const child of node) {
822
- updateParentPointers(child, parent, depth);
823
- }
344
+ if (!exp) {
345
+ return;
346
+ }
347
+ if (isExit(exp)) {
824
348
  return;
825
349
  }
826
- node = node;
827
- if (parent != null) {
828
- node.parent = parent;
829
- }
830
- if (depth && isParent(node)) {
831
- for (const child of node.children) {
832
- updateParentPointers(child, node, depth - 1);
833
- }
350
+ const outer = exp;
351
+ let { type } = exp;
352
+ if (type === "LabelledStatement") {
353
+ exp = exp.statement;
354
+ ({ type } = exp);
834
355
  }
835
- }
836
- function makeNode(node) {
837
- updateParentPointers(node);
838
- return node;
839
- }
840
- function makeRef(base = "ref", id = base) {
841
- return {
842
- type: "Ref",
843
- base,
844
- id
845
- };
846
- }
847
- function needsRef(expression, base = "ref") {
848
- switch (expression.type) {
849
- case "Ref":
850
- case "Identifier":
851
- case "Literal":
356
+ switch (exp.type) {
357
+ case "BreakStatement":
358
+ case "ContinueStatement":
359
+ case "DebuggerStatement":
360
+ case "EmptyStatement":
361
+ case "ReturnStatement":
362
+ case "ThrowStatement":
363
+ return;
364
+ case "Declaration":
365
+ exp.children.push([
366
+ "",
367
+ [";", collect(patternAsValue(exp.bindings.at(-1).pattern))]
368
+ ]);
369
+ return;
370
+ case "ForStatement":
371
+ case "IterationStatement":
372
+ case "DoStatement":
373
+ wrapIterationReturningResults(exp, outer, collect);
374
+ return;
375
+ case "BlockStatement":
376
+ assignResults(exp.expressions[exp.expressions.length - 1], collect);
377
+ return;
378
+ case "IfStatement":
379
+ assignResults(exp.then, collect);
380
+ if (exp.then.bare && !exp.then.semicolon) {
381
+ exp.then.children.push(exp.then.semicolon = ";");
382
+ }
383
+ if (exp.else) {
384
+ assignResults(exp.else[2], collect);
385
+ } else {
386
+ exp.children.push([" else {", collect("undefined"), "}"]);
387
+ }
388
+ return;
389
+ case "PatternMatchingStatement":
390
+ assignResults(exp.children[0][0], collect);
391
+ return;
392
+ case "SwitchStatement":
393
+ assignResults(exp.children[2], collect);
394
+ return;
395
+ case "TryStatement":
396
+ exp.blocks.forEach((block) => assignResults(block, collect));
852
397
  return;
853
398
  }
854
- return makeRef(base);
855
- }
856
- function maybeRef(exp, base = "ref") {
857
- if (!needsRef(exp))
858
- return exp;
859
- return makeRef(base);
860
- }
861
- function skipIfOnlyWS(target) {
862
- if (!target)
863
- return target;
864
- if (Array.isArray(target)) {
865
- if (target.length === 1) {
866
- return skipIfOnlyWS(target[0]);
867
- } else if (target.every((e) => skipIfOnlyWS(e) === void 0)) {
868
- return void 0;
869
- }
870
- return target;
871
- }
872
- if (target.token != null && target.token.trim() === "") {
873
- return void 0;
399
+ if (node.at(-1)?.type === "SemicolonDelimiter") {
400
+ return;
874
401
  }
875
- return target;
402
+ node[1] = collect(node[1]);
876
403
  }
877
- function spliceChild(node, child, del, ...replacements) {
878
- const children = node?.children ?? node;
879
- if (!Array.isArray(children)) {
880
- throw new Error("spliceChild: non-array node has no children field");
404
+ function insertReturn(node, outerNode = node) {
405
+ if (!node)
406
+ return;
407
+ switch (node.type) {
408
+ case "BlockStatement":
409
+ if (node.expressions.length) {
410
+ const last = node.expressions[node.expressions.length - 1];
411
+ insertReturn(last);
412
+ } else {
413
+ if (node.parent.type === "CatchClause") {
414
+ node.expressions.push(["return"]);
415
+ }
416
+ }
417
+ return;
418
+ case "WhenClause":
419
+ if (node.break) {
420
+ node.children.splice(node.children.indexOf(node.break), 1);
421
+ }
422
+ if (node.block.expressions.length) {
423
+ insertReturn(node.block);
424
+ } else {
425
+ node.block.expressions.push(wrapWithReturn());
426
+ }
427
+ return;
428
+ case "DefaultClause":
429
+ insertReturn(node.block);
430
+ return;
881
431
  }
882
- const index = children.indexOf(child);
883
- if (index < 0) {
884
- throw new Error("spliceChild: child not found");
432
+ if (!Array.isArray(node))
433
+ return;
434
+ let [, exp, semi] = node;
435
+ if (semi?.type === "SemicolonDelimiter") {
436
+ return;
885
437
  }
886
- return children.splice(index, del, ...replacements);
887
- }
888
- function convertOptionalType(suffix) {
889
- if (suffix.t.type === "AssertsType") {
890
- spliceChild(suffix, suffix.optional, 1, suffix.optional = {
891
- type: "Error",
892
- message: "Can't use optional ?: syntax with asserts type"
893
- });
438
+ if (!exp) {
894
439
  return;
895
440
  }
896
- spliceChild(suffix, suffix.optional, 1, suffix.optional = void 0);
897
- const wrap = suffix.type === "ReturnTypeAnnotation";
898
- spliceChild(suffix, suffix.t, 1, suffix.t = [
899
- getTrimmingSpace(suffix.t),
900
- wrap && "(",
901
- // TODO: avoid parens if unnecessary
902
- "undefined | ",
903
- parenthesizeType(insertTrimmingSpace(suffix.t, "")),
904
- wrap && ")"
905
- ]);
906
- }
907
- function parenthesizeType(type) {
908
- if (typeNeedsNoParens.has(type.type)) {
909
- return type;
441
+ if (isExit(exp)) {
442
+ return;
910
443
  }
911
- return ["(", type, ")"];
912
- }
913
- function wrapIIFE(expressions, asyncFlag) {
914
- let prefix;
915
- let async;
916
- if (asyncFlag) {
917
- async = "async ";
918
- } else if (hasAwait(expressions)) {
919
- async = "async ";
920
- prefix = {
921
- type: "Await",
922
- children: ["await "]
923
- };
444
+ const outer = exp;
445
+ let { type } = exp;
446
+ if (type === "LabelledStatement") {
447
+ exp = exp.statement;
448
+ ({ type } = exp);
924
449
  }
925
- const block = makeNode({
926
- type: "BlockStatement",
927
- expressions,
928
- children: ["{", expressions, "}"],
929
- bare: false,
930
- root: false,
931
- parent: void 0
932
- });
933
- const parameters = {
934
- type: "Parameters",
935
- children: ["()"],
936
- names: []
937
- };
938
- const signature = {
939
- modifier: {
940
- async: !!async
941
- },
942
- returnType: void 0
943
- };
944
- const fn = makeNode({
945
- type: "ArrowFunction",
946
- signature,
947
- parameters,
948
- returnType: void 0,
949
- ts: false,
950
- async,
951
- block,
952
- children: [async, parameters, "=>", block]
953
- });
954
- const exp = makeNode({
955
- type: "CallExpression",
956
- children: [makeLeftHandSideExpression(fn), "()"]
957
- });
958
- if (prefix) {
959
- return [makeLeftHandSideExpression([prefix, exp])];
450
+ switch (type) {
451
+ case "BreakStatement":
452
+ case "ContinueStatement":
453
+ case "DebuggerStatement":
454
+ case "EmptyStatement":
455
+ case "ReturnStatement":
456
+ case "ThrowStatement":
457
+ return;
458
+ case "Declaration":
459
+ exp.children.push(["", {
460
+ type: "ReturnStatement",
461
+ children: [";return ", patternAsValue(exp.bindings.at(-1).pattern)],
462
+ parent: exp
463
+ }]);
464
+ return;
465
+ case "FunctionExpression":
466
+ if (exp.id) {
467
+ exp.children.push([
468
+ "",
469
+ {
470
+ type: "ReturnStatement",
471
+ children: [";return ", exp.id],
472
+ parent: exp
473
+ }
474
+ ]);
475
+ return;
476
+ }
477
+ break;
478
+ case "ForStatement":
479
+ case "IterationStatement":
480
+ case "DoStatement":
481
+ wrapIterationReturningResults(exp, outer);
482
+ return;
483
+ case "BlockStatement":
484
+ insertReturn(exp.expressions[exp.expressions.length - 1]);
485
+ return;
486
+ case "IfStatement":
487
+ insertReturn(exp.then);
488
+ if (exp.else && exp.else.length !== 0)
489
+ insertReturn(exp.else[2]);
490
+ else
491
+ exp.children.push(["", {
492
+ type: "ReturnStatement",
493
+ // NOTE: add a prefixed semi-colon because the if block may not be braced
494
+ children: [";return"],
495
+ parent: exp
496
+ }]);
497
+ return;
498
+ case "PatternMatchingStatement":
499
+ insertReturn(exp.children[0][0]);
500
+ return;
501
+ case "SwitchStatement":
502
+ insertSwitchReturns(exp);
503
+ return;
504
+ case "TryStatement":
505
+ exp.blocks.forEach((block) => insertReturn(block));
506
+ return;
960
507
  }
961
- return [exp];
508
+ if (node[node.length - 1]?.type === "SemicolonDelimiter")
509
+ return;
510
+ const returnStatement = wrapWithReturn(node[1]);
511
+ node.splice(1, 1, returnStatement);
962
512
  }
963
- function wrapWithReturn(expression) {
964
- const children = expression ? ["return ", expression] : ["return"];
965
- return makeNode({
966
- type: "ReturnStatement",
967
- children,
968
- expression,
969
- parent: expression?.parent
513
+ function insertSwitchReturns(exp) {
514
+ exp.caseBlock.clauses.forEach((clause) => {
515
+ return insertReturn(clause);
970
516
  });
971
517
  }
972
- var assert, typeNeedsNoParens;
973
- var init_util = __esm({
974
- "source/parser/util.civet"() {
975
- "use strict";
976
- init_traversal();
977
- init_op();
978
- init_unary();
979
- assert = {
980
- equal(a, b, msg) {
981
- if (a !== b) {
982
- throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
983
- }
984
- }
985
- };
986
- typeNeedsNoParens = /* @__PURE__ */ new Set([
987
- "IdentifierType",
988
- "ImportType",
989
- "LiteralType",
990
- "TupleType",
991
- "ParenthesizedType",
992
- "UnaryType"
993
- ]);
518
+ function wrapIterationReturningResults(statement, outer, collect) {
519
+ if (statement.type === "DoStatement") {
520
+ if (collect) {
521
+ assignResults(statement.block, collect);
522
+ } else {
523
+ insertReturn(statement.block, outer);
524
+ }
525
+ return;
994
526
  }
995
- });
996
-
997
- // source/parser/traversal.civet
998
- function gatherRecursiveWithinFunction(node, predicate) {
999
- return gatherRecursive(node, predicate, isFunction);
1000
- }
1001
- function findChildIndex(parent, child) {
1002
- if (!(parent != null)) {
1003
- return -1;
527
+ assert.equal(
528
+ statement.resultsRef,
529
+ void 0,
530
+ "wrapIterationReturningResults should not be called twice on the same statement"
531
+ );
532
+ const resultsRef = statement.resultsRef = makeRef("results");
533
+ const declaration = {
534
+ type: "Declaration",
535
+ children: ["const ", resultsRef, "=[]"]
536
+ };
537
+ outer.children.unshift(["", declaration, ";"]);
538
+ assignResults(statement.block, (node) => {
539
+ return [resultsRef, ".push(", node, ")"];
540
+ });
541
+ if (collect) {
542
+ statement.children.push(collect(resultsRef));
543
+ } else {
544
+ statement.children.push(";return ", resultsRef, ";");
1004
545
  }
1005
- const children = Array.isArray(parent) ? parent : parent.children;
1006
- if (!(children != null)) {
1007
- return -1;
546
+ }
547
+ function processParams(f) {
548
+ const { type, parameters, block } = f;
549
+ const isConstructor = f.name === "constructor";
550
+ if (type === "ArrowFunction" && parameters && parameters.tp && parameters.tp.parameters.length === 1) {
551
+ parameters.tp.parameters.push(",");
1008
552
  }
1009
- for (let i1 = 0, len = children.length; i1 < len; i1++) {
1010
- const i = i1;
1011
- const c = children[i1];
1012
- if (c === child || Array.isArray(c) && arrayRecurse(c)) {
1013
- return i;
1014
- }
553
+ if (!block)
554
+ return;
555
+ const { expressions } = block;
556
+ if (!expressions)
557
+ return;
558
+ const { blockPrefix } = parameters;
559
+ let indent;
560
+ if (!expressions.length) {
561
+ indent = "";
562
+ } else {
563
+ indent = expressions[0][0];
1015
564
  }
1016
- function arrayRecurse(array) {
1017
- for (let i2 = 0, len1 = array.length; i2 < len1; i2++) {
1018
- const c = array[i2];
1019
- if (c === child || Array.isArray(c) && arrayRecurse(c)) {
1020
- return true;
565
+ const [splices, thisAssignments] = gatherBindingCode(parameters, {
566
+ injectParamProps: isConstructor
567
+ });
568
+ const delimiter = {
569
+ type: "SemicolonDelimiter",
570
+ children: [";"]
571
+ };
572
+ const prefix = splices.map((s) => ["let ", s]).concat(thisAssignments).map(
573
+ (s) => s.type ? {
574
+ // TODO: figure out how to get JS only statement tuples
575
+ ...s,
576
+ children: [indent, ...s.children, delimiter]
577
+ } : [indent, s, delimiter]
578
+ );
579
+ if (!prefix.length)
580
+ return;
581
+ if (isConstructor) {
582
+ const superCalls = gatherNodes(expressions, (exp) => {
583
+ return exp.type === "CallExpression" && exp.children[0]?.token === "super";
584
+ });
585
+ if (superCalls.length) {
586
+ const { child } = findAncestor(
587
+ superCalls[0],
588
+ (ancestor) => ancestor === block
589
+ );
590
+ const index = findChildIndex(expressions, child);
591
+ if (index < 0) {
592
+ throw new Error("Could not find super call within top-level expressions");
1021
593
  }
594
+ expressions.splice(index + 1, 0, ...prefix);
595
+ return;
1022
596
  }
1023
- return false;
1024
- }
1025
- return -1;
1026
- }
1027
- function findAncestor(node, predicate, stopPredicate) {
1028
- let { parent } = node;
1029
- while (parent && !stopPredicate?.(parent, node)) {
1030
- if (predicate(parent, node)) {
1031
- return { ancestor: parent, child: node };
1032
- }
1033
- node = parent;
1034
- ({ parent } = node);
1035
597
  }
1036
- return { ancestor: void 0, child: node };
598
+ expressions.unshift(...prefix);
1037
599
  }
1038
- function gatherNodes(node, predicate) {
1039
- if (node == null)
1040
- return [];
1041
- if (Array.isArray(node)) {
1042
- return node.flatMap((n) => gatherNodes(n, predicate));
1043
- }
1044
- if (predicate(node)) {
1045
- return [node];
1046
- }
1047
- switch (node.type) {
1048
- case "BlockStatement":
1049
- return [];
1050
- case "ForStatement":
1051
- const isDec = node.declaration?.type === "Declaration";
1052
- return node.children.flatMap((n) => {
1053
- if (isDec && n === node.declaration)
1054
- return [];
1055
- return gatherNodes(n, predicate);
1056
- });
1057
- default:
1058
- return gatherNodes(node.children, predicate);
1059
- }
600
+ function processFunctions(statements, config) {
601
+ gatherRecursiveAll(statements, ({ type }) => type === "FunctionExpression" || type === "ArrowFunction").forEach((f) => {
602
+ if (f.type === "FunctionExpression")
603
+ implicitFunctionBlock(f);
604
+ processParams(f);
605
+ return processReturn(f, config.implicitReturns);
606
+ });
607
+ gatherRecursiveAll(statements, ({ type }) => type === "MethodDefinition").forEach((f) => {
608
+ implicitFunctionBlock(f);
609
+ processParams(f);
610
+ return processReturn(f, config.implicitReturns);
611
+ });
1060
612
  }
1061
- function gatherRecursive(node, predicate, skipPredicate) {
1062
- if (node == null)
1063
- return [];
1064
- if (Array.isArray(node)) {
1065
- return node.flatMap((n) => gatherRecursive(n, predicate, skipPredicate));
613
+ function expressionizeIteration(exp) {
614
+ const { async, subtype, block, children, statement } = exp;
615
+ const i = children.indexOf(statement);
616
+ if (i < 0) {
617
+ throw new Error("Could not find iteration statement in iteration expression");
1066
618
  }
1067
- if (skipPredicate?.(node))
1068
- return [];
1069
- if (predicate(node)) {
1070
- return [node];
619
+ if (subtype === "DoStatement") {
620
+ children.splice(i, 1, ...wrapIIFE([["", statement, void 0]], async));
621
+ updateParentPointers(exp);
622
+ return;
1071
623
  }
1072
- return gatherRecursive(node.children, predicate, skipPredicate);
624
+ exp.resultsRef ??= makeRef("results");
625
+ const { resultsRef } = exp;
626
+ assignResults(block, (node) => {
627
+ return [resultsRef, ".push(", node, ")"];
628
+ });
629
+ braceBlock(block);
630
+ children.splice(
631
+ i,
632
+ 1,
633
+ ...wrapIIFE([
634
+ ["", ["const ", resultsRef, "=[]"], ";"],
635
+ ...children.map((c) => ["", c, void 0]),
636
+ ["", wrapWithReturn(resultsRef)]
637
+ ], async)
638
+ );
639
+ updateParentPointers(exp);
1073
640
  }
1074
- function gatherRecursiveAll(node, predicate) {
1075
- if (node == null)
1076
- return [];
1077
- if (Array.isArray(node)) {
1078
- return node.flatMap((n) => gatherRecursiveAll(n, predicate));
1079
- }
1080
- const nodes = gatherRecursiveAll(node.children, predicate);
1081
- if (predicate(node)) {
1082
- nodes.push(node);
641
+ function skipImplicitArguments(args) {
642
+ if (args.length === 1) {
643
+ let arg0 = args[0];
644
+ if (arg0.type === "StatementExpression") {
645
+ arg0 = arg0.statement;
646
+ }
647
+ return arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block);
1083
648
  }
1084
- return nodes;
649
+ return false;
1085
650
  }
1086
- var init_traversal = __esm({
1087
- "source/parser/traversal.civet"() {
651
+ var init_function = __esm({
652
+ "source/parser/function.civet"() {
1088
653
  "use strict";
654
+ init_block();
655
+ init_binding();
656
+ init_traversal();
1089
657
  init_util();
1090
658
  }
1091
659
  });
@@ -1118,7 +686,13 @@ function braceBlock(block) {
1118
686
  }
1119
687
  block.children.unshift(" {");
1120
688
  block.children.push("}");
1121
- return block.bare = false;
689
+ const { implicitlyReturned } = block;
690
+ block.bare = block.implicitlyReturned = false;
691
+ if (implicitlyReturned) {
692
+ return processReturn(block.parent, true);
693
+ }
694
+ ;
695
+ return;
1122
696
  }
1123
697
  ;
1124
698
  return;
@@ -1292,1010 +866,1379 @@ var init_block = __esm({
1292
866
  "use strict";
1293
867
  init_util();
1294
868
  init_traversal();
869
+ init_function();
1295
870
  }
1296
871
  });
1297
872
 
1298
- // source/parser/binding.civet
1299
- function adjustAtBindings(statements, asThis = false) {
1300
- gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
1301
- const { ref } = binding;
1302
- if (asThis) {
1303
- const atBinding = binding.binding;
1304
- atBinding.children.pop();
1305
- atBinding.type = void 0;
1306
- binding.children.unshift(ref.id, ": this.", ref.base);
1307
- binding.type = "Property";
1308
- binding.ref = void 0;
1309
- return;
1310
- }
1311
- if (ref.names[0] !== ref.base) {
1312
- return binding.children.unshift(ref.base, ": ");
873
+ // source/parser/util.civet
874
+ function addParentPointers(node, parent) {
875
+ if (node == null)
876
+ return;
877
+ if (typeof node !== "object")
878
+ return;
879
+ if (Array.isArray(node)) {
880
+ for (const child of node) {
881
+ addParentPointers(child, parent);
1313
882
  }
1314
- ;
1315
883
  return;
1316
- });
884
+ }
885
+ node = node;
886
+ node.parent = parent;
887
+ if (node.children) {
888
+ for (const child of node.children) {
889
+ addParentPointers(child, node);
890
+ }
891
+ }
1317
892
  }
1318
- function adjustBindingElements(elements) {
1319
- const names = elements.flatMap((p) => p.names || []), { length } = elements;
1320
- let blockPrefix, restIndex = -1, restCount = 0;
1321
- elements.forEach(({ type }, i) => {
1322
- if (type === "BindingRestElement") {
1323
- if (restIndex < 0)
1324
- restIndex = i;
1325
- return restCount++;
893
+ function clone(node) {
894
+ removeParentPointers(node);
895
+ return deepCopy(node);
896
+ }
897
+ function removeParentPointers(node) {
898
+ if (node == null)
899
+ return;
900
+ if (typeof node !== "object")
901
+ return;
902
+ if (Array.isArray(node)) {
903
+ for (const child of node) {
904
+ removeParentPointers(child);
1326
905
  }
1327
- ;
1328
906
  return;
1329
- });
1330
- if (restCount === 0) {
907
+ }
908
+ node.parent = null;
909
+ if (node.children) {
910
+ for (const child of node.children) {
911
+ removeParentPointers(child);
912
+ }
913
+ }
914
+ }
915
+ function maybeWrap(node, parent) {
916
+ if (!isASTNodeObject(node)) {
917
+ updateParentPointers(node = {
918
+ type: "Wrapper",
919
+ children: [node],
920
+ parent
921
+ });
922
+ }
923
+ return node;
924
+ }
925
+ function maybeUnwrap(node) {
926
+ if (node?.type === "Wrapper") {
927
+ return node.children[0];
928
+ } else {
929
+ return node;
930
+ }
931
+ }
932
+ function isASTNodeObject(node) {
933
+ return typeof node === "object" && node != null && !Array.isArray(node);
934
+ }
935
+ function isParent(node) {
936
+ return node != null && node.children != null;
937
+ }
938
+ function isToken(node) {
939
+ return node != null && node.token != null;
940
+ }
941
+ function isEmptyBareBlock(node) {
942
+ if (node?.type !== "BlockStatement")
943
+ return false;
944
+ const { bare, expressions } = node;
945
+ return bare && (expressions.length === 0 || expressions.length === 1 && expressions[0][1]?.type === "EmptyStatement");
946
+ }
947
+ function isFunction(node) {
948
+ const { type } = node;
949
+ return type === "FunctionExpression" || type === "ArrowFunction" || type === "MethodDefinition" || !!node.async;
950
+ }
951
+ function isStatement(node) {
952
+ return isASTNodeObject(node) && node.type != null && // forbid leaf
953
+ statementTypes.has(node.type);
954
+ }
955
+ function isWhitespaceOrEmpty(node) {
956
+ if (!node)
957
+ return true;
958
+ if (node.type === "Ref")
959
+ return false;
960
+ if (node.token)
961
+ return node.token.match(/^\s*$/);
962
+ if (node.children)
963
+ node = node.children;
964
+ if (!node.length)
965
+ return true;
966
+ if (typeof node === "string")
967
+ return node.match(/^\s*$/);
968
+ if (Array.isArray(node))
969
+ return node.every(isWhitespaceOrEmpty);
970
+ return;
971
+ }
972
+ function isExit(node) {
973
+ if (!(node != null)) {
974
+ return false;
975
+ }
976
+ switch (node.type) {
977
+ case "ReturnStatement":
978
+ case "ThrowStatement":
979
+ case "BreakStatement":
980
+ case "ContinueStatement": {
981
+ return true;
982
+ }
983
+ case "IfStatement": {
984
+ return isExit(node.then) && isExit(node.else?.at(-1));
985
+ }
986
+ case "BlockStatement": {
987
+ return isExit(node.expressions.at(-1)?.[1]);
988
+ }
989
+ case "IterationStatement": {
990
+ return node.condition?.type === "ParenthesizedExpression" && node.condition.expression?.type === "Literal" && node.condition.expression?.raw === "true" && gatherRecursiveWithinFunction(
991
+ node.block,
992
+ ({ type }) => type === "BreakStatement"
993
+ ).length === 0;
994
+ }
995
+ default: {
996
+ return false;
997
+ }
998
+ }
999
+ }
1000
+ function isComma(node) {
1001
+ if (node?.token === ",") {
1002
+ return node;
1003
+ } else if (Array.isArray(node) && node.at(-1)?.token === ",") {
1004
+ return node.at(-1);
1005
+ }
1006
+ ;
1007
+ return;
1008
+ }
1009
+ function insertTrimmingSpace(target, c) {
1010
+ if (!(target != null)) {
1011
+ return target;
1012
+ }
1013
+ if (Array.isArray(target)) {
1014
+ if (target.length === 0) {
1015
+ return c;
1016
+ }
1017
+ return target.map((e, i) => {
1018
+ if (i === 0) {
1019
+ return insertTrimmingSpace(e, c);
1020
+ } else {
1021
+ return e;
1022
+ }
1023
+ });
1024
+ } else if (isParent(target)) {
1331
1025
  return {
1332
- children: elements,
1333
- names,
1334
- blockPrefix,
1335
- length
1026
+ ...target,
1027
+ children: insertTrimmingSpace(target.children, c)
1336
1028
  };
1337
- } else if (restCount === 1) {
1338
- const rest = elements[restIndex];
1339
- const after = elements.slice(restIndex + 1);
1340
- const restIdentifier = rest.binding.ref || rest.binding;
1341
- names.push(...rest.names || []);
1342
- let l = after.length;
1343
- if (l) {
1344
- if (arrayElementHasTrailingComma(after[l - 1]))
1345
- l++;
1346
- blockPrefix = {
1347
- type: "PostRestBindingElements",
1348
- children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
1349
- names: after.flatMap((p) => p.names)
1350
- };
1351
- }
1029
+ } else if (isToken(target)) {
1352
1030
  return {
1353
- names,
1354
- children: [...elements.slice(0, restIndex), {
1355
- ...rest,
1356
- children: rest.children.slice(0, -1)
1357
- // remove trailing comma
1358
- }],
1359
- blockPrefix,
1360
- length
1031
+ ...target,
1032
+ token: target.token.replace(/^ ?/, c)
1361
1033
  };
1034
+ } else {
1035
+ return target;
1362
1036
  }
1363
- const err = {
1364
- type: "Error",
1365
- children: ["Multiple rest elements in array pattern"]
1366
- };
1367
- return {
1368
- names,
1369
- children: [...elements, err],
1370
- blockPrefix,
1371
- length
1372
- };
1373
1037
  }
1374
- function gatherBindingCode(statements, opts) {
1375
- const thisAssignments = [];
1376
- const splices = [];
1377
- function insertRestSplices(s, p, thisAssignments2) {
1378
- gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
1379
- if (n.type === "AtBinding") {
1380
- const { ref } = n;
1381
- const { id } = ref;
1382
- thisAssignments2.push([`this.${id} = `, ref]);
1383
- return;
1384
- }
1385
- if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
1386
- n.names.forEach((id) => ({
1387
- push: thisAssignments2.push({
1388
- type: "AssignmentExpression",
1389
- children: [`this.${id} = `, id],
1390
- js: true
1391
- })
1392
- }));
1393
- return;
1394
- }
1395
- const { blockPrefix } = n;
1396
- p.push(blockPrefix);
1397
- return insertRestSplices(blockPrefix, p, thisAssignments2);
1398
- });
1038
+ function inplaceInsertTrimmingSpace(target, c) {
1039
+ if (!(target != null)) {
1040
+ return target;
1041
+ }
1042
+ if (Array.isArray(target)) {
1043
+ inplaceInsertTrimmingSpace(target[0], c);
1044
+ } else if (isParent(target)) {
1045
+ inplaceInsertTrimmingSpace(target.children, c);
1046
+ } else if (isToken(target)) {
1047
+ target.token = target.token.replace(/^ ?/, c);
1048
+ }
1049
+ }
1050
+ function getTrimmingSpace(target) {
1051
+ if (!(target != null)) {
1052
+ return;
1399
1053
  }
1400
- insertRestSplices(statements, splices, thisAssignments);
1401
- return [splices, thisAssignments];
1054
+ if (Array.isArray(target)) {
1055
+ return getTrimmingSpace(target[0]);
1056
+ } else if (isParent(target)) {
1057
+ return getTrimmingSpace(target.children[0]);
1058
+ } else if (isToken(target)) {
1059
+ return target.token.match(/^ ?/)[0];
1060
+ }
1061
+ ;
1062
+ return;
1402
1063
  }
1403
- function arrayElementHasTrailingComma(elementNode) {
1404
- const lastChild = elementNode.children.at(-1);
1405
- return lastChild && lastChild[lastChild.length - 1]?.token === ",";
1064
+ function prepend(prefix, node) {
1065
+ if (!(prefix && prefix.length)) {
1066
+ return node;
1067
+ }
1068
+ if (Array.isArray(node)) {
1069
+ return [prefix, ...node];
1070
+ } else if (isParent(node)) {
1071
+ return {
1072
+ ...node,
1073
+ children: [prefix, ...node.children]
1074
+ };
1075
+ } else {
1076
+ return [prefix, node];
1077
+ }
1406
1078
  }
1407
- var init_binding = __esm({
1408
- "source/parser/binding.civet"() {
1409
- "use strict";
1410
- init_traversal();
1411
- init_util();
1079
+ function inplacePrepend(prefix, node) {
1080
+ if (!prefix) {
1081
+ return;
1412
1082
  }
1413
- });
1414
-
1415
- // source/parser/pattern-matching.civet
1416
- function processPatternMatching(statements, ReservedWord, getRef) {
1417
- gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
1418
- const { caseBlock } = s;
1419
- const { clauses } = caseBlock;
1420
- for (const c of clauses) {
1421
- if (c.type === "WhenClause" && c.break) {
1422
- if (isExit(c.block)) {
1423
- c.children.splice(c.children.indexOf(c.break), 1);
1424
- c.break = void 0;
1425
- }
1083
+ if (Array.isArray(prefix) && !prefix.length) {
1084
+ return;
1085
+ }
1086
+ if (Array.isArray(node)) {
1087
+ node.unshift(prefix);
1088
+ } else if (isParent(node)) {
1089
+ node.children.unshift(prefix);
1090
+ } else {
1091
+ throw new Error("Can't prepend to a leaf node");
1092
+ }
1093
+ }
1094
+ function literalValue(literal) {
1095
+ let { raw } = literal;
1096
+ switch (raw) {
1097
+ case "null":
1098
+ return null;
1099
+ case "true":
1100
+ return true;
1101
+ case "false":
1102
+ return false;
1103
+ }
1104
+ if (raw.startsWith('"') && raw.endsWith('"') || raw.startsWith("'") && raw.endsWith("'")) {
1105
+ return raw.slice(1, -1);
1106
+ }
1107
+ const numeric = literal.children.find(
1108
+ (child) => child.type === "NumericLiteral"
1109
+ );
1110
+ if (numeric) {
1111
+ raw = raw.replace(/_/g, "");
1112
+ const { token } = numeric;
1113
+ if (token.endsWith("n")) {
1114
+ return BigInt(raw.slice(0, -1));
1115
+ } else if (token.match(/[\.eE]/)) {
1116
+ return parseFloat(raw);
1117
+ } else if (token.startsWith("0")) {
1118
+ switch (token.charAt(1).toLowerCase()) {
1119
+ case "x":
1120
+ return parseInt(raw.replace(/0[xX]/, ""), 16);
1121
+ case "b":
1122
+ return parseInt(raw.replace(/0[bB]/, ""), 2);
1123
+ case "o":
1124
+ return parseInt(raw.replace(/0[oO]/, ""), 8);
1426
1125
  }
1427
1126
  }
1428
- let errors = false;
1429
- let isPattern = false;
1430
- if (clauses.some(($1) => $1.type === "PatternClause")) {
1431
- isPattern = true;
1432
- clauses.forEach((c) => {
1433
- if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
1434
- errors = true;
1435
- return c.children.push({
1436
- type: "Error",
1437
- message: "Can't mix pattern matching and non-pattern matching clauses"
1438
- });
1439
- }
1440
- ;
1441
- return;
1442
- });
1127
+ return parseInt(raw, 10);
1128
+ }
1129
+ throw new Error("Unrecognized literal " + JSON.stringify(literal));
1130
+ }
1131
+ function startsWith(target, value) {
1132
+ if (!target)
1133
+ return;
1134
+ if (Array.isArray(target)) {
1135
+ let i = 0;
1136
+ let l = target.length;
1137
+ while (i < l) {
1138
+ const t = target[i];
1139
+ if (t && (t.length || t.token || t.children)) {
1140
+ break;
1141
+ }
1142
+ i++;
1443
1143
  }
1444
- if (errors || !isPattern) {
1445
- return;
1144
+ if (i < l) {
1145
+ return startsWith(target[i], value);
1446
1146
  }
1447
- let { condition } = s;
1448
- if (condition.type === "ParenthesizedExpression") {
1449
- condition = condition.expression;
1147
+ }
1148
+ if (typeof target === "string")
1149
+ return value.test(target);
1150
+ if (target.children)
1151
+ return startsWith(target.children, value);
1152
+ if (target.token)
1153
+ return value.test(target.token);
1154
+ return;
1155
+ }
1156
+ function hasAwait(exp) {
1157
+ return gatherRecursiveWithinFunction(exp, ({ type }) => type === "Await").length > 0;
1158
+ }
1159
+ function hasYield(exp) {
1160
+ return gatherRecursiveWithinFunction(exp, ({ type }) => type === "Yield").length > 0;
1161
+ }
1162
+ function hasImportDeclaration(exp) {
1163
+ return gatherRecursiveWithinFunction(exp, ({ type }) => type === "ImportDeclaration").length > 0;
1164
+ }
1165
+ function deepCopy(node) {
1166
+ if (node == null)
1167
+ return node;
1168
+ if (typeof node !== "object")
1169
+ return node;
1170
+ if (Array.isArray(node)) {
1171
+ return node.map(deepCopy);
1172
+ }
1173
+ if (node?.type === "Ref")
1174
+ return node;
1175
+ return Object.fromEntries(
1176
+ Object.entries(node).map(([key, value]) => {
1177
+ return [key, deepCopy(value)];
1178
+ })
1179
+ );
1180
+ }
1181
+ function removeHoistDecs(node) {
1182
+ if (node == null)
1183
+ return;
1184
+ if (typeof node !== "object")
1185
+ return;
1186
+ if ("hoistDec" in node) {
1187
+ node.hoistDec = void 0;
1188
+ }
1189
+ if (Array.isArray(node)) {
1190
+ for (const child of node) {
1191
+ removeHoistDecs(child);
1450
1192
  }
1451
- let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
1452
- if (ref !== condition) {
1453
- hoistDec = {
1454
- type: "Declaration",
1455
- children: ["let ", ref],
1456
- names: []
1457
- };
1458
- refAssignment = [{
1459
- type: "AssignmentExpression",
1460
- children: [ref, " = ", condition]
1461
- }, ","];
1193
+ return;
1194
+ }
1195
+ if (node.children) {
1196
+ for (const child of node.children) {
1197
+ removeHoistDecs(child);
1462
1198
  }
1463
- let prev = [], root = prev;
1464
- const l = clauses.length;
1465
- clauses.forEach((c, i) => {
1466
- if (c.type === "DefaultClause") {
1467
- prev.push(c.block);
1468
- return;
1469
- }
1470
- let { patterns, block } = c;
1471
- let pattern = patterns[0];
1472
- const indent = block.expressions?.[0]?.[0] || "";
1473
- const alternativeConditions = patterns.map((pattern2, i2) => {
1474
- const conditions = [];
1475
- getPatternConditions(pattern2, ref, conditions, getRef);
1476
- return conditions;
1477
- });
1478
- const conditionExpression = alternativeConditions.map((conditions, i2) => {
1479
- const conditionArray = conditions.map((c2, i3) => {
1480
- if (i3 === 0)
1481
- return c2;
1482
- return [" && ", ...c2];
1483
- });
1484
- if (i2 === 0)
1485
- return conditionArray;
1486
- return [" || ", ...conditionArray];
1487
- });
1488
- const condition2 = {
1489
- type: "ParenthesizedExpression",
1490
- children: ["(", ...refAssignment, conditionExpression, ")"],
1491
- expression: conditionExpression
1492
- };
1493
- const prefix = [];
1494
- switch (pattern.type) {
1495
- case "ArrayBindingPattern":
1496
- if (pattern.length === 0)
1497
- break;
1498
- case "ObjectBindingPattern": {
1499
- if (pattern.properties?.length === 0)
1500
- break;
1501
- let [splices, thisAssignments] = gatherBindingCode(pattern);
1502
- const patternBindings = nonMatcherBindings(pattern);
1503
- splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
1504
- thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
1505
- const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
1506
- prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
1507
- prefix.push(...thisAssignments);
1508
- prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
1509
- break;
1510
- }
1199
+ }
1200
+ }
1201
+ function makeAmpersandFunction(rhs) {
1202
+ let { ref, typeSuffix, body } = rhs;
1203
+ if (!(ref != null)) {
1204
+ ref = makeRef("$");
1205
+ inplacePrepend(ref, body);
1206
+ }
1207
+ if (body?.type === "ObjectExpression") {
1208
+ body = makeLeftHandSideExpression(body);
1209
+ }
1210
+ const parameters = makeNode({
1211
+ type: "Parameters",
1212
+ children: typeSuffix ? ["(", ref, typeSuffix, ")"] : [ref],
1213
+ names: []
1214
+ });
1215
+ const expressions = [[" ", body]];
1216
+ const block = makeNode({
1217
+ type: "BlockStatement",
1218
+ bare: true,
1219
+ expressions,
1220
+ children: [expressions],
1221
+ implicitlyReturned: true
1222
+ });
1223
+ const children = [parameters, " =>", block];
1224
+ const async = hasAwait(body);
1225
+ if (async) {
1226
+ children.unshift("async ");
1227
+ }
1228
+ const fn = makeNode({
1229
+ type: "ArrowFunction",
1230
+ signature: {
1231
+ modifier: {
1232
+ async
1511
1233
  }
1512
- block.expressions.unshift(...prefix);
1513
- const next = [];
1514
- braceBlock(block);
1515
- if (i < l - 1)
1516
- next.push("\n", "else ");
1517
- prev.push(["", {
1518
- type: "IfStatement",
1519
- children: ["if", condition2, block, next],
1520
- then: block,
1521
- else: next,
1522
- hoistDec
1523
- }]);
1524
- hoistDec = void 0;
1525
- refAssignment = [];
1526
- return prev = next;
1527
- });
1528
- s.type = "PatternMatchingStatement";
1529
- s.children = [root];
1530
- return addParentPointers(s, s.parent);
1234
+ },
1235
+ children,
1236
+ ref,
1237
+ block,
1238
+ parameters,
1239
+ ampersandBlock: true,
1240
+ body
1531
1241
  });
1242
+ if (isStatement(body)) {
1243
+ braceBlock(block);
1244
+ fn.ampersandBlock = false;
1245
+ delete fn.body;
1246
+ }
1247
+ return fn;
1532
1248
  }
1533
- function getPatternConditions(pattern, ref, conditions, getRef) {
1534
- if (pattern.rest)
1249
+ function makeLeftHandSideExpression(expression) {
1250
+ if (expression.parenthesized) {
1251
+ return expression;
1252
+ }
1253
+ switch (expression.type) {
1254
+ case "AmpersandRef":
1255
+ case "CallExpression":
1256
+ case "Identifier":
1257
+ case "JSXElement":
1258
+ case "JSXFragment":
1259
+ case "Literal":
1260
+ case "MemberExpression":
1261
+ case "NewExpression":
1262
+ case "ParenthesizedExpression":
1263
+ case "Ref":
1264
+ case "Placeholder":
1265
+ case "StatementExpression":
1266
+ return expression;
1267
+ }
1268
+ return makeNode({
1269
+ type: "ParenthesizedExpression",
1270
+ children: ["(", expression, ")"],
1271
+ expression,
1272
+ implicit: true,
1273
+ parent: void 0
1274
+ });
1275
+ }
1276
+ function updateParentPointers(node, parent, depth = 1) {
1277
+ if (!(node != null)) {
1535
1278
  return;
1536
- switch (pattern.type) {
1537
- case "ArrayBindingPattern": {
1538
- const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), l = (length - hasRest).toString(), lengthCheck = hasRest ? [ref, ".length >= ", l] : [getRef("len"), "(", ref, ", ", l, ")"];
1539
- conditions.push(
1540
- ["Array.isArray(", ref, ")"],
1541
- lengthCheck
1542
- );
1543
- elements.forEach(({ children: [, e] }, i) => {
1544
- const subRef = [ref, "[", i.toString(), "]"];
1545
- return getPatternConditions(e, subRef, conditions, getRef);
1546
- });
1547
- const { blockPrefix } = pattern;
1548
- if (blockPrefix) {
1549
- const postElements = blockPrefix.children[1], { length: postLength } = postElements;
1550
- postElements.forEach(({ children: [, e] }, i) => {
1551
- const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
1552
- return getPatternConditions(e, subRef, conditions, getRef);
1553
- });
1554
- }
1555
- break;
1556
- }
1557
- case "ObjectBindingPattern": {
1558
- conditions.push(
1559
- ["typeof ", ref, " === 'object'"],
1560
- [ref, " != null"]
1561
- );
1562
- pattern.properties.forEach((p) => {
1563
- switch (p.type) {
1564
- case "PinProperty":
1565
- case "BindingProperty": {
1566
- const { name, value } = p;
1567
- let subRef;
1568
- switch (name.type) {
1569
- case "ComputedPropertyName":
1570
- conditions.push([name.expression, " in ", ref]);
1571
- subRef = [ref, name];
1572
- break;
1573
- case "Literal":
1574
- case "StringLiteral":
1575
- case "NumericLiteral":
1576
- conditions.push([name, " in ", ref]);
1577
- subRef = [ref, "[", name, "]"];
1578
- break;
1579
- default:
1580
- conditions.push(["'", name, "' in ", ref]);
1581
- subRef = [ref, ".", name];
1582
- }
1583
- if (value) {
1584
- getPatternConditions(value, subRef, conditions, getRef);
1585
- }
1586
- break;
1587
- }
1588
- }
1589
- });
1590
- break;
1591
- }
1592
- case "ConditionFragment": {
1593
- let { children } = pattern;
1594
- if (children.length) {
1595
- let [first, ...rest] = children;
1596
- let [ws, ...op] = first;
1597
- ws = [" "].concat(ws);
1598
- first = [ws, ...op];
1599
- children = [first, ...rest];
1600
- }
1601
- conditions.push(
1602
- processBinaryOpExpression([ref, children])
1603
- );
1604
- break;
1279
+ }
1280
+ if (!(typeof node === "object")) {
1281
+ return;
1282
+ }
1283
+ if (Array.isArray(node)) {
1284
+ for (const child of node) {
1285
+ updateParentPointers(child, parent, depth);
1605
1286
  }
1606
- case "RegularExpressionLiteral": {
1607
- conditions.push(
1608
- ["typeof ", ref, " === 'string'"],
1609
- [pattern, ".test(", ref, ")"]
1610
- );
1611
- break;
1287
+ return;
1288
+ }
1289
+ node = node;
1290
+ if (parent != null) {
1291
+ node.parent = parent;
1292
+ }
1293
+ if (depth && isParent(node)) {
1294
+ for (const child of node.children) {
1295
+ updateParentPointers(child, node, depth - 1);
1612
1296
  }
1613
- case "PinPattern":
1614
- conditions.push([
1615
- ref,
1616
- " === ",
1617
- pattern.expression
1618
- ]);
1619
- break;
1297
+ }
1298
+ }
1299
+ function makeNode(node) {
1300
+ updateParentPointers(node);
1301
+ return node;
1302
+ }
1303
+ function makeRef(base = "ref", id = base) {
1304
+ return {
1305
+ type: "Ref",
1306
+ base,
1307
+ id
1308
+ };
1309
+ }
1310
+ function needsRef(expression, base = "ref") {
1311
+ switch (expression.type) {
1312
+ case "Ref":
1313
+ case "Identifier":
1620
1314
  case "Literal":
1621
- conditions.push([
1622
- ref,
1623
- " === ",
1624
- pattern
1625
- ]);
1626
- break;
1627
- default:
1628
- break;
1315
+ return;
1316
+ }
1317
+ return makeRef(base);
1318
+ }
1319
+ function maybeRef(exp, base = "ref") {
1320
+ if (!needsRef(exp))
1321
+ return exp;
1322
+ return makeRef(base);
1323
+ }
1324
+ function skipIfOnlyWS(target) {
1325
+ if (!target)
1326
+ return target;
1327
+ if (Array.isArray(target)) {
1328
+ if (target.length === 1) {
1329
+ return skipIfOnlyWS(target[0]);
1330
+ } else if (target.every((e) => skipIfOnlyWS(e) === void 0)) {
1331
+ return void 0;
1332
+ }
1333
+ return target;
1334
+ }
1335
+ if (target.token != null && target.token.trim() === "") {
1336
+ return void 0;
1337
+ }
1338
+ return target;
1339
+ }
1340
+ function spliceChild(node, child, del, ...replacements) {
1341
+ const children = node?.children ?? node;
1342
+ if (!Array.isArray(children)) {
1343
+ throw new Error("spliceChild: non-array node has no children field");
1344
+ }
1345
+ const index = children.indexOf(child);
1346
+ if (index < 0) {
1347
+ throw new Error("spliceChild: child not found");
1348
+ }
1349
+ return children.splice(index, del, ...replacements);
1350
+ }
1351
+ function convertOptionalType(suffix) {
1352
+ if (suffix.t.type === "AssertsType") {
1353
+ spliceChild(suffix, suffix.optional, 1, suffix.optional = {
1354
+ type: "Error",
1355
+ message: "Can't use optional ?: syntax with asserts type"
1356
+ });
1357
+ return;
1358
+ }
1359
+ spliceChild(suffix, suffix.optional, 1, suffix.optional = void 0);
1360
+ const wrap = suffix.type === "ReturnTypeAnnotation";
1361
+ spliceChild(suffix, suffix.t, 1, suffix.t = [
1362
+ getTrimmingSpace(suffix.t),
1363
+ wrap && "(",
1364
+ // TODO: avoid parens if unnecessary
1365
+ "undefined | ",
1366
+ parenthesizeType(insertTrimmingSpace(suffix.t, "")),
1367
+ wrap && ")"
1368
+ ]);
1369
+ }
1370
+ function parenthesizeType(type) {
1371
+ if (typeNeedsNoParens.has(type.type)) {
1372
+ return type;
1373
+ }
1374
+ return ["(", type, ")"];
1375
+ }
1376
+ function wrapIIFE(expressions, asyncFlag) {
1377
+ let prefix;
1378
+ let async;
1379
+ if (asyncFlag) {
1380
+ async = "async ";
1381
+ } else if (hasAwait(expressions)) {
1382
+ async = "async ";
1383
+ prefix = {
1384
+ type: "Await",
1385
+ children: ["await "]
1386
+ };
1387
+ }
1388
+ const block = makeNode({
1389
+ type: "BlockStatement",
1390
+ expressions,
1391
+ children: ["{", expressions, "}"],
1392
+ bare: false,
1393
+ root: false,
1394
+ parent: void 0
1395
+ });
1396
+ const parameters = {
1397
+ type: "Parameters",
1398
+ children: ["()"],
1399
+ names: []
1400
+ };
1401
+ const signature = {
1402
+ modifier: {
1403
+ async: !!async
1404
+ },
1405
+ returnType: void 0
1406
+ };
1407
+ const fn = makeNode({
1408
+ type: "ArrowFunction",
1409
+ signature,
1410
+ parameters,
1411
+ returnType: void 0,
1412
+ ts: false,
1413
+ async,
1414
+ block,
1415
+ children: [async, parameters, "=>", block]
1416
+ });
1417
+ const exp = makeNode({
1418
+ type: "CallExpression",
1419
+ children: [makeLeftHandSideExpression(fn), "()"]
1420
+ });
1421
+ if (prefix) {
1422
+ return [makeLeftHandSideExpression([prefix, exp])];
1629
1423
  }
1424
+ return [exp];
1630
1425
  }
1631
- function elideMatchersFromArrayBindings(elements) {
1632
- return elements.map((el) => {
1633
- if (el.type === "BindingRestElement") {
1634
- return ["", el, void 0];
1635
- }
1636
- const { children: [ws, e, delim] } = el;
1637
- switch (e.type) {
1638
- case "Literal":
1639
- case "RegularExpressionLiteral":
1640
- case "StringLiteral":
1641
- case "PinPattern":
1642
- return delim;
1643
- default:
1644
- return [ws, nonMatcherBindings(e), delim];
1645
- }
1426
+ function wrapWithReturn(expression) {
1427
+ const children = expression ? ["return ", expression] : ["return"];
1428
+ return makeNode({
1429
+ type: "ReturnStatement",
1430
+ children,
1431
+ expression,
1432
+ parent: expression?.parent
1646
1433
  });
1647
1434
  }
1648
- function elideMatchersFromPropertyBindings(properties) {
1649
- return properties.map((p) => {
1650
- switch (p.type) {
1651
- case "BindingProperty": {
1652
- const { children, name, value } = p;
1653
- const [ws] = children;
1654
- switch (value && value.type) {
1655
- case "ArrayBindingPattern":
1656
- case "ObjectBindingPattern":
1657
- return {
1658
- ...p,
1659
- children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
1660
- };
1661
- case "Identifier":
1662
- return p;
1663
- case "Literal":
1664
- case "RegularExpressionLiteral":
1665
- case "StringLiteral":
1666
- default:
1667
- return {
1668
- ...p,
1669
- children: [ws, name, p.delim]
1670
- };
1435
+ var assert, statementTypes, typeNeedsNoParens;
1436
+ var init_util = __esm({
1437
+ "source/parser/util.civet"() {
1438
+ "use strict";
1439
+ init_block();
1440
+ init_traversal();
1441
+ init_function();
1442
+ assert = {
1443
+ equal(a, b, msg) {
1444
+ if (a !== b) {
1445
+ throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
1671
1446
  }
1672
1447
  }
1673
- case "PinProperty":
1674
- case "BindingRestProperty":
1675
- default:
1676
- return p;
1677
- }
1678
- });
1448
+ };
1449
+ statementTypes = /* @__PURE__ */ new Set([
1450
+ "BlockStatement",
1451
+ "BreakStatement",
1452
+ "ContinueStatement",
1453
+ "DebuggerStatement",
1454
+ "Declaration",
1455
+ "DoStatement",
1456
+ "ForStatement",
1457
+ "IfStatement",
1458
+ "IterationStatement",
1459
+ "LabeledStatement",
1460
+ "ReturnStatement",
1461
+ "SwitchStatement",
1462
+ "ThrowStatement",
1463
+ "TryStatement"
1464
+ ]);
1465
+ typeNeedsNoParens = /* @__PURE__ */ new Set([
1466
+ "IdentifierType",
1467
+ "ImportType",
1468
+ "LiteralType",
1469
+ "TupleType",
1470
+ "ParenthesizedType",
1471
+ "UnaryType"
1472
+ ]);
1473
+ }
1474
+ });
1475
+
1476
+ // source/parser/traversal.civet
1477
+ function gatherRecursiveWithinFunction(node, predicate) {
1478
+ return gatherRecursive(node, predicate, isFunction);
1679
1479
  }
1680
- function nonMatcherBindings(pattern) {
1681
- switch (pattern.type) {
1682
- case "ArrayBindingPattern": {
1683
- const elements = elideMatchersFromArrayBindings(pattern.elements);
1684
- const children = ["[", elements, "]"];
1685
- return {
1686
- ...pattern,
1687
- children,
1688
- elements
1689
- };
1690
- }
1691
- case "PostRestBindingElements": {
1692
- const els = elideMatchersFromArrayBindings(pattern.children[1]);
1693
- return {
1694
- ...pattern,
1695
- children: [
1696
- pattern.children[0],
1697
- els,
1698
- ...pattern.children.slice(2)
1699
- ]
1700
- };
1480
+ function findChildIndex(parent, child) {
1481
+ if (!(parent != null)) {
1482
+ return -1;
1483
+ }
1484
+ const children = Array.isArray(parent) ? parent : parent.children;
1485
+ if (!(children != null)) {
1486
+ return -1;
1487
+ }
1488
+ for (let i1 = 0, len = children.length; i1 < len; i1++) {
1489
+ const i = i1;
1490
+ const c = children[i1];
1491
+ if (c === child || Array.isArray(c) && arrayRecurse(c)) {
1492
+ return i;
1701
1493
  }
1702
- case "ObjectBindingPattern":
1703
- return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
1704
- default:
1705
- return pattern;
1706
1494
  }
1707
- }
1708
- function aggregateDuplicateBindings(bindings, ReservedWord) {
1709
- const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
1710
- const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
1711
- arrayBindings.forEach((a) => {
1712
- const { elements } = a;
1713
- return elements.forEach((element) => {
1714
- if (Array.isArray(element)) {
1715
- const [, e] = element;
1716
- if (e.type === "Identifier") {
1717
- return props.push(e);
1718
- } else if (e.type === "BindingRestElement") {
1719
- return props.push(e);
1720
- }
1721
- ;
1722
- return;
1495
+ function arrayRecurse(array) {
1496
+ for (let i2 = 0, len1 = array.length; i2 < len1; i2++) {
1497
+ const c = array[i2];
1498
+ if (c === child || Array.isArray(c) && arrayRecurse(c)) {
1499
+ return true;
1723
1500
  }
1724
- ;
1725
- return;
1726
- });
1727
- });
1728
- const declarations = [];
1729
- const propsGroupedByName = /* @__PURE__ */ new Map();
1730
- for (const p of props) {
1731
- const { name, value } = p;
1732
- const key = value?.name || name?.name || name;
1733
- if (propsGroupedByName.has(key)) {
1734
- propsGroupedByName.get(key).push(p);
1735
- } else {
1736
- propsGroupedByName.set(key, [p]);
1737
1501
  }
1502
+ return false;
1738
1503
  }
1739
- propsGroupedByName.forEach((shared, key) => {
1740
- if (!key) {
1741
- return;
1504
+ return -1;
1505
+ }
1506
+ function findAncestor(node, predicate, stopPredicate) {
1507
+ let { parent } = node;
1508
+ while (parent && !stopPredicate?.(parent, node)) {
1509
+ if (predicate(parent, node)) {
1510
+ return { ancestor: parent, child: node };
1742
1511
  }
1743
- if (ReservedWord({ fail() {
1744
- } }, {
1745
- pos: 0,
1746
- input: key
1747
- })) {
1748
- shared.forEach((p) => {
1749
- return aliasBinding(p, makeRef(`_${key}`, key));
1512
+ node = parent;
1513
+ ({ parent } = node);
1514
+ }
1515
+ return { ancestor: void 0, child: node };
1516
+ }
1517
+ function gatherNodes(node, predicate) {
1518
+ if (node == null)
1519
+ return [];
1520
+ if (Array.isArray(node)) {
1521
+ return node.flatMap((n) => gatherNodes(n, predicate));
1522
+ }
1523
+ if (predicate(node)) {
1524
+ return [node];
1525
+ }
1526
+ switch (node.type) {
1527
+ case "BlockStatement":
1528
+ return [];
1529
+ case "ForStatement":
1530
+ const isDec = node.declaration?.type === "Declaration";
1531
+ return node.children.flatMap((n) => {
1532
+ if (isDec && n === node.declaration)
1533
+ return [];
1534
+ return gatherNodes(n, predicate);
1750
1535
  });
1751
- return;
1752
- }
1753
- if (shared.length === 1) {
1754
- return;
1755
- }
1756
- const refs = shared.map((p) => {
1757
- const ref = makeRef(key);
1758
- aliasBinding(p, ref);
1759
- return ref;
1760
- });
1761
- return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
1762
- return i === 0 ? r : [", ", r];
1763
- }), "]"]);
1764
- });
1765
- return declarations;
1536
+ default:
1537
+ return gatherNodes(node.children, predicate);
1538
+ }
1539
+ }
1540
+ function gatherRecursive(node, predicate, skipPredicate) {
1541
+ if (node == null)
1542
+ return [];
1543
+ if (Array.isArray(node)) {
1544
+ return node.flatMap((n) => gatherRecursive(n, predicate, skipPredicate));
1545
+ }
1546
+ if (skipPredicate?.(node))
1547
+ return [];
1548
+ if (predicate(node)) {
1549
+ return [node];
1550
+ }
1551
+ return gatherRecursive(node.children, predicate, skipPredicate);
1766
1552
  }
1767
- function aliasBinding(p, ref) {
1768
- if (p.type === "Identifier") {
1769
- p.children[0] = ref;
1770
- } else if (p.type === "BindingRestElement") {
1771
- aliasBinding(p.binding, ref);
1772
- } else if (p.value?.type === "Identifier") {
1773
- aliasBinding(p.value, ref);
1774
- } else {
1775
- p.value = ref;
1776
- const index = p.children.indexOf(p.name);
1777
- p.children.splice(index + 1, 0, ": ", ref);
1553
+ function gatherRecursiveAll(node, predicate) {
1554
+ if (node == null)
1555
+ return [];
1556
+ if (Array.isArray(node)) {
1557
+ return node.flatMap((n) => gatherRecursiveAll(n, predicate));
1558
+ }
1559
+ const nodes = gatherRecursiveAll(node.children, predicate);
1560
+ if (predicate(node)) {
1561
+ nodes.push(node);
1778
1562
  }
1563
+ return nodes;
1779
1564
  }
1780
- var init_pattern_matching = __esm({
1781
- "source/parser/pattern-matching.civet"() {
1565
+ var init_traversal = __esm({
1566
+ "source/parser/traversal.civet"() {
1782
1567
  "use strict";
1783
- init_traversal();
1784
1568
  init_util();
1785
- init_block();
1786
- init_binding();
1787
- init_op();
1788
1569
  }
1789
1570
  });
1790
1571
 
1791
- // source/parser/function.civet
1792
- function isVoidType(t) {
1793
- return t?.type === "LiteralType" && t.t.type === "VoidType";
1794
- }
1795
- function isPromiseVoidType(t) {
1796
- return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
1797
- }
1798
- function isGeneratorVoidType(t) {
1799
- return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1800
- }
1801
- function isAsyncGeneratorVoidType(t) {
1802
- return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1803
- }
1804
- function implicitFunctionBlock(f) {
1805
- if (f.abstract || f.block || f.signature?.optional)
1806
- return;
1807
- const { name, parent } = f;
1808
- if (parent?.type === "ExportDeclaration")
1809
- return;
1810
- const expressions = parent?.expressions ?? parent?.elements;
1811
- const currentIndex = expressions?.findIndex(([, def]) => def === f);
1812
- const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
1813
- if (f.type === following?.type && name && name === following.name) {
1814
- f.ts = true;
1572
+ // source/parser/op.civet
1573
+ function getPrecedence(op) {
1574
+ if (typeof op === "string") {
1575
+ return precedenceMap.get(op) ?? (() => {
1576
+ throw new Error(`Unknown operator: ${op}`);
1577
+ })();
1578
+ } else if (typeof op.prec === "number") {
1579
+ return op.prec;
1815
1580
  } else {
1816
- const block = makeEmptyBlock();
1817
- block.parent = f;
1818
- f.block = block;
1819
- f.children.push(block);
1820
- f.ts = false;
1581
+ return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
1821
1582
  }
1822
1583
  }
1823
- function processReturn(f, implicitReturns) {
1824
- let { returnType } = f.signature;
1825
- if (returnType && returnType.optional) {
1826
- convertOptionalType(returnType);
1827
- }
1828
- if (!processReturnValue(f) && implicitReturns) {
1829
- const { signature, block } = f;
1830
- const { modifier, name, returnType: returnType2 } = signature;
1831
- const { async, generator, set } = modifier;
1832
- const isMethod = f.type === "MethodDefinition";
1833
- const isConstructor = isMethod && name === "constructor";
1834
- const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
1835
- if (block?.type === "BlockStatement") {
1836
- if (isVoid || set || isConstructor) {
1837
- if (block.bare && block.implicitlyReturned) {
1838
- block.children = [" {", ...block.children, " }"];
1839
- block.bare = block.implicitlyReturned = false;
1584
+ function processBinaryOpExpression($0) {
1585
+ return recurse(expandChainedComparisons($0));
1586
+ function recurse(expandedOps) {
1587
+ let i = 2;
1588
+ while (i < expandedOps.length) {
1589
+ let op = expandedOps[i];
1590
+ if (op.special) {
1591
+ let advanceLeft2 = function(allowEqual) {
1592
+ while (start >= 4) {
1593
+ const prevPrec = getPrecedence(expandedOps[start - 2]);
1594
+ if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
1595
+ return prevPrec === prec;
1596
+ }
1597
+ start -= 4;
1598
+ }
1599
+ return false;
1600
+ }, advanceRight2 = function(allowEqual) {
1601
+ while (end + 4 < expandedOps.length) {
1602
+ const nextPrec = getPrecedence(expandedOps[end + 2]);
1603
+ if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
1604
+ return nextPrec === prec;
1605
+ }
1606
+ end += 4;
1607
+ }
1608
+ return false;
1609
+ };
1610
+ var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
1611
+ let start = i - 2, end = i + 2;
1612
+ const prec = getPrecedence(op);
1613
+ let error;
1614
+ switch (op.assoc) {
1615
+ case "left":
1616
+ case void 0: {
1617
+ advanceLeft2(true);
1618
+ advanceRight2(false);
1619
+ break;
1620
+ }
1621
+ case "right": {
1622
+ advanceLeft2(false);
1623
+ advanceRight2(true);
1624
+ break;
1625
+ }
1626
+ case "non": {
1627
+ if (advanceLeft2(false) || advanceRight2(false)) {
1628
+ error = {
1629
+ type: "Error",
1630
+ message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
1631
+ };
1632
+ }
1633
+ ;
1634
+ break;
1635
+ }
1636
+ case "arguments": {
1637
+ if (advanceLeft2(false)) {
1638
+ error = {
1639
+ type: "Error",
1640
+ message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
1641
+ };
1642
+ }
1643
+ advanceRight2(true);
1644
+ break;
1645
+ }
1646
+ default: {
1647
+ throw new Error(`Unsupported associativity: ${op.assoc}`);
1648
+ }
1840
1649
  }
1841
- } else {
1842
- if (!block.implicitlyReturned) {
1843
- insertReturn(block);
1650
+ let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
1651
+ let wsOp = expandedOps[i - 1];
1652
+ let wsB = expandedOps[i + 1];
1653
+ let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
1654
+ if (op.assoc === "arguments") {
1655
+ let i2 = 2;
1656
+ while (i2 < b.length) {
1657
+ if (prec === getPrecedence(b[i2])) {
1658
+ if (!(b[i2].token === op.token)) {
1659
+ error ??= {
1660
+ type: "Error",
1661
+ message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
1662
+ };
1663
+ }
1664
+ b[i2] = ",";
1665
+ }
1666
+ i2 += 4;
1667
+ }
1668
+ } else {
1669
+ b = recurse(b);
1844
1670
  }
1671
+ if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
1672
+ a = ["typeof ", makeLeftHandSideExpression(a)];
1673
+ if (op.negated) {
1674
+ op = { ...op, token: "!==", negated: false };
1675
+ } else {
1676
+ op = { ...op, token: "===" };
1677
+ }
1678
+ }
1679
+ if (op.asConst) {
1680
+ a = makeAsConst(a);
1681
+ b = makeAsConst(b);
1682
+ }
1683
+ let children;
1684
+ if (op.call) {
1685
+ wsOp = insertTrimmingSpace(wsOp, "");
1686
+ if (op.reversed) {
1687
+ wsB = insertTrimmingSpace(wsB, "");
1688
+ children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
1689
+ } else {
1690
+ children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
1691
+ }
1692
+ } else if (op.method) {
1693
+ wsOp = insertTrimmingSpace(wsOp, "");
1694
+ wsB = insertTrimmingSpace(wsB, "");
1695
+ if (op.reversed) {
1696
+ if (end !== i + 2)
1697
+ b = makeLeftHandSideExpression(b);
1698
+ b = dotNumericLiteral(b);
1699
+ children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
1700
+ } else {
1701
+ if (start !== i - 2 || a.type === "NumericLiteral") {
1702
+ a = makeLeftHandSideExpression(a);
1703
+ }
1704
+ a = dotNumericLiteral(a);
1705
+ children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
1706
+ }
1707
+ } else if (op.token) {
1708
+ children = [a, wsOp, op, wsB, b];
1709
+ if (op.negated)
1710
+ children = ["(", ...children, ")"];
1711
+ } else {
1712
+ throw new Error("Unknown operator: " + JSON.stringify(op));
1713
+ }
1714
+ if (op.negated)
1715
+ children.unshift("!");
1716
+ if (error != null) {
1717
+ children.push(error);
1718
+ }
1719
+ expandedOps.splice(start, end - start + 1, {
1720
+ children
1721
+ });
1722
+ i = start + 2;
1723
+ } else {
1724
+ i += 4;
1845
1725
  }
1846
- }
1847
- }
1848
- }
1849
- function processReturnValue(func) {
1850
- const { block } = func;
1851
- const values = gatherRecursiveWithinFunction(
1852
- block,
1853
- ({ type }) => type === "ReturnValue"
1854
- );
1855
- if (!values.length) {
1856
- return false;
1857
- }
1858
- const ref = makeRef("ret");
1859
- let declaration;
1860
- values.forEach((value) => {
1861
- value.children = [ref];
1862
- const { ancestor, child } = findAncestor(
1863
- value,
1864
- ({ type }) => type === "Declaration",
1865
- isFunction
1866
- );
1867
- if (ancestor) {
1868
- return declaration ??= child;
1869
- }
1870
- ;
1871
- return;
1872
- });
1873
- let returnType = func.returnType ?? func.signature?.returnType;
1874
- if (returnType) {
1875
- const { t } = returnType;
1876
- let m;
1877
- if (m = t.type, m === "TypePredicate") {
1878
- returnType = ": boolean";
1879
- } else if (m === "AssertsType") {
1880
- returnType = void 0;
1881
- }
1882
- }
1883
- if (declaration) {
1884
- if (!(declaration.suffix != null)) {
1885
- declaration.children[1] = declaration.suffix = returnType;
1886
- }
1887
- } else {
1888
- block.expressions.unshift([
1889
- getIndent(block.expressions[0]),
1890
- {
1891
- type: "Declaration",
1892
- children: ["let ", ref, returnType],
1893
- names: []
1894
- },
1895
- ";"
1896
- ]);
1897
- }
1898
- gatherRecursiveWithinFunction(
1899
- block,
1900
- (r) => r.type === "ReturnStatement" && !r.expression
1901
- ).forEach((r) => {
1902
- r.expression = ref;
1903
- return r.children.splice(-1, 1, " ", ref);
1904
- });
1905
- if (!(block.children.at(-2)?.type === "ReturnStatement")) {
1906
- const indent = getIndent(block.expressions.at(-1)) || ";";
1907
- block.expressions.push([
1908
- [indent],
1909
- {
1910
- type: "ReturnStatement",
1911
- expression: ref,
1912
- children: ["return ", ref]
1913
- }
1914
- ]);
1726
+ }
1727
+ return expandedOps;
1915
1728
  }
1916
- return true;
1729
+ ;
1730
+ return recurse;
1917
1731
  }
1918
- function patternAsValue(pattern) {
1919
- switch (pattern.type) {
1920
- case "ArrayBindingPattern": {
1921
- const children = [...pattern.children];
1922
- const index = children.indexOf(pattern.elements);
1923
- if (index < 0)
1924
- throw new Error("failed to find elements in ArrayBindingPattern");
1925
- children[index] = pattern.elements.map((el) => {
1926
- const [ws, e, delim] = el.children;
1927
- return { ...el, children: [ws, patternAsValue(e), delim] };
1928
- });
1929
- return { ...pattern, children };
1930
- }
1931
- case "ObjectBindingPattern": {
1932
- const children = [...pattern.children];
1933
- const index = children.indexOf(pattern.properties);
1934
- if (index < 0)
1935
- throw new Error("failed to find properties in ArrayBindingPattern");
1936
- children[index] = pattern.properties.map(patternAsValue);
1937
- return { ...pattern, children };
1938
- }
1939
- case "Identifier":
1940
- case "BindingProperty": {
1941
- const children = [
1942
- // { name: value } = ... declares value, not name
1943
- pattern.value ?? pattern.name,
1944
- pattern.delim
1945
- ];
1946
- if (isWhitespaceOrEmpty(pattern.children[0])) {
1947
- children.unshift(pattern.children[0]);
1948
- }
1949
- return { ...pattern, children };
1950
- }
1951
- default:
1952
- return pattern;
1732
+ function dotNumericLiteral(literal) {
1733
+ if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
1734
+ literal.children.push(".");
1735
+ literal.raw += ".";
1953
1736
  }
1737
+ return literal;
1954
1738
  }
1955
- function assignResults(node, collect) {
1956
- if (!node)
1957
- return;
1958
- switch (node.type) {
1959
- case "BlockStatement":
1960
- if (node.expressions.length) {
1961
- assignResults(node.expressions.at(-1), collect);
1962
- } else {
1963
- node.expressions.push(["", collect("void 0"), ";"]);
1964
- }
1965
- return;
1966
- case "CaseBlock":
1967
- node.clauses.forEach((clause) => {
1968
- return assignResults(clause, collect);
1969
- });
1970
- return;
1971
- case "WhenClause":
1972
- case "DefaultClause":
1973
- case "PatternClause": {
1974
- assignResults(node.block, collect);
1975
- return;
1976
- }
1739
+ function makeAsConst(node) {
1740
+ if (Array.isArray(node) && node.length === 1) {
1741
+ node = node[0];
1977
1742
  }
1978
- if (!Array.isArray(node)) {
1979
- return;
1743
+ if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
1744
+ return { ...node, children: [...node.children, asConst] };
1745
+ } else {
1746
+ return node;
1980
1747
  }
1981
- let [, exp, semi] = node;
1982
- if (semi?.type === "SemicolonDelimiter") {
1983
- return;
1748
+ }
1749
+ function isExistence(exp) {
1750
+ if (exp?.type === "ParenthesizedExpression" && exp.implicit) {
1751
+ exp = exp.expression;
1984
1752
  }
1985
- if (!exp) {
1986
- return;
1753
+ if (exp?.type === "Existence") {
1754
+ return exp;
1987
1755
  }
1988
- if (isExit(exp)) {
1989
- return;
1756
+ ;
1757
+ return;
1758
+ }
1759
+ function isRelationalOp(op) {
1760
+ return op.relational || getPrecedence(op) === precedenceRelational;
1761
+ }
1762
+ function expandChainedComparisons([first, binops]) {
1763
+ if (!binops.length) {
1764
+ return [first];
1990
1765
  }
1991
- const outer = exp;
1992
- let { type } = exp;
1993
- if (type === "LabelledStatement") {
1994
- exp = exp.statement;
1995
- ({ type } = exp);
1766
+ const results = [];
1767
+ let start = 0;
1768
+ const chains = [];
1769
+ var i = 0;
1770
+ for (let i3 = 0, len2 = binops.length; i3 < len2; i3++) {
1771
+ var i = i3;
1772
+ var [, op] = binops[i3];
1773
+ if (isRelationalOp(op)) {
1774
+ chains.push(i);
1775
+ } else if (getPrecedence(op) < precedenceRelational) {
1776
+ processChains();
1777
+ first = results.pop();
1778
+ }
1996
1779
  }
1997
- switch (exp.type) {
1998
- case "BreakStatement":
1999
- case "ContinueStatement":
2000
- case "DebuggerStatement":
2001
- case "EmptyStatement":
2002
- case "ReturnStatement":
2003
- case "ThrowStatement":
2004
- return;
2005
- case "Declaration":
2006
- exp.children.push([
2007
- "",
2008
- [";", collect(patternAsValue(exp.bindings.at(-1).pattern))]
2009
- ]);
2010
- return;
2011
- case "ForStatement":
2012
- case "IterationStatement":
2013
- case "DoStatement":
2014
- wrapIterationReturningResults(exp, outer, collect);
2015
- return;
2016
- case "BlockStatement":
2017
- assignResults(exp.expressions[exp.expressions.length - 1], collect);
2018
- return;
2019
- case "IfStatement":
2020
- assignResults(exp.then, collect);
2021
- if (exp.then.bare && !exp.then.semicolon) {
2022
- exp.then.children.push(exp.then.semicolon = ";");
1780
+ processChains();
1781
+ return results;
1782
+ function processChains() {
1783
+ if (chains.length > 0) {
1784
+ first = expandExistence(first);
1785
+ for (let i4 = 0, len3 = chains.length; i4 < len3; i4++) {
1786
+ const k = i4;
1787
+ const index = chains[i4];
1788
+ if (k > 0) {
1789
+ results.push(" ", "&&", " ");
1790
+ }
1791
+ const binop = binops[index];
1792
+ const exp = binop[3] = expandExistence(binop[3]);
1793
+ results.push(first);
1794
+ const endIndex = chains[k + 1] ?? i + 1;
1795
+ results.push(...binops.slice(start, endIndex).flat());
1796
+ first = [exp].concat(binops.slice(index + 1, endIndex));
1797
+ start = endIndex;
2023
1798
  }
2024
- if (exp.else) {
2025
- assignResults(exp.else[2], collect);
2026
- } else {
2027
- exp.children.push([" else {", collect("undefined"), "}"]);
1799
+ } else {
1800
+ results.push(first);
1801
+ results.push(...binops.slice(start, i + 1).flat());
1802
+ start = i + 1;
1803
+ }
1804
+ chains.length = 0;
1805
+ }
1806
+ function expandExistence(exp) {
1807
+ let ref;
1808
+ if (ref = isExistence(exp)) {
1809
+ const existence = ref;
1810
+ results.push(existence, " ", "&&", " ");
1811
+ return existence.expression;
1812
+ } else {
1813
+ return exp;
1814
+ }
1815
+ }
1816
+ ;
1817
+ }
1818
+ var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
1819
+ var init_op = __esm({
1820
+ "source/parser/op.civet"() {
1821
+ "use strict";
1822
+ init_util();
1823
+ precedenceOrder = [
1824
+ ["||", "??"],
1825
+ ["^^"],
1826
+ ["&&"],
1827
+ ["|"],
1828
+ ["^"],
1829
+ ["&"],
1830
+ // NOTE: Equality and inequality merged because of relational chaining
1831
+ [
1832
+ "==",
1833
+ "!=",
1834
+ "===",
1835
+ "!==",
1836
+ "<",
1837
+ "<=",
1838
+ ">",
1839
+ ">=",
1840
+ "in",
1841
+ "instanceof"
1842
+ ],
1843
+ // NOTE: Extra in-between level for default custom operators
1844
+ ["custom"],
1845
+ ["<<", ">>", ">>>"],
1846
+ ["+", "-"],
1847
+ ["*", "/", "%"],
1848
+ ["**"]
1849
+ ];
1850
+ precedenceMap = /* @__PURE__ */ new Map();
1851
+ for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
1852
+ const prec = i1;
1853
+ const ops = precedenceOrder[i1];
1854
+ for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
1855
+ const op = ops[i2];
1856
+ precedenceMap.set(op, prec);
2028
1857
  }
2029
- return;
2030
- case "PatternMatchingStatement":
2031
- assignResults(exp.children[0][0], collect);
2032
- return;
2033
- case "SwitchStatement":
2034
- assignResults(exp.children[2], collect);
2035
- return;
2036
- case "TryStatement":
2037
- exp.blocks.forEach((block) => assignResults(block, collect));
2038
- return;
2039
- }
2040
- if (node.at(-1)?.type === "SemicolonDelimiter") {
2041
- return;
1858
+ }
1859
+ precedenceStep = 1 / 64;
1860
+ precedenceRelational = precedenceMap.get("==");
1861
+ precedenceCustomDefault = precedenceMap.get("custom");
1862
+ asConst = {
1863
+ ts: true,
1864
+ children: [" as const"]
1865
+ };
2042
1866
  }
2043
- node[1] = collect(node[1]);
2044
- }
2045
- function insertReturn(node, outerNode = node) {
2046
- if (!node)
2047
- return;
2048
- switch (node.type) {
2049
- case "BlockStatement":
2050
- if (node.expressions.length) {
2051
- const last = node.expressions[node.expressions.length - 1];
2052
- insertReturn(last);
2053
- } else {
2054
- if (node.parent.type === "CatchClause") {
2055
- node.expressions.push(["return"]);
1867
+ });
1868
+
1869
+ // source/parser/pattern-matching.civet
1870
+ function processPatternMatching(statements, ReservedWord, getRef) {
1871
+ gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
1872
+ const { caseBlock } = s;
1873
+ const { clauses } = caseBlock;
1874
+ for (const c of clauses) {
1875
+ if (c.type === "WhenClause" && c.break) {
1876
+ if (isExit(c.block)) {
1877
+ c.children.splice(c.children.indexOf(c.break), 1);
1878
+ c.break = void 0;
2056
1879
  }
2057
1880
  }
1881
+ }
1882
+ let errors = false;
1883
+ let isPattern = false;
1884
+ if (clauses.some(($1) => $1.type === "PatternClause")) {
1885
+ isPattern = true;
1886
+ clauses.forEach((c) => {
1887
+ if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
1888
+ errors = true;
1889
+ return c.children.push({
1890
+ type: "Error",
1891
+ message: "Can't mix pattern matching and non-pattern matching clauses"
1892
+ });
1893
+ }
1894
+ ;
1895
+ return;
1896
+ });
1897
+ }
1898
+ if (errors || !isPattern) {
2058
1899
  return;
2059
- case "WhenClause":
2060
- if (node.break) {
2061
- node.children.splice(node.children.indexOf(node.break), 1);
1900
+ }
1901
+ let { condition } = s;
1902
+ if (condition.type === "ParenthesizedExpression") {
1903
+ condition = condition.expression;
1904
+ }
1905
+ let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
1906
+ if (ref !== condition) {
1907
+ hoistDec = {
1908
+ type: "Declaration",
1909
+ children: ["let ", ref],
1910
+ names: []
1911
+ };
1912
+ refAssignment = [{
1913
+ type: "AssignmentExpression",
1914
+ children: [ref, " = ", condition]
1915
+ }, ","];
1916
+ }
1917
+ let prev = [], root = prev;
1918
+ const l = clauses.length;
1919
+ clauses.forEach((c, i) => {
1920
+ if (c.type === "DefaultClause") {
1921
+ prev.push(c.block);
1922
+ return;
2062
1923
  }
2063
- if (node.block.expressions.length) {
2064
- insertReturn(node.block);
2065
- } else {
2066
- node.block.expressions.push(wrapWithReturn());
1924
+ let { patterns, block } = c;
1925
+ let pattern = patterns[0];
1926
+ const indent = block.expressions?.[0]?.[0] || "";
1927
+ const alternativeConditions = patterns.map((pattern2, i2) => {
1928
+ const conditions = [];
1929
+ getPatternConditions(pattern2, ref, conditions, getRef);
1930
+ return conditions;
1931
+ });
1932
+ const conditionExpression = alternativeConditions.map((conditions, i2) => {
1933
+ const conditionArray = conditions.map((c2, i3) => {
1934
+ if (i3 === 0)
1935
+ return c2;
1936
+ return [" && ", ...c2];
1937
+ });
1938
+ if (i2 === 0)
1939
+ return conditionArray;
1940
+ return [" || ", ...conditionArray];
1941
+ });
1942
+ const condition2 = {
1943
+ type: "ParenthesizedExpression",
1944
+ children: ["(", ...refAssignment, conditionExpression, ")"],
1945
+ expression: conditionExpression
1946
+ };
1947
+ const prefix = [];
1948
+ switch (pattern.type) {
1949
+ case "ArrayBindingPattern":
1950
+ if (pattern.length === 0)
1951
+ break;
1952
+ case "ObjectBindingPattern": {
1953
+ if (pattern.properties?.length === 0)
1954
+ break;
1955
+ let [splices, thisAssignments] = gatherBindingCode(pattern);
1956
+ const patternBindings = nonMatcherBindings(pattern);
1957
+ splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
1958
+ thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
1959
+ const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
1960
+ prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
1961
+ prefix.push(...thisAssignments);
1962
+ prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
1963
+ break;
1964
+ }
2067
1965
  }
2068
- return;
2069
- case "DefaultClause":
2070
- insertReturn(node.block);
2071
- return;
2072
- }
2073
- if (!Array.isArray(node))
2074
- return;
2075
- let [, exp, semi] = node;
2076
- if (semi?.type === "SemicolonDelimiter") {
2077
- return;
2078
- }
2079
- if (!exp) {
2080
- return;
2081
- }
2082
- if (isExit(exp)) {
2083
- return;
2084
- }
2085
- const outer = exp;
2086
- let { type } = exp;
2087
- if (type === "LabelledStatement") {
2088
- exp = exp.statement;
2089
- ({ type } = exp);
2090
- }
2091
- switch (type) {
2092
- case "BreakStatement":
2093
- case "ContinueStatement":
2094
- case "DebuggerStatement":
2095
- case "EmptyStatement":
2096
- case "ReturnStatement":
2097
- case "ThrowStatement":
2098
- return;
2099
- case "Declaration":
2100
- exp.children.push(["", {
2101
- type: "ReturnStatement",
2102
- children: [";return ", patternAsValue(exp.bindings.at(-1).pattern)],
2103
- parent: exp
1966
+ block.expressions.unshift(...prefix);
1967
+ const next = [];
1968
+ braceBlock(block);
1969
+ if (i < l - 1)
1970
+ next.push("\n", "else ");
1971
+ prev.push(["", {
1972
+ type: "IfStatement",
1973
+ children: ["if", condition2, block, next],
1974
+ then: block,
1975
+ else: next,
1976
+ hoistDec
2104
1977
  }]);
2105
- return;
2106
- case "FunctionExpression":
2107
- if (exp.id) {
2108
- exp.children.push([
2109
- "",
2110
- {
2111
- type: "ReturnStatement",
2112
- children: [";return ", exp.id],
2113
- parent: exp
1978
+ hoistDec = void 0;
1979
+ refAssignment = [];
1980
+ return prev = next;
1981
+ });
1982
+ s.type = "PatternMatchingStatement";
1983
+ s.children = [root];
1984
+ return addParentPointers(s, s.parent);
1985
+ });
1986
+ }
1987
+ function getPatternConditions(pattern, ref, conditions, getRef) {
1988
+ if (pattern.rest)
1989
+ return;
1990
+ switch (pattern.type) {
1991
+ case "ArrayBindingPattern": {
1992
+ const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), l = (length - hasRest).toString(), lengthCheck = hasRest ? [ref, ".length >= ", l] : [getRef("len"), "(", ref, ", ", l, ")"];
1993
+ conditions.push(
1994
+ ["Array.isArray(", ref, ")"],
1995
+ lengthCheck
1996
+ );
1997
+ elements.forEach(({ children: [, e] }, i) => {
1998
+ const subRef = [ref, "[", i.toString(), "]"];
1999
+ return getPatternConditions(e, subRef, conditions, getRef);
2000
+ });
2001
+ const { blockPrefix } = pattern;
2002
+ if (blockPrefix) {
2003
+ const postElements = blockPrefix.children[1], { length: postLength } = postElements;
2004
+ postElements.forEach(({ children: [, e] }, i) => {
2005
+ const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
2006
+ return getPatternConditions(e, subRef, conditions, getRef);
2007
+ });
2008
+ }
2009
+ break;
2010
+ }
2011
+ case "ObjectBindingPattern": {
2012
+ conditions.push(
2013
+ ["typeof ", ref, " === 'object'"],
2014
+ [ref, " != null"]
2015
+ );
2016
+ pattern.properties.forEach((p) => {
2017
+ switch (p.type) {
2018
+ case "PinProperty":
2019
+ case "BindingProperty": {
2020
+ const { name, value } = p;
2021
+ let subRef;
2022
+ switch (name.type) {
2023
+ case "ComputedPropertyName":
2024
+ conditions.push([name.expression, " in ", ref]);
2025
+ subRef = [ref, name];
2026
+ break;
2027
+ case "Literal":
2028
+ case "StringLiteral":
2029
+ case "NumericLiteral":
2030
+ conditions.push([name, " in ", ref]);
2031
+ subRef = [ref, "[", name, "]"];
2032
+ break;
2033
+ default:
2034
+ conditions.push(["'", name, "' in ", ref]);
2035
+ subRef = [ref, ".", name];
2036
+ }
2037
+ if (value) {
2038
+ getPatternConditions(value, subRef, conditions, getRef);
2039
+ }
2040
+ break;
2114
2041
  }
2115
- ]);
2116
- return;
2042
+ }
2043
+ });
2044
+ break;
2045
+ }
2046
+ case "ConditionFragment": {
2047
+ let { children } = pattern;
2048
+ if (children.length) {
2049
+ let [first, ...rest] = children;
2050
+ let [ws, ...op] = first;
2051
+ ws = [" "].concat(ws);
2052
+ first = [ws, ...op];
2053
+ children = [first, ...rest];
2117
2054
  }
2055
+ conditions.push(
2056
+ processBinaryOpExpression([ref, children])
2057
+ );
2058
+ break;
2059
+ }
2060
+ case "RegularExpressionLiteral": {
2061
+ conditions.push(
2062
+ ["typeof ", ref, " === 'string'"],
2063
+ [pattern, ".test(", ref, ")"]
2064
+ );
2065
+ break;
2066
+ }
2067
+ case "PinPattern":
2068
+ conditions.push([
2069
+ ref,
2070
+ " === ",
2071
+ pattern.expression
2072
+ ]);
2073
+ break;
2074
+ case "Literal":
2075
+ conditions.push([
2076
+ ref,
2077
+ " === ",
2078
+ pattern
2079
+ ]);
2080
+ break;
2081
+ default:
2118
2082
  break;
2119
- case "ForStatement":
2120
- case "IterationStatement":
2121
- case "DoStatement":
2122
- wrapIterationReturningResults(exp, outer);
2123
- return;
2124
- case "BlockStatement":
2125
- insertReturn(exp.expressions[exp.expressions.length - 1]);
2126
- return;
2127
- case "IfStatement":
2128
- insertReturn(exp.then);
2129
- if (exp.else && exp.else.length !== 0)
2130
- insertReturn(exp.else[2]);
2131
- else
2132
- exp.children.push(["", {
2133
- type: "ReturnStatement",
2134
- // NOTE: add a prefixed semi-colon because the if block may not be braced
2135
- children: [";return"],
2136
- parent: exp
2137
- }]);
2138
- return;
2139
- case "PatternMatchingStatement":
2140
- insertReturn(exp.children[0][0]);
2141
- return;
2142
- case "SwitchStatement":
2143
- insertSwitchReturns(exp);
2144
- return;
2145
- case "TryStatement":
2146
- exp.blocks.forEach((block) => insertReturn(block));
2147
- return;
2148
2083
  }
2149
- if (node[node.length - 1]?.type === "SemicolonDelimiter")
2150
- return;
2151
- const returnStatement = wrapWithReturn(node[1]);
2152
- node.splice(1, 1, returnStatement);
2153
2084
  }
2154
- function insertSwitchReturns(exp) {
2155
- exp.caseBlock.clauses.forEach((clause) => {
2156
- return insertReturn(clause);
2085
+ function elideMatchersFromArrayBindings(elements) {
2086
+ return elements.map((el) => {
2087
+ if (el.type === "BindingRestElement") {
2088
+ return ["", el, void 0];
2089
+ }
2090
+ const { children: [ws, e, delim] } = el;
2091
+ switch (e.type) {
2092
+ case "Literal":
2093
+ case "RegularExpressionLiteral":
2094
+ case "StringLiteral":
2095
+ case "PinPattern":
2096
+ return delim;
2097
+ default:
2098
+ return [ws, nonMatcherBindings(e), delim];
2099
+ }
2157
2100
  });
2158
2101
  }
2159
- function wrapIterationReturningResults(statement, outer, collect) {
2160
- if (statement.type === "DoStatement") {
2161
- if (collect) {
2162
- assignResults(statement.block, collect);
2163
- } else {
2164
- insertReturn(statement.block, outer);
2102
+ function elideMatchersFromPropertyBindings(properties) {
2103
+ return properties.map((p) => {
2104
+ switch (p.type) {
2105
+ case "BindingProperty": {
2106
+ const { children, name, value } = p;
2107
+ const [ws] = children;
2108
+ switch (value && value.type) {
2109
+ case "ArrayBindingPattern":
2110
+ case "ObjectBindingPattern":
2111
+ return {
2112
+ ...p,
2113
+ children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
2114
+ };
2115
+ case "Identifier":
2116
+ return p;
2117
+ case "Literal":
2118
+ case "RegularExpressionLiteral":
2119
+ case "StringLiteral":
2120
+ default:
2121
+ return {
2122
+ ...p,
2123
+ children: [ws, name, p.delim]
2124
+ };
2125
+ }
2126
+ }
2127
+ case "PinProperty":
2128
+ case "BindingRestProperty":
2129
+ default:
2130
+ return p;
2165
2131
  }
2166
- return;
2167
- }
2168
- assert.equal(
2169
- statement.resultsRef,
2170
- void 0,
2171
- "wrapIterationReturningResults should not be called twice on the same statement"
2172
- );
2173
- const resultsRef = statement.resultsRef = makeRef("results");
2174
- const declaration = {
2175
- type: "Declaration",
2176
- children: ["const ", resultsRef, "=[]"]
2177
- };
2178
- outer.children.unshift(["", declaration, ";"]);
2179
- assignResults(statement.block, (node) => {
2180
- return [resultsRef, ".push(", node, ")"];
2181
2132
  });
2182
- if (collect) {
2183
- statement.children.push(collect(resultsRef));
2184
- } else {
2185
- statement.children.push(";return ", resultsRef, ";");
2186
- }
2187
2133
  }
2188
- function processParams(f) {
2189
- const { type, parameters, block } = f;
2190
- const isConstructor = f.name === "constructor";
2191
- if (type === "ArrowFunction" && parameters && parameters.tp && parameters.tp.parameters.length === 1) {
2192
- parameters.tp.parameters.push(",");
2193
- }
2194
- if (!block)
2195
- return;
2196
- const { expressions } = block;
2197
- if (!expressions)
2198
- return;
2199
- const { blockPrefix } = parameters;
2200
- let indent;
2201
- if (!expressions.length) {
2202
- indent = "";
2203
- } else {
2204
- indent = expressions[0][0];
2205
- }
2206
- const [splices, thisAssignments] = gatherBindingCode(parameters, {
2207
- injectParamProps: isConstructor
2208
- });
2209
- const delimiter = {
2210
- type: "SemicolonDelimiter",
2211
- children: [";"]
2212
- };
2213
- const prefix = splices.map((s) => ["let ", s]).concat(thisAssignments).map(
2214
- (s) => s.type ? {
2215
- // TODO: figure out how to get JS only statement tuples
2216
- ...s,
2217
- children: [indent, ...s.children, delimiter]
2218
- } : [indent, s, delimiter]
2219
- );
2220
- if (!prefix.length)
2221
- return;
2222
- if (isConstructor) {
2223
- const superCalls = gatherNodes(expressions, (exp) => {
2224
- return exp.type === "CallExpression" && exp.children[0]?.token === "super";
2225
- });
2226
- if (superCalls.length) {
2227
- const { child } = findAncestor(
2228
- superCalls[0],
2229
- (ancestor) => ancestor === block
2230
- );
2231
- const index = findChildIndex(expressions, child);
2232
- if (index < 0) {
2233
- throw new Error("Could not find super call within top-level expressions");
2234
- }
2235
- expressions.splice(index + 1, 0, ...prefix);
2236
- return;
2134
+ function nonMatcherBindings(pattern) {
2135
+ switch (pattern.type) {
2136
+ case "ArrayBindingPattern": {
2137
+ const elements = elideMatchersFromArrayBindings(pattern.elements);
2138
+ const children = ["[", elements, "]"];
2139
+ return {
2140
+ ...pattern,
2141
+ children,
2142
+ elements
2143
+ };
2144
+ }
2145
+ case "PostRestBindingElements": {
2146
+ const els = elideMatchersFromArrayBindings(pattern.children[1]);
2147
+ return {
2148
+ ...pattern,
2149
+ children: [
2150
+ pattern.children[0],
2151
+ els,
2152
+ ...pattern.children.slice(2)
2153
+ ]
2154
+ };
2237
2155
  }
2156
+ case "ObjectBindingPattern":
2157
+ return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
2158
+ default:
2159
+ return pattern;
2238
2160
  }
2239
- expressions.unshift(...prefix);
2240
2161
  }
2241
- function processFunctions(statements, config) {
2242
- gatherRecursiveAll(statements, ({ type }) => type === "FunctionExpression" || type === "ArrowFunction").forEach((f) => {
2243
- if (f.type === "FunctionExpression")
2244
- implicitFunctionBlock(f);
2245
- processParams(f);
2246
- return processReturn(f, config.implicitReturns);
2247
- });
2248
- gatherRecursiveAll(statements, ({ type }) => type === "MethodDefinition").forEach((f) => {
2249
- implicitFunctionBlock(f);
2250
- processParams(f);
2251
- return processReturn(f, config.implicitReturns);
2162
+ function aggregateDuplicateBindings(bindings, ReservedWord) {
2163
+ const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
2164
+ const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
2165
+ arrayBindings.forEach((a) => {
2166
+ const { elements } = a;
2167
+ return elements.forEach((element) => {
2168
+ if (Array.isArray(element)) {
2169
+ const [, e] = element;
2170
+ if (e.type === "Identifier") {
2171
+ return props.push(e);
2172
+ } else if (e.type === "BindingRestElement") {
2173
+ return props.push(e);
2174
+ }
2175
+ ;
2176
+ return;
2177
+ }
2178
+ ;
2179
+ return;
2180
+ });
2252
2181
  });
2253
- }
2254
- function expressionizeIteration(exp) {
2255
- const { async, subtype, block, children, statement } = exp;
2256
- const i = children.indexOf(statement);
2257
- if (i < 0) {
2258
- throw new Error("Could not find iteration statement in iteration expression");
2259
- }
2260
- if (subtype === "DoStatement") {
2261
- children.splice(i, 1, ...wrapIIFE([["", statement, void 0]], async));
2262
- updateParentPointers(exp);
2263
- return;
2182
+ const declarations = [];
2183
+ const propsGroupedByName = /* @__PURE__ */ new Map();
2184
+ for (const p of props) {
2185
+ const { name, value } = p;
2186
+ const key = value?.name || name?.name || name;
2187
+ if (propsGroupedByName.has(key)) {
2188
+ propsGroupedByName.get(key).push(p);
2189
+ } else {
2190
+ propsGroupedByName.set(key, [p]);
2191
+ }
2264
2192
  }
2265
- exp.resultsRef ??= makeRef("results");
2266
- const { resultsRef } = exp;
2267
- assignResults(block, (node) => {
2268
- return [resultsRef, ".push(", node, ")"];
2193
+ propsGroupedByName.forEach((shared, key) => {
2194
+ if (!key) {
2195
+ return;
2196
+ }
2197
+ if (ReservedWord({ fail() {
2198
+ } }, {
2199
+ pos: 0,
2200
+ input: key
2201
+ })) {
2202
+ shared.forEach((p) => {
2203
+ return aliasBinding(p, makeRef(`_${key}`, key));
2204
+ });
2205
+ return;
2206
+ }
2207
+ if (shared.length === 1) {
2208
+ return;
2209
+ }
2210
+ const refs = shared.map((p) => {
2211
+ const ref = makeRef(key);
2212
+ aliasBinding(p, ref);
2213
+ return ref;
2214
+ });
2215
+ return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
2216
+ return i === 0 ? r : [", ", r];
2217
+ }), "]"]);
2269
2218
  });
2270
- braceBlock(block);
2271
- children.splice(
2272
- i,
2273
- 1,
2274
- ...wrapIIFE([
2275
- ["", ["const ", resultsRef, "=[]"], ";"],
2276
- ...children.map((c) => ["", c, void 0]),
2277
- ["", wrapWithReturn(resultsRef)]
2278
- ], async)
2279
- );
2280
- updateParentPointers(exp);
2219
+ return declarations;
2281
2220
  }
2282
- function skipImplicitArguments(args) {
2283
- if (args.length === 1) {
2284
- let arg0 = args[0];
2285
- if (arg0.type === "StatementExpression") {
2286
- arg0 = arg0.statement;
2287
- }
2288
- return arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block);
2221
+ function aliasBinding(p, ref) {
2222
+ if (p.type === "Identifier") {
2223
+ p.children[0] = ref;
2224
+ } else if (p.type === "BindingRestElement") {
2225
+ aliasBinding(p.binding, ref);
2226
+ } else if (p.value?.type === "Identifier") {
2227
+ aliasBinding(p.value, ref);
2228
+ } else {
2229
+ p.value = ref;
2230
+ const index = p.children.indexOf(p.name);
2231
+ p.children.splice(index + 1, 0, ": ", ref);
2289
2232
  }
2290
- return false;
2291
2233
  }
2292
- var init_function = __esm({
2293
- "source/parser/function.civet"() {
2234
+ var init_pattern_matching = __esm({
2235
+ "source/parser/pattern-matching.civet"() {
2294
2236
  "use strict";
2295
- init_block();
2296
- init_binding();
2297
2237
  init_traversal();
2298
2238
  init_util();
2239
+ init_block();
2240
+ init_binding();
2241
+ init_op();
2299
2242
  }
2300
2243
  });
2301
2244
 
@@ -2313,7 +2256,7 @@ function processAssignmentDeclaration(decl, pattern, suffix, ws, assign, e) {
2313
2256
  const thisAssignments = assignments.map((a) => ["", a, ";"]);
2314
2257
  const initializer = makeNode({
2315
2258
  type: "Initializer",
2316
- exp: e,
2259
+ expression: e,
2317
2260
  children: [ws, assign, e]
2318
2261
  });
2319
2262
  const binding = makeNode({
@@ -2354,7 +2297,7 @@ function processDeclarations(statements) {
2354
2297
  });
2355
2298
  }
2356
2299
  function prependStatementExpressionBlock(initializer, statement) {
2357
- let { exp } = initializer;
2300
+ let { expression: exp } = initializer;
2358
2301
  let ws;
2359
2302
  if (Array.isArray(exp)) {
2360
2303
  ws = exp[0];
@@ -2374,7 +2317,7 @@ function prependStatementExpressionBlock(initializer, statement) {
2374
2317
  const statement2 = statementExp.statement;
2375
2318
  blockStatement[1] = statement2;
2376
2319
  if (statement2.type === "DoStatement") {
2377
- ref = initializer.exp = initializer.children[2] = makeRef();
2320
+ ref = initializer.expression = initializer.children[2] = makeRef();
2378
2321
  assignResults(blockStatement, (resultNode) => {
2379
2322
  return makeNode({
2380
2323
  type: "AssignmentExpression",
@@ -2390,10 +2333,10 @@ function prependStatementExpressionBlock(initializer, statement) {
2390
2333
  } else {
2391
2334
  wrapIterationReturningResults(statement2, { children: blockStatement }, function() {
2392
2335
  });
2393
- ref = initializer.exp = initializer.children[2] = statement2.resultsRef;
2336
+ ref = initializer.expression = initializer.children[2] = statement2.resultsRef;
2394
2337
  }
2395
2338
  } else {
2396
- ref = initializer.exp = initializer.children[2] = makeRef();
2339
+ ref = initializer.expression = initializer.children[2] = makeRef();
2397
2340
  assignResults(blockStatement, (resultNode) => {
2398
2341
  return makeNode({
2399
2342
  type: "AssignmentExpression",
@@ -2592,7 +2535,7 @@ function dynamizeImportDeclaration(decl) {
2592
2535
  }
2593
2536
  })();
2594
2537
  const c = "const";
2595
- const exp = [
2538
+ const expression = [
2596
2539
  justDefault ? "(" : void 0,
2597
2540
  { type: "Await", children: ["await"] },
2598
2541
  " ",
@@ -2603,8 +2546,8 @@ function dynamizeImportDeclaration(decl) {
2603
2546
  ];
2604
2547
  const initializer = {
2605
2548
  type: "Initializer",
2606
- exp,
2607
- children: [" ", "= ", exp]
2549
+ expression,
2550
+ children: [" ", "= ", expression]
2608
2551
  };
2609
2552
  const bindings = [{
2610
2553
  type: "Binding",
@@ -2621,7 +2564,7 @@ function dynamizeImportDeclaration(decl) {
2621
2564
  ];
2622
2565
  const initializer2 = {
2623
2566
  type: "Initializer",
2624
- exp,
2567
+ expression,
2625
2568
  children: [" ", "= ", exp2]
2626
2569
  };
2627
2570
  bindings.push({
@@ -2634,7 +2577,7 @@ function dynamizeImportDeclaration(decl) {
2634
2577
  const pattern3 = convertNamedImportsToObject(imports.children.at(-1), true);
2635
2578
  const initializer3 = {
2636
2579
  type: "Initializer",
2637
- exp: pattern,
2580
+ expression: pattern,
2638
2581
  children: [" ", "= ", pattern]
2639
2582
  };
2640
2583
  bindings.push({
@@ -2692,6 +2635,97 @@ var init_declaration = __esm({
2692
2635
  }
2693
2636
  });
2694
2637
 
2638
+ // source/parser/unary.civet
2639
+ function processUnaryExpression(pre, exp, post) {
2640
+ if (!(pre.length || post))
2641
+ return exp;
2642
+ if (post?.token === "?") {
2643
+ post = {
2644
+ $loc: post.$loc,
2645
+ token: " != null"
2646
+ };
2647
+ if (pre.length) {
2648
+ const lastPre = pre.at(-1);
2649
+ if (lastPre.token === "!") {
2650
+ post.token = " == null";
2651
+ pre = pre.slice(0, -1);
2652
+ } else if (lastPre.length === 2 && lastPre[0].token === "!") {
2653
+ post.token = " == null";
2654
+ pre = pre.slice(0, -1);
2655
+ }
2656
+ }
2657
+ const existence = {
2658
+ type: "Existence",
2659
+ expression: exp,
2660
+ children: [exp, post],
2661
+ parent: void 0
2662
+ };
2663
+ exp = makeLeftHandSideExpression(existence);
2664
+ if (pre.length) {
2665
+ return {
2666
+ type: "UnaryExpression",
2667
+ children: [...pre, exp]
2668
+ };
2669
+ }
2670
+ return exp;
2671
+ }
2672
+ if (exp.type === "Literal") {
2673
+ if (pre.length === 1) {
2674
+ const { token } = pre[0];
2675
+ if (token === "-" || token === "+") {
2676
+ const children = [pre[0], ...exp.children];
2677
+ const literal = {
2678
+ type: "Literal",
2679
+ children,
2680
+ raw: `${token}${exp.raw}`
2681
+ };
2682
+ if (post) {
2683
+ return {
2684
+ type: "UnaryExpression",
2685
+ children: [literal, post]
2686
+ };
2687
+ }
2688
+ return literal;
2689
+ }
2690
+ }
2691
+ }
2692
+ let ref;
2693
+ while (ref = pre.length) {
2694
+ const l = ref;
2695
+ const last = pre[l - 1];
2696
+ if (last.type === "Await") {
2697
+ if (last.op) {
2698
+ if (exp.type !== "ParenthesizedExpression") {
2699
+ exp = ["(", exp, ")"];
2700
+ }
2701
+ exp = {
2702
+ type: "CallExpression",
2703
+ children: [...last.children, "Promise", last.op, exp]
2704
+ };
2705
+ pre = pre.slice(0, -1);
2706
+ } else {
2707
+ exp = {
2708
+ type: "AwaitExpression",
2709
+ children: [...last.children, exp]
2710
+ };
2711
+ pre = pre.slice(0, -1);
2712
+ }
2713
+ } else {
2714
+ break;
2715
+ }
2716
+ }
2717
+ return {
2718
+ type: "UnaryExpression",
2719
+ children: [...pre, exp, post]
2720
+ };
2721
+ }
2722
+ var init_unary = __esm({
2723
+ "source/parser/unary.civet"() {
2724
+ "use strict";
2725
+ init_util();
2726
+ }
2727
+ });
2728
+
2695
2729
  // source/parser/pipe.civet
2696
2730
  function constructInvocation(fn, arg) {
2697
2731
  const fnArr = [fn.leadingComment, fn.expr, fn.trailingComment];
@@ -2818,7 +2852,7 @@ function processPipelineExpressions(statements) {
2818
2852
  names: null,
2819
2853
  lhs,
2820
2854
  assigned: arg,
2821
- exp: children
2855
+ expression: children
2822
2856
  });
2823
2857
  arg = clone(arg);
2824
2858
  removeHoistDecs(arg);
@@ -3194,7 +3228,7 @@ function createConstLetDecs(statements, scopes, letOrConst) {
3194
3228
  scopes.pop();
3195
3229
  statements.splice(0, statements.length, ...targetStatements);
3196
3230
  }
3197
- function createVarDecs(statements, scopes, pushVar) {
3231
+ function createVarDecs(block, scopes, pushVar) {
3198
3232
  function hasDec(name) {
3199
3233
  return scopes.some((s) => s.has(name));
3200
3234
  }
@@ -3213,6 +3247,7 @@ function createVarDecs(statements, scopes, pushVar) {
3213
3247
  return decs.add(name);
3214
3248
  };
3215
3249
  }
3250
+ const { expressions: statements } = block;
3216
3251
  const decs = findDecs(statements);
3217
3252
  scopes.push(decs);
3218
3253
  const varIds = [];
@@ -3226,19 +3261,19 @@ function createVarDecs(statements, scopes, pushVar) {
3226
3261
  const fnNodes = gatherNodes(statements, isFunction);
3227
3262
  const forNodes = gatherNodes(statements, (s) => s.type === "ForStatement");
3228
3263
  const blockNodes = new Set(gatherNodes(statements, (s) => s.type === "BlockStatement"));
3229
- fnNodes.forEach(({ block }) => blockNodes.delete(block));
3230
- forNodes.forEach(({ block }) => blockNodes.delete(block));
3231
- blockNodes.forEach((block) => {
3232
- return createVarDecs(block.expressions, scopes, pushVar);
3264
+ fnNodes.forEach(({ block: block2 }) => blockNodes.delete(block2));
3265
+ forNodes.forEach(({ block: block2 }) => blockNodes.delete(block2));
3266
+ blockNodes.forEach((block2) => {
3267
+ return createVarDecs(block2, scopes, pushVar);
3233
3268
  });
3234
- forNodes.forEach(({ block, declaration }) => {
3269
+ forNodes.forEach(({ block: block2, declaration }) => {
3235
3270
  scopes.push(new Set(declaration.names));
3236
- createVarDecs(block.expressions, scopes, pushVar);
3271
+ createVarDecs(block2, scopes, pushVar);
3237
3272
  return scopes.pop();
3238
3273
  });
3239
- fnNodes.forEach(({ block, parameters }) => {
3274
+ fnNodes.forEach(({ block: block2, parameters }) => {
3240
3275
  scopes.push(new Set(parameters.names));
3241
- createVarDecs(block.expressions, scopes);
3276
+ createVarDecs(block2, scopes);
3242
3277
  return scopes.pop();
3243
3278
  });
3244
3279
  if (varIds.length) {
@@ -3247,6 +3282,7 @@ function createVarDecs(statements, scopes, pushVar) {
3247
3282
  if (statements[0][1]?.parent?.root) {
3248
3283
  delimiter = ";\n";
3249
3284
  }
3285
+ braceBlock(block);
3250
3286
  statements.unshift([indent, {
3251
3287
  type: "Declaration",
3252
3288
  children: ["var ", varIds.join(", ")]
@@ -3670,7 +3706,7 @@ function processCallMemberExpression(node) {
3670
3706
  2,
3671
3707
  commaCount ? {
3672
3708
  type: "ParenthesizedExpression",
3673
- children: ["(", call, ")"]
3709
+ children: ["(", ...call.children, ")"]
3674
3710
  } : { ...call, type: "ParenthesizedExpression" }
3675
3711
  );
3676
3712
  }
@@ -4090,13 +4126,13 @@ function processAssignments(statements) {
4090
4126
  statements,
4091
4127
  (n) => n.type === "AssignmentExpression" && n.names === null,
4092
4128
  (exp) => {
4093
- let { lhs: $1, exp: $2 } = exp, tail = [], i = 0, len = $1.length;
4129
+ let { lhs: $1, expression: $2 } = exp, tail = [], i = 0, len = $1.length;
4094
4130
  let block;
4095
4131
  if (exp.parent?.type === "BlockStatement" && !$1.at(-1)?.at(-1)?.special) {
4096
4132
  block = makeBlockFragment();
4097
4133
  let ref4;
4098
4134
  if (ref4 = prependStatementExpressionBlock(
4099
- { type: "Initializer", exp: $2, children: [void 0, void 0, $2] },
4135
+ { type: "Initializer", expression: $2, children: [void 0, void 0, $2] },
4100
4136
  block
4101
4137
  )) {
4102
4138
  const ref = ref4;
@@ -4122,7 +4158,7 @@ function processAssignments(statements) {
4122
4158
  exp.children.splice(
4123
4159
  index2,
4124
4160
  1,
4125
- exp.exp = $2 = [call, "(", lhs, ", ", $2, ")"]
4161
+ exp.expression = $2 = [call, "(", lhs, ", ", $2, ")"]
4126
4162
  );
4127
4163
  if (omitLhs) {
4128
4164
  return $2;
@@ -4439,7 +4475,7 @@ function processProgram(root, config, m, ReservedWord) {
4439
4475
  } else if (config.autoConst) {
4440
4476
  createConstLetDecs(statements, [], "const");
4441
4477
  } else if (config.autoVar) {
4442
- createVarDecs(statements, []);
4478
+ createVarDecs(root, []);
4443
4479
  }
4444
4480
  processBlocks(statements);
4445
4481
  populateRefs(statements);
@@ -4490,7 +4526,7 @@ function processPlaceholders(statements) {
4490
4526
  const { type } = ancestor2;
4491
4527
  return type === "Call" || type === "BlockStatement" || type === "PipelineExpression" || // Declaration
4492
4528
  type === "Initializer" || // Right-hand side of assignment
4493
- type === "AssignmentExpression" && ancestor2.exp === child2;
4529
+ type === "AssignmentExpression" && ancestor2.expression === child2 || type === "ReturnStatement" || type === "YieldExpression";
4494
4530
  }));
4495
4531
  switch (ancestor?.type) {
4496
4532
  case "Call": {
@@ -4530,11 +4566,13 @@ function processPlaceholders(statements) {
4530
4566
  break;
4531
4567
  }
4532
4568
  case "AssignmentExpression":
4533
- case "Initializer": {
4569
+ case "Initializer":
4570
+ case "ReturnStatement":
4571
+ case "YieldExpression": {
4534
4572
  const i = findChildIndex(ancestor, child);
4535
- if (i >= 0 && ancestor.exp === ancestor.children[i]) {
4536
- ancestor.exp = ancestor.children[i] = maybeWrap(ancestor.exp, ancestor);
4537
- ancestor = ancestor.exp;
4573
+ if (i >= 0 && ancestor.expression === ancestor.children[i]) {
4574
+ ancestor.expression = ancestor.children[i] = maybeWrap(ancestor.expression, ancestor);
4575
+ ancestor = ancestor.expression;
4538
4576
  } else {
4539
4577
  ancestor = void 0;
4540
4578
  }
@@ -4585,8 +4623,10 @@ function processPlaceholders(statements) {
4585
4623
  break;
4586
4624
  }
4587
4625
  case "AssignmentExpression":
4588
- case "Initializer": {
4589
- outer = ancestor === parent.exp;
4626
+ case "Initializer":
4627
+ case "ReturnStatement":
4628
+ case "YieldExpression": {
4629
+ outer = ancestor === parent.expression;
4590
4630
  break;
4591
4631
  }
4592
4632
  }
@@ -5334,7 +5374,6 @@ var require_parser = __commonJS({
5334
5374
  ActualAssignment,
5335
5375
  NonPipelineActualAssignment,
5336
5376
  YieldExpression,
5337
- YieldTail,
5338
5377
  ArrowFunction,
5339
5378
  FatArrow,
5340
5379
  TrailingDeclaration,
@@ -6946,7 +6985,7 @@ var require_parser = __commonJS({
6946
6985
  names: null,
6947
6986
  lhs: $1,
6948
6987
  assigned: $1[0][1],
6949
- exp: $2
6988
+ expression: $2
6950
6989
  };
6951
6990
  });
6952
6991
  function ActualAssignment(ctx, state) {
@@ -6963,22 +7002,30 @@ var require_parser = __commonJS({
6963
7002
  names: null,
6964
7003
  lhs: $1,
6965
7004
  assigned: $1[0][1],
6966
- exp: $2
7005
+ expression: $2
6967
7006
  };
6968
7007
  });
6969
7008
  function NonPipelineActualAssignment(ctx, state) {
6970
7009
  return $EVENT(ctx, state, "NonPipelineActualAssignment", NonPipelineActualAssignment$0);
6971
7010
  }
6972
- var YieldExpression$0 = $S(Yield, YieldTail);
7011
+ var YieldExpression$0 = $TS($S(Yield, $E($S($E($S($E(_), Star)), MaybeNestedExpression))), function($skip, $loc, $0, $1, $2) {
7012
+ if ($2) {
7013
+ const [star, expression] = $2;
7014
+ return {
7015
+ type: "YieldExpression",
7016
+ star,
7017
+ expression,
7018
+ children: [$1, star, expression]
7019
+ };
7020
+ }
7021
+ return {
7022
+ type: "YieldExpression",
7023
+ children: [$1]
7024
+ };
7025
+ });
6973
7026
  function YieldExpression(ctx, state) {
6974
7027
  return $EVENT(ctx, state, "YieldExpression", YieldExpression$0);
6975
7028
  }
6976
- var YieldTail$0 = $Y(EOS);
6977
- var YieldTail$1 = $S($E($S($E(_), Star)), AssignmentExpression);
6978
- var YieldTail$$ = [YieldTail$0, YieldTail$1];
6979
- function YieldTail(ctx, state) {
6980
- return $EVENT_C(ctx, state, "YieldTail", YieldTail$$);
6981
- }
6982
7029
  var ArrowFunction$0 = ThinArrowFunction;
6983
7030
  var ArrowFunction$1 = $TS($S($E($S(Async, _)), ArrowParameters, $E(ReturnTypeSuffix), FatArrow, FatArrowBody), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
6984
7031
  var async = $1;
@@ -8698,66 +8745,66 @@ var require_parser = __commonJS({
8698
8745
  var op = $4;
8699
8746
  var ws2 = $5;
8700
8747
  var close = $6;
8701
- const refB = makeRef("b"), body = processBinaryOpExpression([lhs, [
8702
- [ws1, op, ws2, refB]
8703
- // BinaryOpRHS
8704
- ]]);
8705
- const parameters = {
8706
- type: "Parameters",
8707
- children: ["(", refB, ")"],
8708
- names: []
8709
- };
8710
- const block = {
8711
- expressions: [body]
8712
- };
8748
+ const refB = makeRef("b");
8749
+ const fn = makeAmpersandFunction({
8750
+ ref: refB,
8751
+ body: processBinaryOpExpression([lhs, [
8752
+ [ws1, op, ws2, refB]
8753
+ // BinaryOpRHS
8754
+ ]])
8755
+ });
8713
8756
  return {
8714
- type: "ArrowFunction",
8715
- signature: {
8716
- modifier: {}
8717
- },
8718
- children: [open, parameters, " => ", body, close],
8719
- body,
8720
- parenthesized: true,
8721
- ampersandBlock: true,
8757
+ type: "ParenthesizedExpression",
8758
+ children: [open, fn, close],
8759
+ expression: fn
8760
+ };
8761
+ });
8762
+ var FunctionExpression$3 = $TS($S(OpenParen, $P($S(NotDedented, UpdateExpression, WAssignmentOp)), __, CloseParen), function($skip, $loc, $0, $1, $2, $3, $4) {
8763
+ var open = $1;
8764
+ var lhs = $2;
8765
+ var ws2 = $3;
8766
+ var close = $4;
8767
+ lhs = lhs.map((x) => [x[0], x[1], ...x[2]]);
8768
+ const refB = makeRef("b");
8769
+ const fn = makeAmpersandFunction({
8722
8770
  ref: refB,
8723
- block,
8724
- parameters
8771
+ body: {
8772
+ type: "AssignmentExpression",
8773
+ children: [lhs, ws2, refB],
8774
+ names: null,
8775
+ lhs,
8776
+ assigned: lhs[0][1],
8777
+ expression: refB
8778
+ }
8779
+ });
8780
+ return {
8781
+ type: "ParenthesizedExpression",
8782
+ children: [open, fn, close],
8783
+ expression: fn
8725
8784
  };
8726
8785
  });
8727
- var FunctionExpression$3 = $TS($S(OpenParen, __, $N($EXPECT($R13, "FunctionExpression /\\+\\+|--|[\\+\\-&]\\S/")), BinaryOp, __, NonPipelineAssignmentExpression, CloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5, $6, $7) {
8786
+ var FunctionExpression$4 = $TS($S(OpenParen, __, $N($EXPECT($R13, "FunctionExpression /\\+\\+|--|[\\+\\-&]\\S/")), BinaryOp, __, NonPipelineAssignmentExpression, CloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5, $6, $7) {
8728
8787
  var open = $1;
8729
8788
  var ws1 = $2;
8730
8789
  var op = $4;
8731
8790
  var ws2 = $5;
8732
8791
  var rhs = $6;
8733
8792
  var close = $7;
8734
- const refA = makeRef("a"), body = processBinaryOpExpression([refA, [
8735
- [ws1, op, ws2, rhs]
8736
- // BinaryOpRHS
8737
- ]]);
8738
- const parameters = {
8739
- type: "Parameters",
8740
- children: ["(", refA, ")"],
8741
- names: []
8742
- };
8743
- const block = {
8744
- expressions: [body]
8745
- };
8746
- return {
8747
- type: "ArrowFunction",
8748
- signature: {
8749
- modifier: {}
8750
- },
8751
- children: [open, parameters, " => ", body, close],
8752
- body,
8753
- parenthesized: true,
8754
- ampersandBlock: true,
8793
+ const refA = makeRef("a");
8794
+ const fn = makeAmpersandFunction({
8755
8795
  ref: refA,
8756
- block,
8757
- parameters
8796
+ body: processBinaryOpExpression([refA, [
8797
+ [ws1, op, ws2, rhs]
8798
+ // BinaryOpRHS
8799
+ ]])
8800
+ });
8801
+ return {
8802
+ type: "ParenthesizedExpression",
8803
+ children: [open, fn, close],
8804
+ expression: fn
8758
8805
  };
8759
8806
  });
8760
- var FunctionExpression$$ = [FunctionExpression$0, FunctionExpression$1, FunctionExpression$2, FunctionExpression$3];
8807
+ var FunctionExpression$$ = [FunctionExpression$0, FunctionExpression$1, FunctionExpression$2, FunctionExpression$3, FunctionExpression$4];
8761
8808
  function FunctionExpression(ctx, state) {
8762
8809
  return $EVENT_C(ctx, state, "FunctionExpression", FunctionExpression$$);
8763
8810
  }
@@ -12329,8 +12376,8 @@ var require_parser = __commonJS({
12329
12376
  return $EVENT_C(ctx, state, "LexicalBinding", LexicalBinding$$);
12330
12377
  }
12331
12378
  var Initializer$0 = $T($S(__, Equals, ExtendedExpression), function(value) {
12332
- var exp = value[2];
12333
- return { "type": "Initializer", "exp": exp, "children": value };
12379
+ var expression = value[2];
12380
+ return { "type": "Initializer", "expression": expression, "children": value };
12334
12381
  });
12335
12382
  function Initializer(ctx, state) {
12336
12383
  return $EVENT(ctx, state, "Initializer", Initializer$0);
@@ -15802,7 +15849,6 @@ var require_parser = __commonJS({
15802
15849
  exports.ActualAssignment = ActualAssignment;
15803
15850
  exports.NonPipelineActualAssignment = NonPipelineActualAssignment;
15804
15851
  exports.YieldExpression = YieldExpression;
15805
- exports.YieldTail = YieldTail;
15806
15852
  exports.ArrowFunction = ArrowFunction;
15807
15853
  exports.FatArrow = FatArrow;
15808
15854
  exports.TrailingDeclaration = TrailingDeclaration;