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