@danielx/civet 0.6.82 → 0.6.84

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 (5) hide show
  1. package/dist/browser.js +2022 -1864
  2. package/dist/civet +0 -0
  3. package/dist/main.js +2022 -1864
  4. package/dist/main.mjs +2022 -1864
  5. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -270,27 +270,25 @@ function makeLeftHandSideExpression(expression) {
270
270
  return expression;
271
271
  }
272
272
  switch (expression.type) {
273
- case "Ref":
274
273
  case "AmpersandRef":
274
+ case "CallExpression":
275
275
  case "Identifier":
276
+ case "JSXElement":
277
+ case "JSXFragment":
276
278
  case "Literal":
277
- case "IterationExpression":
278
- case "CallExpression":
279
279
  case "MemberExpression":
280
280
  case "NewExpression":
281
281
  case "ParenthesizedExpression":
282
- case "IfExpression":
283
- case "DebuggerExpression":
284
- case "SwitchExpression":
285
- case "ThrowExpression":
286
- case "TryExpression":
282
+ case "Ref":
283
+ case "StatementExpression":
287
284
  return expression;
288
285
  }
289
286
  return makeNode({
290
287
  type: "ParenthesizedExpression",
291
288
  children: ["(", expression, ")"],
292
289
  expression,
293
- implicit: true
290
+ implicit: true,
291
+ parent: void 0
294
292
  });
295
293
  }
296
294
  function updateParentPointers(node, parent, depth = 1) {
@@ -405,7 +403,9 @@ function wrapIIFE(expressions, async) {
405
403
  type: "BlockStatement",
406
404
  expressions,
407
405
  children: ["{", expressions, "}"],
408
- bare: false
406
+ bare: false,
407
+ root: false,
408
+ parent: void 0
409
409
  });
410
410
  const parameters = {
411
411
  type: "Parameters",
@@ -444,11 +444,18 @@ function wrapWithReturn(expression) {
444
444
  children
445
445
  });
446
446
  }
447
- var typeNeedsNoParens;
447
+ var assert, typeNeedsNoParens;
448
448
  var init_util = __esm({
449
449
  "source/parser/util.civet"() {
450
450
  "use strict";
451
451
  init_traversal();
452
+ assert = {
453
+ equal(a, b, msg) {
454
+ if (a !== b) {
455
+ throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
456
+ }
457
+ }
458
+ };
452
459
  typeNeedsNoParens = /* @__PURE__ */ new Set([
453
460
  "IdentifierType",
454
461
  "ImportType",
@@ -608,6 +615,17 @@ function makeEmptyBlock() {
608
615
  empty: true
609
616
  };
610
617
  }
618
+ function makeBlockFragment() {
619
+ const expressions = [];
620
+ return {
621
+ type: "BlockStatement",
622
+ children: expressions,
623
+ parent: void 0,
624
+ expressions,
625
+ bare: false,
626
+ root: false
627
+ };
628
+ }
611
629
  function replaceBlockExpression(node, child, replacement) {
612
630
  let found = false;
613
631
  const { expressions } = node;
@@ -739,816 +757,1092 @@ var init_block = __esm({
739
757
  }
740
758
  });
741
759
 
742
- // source/parser/pipe.civet
743
- function constructInvocation(fn, arg) {
744
- const fnArr = [fn.leadingComment, fn.expr, fn.trailingComment];
745
- let expr = fn.expr;
746
- while (expr.type === "ParenthesizedExpression") {
747
- expr = expr.expression;
748
- }
749
- if (expr.ampersandBlock) {
750
- const { ref, body } = expr;
751
- ref.type = "PipedExpression";
752
- ref.children = [makeLeftHandSideExpression(arg)];
753
- updateParentPointers(ref);
754
- return makeNode({
755
- type: "UnwrappedExpression",
756
- children: [skipIfOnlyWS(fn.leadingComment), body, skipIfOnlyWS(fn.trailingComment)]
757
- });
758
- }
759
- expr = fn.expr;
760
- const lhs = makeLeftHandSideExpression(expr);
761
- let comment = skipIfOnlyWS(fn.trailingComment);
762
- if (comment)
763
- lhs.children.splice(2, 0, comment);
764
- comment = skipIfOnlyWS(fn.leadingComment);
765
- if (comment)
766
- lhs.children.splice(1, 0, comment);
767
- switch (arg.type) {
768
- case "CommaExpression":
769
- arg = makeLeftHandSideExpression(arg);
770
- break;
760
+ // source/parser/binding.civet
761
+ function adjustAtBindings(statements, asThis = false) {
762
+ gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
763
+ const { ref } = binding;
764
+ if (asThis) {
765
+ const atBinding = binding.binding;
766
+ atBinding.children.pop();
767
+ atBinding.type = void 0;
768
+ binding.children.unshift(ref.id, ": this.", ref.base);
769
+ binding.type = "Property";
770
+ binding.ref = void 0;
771
+ return;
772
+ }
773
+ if (ref.names[0] !== ref.base) {
774
+ return binding.children.unshift(ref.base, ": ");
775
+ }
776
+ ;
777
+ return;
778
+ });
779
+ }
780
+ function adjustBindingElements(elements) {
781
+ const names = elements.flatMap((p) => p.names || []), { length } = elements;
782
+ let blockPrefix, restIndex = -1, restCount = 0;
783
+ elements.forEach(({ type }, i) => {
784
+ if (type === "BindingRestElement") {
785
+ if (restIndex < 0)
786
+ restIndex = i;
787
+ return restCount++;
788
+ }
789
+ ;
790
+ return;
791
+ });
792
+ if (restCount === 0) {
793
+ return {
794
+ children: elements,
795
+ names,
796
+ blockPrefix,
797
+ length
798
+ };
799
+ } else if (restCount === 1) {
800
+ const rest = elements[restIndex];
801
+ const after = elements.slice(restIndex + 1);
802
+ const restIdentifier = rest.binding.ref || rest.binding;
803
+ names.push(...rest.names || []);
804
+ let l = after.length;
805
+ if (l) {
806
+ if (arrayElementHasTrailingComma(after[l - 1]))
807
+ l++;
808
+ blockPrefix = {
809
+ type: "PostRestBindingElements",
810
+ children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
811
+ names: after.flatMap((p) => p.names)
812
+ };
813
+ }
814
+ return {
815
+ names,
816
+ children: [...elements.slice(0, restIndex), {
817
+ ...rest,
818
+ children: rest.children.slice(0, -1)
819
+ // remove trailing comma
820
+ }],
821
+ blockPrefix,
822
+ length
823
+ };
771
824
  }
825
+ const err = {
826
+ type: "Error",
827
+ children: ["Multiple rest elements in array pattern"]
828
+ };
772
829
  return {
773
- type: "CallExpression",
774
- children: [lhs, "(", arg, ")"]
830
+ names,
831
+ children: [...elements, err],
832
+ blockPrefix,
833
+ length
775
834
  };
776
835
  }
777
- function constructPipeStep(fn, arg, returning) {
778
- const children = [[fn.leadingComment, fn.expr, fn.trailingComment].map(skipIfOnlyWS), " ", arg];
779
- switch (fn.expr.token) {
780
- case "yield":
781
- case "await":
782
- if (returning) {
783
- return [
784
- children,
785
- returning
786
- ];
836
+ function gatherBindingCode(statements, opts) {
837
+ const thisAssignments = [];
838
+ const splices = [];
839
+ function insertRestSplices(s, p, thisAssignments2) {
840
+ gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
841
+ if (n.type === "AtBinding") {
842
+ const { ref } = n;
843
+ const { id } = ref;
844
+ thisAssignments2.push([`this.${id} = `, ref]);
845
+ return;
787
846
  }
788
- return [
789
- children,
790
- null
791
- ];
792
- case "return":
793
- return [{
794
- type: "ReturnStatement",
795
- children
796
- }, null];
847
+ if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
848
+ n.names.forEach((id) => ({
849
+ push: thisAssignments2.push({
850
+ type: "AssignmentExpression",
851
+ children: [`this.${id} = `, id],
852
+ js: true
853
+ })
854
+ }));
855
+ return;
856
+ }
857
+ const { blockPrefix } = n;
858
+ p.push(blockPrefix);
859
+ return insertRestSplices(blockPrefix, p, thisAssignments2);
860
+ });
797
861
  }
798
- if (returning) {
799
- return [
800
- constructInvocation(fn, arg),
801
- returning
802
- ];
862
+ insertRestSplices(statements, splices, thisAssignments);
863
+ return [splices, thisAssignments];
864
+ }
865
+ function arrayElementHasTrailingComma(elementNode) {
866
+ const lastChild = elementNode.children.at(-1);
867
+ return lastChild && lastChild[lastChild.length - 1]?.token === ",";
868
+ }
869
+ var init_binding = __esm({
870
+ "source/parser/binding.civet"() {
871
+ "use strict";
872
+ init_traversal();
873
+ init_util();
874
+ }
875
+ });
876
+
877
+ // source/parser/op.civet
878
+ function getPrecedence(op) {
879
+ if (typeof op === "string") {
880
+ return precedenceMap.get(op) ?? (() => {
881
+ throw new Error(`Unknown operator: ${op}`);
882
+ })();
883
+ } else if (typeof op.prec === "number") {
884
+ return op.prec;
885
+ } else {
886
+ return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
803
887
  }
804
- return [constructInvocation(fn, arg), null];
805
888
  }
806
- function processPipelineExpressions(statements) {
807
- gatherRecursiveAll(statements, (n) => n.type === "PipelineExpression").forEach((s) => {
808
- const [ws, , body] = s.children;
809
- let [, arg] = s.children;
810
- let i = 0, l = body.length;
811
- const children = [ws];
812
- let usingRef = null;
813
- for (i = 0; i < l; i++) {
814
- const step = body[i];
815
- const [leadingComment, pipe, trailingComment, expr] = step;
816
- const returns = pipe.token === "||>";
817
- let ref, result, returning = returns ? arg : null;
818
- if (pipe.token === "|>=") {
819
- let initRef;
820
- if (i === 0) {
821
- outer:
822
- switch (arg.type) {
823
- case "MemberExpression":
824
- if (arg.children.length <= 2)
825
- break;
826
- case "CallExpression":
827
- const access = arg.children.pop();
828
- switch (access.type) {
829
- case "PropertyAccess":
830
- case "SliceExpression":
831
- break;
832
- default:
833
- children.unshift({
834
- type: "Error",
835
- $loc: pipe.token.$loc,
836
- message: `Can't assign to ${access.type}`
837
- });
838
- arg.children.push(access);
839
- break outer;
840
- }
841
- usingRef = makeRef();
842
- initRef = {
843
- type: "AssignmentExpression",
844
- children: [usingRef, " = ", arg, ","]
845
- };
846
- arg = {
847
- type: "MemberExpression",
848
- children: [usingRef, access]
849
- };
850
- break;
889
+ function processBinaryOpExpression($0) {
890
+ return recurse(expandChainedComparisons($0));
891
+ function recurse(expandedOps) {
892
+ let i = 2;
893
+ while (i < expandedOps.length) {
894
+ let op = expandedOps[i];
895
+ if (op.special) {
896
+ let advanceLeft2 = function(allowEqual) {
897
+ while (start >= 4) {
898
+ const prevPrec = getPrecedence(expandedOps[start - 2]);
899
+ if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
900
+ return prevPrec === prec;
851
901
  }
852
- const lhs = [[
853
- [initRef],
854
- arg,
855
- [],
856
- { token: "=", children: [" = "] }
857
- ]];
858
- Object.assign(s, {
859
- type: "AssignmentExpression",
860
- children: [lhs, children],
861
- names: null,
862
- lhs,
863
- assigned: arg,
864
- exp: children
865
- });
866
- arg = clone(arg);
867
- if (arg.children[0].type === "Ref") {
868
- arg.children[0] = usingRef;
902
+ start -= 4;
903
+ }
904
+ return false;
905
+ }, advanceRight2 = function(allowEqual) {
906
+ while (end + 4 < expandedOps.length) {
907
+ const nextPrec = getPrecedence(expandedOps[end + 2]);
908
+ if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
909
+ return nextPrec === prec;
910
+ }
911
+ end += 4;
912
+ }
913
+ return false;
914
+ };
915
+ var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
916
+ let start = i - 2, end = i + 2;
917
+ const prec = getPrecedence(op);
918
+ let error;
919
+ switch (op.assoc) {
920
+ case "left":
921
+ case void 0: {
922
+ advanceLeft2(true);
923
+ advanceRight2(false);
924
+ break;
925
+ }
926
+ case "right": {
927
+ advanceLeft2(false);
928
+ advanceRight2(true);
929
+ break;
930
+ }
931
+ case "non": {
932
+ if (advanceLeft2(false) || advanceRight2(false)) {
933
+ error = {
934
+ type: "Error",
935
+ message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
936
+ };
937
+ }
938
+ ;
939
+ break;
940
+ }
941
+ case "arguments": {
942
+ if (advanceLeft2(false)) {
943
+ error = {
944
+ type: "Error",
945
+ message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
946
+ };
947
+ }
948
+ advanceRight2(true);
949
+ break;
950
+ }
951
+ default: {
952
+ throw new Error(`Unsupported associativity: ${op.assoc}`);
953
+ }
954
+ }
955
+ let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
956
+ let wsOp = expandedOps[i - 1];
957
+ let wsB = expandedOps[i + 1];
958
+ let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
959
+ if (op.assoc === "arguments") {
960
+ let i2 = 2;
961
+ while (i2 < b.length) {
962
+ if (prec === getPrecedence(b[i2])) {
963
+ if (!(b[i2].token === op.token)) {
964
+ error ??= {
965
+ type: "Error",
966
+ message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
967
+ };
968
+ }
969
+ b[i2] = ",";
970
+ }
971
+ i2 += 4;
869
972
  }
870
973
  } else {
871
- children.unshift({
872
- type: "Error",
873
- $loc: pipe.token.$loc,
874
- message: "Can't use |>= in the middle of a pipeline"
875
- });
974
+ b = recurse(b);
876
975
  }
877
- } else {
878
- if (i === 0)
879
- s.children = children;
880
- }
881
- if (returns && (ref = needsRef(arg))) {
882
- usingRef = usingRef || ref;
883
- arg = {
884
- type: "ParenthesizedExpression",
885
- children: ["(", {
886
- type: "AssignmentExpression",
887
- children: [usingRef, " = ", arg]
888
- }, ")"]
889
- };
890
- returning = usingRef;
891
- }
892
- ;
893
- [result, returning] = constructPipeStep(
894
- {
895
- leadingComment: skipIfOnlyWS(leadingComment),
896
- trailingComment: skipIfOnlyWS(trailingComment),
897
- expr
898
- },
899
- arg,
900
- returning
901
- );
902
- if (result.type === "ReturnStatement") {
903
- if (i < l - 1) {
904
- result.children.push({
905
- type: "Error",
906
- message: "Can't continue a pipeline after returning"
907
- });
976
+ if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
977
+ a = ["typeof ", makeLeftHandSideExpression(a)];
978
+ if (op.negated) {
979
+ op = { ...op, token: "!==", negated: false };
980
+ } else {
981
+ op = { ...op, token: "===" };
982
+ }
908
983
  }
909
- arg = result;
910
- if (children[children.length - 1] === ",") {
911
- children.pop();
912
- children.push(";");
984
+ if (op.asConst) {
985
+ a = makeAsConst(a);
986
+ b = makeAsConst(b);
913
987
  }
914
- break;
915
- }
916
- if (returning) {
917
- arg = returning;
918
- children.push(result, ",");
988
+ let children;
989
+ if (op.call) {
990
+ wsOp = insertTrimmingSpace(wsOp, "");
991
+ if (op.reversed) {
992
+ wsB = insertTrimmingSpace(wsB, "");
993
+ children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
994
+ } else {
995
+ children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
996
+ }
997
+ } else if (op.method) {
998
+ wsOp = insertTrimmingSpace(wsOp, "");
999
+ wsB = insertTrimmingSpace(wsB, "");
1000
+ if (op.reversed) {
1001
+ if (end !== i + 2)
1002
+ b = makeLeftHandSideExpression(b);
1003
+ b = dotNumericLiteral(b);
1004
+ children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
1005
+ } else {
1006
+ if (start !== i - 2 || a.type === "NumericLiteral") {
1007
+ a = makeLeftHandSideExpression(a);
1008
+ }
1009
+ a = dotNumericLiteral(a);
1010
+ children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
1011
+ }
1012
+ } else if (op.token) {
1013
+ children = [a, wsOp, op, wsB, b];
1014
+ if (op.negated)
1015
+ children = ["(", ...children, ")"];
1016
+ } else {
1017
+ throw new Error("Unknown operator: " + JSON.stringify(op));
1018
+ }
1019
+ if (op.negated)
1020
+ children.unshift("!");
1021
+ if (error != null) {
1022
+ children.push(error);
1023
+ }
1024
+ expandedOps.splice(start, end - start + 1, {
1025
+ children
1026
+ });
1027
+ i = start + 2;
919
1028
  } else {
920
- arg = result;
1029
+ i += 4;
921
1030
  }
922
1031
  }
923
- if (usingRef) {
924
- s.hoistDec = {
925
- type: "Declaration",
926
- children: ["let ", usingRef],
927
- names: []
928
- };
929
- }
930
- children.push(arg);
931
- if (!children.some(($) => $?.type === "ReturnStatement") && children.some(($1) => $1 === ",")) {
932
- const { parent } = s;
933
- const parenthesizedExpression = makeLeftHandSideExpression({ ...s });
934
- Object.assign(s, parenthesizedExpression, {
935
- parent,
936
- hoistDec: void 0
937
- });
938
- }
939
- return addParentPointers(s, s.parent);
940
- });
1032
+ return expandedOps;
1033
+ }
1034
+ ;
1035
+ return recurse;
941
1036
  }
942
- var init_pipe = __esm({
943
- "source/parser/pipe.civet"() {
944
- "use strict";
945
- init_traversal();
946
- init_util();
1037
+ function dotNumericLiteral(literal) {
1038
+ if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
1039
+ literal.children.push(".");
1040
+ literal.raw += ".";
947
1041
  }
948
- });
949
-
950
- // source/parser/for.civet
951
- function forRange(open, forDeclaration, range, stepExp, close) {
952
- const { start, end, inclusive } = range;
953
- const counterRef = makeRef("i");
954
- let stepRef;
955
- if (stepExp) {
956
- stepExp = insertTrimmingSpace(stepExp, "");
957
- stepRef = maybeRef(stepExp, "step");
1042
+ return literal;
1043
+ }
1044
+ function makeAsConst(node) {
1045
+ if (Array.isArray(node) && node.length === 1) {
1046
+ node = node[0];
958
1047
  }
959
- const startRef = maybeRef(start, "start");
960
- const endRef = maybeRef(end, "end");
961
- const startRefDec = startRef !== start ? [startRef, " = ", start, ", "] : [];
962
- const endRefDec = endRef !== end ? [endRef, " = ", end, ", "] : [];
963
- let ascDec = [], ascRef, asc;
964
- if (stepRef) {
965
- if (stepRef !== stepExp) {
966
- ascDec = [", ", stepRef, " = ", stepExp];
967
- }
968
- } else if (start.type === "Literal" && end.type === "Literal") {
969
- asc = literalValue(start) <= literalValue(end);
1048
+ if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
1049
+ return { ...node, children: [...node.children, asConst] };
970
1050
  } else {
971
- ascRef = makeRef("asc");
972
- ascDec = [", ", ascRef, " = ", startRef, " <= ", endRef];
973
- }
974
- let varAssign = [], varLetAssign = varAssign, varLet = varAssign, blockPrefix;
975
- if (forDeclaration?.declare) {
976
- if (forDeclaration.declare.token === "let") {
977
- const varName = forDeclaration.children.splice(1);
978
- varAssign = [...insertTrimmingSpace(varName, ""), " = "];
979
- varLet = [",", ...varName, " = ", counterRef];
980
- } else {
981
- blockPrefix = [
982
- ["", forDeclaration, " = ", counterRef, ";"]
983
- ];
984
- }
985
- } else if (forDeclaration) {
986
- varAssign = varLetAssign = [forDeclaration, " = "];
1051
+ return node;
987
1052
  }
988
- const declaration = {
989
- type: "Declaration",
990
- children: ["let ", ...startRefDec, ...endRefDec, counterRef, " = ", ...varLetAssign, startRef, ...varLet, ...ascDec],
991
- names: forDeclaration?.names
992
- };
993
- const counterPart = inclusive ? [counterRef, " <= ", endRef, " : ", counterRef, " >= ", endRef] : [counterRef, " < ", endRef, " : ", counterRef, " > ", endRef];
994
- const condition = stepRef ? [stepRef, " !== 0 && (", stepRef, " > 0 ? ", ...counterPart, ")"] : ascRef ? [ascRef, " ? ", ...counterPart] : asc ? counterPart.slice(0, 3) : counterPart.slice(4);
995
- const increment = stepRef ? [...varAssign, counterRef, " += ", stepRef] : ascRef ? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef] : [...varAssign, asc ? "++" : "--", counterRef];
996
- return {
997
- declaration,
998
- children: [open, declaration, "; ", ...condition, "; ", ...increment, close],
999
- blockPrefix
1000
- };
1001
1053
  }
1002
- function processForInOf($0, getRef) {
1003
- let [awaits, eachOwn, open, declaration, declaration2, ws, inOf, exp, step, close] = $0;
1004
- if (exp.type === "RangeExpression" && inOf.token === "of" && !declaration2) {
1005
- return forRange(open, declaration, exp, step, close);
1006
- } else if (step) {
1007
- throw new Error("for..of/in cannot use 'by' except with range literals");
1054
+ function isExistence(exp) {
1055
+ if (exp.type === "ParenthesizedExpression" && exp.implicit) {
1056
+ exp = exp.expression;
1008
1057
  }
1009
- let eachOwnError;
1010
- let hoistDec, blockPrefix = [];
1011
- if (eachOwn && eachOwn[0].token === "each") {
1012
- if (inOf.token === "of") {
1013
- const counterRef = makeRef("i");
1014
- const lenRef = makeRef("len");
1015
- const expRef2 = maybeRef(exp);
1016
- const increment = "++";
1017
- let assignmentNames = [...declaration.names];
1018
- if (declaration2) {
1019
- const [, , ws22, decl22] = declaration2;
1020
- blockPrefix.push(["", [
1021
- insertTrimmingSpace(ws22, ""),
1022
- decl22,
1023
- " = ",
1024
- counterRef
1025
- ], ";"]);
1026
- assignmentNames.push(...decl22.names);
1027
- }
1028
- const expRefDec = expRef2 !== exp ? [insertTrimmingSpace(expRef2, " "), " = ", insertTrimmingSpace(exp, ""), ", "] : [];
1029
- blockPrefix.push(["", {
1030
- type: "Declaration",
1031
- children: [declaration, " = ", insertTrimmingSpace(expRef2, ""), "[", counterRef, "]"],
1032
- names: assignmentNames
1033
- }, ";"]);
1034
- declaration = {
1035
- type: "Declaration",
1036
- children: ["let ", ...expRefDec, counterRef, " = 0, ", lenRef, " = ", insertTrimmingSpace(expRef2, ""), ".length"],
1037
- names: []
1038
- };
1039
- const condition = [counterRef, " < ", lenRef, "; "];
1040
- const children = [open, declaration, "; ", condition, counterRef, increment, close];
1041
- return { declaration, children, blockPrefix };
1042
- } else {
1043
- eachOwnError = {
1044
- type: "Error",
1045
- message: "'each' is only meaningful in for..of loops"
1046
- };
1047
- }
1058
+ if (exp.type === "Existence") {
1059
+ return exp;
1048
1060
  }
1049
- let own = eachOwn && eachOwn[0].token === "own";
1050
- let expRef;
1051
- if (own && inOf.token !== "in") {
1052
- own = false;
1053
- eachOwnError = {
1054
- type: "Error",
1055
- message: "'own' is only meaningful in for..in loops"
1056
- };
1061
+ ;
1062
+ return;
1063
+ }
1064
+ function isRelationalOp(op) {
1065
+ return op.relational || getPrecedence(op) === precedenceRelational;
1066
+ }
1067
+ function expandChainedComparisons([first, binops]) {
1068
+ const results = [];
1069
+ let i = 0;
1070
+ const l = binops.length;
1071
+ let start = 0;
1072
+ let chains = [];
1073
+ let op;
1074
+ while (i < l) {
1075
+ [, op] = binops[i];
1076
+ if (isRelationalOp(op)) {
1077
+ chains.push(i);
1078
+ } else if (getPrecedence(op) < precedenceRelational) {
1079
+ processChains(op);
1080
+ first = void 0;
1081
+ }
1082
+ i++;
1057
1083
  }
1058
- if (!declaration2 && !own) {
1059
- return {
1060
- declaration,
1061
- blockPrefix,
1062
- children: [awaits, eachOwnError, open, declaration, ws, inOf, expRef ?? exp, step, close]
1063
- // omit declaration2, replace eachOwn with eachOwnError, replace exp with expRef
1064
- };
1084
+ if (op != null) {
1085
+ processChains(op);
1065
1086
  }
1066
- let ws2, decl2;
1067
- if (declaration2)
1068
- [, , ws2, decl2] = declaration2;
1069
- switch (inOf.token) {
1070
- case "of": {
1071
- const counterRef = makeRef("i");
1072
- hoistDec = {
1073
- type: "Declaration",
1074
- children: ["let ", counterRef, " = 0"],
1075
- names: []
1076
- };
1077
- blockPrefix.push(["", {
1078
- type: "Declaration",
1079
- children: [insertTrimmingSpace(ws2, ""), decl2, " = ", counterRef, "++"],
1080
- names: decl2.names
1081
- }, ";"]);
1082
- break;
1087
+ return results;
1088
+ function processChains(op2) {
1089
+ if (first && isRelationalOp(op2)) {
1090
+ first = expandExistence(first);
1083
1091
  }
1084
- case "in": {
1085
- const expRef2 = maybeRef(exp);
1086
- if (expRef2 !== exp) {
1087
- hoistDec = {
1088
- type: "Declaration",
1089
- children: ["let ", expRef2],
1090
- names: []
1091
- };
1092
- exp = {
1093
- type: "AssignmentExpression",
1094
- children: [" ", expRef2, " =", exp]
1095
- };
1096
- }
1097
- let { binding } = declaration;
1098
- if (binding?.type !== "Identifier") {
1099
- const keyRef = makeRef("key");
1100
- blockPrefix.push(["", [
1101
- declaration,
1102
- " = ",
1103
- keyRef
1104
- ], ";"]);
1105
- declaration = {
1106
- type: "ForDeclaration",
1107
- binding: binding = keyRef,
1108
- children: ["const ", keyRef],
1109
- names: []
1110
- };
1111
- }
1112
- if (own) {
1113
- const hasPropRef = getRef("hasProp");
1114
- blockPrefix.push(["", ["if (!", hasPropRef, "(", insertTrimmingSpace(expRef2, ""), ", ", insertTrimmingSpace(binding, ""), ")) continue"], ";"]);
1115
- }
1116
- if (decl2) {
1117
- blockPrefix.push(["", {
1118
- type: "Declaration",
1119
- children: [insertTrimmingSpace(ws2, ""), decl2, " = ", insertTrimmingSpace(expRef2, ""), "[", insertTrimmingSpace(binding, ""), "]"],
1120
- names: decl2.names
1121
- }, ";"]);
1092
+ if (chains.length > 1) {
1093
+ chains.forEach((index, k) => {
1094
+ if (k > 0) {
1095
+ results.push(" ", "&&", " ");
1096
+ }
1097
+ const binop = binops[index];
1098
+ let [, , , exp] = binop;
1099
+ exp = binop[3] = expandExistence(exp);
1100
+ let endIndex;
1101
+ if (k < chains.length - 1) {
1102
+ endIndex = chains[k + 1];
1103
+ } else {
1104
+ endIndex = i + 1;
1105
+ }
1106
+ results.push(first, ...binops.slice(start, endIndex).flat());
1107
+ first = [exp].concat(binops.slice(index + 1, endIndex));
1108
+ return start = endIndex;
1109
+ });
1110
+ } else {
1111
+ if (first) {
1112
+ results.push(first);
1122
1113
  }
1123
- break;
1114
+ results.push(...binops.slice(start, i + 1).flat());
1115
+ start = i + 1;
1124
1116
  }
1125
- default:
1126
- (() => {
1127
- throw new Error(`for item, index must use 'of' or 'in' instead of '${inOf.token}'`);
1128
- })();
1117
+ chains.length = 0;
1129
1118
  }
1130
- return {
1131
- declaration,
1132
- children: [awaits, eachOwnError, open, declaration, ws, inOf, exp, step, close],
1133
- // omit declaration2, replace each with eachOwnError
1134
- blockPrefix,
1135
- hoistDec
1136
- };
1119
+ function expandExistence(exp) {
1120
+ const existence = isExistence(exp);
1121
+ if (existence) {
1122
+ results.push(existence, " ", "&&", " ");
1123
+ return existence.expression;
1124
+ }
1125
+ return exp;
1126
+ }
1127
+ ;
1137
1128
  }
1138
- var init_for = __esm({
1139
- "source/parser/for.civet"() {
1129
+ var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
1130
+ var init_op = __esm({
1131
+ "source/parser/op.civet"() {
1140
1132
  "use strict";
1141
1133
  init_util();
1134
+ precedenceOrder = [
1135
+ ["||", "??"],
1136
+ ["^^"],
1137
+ ["&&"],
1138
+ ["|"],
1139
+ ["^"],
1140
+ ["&"],
1141
+ // NOTE: Equality and inequality merged because of relational chaining
1142
+ [
1143
+ "==",
1144
+ "!=",
1145
+ "===",
1146
+ "!==",
1147
+ "<",
1148
+ "<=",
1149
+ ">",
1150
+ ">=",
1151
+ "in",
1152
+ "instanceof"
1153
+ ],
1154
+ // NOTE: Extra in-between level for default custom operators
1155
+ ["custom"],
1156
+ ["<<", ">>", ">>>"],
1157
+ ["+", "-"],
1158
+ ["*", "/", "%"],
1159
+ ["**"]
1160
+ ];
1161
+ precedenceMap = /* @__PURE__ */ new Map();
1162
+ for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
1163
+ const prec = i1;
1164
+ const ops = precedenceOrder[i1];
1165
+ for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
1166
+ const op = ops[i2];
1167
+ precedenceMap.set(op, prec);
1168
+ }
1169
+ }
1170
+ precedenceStep = 1 / 64;
1171
+ precedenceRelational = precedenceMap.get("==");
1172
+ precedenceCustomDefault = precedenceMap.get("custom");
1173
+ asConst = {
1174
+ ts: true,
1175
+ children: [" as const"]
1176
+ };
1142
1177
  }
1143
1178
  });
1144
1179
 
1145
- // source/parser/binding.civet
1146
- function adjustAtBindings(statements, asThis = false) {
1147
- gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
1148
- const { ref } = binding;
1149
- if (asThis) {
1150
- const atBinding = binding.binding;
1151
- atBinding.children.pop();
1152
- atBinding.type = void 0;
1153
- binding.children.unshift(ref.id, ": this.", ref.base);
1154
- binding.type = "Property";
1155
- binding.ref = void 0;
1156
- return;
1180
+ // source/parser/pattern-matching.civet
1181
+ function processPatternMatching(statements, ReservedWord, getRef) {
1182
+ gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
1183
+ const { caseBlock } = s;
1184
+ const { clauses } = caseBlock;
1185
+ for (const c of clauses) {
1186
+ if (c.type === "WhenClause" && c.break) {
1187
+ const last = c.block?.expressions?.at(-1)?.[1];
1188
+ if (isExit(last)) {
1189
+ c.children.splice(c.children.indexOf(c.break), 1);
1190
+ c.break = void 0;
1191
+ }
1192
+ }
1157
1193
  }
1158
- if (ref.names[0] !== ref.base) {
1159
- return binding.children.unshift(ref.base, ": ");
1194
+ let errors = false;
1195
+ let isPattern = false;
1196
+ if (clauses.some(($1) => $1.type === "PatternClause")) {
1197
+ isPattern = true;
1198
+ clauses.forEach((c) => {
1199
+ if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
1200
+ errors = true;
1201
+ return c.children.push({
1202
+ type: "Error",
1203
+ message: "Can't mix pattern matching and non-pattern matching clauses"
1204
+ });
1205
+ }
1206
+ ;
1207
+ return;
1208
+ });
1160
1209
  }
1161
- ;
1162
- return;
1163
- });
1164
- }
1165
- function adjustBindingElements(elements) {
1166
- const names = elements.flatMap((p) => p.names || []), { length } = elements;
1167
- let blockPrefix, restIndex = -1, restCount = 0;
1168
- elements.forEach(({ type }, i) => {
1169
- if (type === "BindingRestElement") {
1170
- if (restIndex < 0)
1171
- restIndex = i;
1172
- return restCount++;
1210
+ if (errors || !isPattern) {
1211
+ return;
1173
1212
  }
1174
- ;
1175
- return;
1176
- });
1177
- if (restCount === 0) {
1178
- return {
1179
- children: elements,
1180
- names,
1181
- blockPrefix,
1182
- length
1183
- };
1184
- } else if (restCount === 1) {
1185
- const rest = elements[restIndex];
1186
- const after = elements.slice(restIndex + 1);
1187
- const restIdentifier = rest.binding.ref || rest.binding;
1188
- names.push(...rest.names || []);
1189
- let l = after.length;
1190
- if (l) {
1191
- if (arrayElementHasTrailingComma(after[l - 1]))
1192
- l++;
1193
- blockPrefix = {
1194
- type: "PostRestBindingElements",
1195
- children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
1196
- names: after.flatMap((p) => p.names)
1213
+ let { condition } = s;
1214
+ if (condition.type === "ParenthesizedExpression") {
1215
+ condition = condition.expression;
1216
+ }
1217
+ let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
1218
+ if (ref !== condition) {
1219
+ hoistDec = {
1220
+ type: "Declaration",
1221
+ children: ["let ", ref],
1222
+ names: []
1197
1223
  };
1224
+ refAssignment = [{
1225
+ type: "AssignmentExpression",
1226
+ children: [ref, " = ", condition]
1227
+ }, ","];
1198
1228
  }
1199
- return {
1200
- names,
1201
- children: [...elements.slice(0, restIndex), {
1202
- ...rest,
1203
- children: rest.children.slice(0, -1)
1204
- // remove trailing comma
1205
- }],
1206
- blockPrefix,
1207
- length
1208
- };
1209
- }
1210
- const err = {
1211
- type: "Error",
1212
- children: ["Multiple rest elements in array pattern"]
1213
- };
1214
- return {
1215
- names,
1216
- children: [...elements, err],
1217
- blockPrefix,
1218
- length
1219
- };
1220
- }
1221
- function gatherBindingCode(statements, opts) {
1222
- const thisAssignments = [];
1223
- const splices = [];
1224
- function insertRestSplices(s, p, thisAssignments2) {
1225
- gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
1226
- if (n.type === "AtBinding") {
1227
- const { ref } = n;
1228
- const { id } = ref;
1229
- thisAssignments2.push([`this.${id} = `, ref]);
1229
+ let prev = [], root = prev;
1230
+ const l = clauses.length;
1231
+ clauses.forEach((c, i) => {
1232
+ if (c.type === "DefaultClause") {
1233
+ prev.push(c.block);
1230
1234
  return;
1231
1235
  }
1232
- if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
1233
- n.names.forEach((id) => ({
1234
- push: thisAssignments2.push({
1235
- type: "AssignmentExpression",
1236
- children: [`this.${id} = `, id],
1237
- js: true
1238
- })
1239
- }));
1240
- return;
1236
+ let { patterns, block } = c;
1237
+ let pattern = patterns[0];
1238
+ const indent = block.expressions?.[0]?.[0] || "";
1239
+ const alternativeConditions = patterns.map((pattern2, i2) => {
1240
+ const conditions = [];
1241
+ getPatternConditions(pattern2, ref, conditions, getRef);
1242
+ return conditions;
1243
+ });
1244
+ const conditionExpression = alternativeConditions.map((conditions, i2) => {
1245
+ const conditionArray = conditions.map((c2, i3) => {
1246
+ if (i3 === 0)
1247
+ return c2;
1248
+ return [" && ", ...c2];
1249
+ });
1250
+ if (i2 === 0)
1251
+ return conditionArray;
1252
+ return [" || ", ...conditionArray];
1253
+ });
1254
+ const condition2 = {
1255
+ type: "ParenthesizedExpression",
1256
+ children: ["(", ...refAssignment, conditionExpression, ")"],
1257
+ expression: conditionExpression
1258
+ };
1259
+ const prefix = [];
1260
+ switch (pattern.type) {
1261
+ case "ArrayBindingPattern":
1262
+ if (pattern.length === 0)
1263
+ break;
1264
+ case "ObjectBindingPattern": {
1265
+ if (pattern.properties?.length === 0)
1266
+ break;
1267
+ let [splices, thisAssignments] = gatherBindingCode(pattern);
1268
+ const patternBindings = nonMatcherBindings(pattern);
1269
+ splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
1270
+ thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
1271
+ const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
1272
+ prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
1273
+ prefix.push(...thisAssignments);
1274
+ prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
1275
+ break;
1276
+ }
1241
1277
  }
1242
- const { blockPrefix } = n;
1243
- p.push(blockPrefix);
1244
- return insertRestSplices(blockPrefix, p, thisAssignments2);
1278
+ block.expressions.unshift(...prefix);
1279
+ const next = [];
1280
+ braceBlock(block);
1281
+ if (i < l - 1)
1282
+ next.push("\n", "else ");
1283
+ prev.push(["", {
1284
+ type: "IfStatement",
1285
+ children: ["if", condition2, block, next],
1286
+ then: block,
1287
+ else: next,
1288
+ hoistDec
1289
+ }]);
1290
+ hoistDec = void 0;
1291
+ refAssignment = [];
1292
+ return prev = next;
1245
1293
  });
1246
- }
1247
- insertRestSplices(statements, splices, thisAssignments);
1248
- return [splices, thisAssignments];
1249
- }
1250
- function arrayElementHasTrailingComma(elementNode) {
1251
- const lastChild = elementNode.children.at(-1);
1252
- return lastChild && lastChild[lastChild.length - 1]?.token === ",";
1253
- }
1254
- var init_binding = __esm({
1255
- "source/parser/binding.civet"() {
1256
- "use strict";
1257
- init_traversal();
1258
- init_util();
1259
- }
1260
- });
1261
-
1262
- // source/parser/function.civet
1263
- function isVoidType(t) {
1264
- return t?.type === "LiteralType" && t.t.type === "VoidType";
1265
- }
1266
- function isPromiseVoidType(t) {
1267
- return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
1268
- }
1269
- function isGeneratorVoidType(t) {
1270
- return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1271
- }
1272
- function isAsyncGeneratorVoidType(t) {
1273
- return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1294
+ s.type = "PatternMatchingStatement";
1295
+ s.children = [root];
1296
+ return addParentPointers(s, s.parent);
1297
+ });
1274
1298
  }
1275
- function implicitFunctionBlock(f) {
1276
- if (f.abstract || f.block || f.signature?.optional)
1277
- return;
1278
- const { name, parent } = f;
1279
- if (parent?.type === "ExportDeclaration")
1299
+ function getPatternConditions(pattern, ref, conditions, getRef) {
1300
+ if (pattern.rest)
1280
1301
  return;
1281
- const expressions = parent?.expressions ?? parent?.elements;
1282
- const currentIndex = expressions?.findIndex(([, def]) => def === f);
1283
- const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
1284
- if (f.type === following?.type && name && name === following.name) {
1285
- f.ts = true;
1286
- } else {
1287
- const block = makeEmptyBlock();
1288
- block.parent = f;
1289
- f.block = block;
1290
- f.children.push(block);
1291
- f.ts = false;
1292
- }
1293
- }
1294
- function processReturn(f, implicitReturns) {
1295
- let { returnType } = f.signature;
1296
- if (returnType && returnType.optional) {
1297
- convertOptionalType(returnType);
1298
- }
1299
- if (!processReturnValue(f) && implicitReturns) {
1300
- const { signature, block } = f;
1301
- const { modifier, name, returnType: returnType2 } = signature;
1302
- const { async, generator, set } = modifier;
1303
- const isMethod = f.type === "MethodDefinition";
1304
- const isConstructor = isMethod && name === "constructor";
1305
- const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
1306
- if (block?.type === "BlockStatement") {
1307
- if (isVoid || set || isConstructor) {
1308
- if (block.bare && block.implicitlyReturned) {
1309
- block.children = [" {", ...block.children, " }"];
1310
- block.bare = block.implicitlyReturned = false;
1311
- }
1312
- } else {
1313
- if (!block.implicitlyReturned) {
1314
- insertReturn(block);
1302
+ switch (pattern.type) {
1303
+ case "ArrayBindingPattern": {
1304
+ const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), l = (length - hasRest).toString(), lengthCheck = hasRest ? [ref, ".length >= ", l] : [getRef("len"), "(", ref, ", ", l, ")"];
1305
+ conditions.push(
1306
+ ["Array.isArray(", ref, ")"],
1307
+ lengthCheck
1308
+ );
1309
+ elements.forEach(({ children: [, e] }, i) => {
1310
+ const subRef = [ref, "[", i.toString(), "]"];
1311
+ return getPatternConditions(e, subRef, conditions, getRef);
1312
+ });
1313
+ const { blockPrefix } = pattern;
1314
+ if (blockPrefix) {
1315
+ const postElements = blockPrefix.children[1], { length: postLength } = postElements;
1316
+ postElements.forEach(({ children: [, e] }, i) => {
1317
+ const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
1318
+ return getPatternConditions(e, subRef, conditions, getRef);
1319
+ });
1320
+ }
1321
+ break;
1322
+ }
1323
+ case "ObjectBindingPattern": {
1324
+ conditions.push(
1325
+ ["typeof ", ref, " === 'object'"],
1326
+ [ref, " != null"]
1327
+ );
1328
+ pattern.properties.forEach((p) => {
1329
+ switch (p.type) {
1330
+ case "PinProperty":
1331
+ case "BindingProperty": {
1332
+ const { name, value } = p;
1333
+ let subRef;
1334
+ switch (name.type) {
1335
+ case "ComputedPropertyName":
1336
+ conditions.push([name.expression, " in ", ref]);
1337
+ subRef = [ref, name];
1338
+ break;
1339
+ case "Literal":
1340
+ case "StringLiteral":
1341
+ case "NumericLiteral":
1342
+ conditions.push([name, " in ", ref]);
1343
+ subRef = [ref, "[", name, "]"];
1344
+ break;
1345
+ default:
1346
+ conditions.push(["'", name, "' in ", ref]);
1347
+ subRef = [ref, ".", name];
1348
+ }
1349
+ if (value) {
1350
+ getPatternConditions(value, subRef, conditions, getRef);
1351
+ }
1352
+ break;
1353
+ }
1315
1354
  }
1355
+ });
1356
+ break;
1357
+ }
1358
+ case "ConditionFragment": {
1359
+ let { children } = pattern;
1360
+ if (children.length) {
1361
+ let [first, ...rest] = children;
1362
+ let [ws, ...op] = first;
1363
+ ws = [" "].concat(ws);
1364
+ first = [ws, ...op];
1365
+ children = [first, ...rest];
1316
1366
  }
1367
+ conditions.push(
1368
+ processBinaryOpExpression([ref, children])
1369
+ );
1370
+ break;
1371
+ }
1372
+ case "RegularExpressionLiteral": {
1373
+ conditions.push(
1374
+ ["typeof ", ref, " === 'string'"],
1375
+ [pattern, ".test(", ref, ")"]
1376
+ );
1377
+ break;
1317
1378
  }
1379
+ case "PinPattern":
1380
+ conditions.push([
1381
+ ref,
1382
+ " === ",
1383
+ pattern.expression
1384
+ ]);
1385
+ break;
1386
+ case "Literal":
1387
+ conditions.push([
1388
+ ref,
1389
+ " === ",
1390
+ pattern
1391
+ ]);
1392
+ break;
1393
+ default:
1394
+ break;
1318
1395
  }
1319
1396
  }
1320
- function processReturnValue(func) {
1321
- const { block } = func;
1322
- const values = gatherRecursiveWithinFunction(
1323
- block,
1324
- ({ type }) => type === "ReturnValue"
1325
- );
1326
- if (!values.length) {
1327
- return false;
1328
- }
1329
- const ref = makeRef("ret");
1330
- let declaration;
1331
- values.forEach((value) => {
1332
- value.children = [ref];
1333
- const { ancestor, child } = findAncestor(
1334
- value,
1335
- ({ type }) => type === "Declaration",
1336
- isFunction
1337
- );
1338
- if (ancestor) {
1339
- return declaration ??= child;
1340
- }
1341
- ;
1342
- return;
1343
- });
1344
- let returnType = func.returnType ?? func.signature?.returnType;
1345
- if (returnType) {
1346
- const { t } = returnType;
1347
- let m;
1348
- if (m = t.type, m === "TypePredicate") {
1349
- returnType = ": boolean";
1350
- } else if (m === "AssertsType") {
1351
- returnType = void 0;
1397
+ function elideMatchersFromArrayBindings(elements) {
1398
+ return elements.map((el) => {
1399
+ if (el.type === "BindingRestElement") {
1400
+ return ["", el, void 0];
1352
1401
  }
1353
- }
1354
- if (declaration) {
1355
- if (!(declaration.suffix != null)) {
1356
- declaration.children[1] = declaration.suffix = returnType;
1402
+ const { children: [ws, e, delim] } = el;
1403
+ switch (e.type) {
1404
+ case "Literal":
1405
+ case "RegularExpressionLiteral":
1406
+ case "StringLiteral":
1407
+ case "PinPattern":
1408
+ return delim;
1409
+ default:
1410
+ return [ws, nonMatcherBindings(e), delim];
1357
1411
  }
1358
- } else {
1359
- block.expressions.unshift([
1360
- getIndent(block.expressions[0]),
1361
- {
1362
- type: "Declaration",
1363
- children: ["let ", ref, returnType],
1364
- names: []
1365
- },
1366
- ";"
1367
- ]);
1368
- }
1369
- gatherRecursiveWithinFunction(
1370
- block,
1371
- (r) => r.type === "ReturnStatement" && !r.expression
1372
- ).forEach((r) => {
1373
- r.expression = ref;
1374
- return r.children.splice(-1, 1, " ", ref);
1375
1412
  });
1376
- if (!(block.children.at(-2)?.type === "ReturnStatement")) {
1377
- block.expressions.push([
1378
- [getIndent(block.expressions.at(-1))],
1379
- {
1380
- type: "ReturnStatement",
1381
- expression: ref,
1382
- children: ["return ", ref]
1413
+ }
1414
+ function elideMatchersFromPropertyBindings(properties) {
1415
+ return properties.map((p) => {
1416
+ switch (p.type) {
1417
+ case "BindingProperty": {
1418
+ const { children, name, value } = p;
1419
+ const [ws] = children;
1420
+ switch (value && value.type) {
1421
+ case "ArrayBindingPattern":
1422
+ case "ObjectBindingPattern":
1423
+ return {
1424
+ ...p,
1425
+ children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
1426
+ };
1427
+ case "Identifier":
1428
+ return p;
1429
+ case "Literal":
1430
+ case "RegularExpressionLiteral":
1431
+ case "StringLiteral":
1432
+ default:
1433
+ return {
1434
+ ...p,
1435
+ children: [ws, name, p.delim]
1436
+ };
1437
+ }
1383
1438
  }
1384
- ]);
1385
- }
1386
- return true;
1439
+ case "PinProperty":
1440
+ case "BindingRestProperty":
1441
+ default:
1442
+ return p;
1443
+ }
1444
+ });
1387
1445
  }
1388
- function patternAsValue(pattern) {
1446
+ function nonMatcherBindings(pattern) {
1389
1447
  switch (pattern.type) {
1390
1448
  case "ArrayBindingPattern": {
1391
- const children = [...pattern.children];
1392
- const index = children.indexOf(pattern.elements);
1393
- if (index < 0)
1394
- throw new Error("failed to find elements in ArrayBindingPattern");
1395
- children[index] = pattern.elements.map((el) => {
1396
- const [ws, e, delim] = el.children;
1397
- return { ...el, children: [ws, patternAsValue(e), delim] };
1398
- });
1399
- return { ...pattern, children };
1400
- }
1401
- case "ObjectBindingPattern": {
1402
- const children = [...pattern.children];
1403
- const index = children.indexOf(pattern.properties);
1404
- if (index < 0)
1405
- throw new Error("failed to find properties in ArrayBindingPattern");
1406
- children[index] = pattern.properties.map(patternAsValue);
1407
- return { ...pattern, children };
1449
+ const elements = elideMatchersFromArrayBindings(pattern.elements);
1450
+ const children = ["[", elements, "]"];
1451
+ return {
1452
+ ...pattern,
1453
+ children,
1454
+ elements
1455
+ };
1408
1456
  }
1409
- case "Identifier":
1410
- case "BindingProperty": {
1411
- const children = [pattern.name, pattern.delim];
1412
- if (isWhitespaceOrEmpty(pattern.children[0])) {
1413
- children.unshift(pattern.children[0]);
1414
- }
1415
- return { ...pattern, children };
1457
+ case "PostRestBindingElements": {
1458
+ const els = elideMatchersFromArrayBindings(pattern.children[1]);
1459
+ return {
1460
+ ...pattern,
1461
+ children: [
1462
+ pattern.children[0],
1463
+ els,
1464
+ ...pattern.children.slice(2)
1465
+ ]
1466
+ };
1416
1467
  }
1468
+ case "ObjectBindingPattern":
1469
+ return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
1417
1470
  default:
1418
1471
  return pattern;
1419
1472
  }
1420
1473
  }
1421
- function insertPush(node, ref) {
1422
- if (!node)
1423
- return;
1424
- switch (node.type) {
1425
- case "BlockStatement":
1426
- if (node.expressions.length) {
1427
- insertPush(node.expressions.at(-1), ref);
1428
- } else {
1429
- node.expressions.push([ref, ".push(void 0);"]);
1430
- }
1431
- return;
1432
- case "CaseBlock":
1433
- node.clauses.forEach((clause) => {
1434
- return insertPush(clause, ref);
1435
- });
1436
- return;
1437
- case "WhenClause":
1438
- insertPush(node.block, ref);
1439
- return;
1440
- case "DefaultClause":
1441
- insertPush(node.block, ref);
1442
- return;
1443
- }
1444
- if (!Array.isArray(node))
1445
- return;
1446
- let [, exp] = node;
1447
- if (!exp) {
1448
- return;
1449
- }
1450
- const indent = getIndent(node);
1451
- const outer = exp;
1452
- let { type } = exp;
1453
- if (type === "LabelledStatement") {
1454
- exp = exp.statement;
1455
- ({ type } = exp);
1456
- }
1457
- switch (exp.type) {
1458
- case "BreakStatement":
1459
- case "ContinueStatement":
1460
- case "DebuggerStatement":
1461
- case "EmptyStatement":
1462
- case "ReturnStatement":
1463
- case "ThrowStatement":
1464
- return;
1465
- case "Declaration":
1466
- exp.children.push(["", [
1467
- ";",
1468
- ref,
1469
- ".push(",
1470
- patternAsValue(exp.bindings.at(-1).pattern),
1471
- ")"
1472
- ]]);
1473
- return;
1474
- case "ForStatement":
1475
- case "IterationStatement":
1476
- case "DoStatement":
1477
- wrapIterationReturningResults(exp, outer, ref);
1478
- return;
1479
- case "BlockStatement":
1480
- insertPush(exp.expressions[exp.expressions.length - 1], ref);
1481
- return;
1482
- case "IfStatement":
1483
- insertPush(exp.then, ref);
1484
- if (exp.then.bare && !exp.then.semicolon) {
1485
- exp.then.children.push(exp.then.semicolon = ";");
1474
+ function aggregateDuplicateBindings(bindings, ReservedWord) {
1475
+ const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
1476
+ const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
1477
+ arrayBindings.forEach((a) => {
1478
+ const { elements } = a;
1479
+ return elements.forEach((element) => {
1480
+ if (Array.isArray(element)) {
1481
+ const [, e] = element;
1482
+ if (e.type === "Identifier") {
1483
+ return props.push(e);
1484
+ } else if (e.type === "BindingRestElement") {
1485
+ return props.push(e);
1486
+ }
1487
+ ;
1488
+ return;
1486
1489
  }
1487
- if (exp.else)
1488
- insertPush(exp.else[2], ref);
1489
- else
1490
- exp.children.push([" else {\n", indent, ref, ".push(undefined)\n", indent, "}"]);
1490
+ ;
1491
1491
  return;
1492
- case "PatternMatchingStatement":
1493
- insertPush(exp.children[0][0], ref);
1492
+ });
1493
+ });
1494
+ const declarations = [];
1495
+ const propsGroupedByName = /* @__PURE__ */ new Map();
1496
+ for (const p of props) {
1497
+ const { name, value } = p;
1498
+ const key = value?.name || name?.name || name;
1499
+ if (propsGroupedByName.has(key)) {
1500
+ propsGroupedByName.get(key).push(p);
1501
+ } else {
1502
+ propsGroupedByName.set(key, [p]);
1503
+ }
1504
+ }
1505
+ propsGroupedByName.forEach((shared, key) => {
1506
+ if (!key) {
1494
1507
  return;
1495
- case "SwitchStatement":
1496
- insertPush(exp.children[2], ref);
1508
+ }
1509
+ if (ReservedWord({ fail() {
1510
+ } }, {
1511
+ pos: 0,
1512
+ input: key
1513
+ })) {
1514
+ shared.forEach((p) => {
1515
+ return aliasBinding(p, makeRef(`_${key}`, key));
1516
+ });
1497
1517
  return;
1498
- case "TryStatement":
1499
- exp.blocks.forEach((block) => insertPush(block, ref));
1518
+ }
1519
+ if (shared.length === 1) {
1500
1520
  return;
1521
+ }
1522
+ const refs = shared.map((p) => {
1523
+ const ref = makeRef(key);
1524
+ aliasBinding(p, ref);
1525
+ return ref;
1526
+ });
1527
+ return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
1528
+ return i === 0 ? r : [", ", r];
1529
+ }), "]"]);
1530
+ });
1531
+ return declarations;
1532
+ }
1533
+ function aliasBinding(p, ref) {
1534
+ if (p.type === "Identifier") {
1535
+ p.children[0] = ref;
1536
+ } else if (p.type === "BindingRestElement") {
1537
+ aliasBinding(p.binding, ref);
1538
+ } else if (p.value?.type === "Identifier") {
1539
+ aliasBinding(p.value, ref);
1540
+ } else {
1541
+ p.value = ref;
1542
+ const index = p.children.indexOf(p.name);
1543
+ p.children.splice(index + 1, 0, ": ", ref);
1501
1544
  }
1502
- if (node[node.length - 1]?.type === "SemicolonDelimiter")
1503
- return;
1504
- node.splice(1, 0, ref, ".push(");
1505
- node.push(")");
1506
1545
  }
1507
- function insertReturn(node, outerNode = node) {
1508
- if (!node)
1546
+ var init_pattern_matching = __esm({
1547
+ "source/parser/pattern-matching.civet"() {
1548
+ "use strict";
1549
+ init_traversal();
1550
+ init_util();
1551
+ init_block();
1552
+ init_binding();
1553
+ init_op();
1554
+ }
1555
+ });
1556
+
1557
+ // source/parser/function.civet
1558
+ function isVoidType(t) {
1559
+ return t?.type === "LiteralType" && t.t.type === "VoidType";
1560
+ }
1561
+ function isPromiseVoidType(t) {
1562
+ return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
1563
+ }
1564
+ function isGeneratorVoidType(t) {
1565
+ return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1566
+ }
1567
+ function isAsyncGeneratorVoidType(t) {
1568
+ return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1569
+ }
1570
+ function implicitFunctionBlock(f) {
1571
+ if (f.abstract || f.block || f.signature?.optional)
1509
1572
  return;
1510
- switch (node.type) {
1511
- case "BlockStatement":
1512
- if (node.expressions.length) {
1513
- const last = node.expressions[node.expressions.length - 1];
1514
- insertReturn(last);
1515
- } else {
1516
- if (node.parent.type === "CatchClause") {
1517
- node.expressions.push(["return"]);
1573
+ const { name, parent } = f;
1574
+ if (parent?.type === "ExportDeclaration")
1575
+ return;
1576
+ const expressions = parent?.expressions ?? parent?.elements;
1577
+ const currentIndex = expressions?.findIndex(([, def]) => def === f);
1578
+ const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
1579
+ if (f.type === following?.type && name && name === following.name) {
1580
+ f.ts = true;
1581
+ } else {
1582
+ const block = makeEmptyBlock();
1583
+ block.parent = f;
1584
+ f.block = block;
1585
+ f.children.push(block);
1586
+ f.ts = false;
1587
+ }
1588
+ }
1589
+ function processReturn(f, implicitReturns) {
1590
+ let { returnType } = f.signature;
1591
+ if (returnType && returnType.optional) {
1592
+ convertOptionalType(returnType);
1593
+ }
1594
+ if (!processReturnValue(f) && implicitReturns) {
1595
+ const { signature, block } = f;
1596
+ const { modifier, name, returnType: returnType2 } = signature;
1597
+ const { async, generator, set } = modifier;
1598
+ const isMethod = f.type === "MethodDefinition";
1599
+ const isConstructor = isMethod && name === "constructor";
1600
+ const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
1601
+ if (block?.type === "BlockStatement") {
1602
+ if (isVoid || set || isConstructor) {
1603
+ if (block.bare && block.implicitlyReturned) {
1604
+ block.children = [" {", ...block.children, " }"];
1605
+ block.bare = block.implicitlyReturned = false;
1518
1606
  }
1519
- }
1520
- return;
1521
- case "WhenClause":
1522
- if (node.break) {
1523
- node.children.splice(node.children.indexOf(node.break), 1);
1524
- }
1525
- if (node.block.expressions.length) {
1526
- insertReturn(node.block);
1527
1607
  } else {
1528
- node.block.expressions.push(wrapWithReturn());
1608
+ if (!block.implicitlyReturned) {
1609
+ insertReturn(block);
1610
+ }
1529
1611
  }
1530
- return;
1531
- case "DefaultClause":
1532
- insertReturn(node.block);
1533
- return;
1612
+ }
1534
1613
  }
1535
- if (!Array.isArray(node))
1536
- return;
1537
- let [, exp, semi] = node;
1538
- if (semi?.type === "SemicolonDelimiter") {
1539
- return;
1614
+ }
1615
+ function processReturnValue(func) {
1616
+ const { block } = func;
1617
+ const values = gatherRecursiveWithinFunction(
1618
+ block,
1619
+ ({ type }) => type === "ReturnValue"
1620
+ );
1621
+ if (!values.length) {
1622
+ return false;
1540
1623
  }
1541
- if (!exp) {
1624
+ const ref = makeRef("ret");
1625
+ let declaration;
1626
+ values.forEach((value) => {
1627
+ value.children = [ref];
1628
+ const { ancestor, child } = findAncestor(
1629
+ value,
1630
+ ({ type }) => type === "Declaration",
1631
+ isFunction
1632
+ );
1633
+ if (ancestor) {
1634
+ return declaration ??= child;
1635
+ }
1636
+ ;
1542
1637
  return;
1638
+ });
1639
+ let returnType = func.returnType ?? func.signature?.returnType;
1640
+ if (returnType) {
1641
+ const { t } = returnType;
1642
+ let m;
1643
+ if (m = t.type, m === "TypePredicate") {
1644
+ returnType = ": boolean";
1645
+ } else if (m === "AssertsType") {
1646
+ returnType = void 0;
1647
+ }
1543
1648
  }
1544
- const outer = exp;
1545
- let { type } = exp;
1546
- if (type === "LabelledStatement") {
1547
- exp = exp.statement;
1548
- ({ type } = exp);
1649
+ if (declaration) {
1650
+ if (!(declaration.suffix != null)) {
1651
+ declaration.children[1] = declaration.suffix = returnType;
1652
+ }
1653
+ } else {
1654
+ block.expressions.unshift([
1655
+ getIndent(block.expressions[0]),
1656
+ {
1657
+ type: "Declaration",
1658
+ children: ["let ", ref, returnType],
1659
+ names: []
1660
+ },
1661
+ ";"
1662
+ ]);
1549
1663
  }
1550
- switch (type) {
1551
- case "BreakStatement":
1664
+ gatherRecursiveWithinFunction(
1665
+ block,
1666
+ (r) => r.type === "ReturnStatement" && !r.expression
1667
+ ).forEach((r) => {
1668
+ r.expression = ref;
1669
+ return r.children.splice(-1, 1, " ", ref);
1670
+ });
1671
+ if (!(block.children.at(-2)?.type === "ReturnStatement")) {
1672
+ const indent = getIndent(block.expressions.at(-1)) || ";";
1673
+ block.expressions.push([
1674
+ [indent],
1675
+ {
1676
+ type: "ReturnStatement",
1677
+ expression: ref,
1678
+ children: ["return ", ref]
1679
+ }
1680
+ ]);
1681
+ }
1682
+ return true;
1683
+ }
1684
+ function patternAsValue(pattern) {
1685
+ switch (pattern.type) {
1686
+ case "ArrayBindingPattern": {
1687
+ const children = [...pattern.children];
1688
+ const index = children.indexOf(pattern.elements);
1689
+ if (index < 0)
1690
+ throw new Error("failed to find elements in ArrayBindingPattern");
1691
+ children[index] = pattern.elements.map((el) => {
1692
+ const [ws, e, delim] = el.children;
1693
+ return { ...el, children: [ws, patternAsValue(e), delim] };
1694
+ });
1695
+ return { ...pattern, children };
1696
+ }
1697
+ case "ObjectBindingPattern": {
1698
+ const children = [...pattern.children];
1699
+ const index = children.indexOf(pattern.properties);
1700
+ if (index < 0)
1701
+ throw new Error("failed to find properties in ArrayBindingPattern");
1702
+ children[index] = pattern.properties.map(patternAsValue);
1703
+ return { ...pattern, children };
1704
+ }
1705
+ case "Identifier":
1706
+ case "BindingProperty": {
1707
+ const children = [pattern.name, pattern.delim];
1708
+ if (isWhitespaceOrEmpty(pattern.children[0])) {
1709
+ children.unshift(pattern.children[0]);
1710
+ }
1711
+ return { ...pattern, children };
1712
+ }
1713
+ default:
1714
+ return pattern;
1715
+ }
1716
+ }
1717
+ function assignResults(node, collect) {
1718
+ if (!node)
1719
+ return;
1720
+ switch (node.type) {
1721
+ case "BlockStatement":
1722
+ if (node.expressions.length) {
1723
+ assignResults(node.expressions.at(-1), collect);
1724
+ } else {
1725
+ node.expressions.push(["", collect("void 0"), ";"]);
1726
+ }
1727
+ return;
1728
+ case "CaseBlock":
1729
+ node.clauses.forEach((clause) => {
1730
+ return assignResults(clause, collect);
1731
+ });
1732
+ return;
1733
+ case "WhenClause":
1734
+ case "DefaultClause":
1735
+ case "PatternClause": {
1736
+ assignResults(node.block, collect);
1737
+ return;
1738
+ }
1739
+ }
1740
+ if (!Array.isArray(node)) {
1741
+ return;
1742
+ }
1743
+ let [, exp] = node;
1744
+ if (!exp) {
1745
+ return;
1746
+ }
1747
+ const outer = exp;
1748
+ let { type } = exp;
1749
+ if (type === "LabelledStatement") {
1750
+ exp = exp.statement;
1751
+ ({ type } = exp);
1752
+ }
1753
+ switch (exp.type) {
1754
+ case "BreakStatement":
1755
+ case "ContinueStatement":
1756
+ case "DebuggerStatement":
1757
+ case "EmptyStatement":
1758
+ case "ReturnStatement":
1759
+ case "ThrowStatement":
1760
+ return;
1761
+ case "Declaration":
1762
+ exp.children.push([
1763
+ "",
1764
+ [";", collect(patternAsValue(exp.bindings.at(-1).pattern))]
1765
+ ]);
1766
+ return;
1767
+ case "ForStatement":
1768
+ case "IterationStatement":
1769
+ case "DoStatement":
1770
+ wrapIterationReturningResults(exp, outer, collect);
1771
+ return;
1772
+ case "BlockStatement":
1773
+ assignResults(exp.expressions[exp.expressions.length - 1], collect);
1774
+ return;
1775
+ case "IfStatement":
1776
+ assignResults(exp.then, collect);
1777
+ if (exp.then.bare && !exp.then.semicolon) {
1778
+ exp.then.children.push(exp.then.semicolon = ";");
1779
+ }
1780
+ if (exp.else) {
1781
+ assignResults(exp.else[2], collect);
1782
+ } else {
1783
+ exp.children.push([" else {", collect("undefined"), "}"]);
1784
+ }
1785
+ return;
1786
+ case "PatternMatchingStatement":
1787
+ assignResults(exp.children[0][0], collect);
1788
+ return;
1789
+ case "SwitchStatement":
1790
+ assignResults(exp.children[2], collect);
1791
+ return;
1792
+ case "TryStatement":
1793
+ exp.blocks.forEach((block) => assignResults(block, collect));
1794
+ return;
1795
+ }
1796
+ if (node.at(-1)?.type === "SemicolonDelimiter") {
1797
+ return;
1798
+ }
1799
+ node[1] = collect(node[1]);
1800
+ }
1801
+ function insertReturn(node, outerNode = node) {
1802
+ if (!node)
1803
+ return;
1804
+ switch (node.type) {
1805
+ case "BlockStatement":
1806
+ if (node.expressions.length) {
1807
+ const last = node.expressions[node.expressions.length - 1];
1808
+ insertReturn(last);
1809
+ } else {
1810
+ if (node.parent.type === "CatchClause") {
1811
+ node.expressions.push(["return"]);
1812
+ }
1813
+ }
1814
+ return;
1815
+ case "WhenClause":
1816
+ if (node.break) {
1817
+ node.children.splice(node.children.indexOf(node.break), 1);
1818
+ }
1819
+ if (node.block.expressions.length) {
1820
+ insertReturn(node.block);
1821
+ } else {
1822
+ node.block.expressions.push(wrapWithReturn());
1823
+ }
1824
+ return;
1825
+ case "DefaultClause":
1826
+ insertReturn(node.block);
1827
+ return;
1828
+ }
1829
+ if (!Array.isArray(node))
1830
+ return;
1831
+ let [, exp, semi] = node;
1832
+ if (semi?.type === "SemicolonDelimiter") {
1833
+ return;
1834
+ }
1835
+ if (!exp) {
1836
+ return;
1837
+ }
1838
+ const outer = exp;
1839
+ let { type } = exp;
1840
+ if (type === "LabelledStatement") {
1841
+ exp = exp.statement;
1842
+ ({ type } = exp);
1843
+ }
1844
+ switch (type) {
1845
+ case "BreakStatement":
1552
1846
  case "ContinueStatement":
1553
1847
  case "DebuggerStatement":
1554
1848
  case "EmptyStatement":
@@ -1615,24 +1909,31 @@ function insertSwitchReturns(exp) {
1615
1909
  return insertReturn(clause);
1616
1910
  });
1617
1911
  }
1618
- function wrapIterationReturningResults(statement, outer, outerRef) {
1912
+ function wrapIterationReturningResults(statement, outer, collect) {
1619
1913
  if (statement.type === "DoStatement") {
1620
- if (outerRef) {
1621
- insertPush(statement.block, outerRef);
1914
+ if (collect) {
1915
+ assignResults(statement.block, collect);
1622
1916
  } else {
1623
1917
  insertReturn(statement.block, outer);
1624
1918
  }
1625
1919
  return;
1626
1920
  }
1627
- const resultsRef = makeRef("results");
1921
+ assert.equal(
1922
+ statement.resultsRef,
1923
+ void 0,
1924
+ "wrapIterationReturningResults should not be called twice on the same statement"
1925
+ );
1926
+ const resultsRef = statement.resultsRef = makeRef("results");
1628
1927
  const declaration = {
1629
1928
  type: "Declaration",
1630
- children: ["const ", resultsRef, "=[];"]
1929
+ children: ["const ", resultsRef, "=[]"]
1631
1930
  };
1632
- insertPush(statement.block, resultsRef);
1633
- outer.children.unshift(declaration);
1634
- if (outerRef) {
1635
- statement.children.push(";", outerRef, ".push(", resultsRef, ");");
1931
+ outer.children.unshift(["", declaration, ";"]);
1932
+ assignResults(statement.block, (node) => {
1933
+ return [resultsRef, ".push(", node, ")"];
1934
+ });
1935
+ if (collect) {
1936
+ statement.children.push(collect(resultsRef));
1636
1937
  } else {
1637
1938
  statement.children.push(";return ", resultsRef, ";");
1638
1939
  }
@@ -1715,8 +2016,11 @@ function expressionizeIteration(exp) {
1715
2016
  updateParentPointers(exp);
1716
2017
  return;
1717
2018
  }
1718
- const resultsRef = makeRef("results");
1719
- insertPush(block, resultsRef);
2019
+ exp.resultsRef ??= makeRef("results");
2020
+ const { resultsRef } = exp;
2021
+ assignResults(block, (node) => {
2022
+ return [resultsRef, ".push(", node, ")"];
2023
+ });
1720
2024
  braceBlock(block);
1721
2025
  children.splice(
1722
2026
  i,
@@ -1729,6 +2033,19 @@ function expressionizeIteration(exp) {
1729
2033
  );
1730
2034
  updateParentPointers(exp);
1731
2035
  }
2036
+ function skipImplicitArguments(args) {
2037
+ if (args.length === 1) {
2038
+ let arg0 = args[0];
2039
+ if (Array.isArray(arg0)) {
2040
+ arg0 = arg0[1];
2041
+ }
2042
+ if (arg0.type === "StatementExpression") {
2043
+ arg0 = arg0.statement;
2044
+ }
2045
+ return arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block);
2046
+ }
2047
+ return false;
2048
+ }
1732
2049
  var init_function = __esm({
1733
2050
  "source/parser/function.civet"() {
1734
2051
  "use strict";
@@ -1739,864 +2056,764 @@ var init_function = __esm({
1739
2056
  }
1740
2057
  });
1741
2058
 
1742
- // source/parser/op.civet
1743
- function getPrecedence(op) {
1744
- if (typeof op === "string") {
1745
- return precedenceMap.get(op) ?? (() => {
1746
- throw new Error(`Unknown operator: ${op}`);
1747
- })();
1748
- } else if (typeof op.prec === "number") {
1749
- return op.prec;
2059
+ // source/parser/declaration.civet
2060
+ function processAssignmentDeclaration(decl, pattern, suffix, ws, assign, e) {
2061
+ decl = {
2062
+ ...decl,
2063
+ $loc: {
2064
+ pos: assign.$loc.pos - 1,
2065
+ length: assign.$loc.length + 1
2066
+ }
2067
+ };
2068
+ let [splices, assignments] = gatherBindingCode(pattern);
2069
+ splices = splices.map((s) => [", ", s]);
2070
+ const thisAssignments = assignments.map((a) => ["", a, ";"]);
2071
+ const initializer = [ws, assign, e];
2072
+ const binding = makeNode({
2073
+ type: "Binding",
2074
+ pattern,
2075
+ initializer,
2076
+ splices,
2077
+ suffix,
2078
+ thisAssignments,
2079
+ children: [pattern, suffix, initializer]
2080
+ });
2081
+ const children = [decl, binding];
2082
+ return makeNode({
2083
+ type: "Declaration",
2084
+ names: pattern.names,
2085
+ decl,
2086
+ bindings: [binding],
2087
+ splices,
2088
+ thisAssignments,
2089
+ children
2090
+ });
2091
+ }
2092
+ function processDeclarations(statements) {
2093
+ gatherRecursiveAll(statements, ($) => $.type === "Declaration").forEach((statement) => {
2094
+ const { bindings } = statement;
2095
+ return bindings?.forEach((binding) => {
2096
+ const suffix = binding.suffix;
2097
+ if (suffix && suffix.optional && suffix.t) {
2098
+ convertOptionalType(suffix);
2099
+ }
2100
+ const { initializer } = binding;
2101
+ if (initializer) {
2102
+ return prependStatementExpressionBlock(initializer, statement);
2103
+ }
2104
+ ;
2105
+ return;
2106
+ });
2107
+ });
2108
+ }
2109
+ function prependStatementExpressionBlock(initializer, statement) {
2110
+ let exp = initializer[2];
2111
+ let ws;
2112
+ if (Array.isArray(exp)) {
2113
+ ws = exp[0];
2114
+ exp = exp[1];
2115
+ }
2116
+ if (!(exp.type === "StatementExpression")) {
2117
+ return;
2118
+ }
2119
+ const pre = [];
2120
+ const statementExp = exp.statement;
2121
+ const blockStatement = ["", statementExp];
2122
+ let ref;
2123
+ if (statementExp.type === "IterationExpression") {
2124
+ if (statementExp.async) {
2125
+ return;
2126
+ }
2127
+ const statement2 = statementExp.statement;
2128
+ blockStatement[1] = statement2;
2129
+ if (statement2.type === "DoStatement") {
2130
+ ref = initializer[2] = makeRef();
2131
+ assignResults(blockStatement, (resultNode) => {
2132
+ return makeNode({
2133
+ type: "AssignmentExpression",
2134
+ children: [ref, " = ", resultNode]
2135
+ });
2136
+ });
2137
+ const refDec = {
2138
+ type: "Declaration",
2139
+ children: ["let ", ref, ";"]
2140
+ };
2141
+ pre.unshift(refDec);
2142
+ } else {
2143
+ wrapIterationReturningResults(statement2, { children: blockStatement }, function() {
2144
+ });
2145
+ ref = initializer[2] = statement2.resultsRef;
2146
+ }
1750
2147
  } else {
1751
- return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
2148
+ ref = initializer[2] = makeRef();
2149
+ assignResults(blockStatement, (resultNode) => {
2150
+ return makeNode({
2151
+ type: "AssignmentExpression",
2152
+ children: [ref, " = ", resultNode]
2153
+ });
2154
+ });
2155
+ const refDec = {
2156
+ type: "Declaration",
2157
+ children: ["let ", ref, ";"]
2158
+ };
2159
+ pre.unshift(refDec);
2160
+ if (ws) {
2161
+ pre.push(ws);
2162
+ }
1752
2163
  }
2164
+ statement.children.unshift(pre, blockStatement, ";");
2165
+ updateParentPointers(blockStatement, statement);
2166
+ return ref;
1753
2167
  }
1754
- function processBinaryOpExpression($0) {
1755
- return recurse(expandChainedComparisons($0));
1756
- function recurse(expandedOps) {
1757
- let i = 2;
1758
- while (i < expandedOps.length) {
1759
- let op = expandedOps[i];
1760
- if (op.special) {
1761
- let advanceLeft2 = function(allowEqual) {
1762
- while (start >= 4) {
1763
- const prevPrec = getPrecedence(expandedOps[start - 2]);
1764
- if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
1765
- return prevPrec === prec;
1766
- }
1767
- start -= 4;
1768
- }
1769
- return false;
1770
- }, advanceRight2 = function(allowEqual) {
1771
- while (end + 4 < expandedOps.length) {
1772
- const nextPrec = getPrecedence(expandedOps[end + 2]);
1773
- if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
1774
- return nextPrec === prec;
1775
- }
1776
- end += 4;
1777
- }
1778
- return false;
1779
- };
1780
- var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
1781
- let start = i - 2, end = i + 2;
1782
- const prec = getPrecedence(op);
1783
- let error;
1784
- switch (op.assoc) {
1785
- case "left":
1786
- case void 0: {
1787
- advanceLeft2(true);
1788
- advanceRight2(false);
1789
- break;
1790
- }
1791
- case "right": {
1792
- advanceLeft2(false);
1793
- advanceRight2(true);
1794
- break;
1795
- }
1796
- case "non": {
1797
- if (advanceLeft2(false) || advanceRight2(false)) {
1798
- error = {
1799
- type: "Error",
1800
- message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
1801
- };
1802
- }
1803
- ;
1804
- break;
1805
- }
1806
- case "arguments": {
1807
- if (advanceLeft2(false)) {
1808
- error = {
1809
- type: "Error",
1810
- message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
1811
- };
1812
- }
1813
- advanceRight2(true);
1814
- break;
1815
- }
1816
- default: {
1817
- throw new Error(`Unsupported associativity: ${op.assoc}`);
1818
- }
1819
- }
1820
- let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
1821
- let wsOp = expandedOps[i - 1];
1822
- let wsB = expandedOps[i + 1];
1823
- let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
1824
- if (op.assoc === "arguments") {
1825
- let i2 = 2;
1826
- while (i2 < b.length) {
1827
- if (prec === getPrecedence(b[i2])) {
1828
- if (!(b[i2].token === op.token)) {
1829
- error ??= {
1830
- type: "Error",
1831
- message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
1832
- };
1833
- }
1834
- b[i2] = ",";
1835
- }
1836
- i2 += 4;
1837
- }
1838
- } else {
1839
- b = recurse(b);
1840
- }
1841
- if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
1842
- a = ["typeof ", makeLeftHandSideExpression(a)];
1843
- if (op.negated) {
1844
- op = { ...op, token: "!==", negated: false };
1845
- } else {
1846
- op = { ...op, token: "===" };
1847
- }
1848
- }
1849
- if (op.asConst) {
1850
- a = makeAsConst(a);
1851
- b = makeAsConst(b);
1852
- }
1853
- let children;
1854
- if (op.call) {
1855
- wsOp = insertTrimmingSpace(wsOp, "");
1856
- if (op.reversed) {
1857
- wsB = insertTrimmingSpace(wsB, "");
1858
- children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
1859
- } else {
1860
- children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
1861
- }
1862
- } else if (op.method) {
1863
- wsOp = insertTrimmingSpace(wsOp, "");
1864
- wsB = insertTrimmingSpace(wsB, "");
1865
- if (op.reversed) {
1866
- if (end !== i + 2)
1867
- b = makeLeftHandSideExpression(b);
1868
- b = dotNumericLiteral(b);
1869
- children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
1870
- } else {
1871
- if (start !== i - 2 || a.type === "NumericLiteral") {
1872
- a = makeLeftHandSideExpression(a);
1873
- }
1874
- a = dotNumericLiteral(a);
1875
- children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
1876
- }
1877
- } else if (op.token) {
1878
- children = [a, wsOp, op, wsB, b];
1879
- if (op.negated)
1880
- children = ["(", ...children, ")"];
1881
- } else {
1882
- throw new Error("Unknown operator: " + JSON.stringify(op));
1883
- }
1884
- if (op.negated)
1885
- children.unshift("!");
1886
- if (error != null) {
1887
- children.push(error);
1888
- }
1889
- expandedOps.splice(start, end - start + 1, {
1890
- children
1891
- });
1892
- i = start + 2;
1893
- } else {
1894
- i += 4;
1895
- }
1896
- }
1897
- return expandedOps;
1898
- }
1899
- ;
1900
- return recurse;
1901
- }
1902
- function dotNumericLiteral(literal) {
1903
- if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
1904
- literal.children.push(".");
1905
- literal.raw += ".";
1906
- }
1907
- return literal;
1908
- }
1909
- function makeAsConst(node) {
1910
- if (Array.isArray(node) && node.length === 1) {
1911
- node = node[0];
2168
+ function processDeclarationCondition(condition, rootCondition, parent) {
2169
+ if (!(condition.type === "DeclarationCondition")) {
2170
+ return;
1912
2171
  }
1913
- if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
1914
- return { ...node, children: [...node.children, asConst] };
2172
+ const { decl, bindings } = condition.declaration;
2173
+ const binding = bindings[0];
2174
+ const { pattern, suffix, initializer, splices, thisAssignments } = binding;
2175
+ let ref = prependStatementExpressionBlock(initializer, parent);
2176
+ if (ref) {
2177
+ Object.assign(condition, {
2178
+ type: "AssignmentExpression",
2179
+ children: [ref],
2180
+ pattern,
2181
+ ref,
2182
+ statementDeclaration: true
2183
+ });
1915
2184
  } else {
1916
- return node;
1917
- }
1918
- }
1919
- function isExistence(exp) {
1920
- if (exp.type === "ParenthesizedExpression" && exp.implicit) {
1921
- exp = exp.expression;
1922
- }
1923
- if (exp.type === "Existence") {
1924
- return exp;
2185
+ ref = makeRef();
2186
+ const grandparent = condition.parent?.parent;
2187
+ const children = (
2188
+ // Check that the declaration is a plain assignment (no pattern-matching) and the immediate grandchild of an `if` or `while`
2189
+ // More complex conditions (triggered by pattern matching or `until`/`unless`) don't need double parens
2190
+ // @ts-ignore Just because pattern might not have a type at runtime doesn't mean it's unsafe
2191
+ pattern.type === "Identifier" && (grandparent?.type === "IfStatement" || grandparent?.type === "WhileStatement") ? ["(", ref, initializer, ")"] : [ref, initializer]
2192
+ );
2193
+ Object.assign(condition, {
2194
+ type: "AssignmentExpression",
2195
+ children,
2196
+ hoistDec: {
2197
+ type: "Declaration",
2198
+ children: ["let ", ref, suffix],
2199
+ names: []
2200
+ },
2201
+ pattern,
2202
+ ref
2203
+ });
1925
2204
  }
1926
- ;
1927
- return;
2205
+ addParentPointers(condition, parent);
2206
+ Object.assign(rootCondition, {
2207
+ blockPrefix: [
2208
+ ["", [decl, pattern, suffix, " = ", ref, ...splices], ";"],
2209
+ ...thisAssignments
2210
+ ]
2211
+ });
1928
2212
  }
1929
- function isRelationalOp(op) {
1930
- return op.relational || getPrecedence(op) === precedenceRelational;
2213
+ function processDeclarationConditions(node, getRef) {
2214
+ gatherRecursiveAll(node, (n) => {
2215
+ return n.type === "IfStatement" || n.type === "IterationStatement" || n.type === "SwitchStatement";
2216
+ }).forEach((s) => {
2217
+ return processDeclarationConditionStatement(s, getRef);
2218
+ });
1931
2219
  }
1932
- function expandChainedComparisons([first, binops]) {
1933
- const results = [];
1934
- let i = 0;
1935
- const l = binops.length;
1936
- let start = 0;
1937
- let chains = [];
1938
- let op;
1939
- while (i < l) {
1940
- [, op] = binops[i];
1941
- if (isRelationalOp(op)) {
1942
- chains.push(i);
1943
- } else if (getPrecedence(op) < precedenceRelational) {
1944
- processChains(op);
1945
- first = void 0;
1946
- }
1947
- i++;
2220
+ function processDeclarationConditionStatement(s, getRef) {
2221
+ const { condition } = s;
2222
+ if (!condition?.expression) {
2223
+ return;
1948
2224
  }
1949
- if (op != null) {
1950
- processChains(op);
2225
+ let { expression } = condition;
2226
+ if (typeof expression === "object" && expression != null && "type" in expression && expression.type === "UnaryExpression" && "children" in expression && Array.isArray(expression.children) && expression.children.length === 2 && expression.children[0] === "!" && typeof expression.children[1] === "object" && expression.children[1] != null && "type" in expression.children[1] && expression.children[1].type === "ParenthesizedExpression" && "expression" in expression.children[1]) {
2227
+ const { type: type1, children: [, { type: type2, expression: expression2 }] } = expression;
2228
+ const type = [type1, type2];
2229
+ expression = expression2;
1951
2230
  }
1952
- return results;
1953
- function processChains(op2) {
1954
- if (first && isRelationalOp(op2)) {
1955
- first = expandExistence(first);
2231
+ processDeclarationCondition(expression, condition.expression, s);
2232
+ const { ref, pattern } = expression;
2233
+ if (pattern) {
2234
+ let conditions = [];
2235
+ getPatternConditions(pattern, ref, conditions, getRef);
2236
+ conditions = conditions.filter((c) => {
2237
+ return !(c.length === 3 && c[0] === "typeof " && c[1] === ref && c[2] === " === 'object'") && !(c.length === 2 && c[0] === ref && c[1] === " != null");
2238
+ });
2239
+ if (conditions.length) {
2240
+ condition.children.unshift("(");
2241
+ conditions.forEach(function(c) {
2242
+ return condition.children.push(" && ", c);
2243
+ });
2244
+ condition.children.push(")");
1956
2245
  }
1957
- if (chains.length > 1) {
1958
- chains.forEach((index, k) => {
1959
- if (k > 0) {
1960
- results.push(" ", "&&", " ");
1961
- }
1962
- const binop = binops[index];
1963
- let [, , , exp] = binop;
1964
- exp = binop[3] = expandExistence(exp);
1965
- let endIndex;
1966
- if (k < chains.length - 1) {
1967
- endIndex = chains[k + 1];
2246
+ }
2247
+ switch (s.type) {
2248
+ case "IfStatement": {
2249
+ const { else: e } = s;
2250
+ const block = blockWithPrefix(condition.expression.blockPrefix, s.then);
2251
+ if (block.bare && e && !block.semicolon) {
2252
+ block.children.push(block.semicolon = ";");
2253
+ }
2254
+ s.children = s.children.map((c) => {
2255
+ if (c === s.then) {
2256
+ return block;
1968
2257
  } else {
1969
- endIndex = i + 1;
2258
+ return c;
1970
2259
  }
1971
- results.push(first, ...binops.slice(start, endIndex).flat());
1972
- first = [exp].concat(binops.slice(index + 1, endIndex));
1973
- return start = endIndex;
1974
2260
  });
1975
- } else {
1976
- if (first) {
1977
- results.push(first);
1978
- }
1979
- results.push(...binops.slice(start, i + 1).flat());
1980
- start = i + 1;
1981
- }
1982
- chains.length = 0;
1983
- }
1984
- function expandExistence(exp) {
1985
- const existence = isExistence(exp);
1986
- if (existence) {
1987
- results.push(existence, " ", "&&", " ");
1988
- return existence.expression;
2261
+ s.then = block;
2262
+ updateParentPointers(block, s);
2263
+ break;
2264
+ }
2265
+ case "IterationStatement": {
2266
+ const { children, block } = s;
2267
+ const newBlock = blockWithPrefix(condition.expression.blockPrefix, block);
2268
+ s.children = children.map((c) => c?.type === "BlockStatement" ? newBlock : c);
2269
+ updateParentPointers(newBlock, s);
2270
+ break;
2271
+ }
2272
+ case "SwitchStatement": {
2273
+ const { blockPrefix, ref: ref2, statementDeclaration } = condition.expression;
2274
+ if (!blockPrefix) {
2275
+ return;
2276
+ }
2277
+ const newCondition = {
2278
+ type: "ParenthesizedExpression",
2279
+ children: ["(", ref2, ")"],
2280
+ expression: ref2,
2281
+ parent: s
2282
+ };
2283
+ s.children = s.children.map(function(c) {
2284
+ if (c === s.condition) {
2285
+ return newCondition;
2286
+ } else {
2287
+ return c;
2288
+ }
2289
+ });
2290
+ s.condition = newCondition;
2291
+ updateParentPointers(s);
2292
+ if (statementDeclaration) {
2293
+ const block = makeEmptyBlock();
2294
+ replaceBlockExpression(s.parent, s, block);
2295
+ block.expressions.push(["", s]);
2296
+ s.children.splice(s.children.findIndex(($1) => $1.token === "switch"), 0, blockPrefix);
2297
+ s.parent = block;
2298
+ } else {
2299
+ const block = blockWithPrefix([["", [{
2300
+ type: "Declaration",
2301
+ children: ["let ", ...condition.expression.children]
2302
+ }], ";"], ...blockPrefix], makeEmptyBlock());
2303
+ updateParentPointers(block, s.parent);
2304
+ replaceBlockExpression(s.parent, s, block);
2305
+ block.expressions.push(["", s]);
2306
+ s.parent = block;
2307
+ }
2308
+ ;
2309
+ break;
1989
2310
  }
1990
- return exp;
1991
2311
  }
1992
- ;
1993
2312
  }
1994
- var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
1995
- var init_op = __esm({
1996
- "source/parser/op.civet"() {
2313
+ var init_declaration = __esm({
2314
+ "source/parser/declaration.civet"() {
1997
2315
  "use strict";
2316
+ init_block();
2317
+ init_traversal();
2318
+ init_pattern_matching();
1998
2319
  init_util();
1999
- precedenceOrder = [
2000
- ["||", "??"],
2001
- ["^^"],
2002
- ["&&"],
2003
- ["|"],
2004
- ["^"],
2005
- ["&"],
2006
- // NOTE: Equality and inequality merged because of relational chaining
2007
- [
2008
- "==",
2009
- "!=",
2010
- "===",
2011
- "!==",
2012
- "<",
2013
- "<=",
2014
- ">",
2015
- ">=",
2016
- "in",
2017
- "instanceof"
2018
- ],
2019
- // NOTE: Extra in-between level for default custom operators
2020
- ["custom"],
2021
- ["<<", ">>", ">>>"],
2022
- ["+", "-"],
2023
- ["*", "/", "%"],
2024
- ["**"]
2025
- ];
2026
- precedenceMap = /* @__PURE__ */ new Map();
2027
- for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
2028
- const prec = i1;
2029
- const ops = precedenceOrder[i1];
2030
- for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
2031
- const op = ops[i2];
2032
- precedenceMap.set(op, prec);
2033
- }
2034
- }
2035
- precedenceStep = 1 / 64;
2036
- precedenceRelational = precedenceMap.get("==");
2037
- precedenceCustomDefault = precedenceMap.get("custom");
2038
- asConst = {
2039
- ts: true,
2040
- children: [" as const"]
2041
- };
2320
+ init_function();
2321
+ init_binding();
2042
2322
  }
2043
2323
  });
2044
2324
 
2045
- // source/parser/pattern-matching.civet
2046
- function processPatternMatching(statements, ReservedWord) {
2047
- gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
2048
- const { caseBlock } = s;
2049
- const { clauses } = caseBlock;
2050
- for (const c of clauses) {
2051
- if (c.type === "WhenClause" && c.break) {
2052
- const last = c.block?.expressions?.at(-1)?.[1];
2053
- if (isExit(last)) {
2054
- c.children.splice(c.children.indexOf(c.break), 1);
2055
- c.break = void 0;
2056
- }
2325
+ // source/parser/unary.civet
2326
+ function processUnaryExpression(pre, exp, post) {
2327
+ if (!(pre.length || post))
2328
+ return exp;
2329
+ if (post?.token === "?") {
2330
+ post = {
2331
+ $loc: post.$loc,
2332
+ token: " != null"
2333
+ };
2334
+ if (pre.length) {
2335
+ const lastPre = pre[pre.length - 1];
2336
+ if (lastPre.token === "!") {
2337
+ post.token = " == null";
2338
+ pre = pre.slice(0, -1);
2339
+ } else if (lastPre.length === 2 && lastPre[0].token === "!") {
2340
+ post.token = " == null";
2341
+ pre = pre.slice(0, -1);
2057
2342
  }
2058
2343
  }
2059
- let errors = false;
2060
- let isPattern = false;
2061
- if (clauses.some(($1) => $1.type === "PatternClause")) {
2062
- isPattern = true;
2063
- clauses.forEach((c) => {
2064
- if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
2065
- errors = true;
2066
- return c.children.push({
2067
- type: "Error",
2068
- message: "Can't mix pattern matching and non-pattern matching clauses"
2069
- });
2070
- }
2071
- ;
2072
- return;
2073
- });
2074
- }
2075
- if (errors || !isPattern) {
2076
- return;
2077
- }
2078
- let { condition } = s;
2079
- if (condition.type === "ParenthesizedExpression") {
2080
- condition = condition.expression;
2081
- }
2082
- let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
2083
- if (ref !== condition) {
2084
- hoistDec = {
2085
- type: "Declaration",
2086
- children: ["let ", ref],
2087
- names: []
2344
+ const existence = {
2345
+ type: "Existence",
2346
+ expression: exp,
2347
+ children: [exp, post]
2348
+ };
2349
+ exp = makeLeftHandSideExpression(existence);
2350
+ if (pre.length) {
2351
+ return {
2352
+ type: "UnaryExpression",
2353
+ children: [...pre, exp]
2088
2354
  };
2089
- refAssignment = [{
2090
- type: "AssignmentExpression",
2091
- children: [ref, " = ", condition]
2092
- }, ","];
2093
2355
  }
2094
- let prev = [], root = prev;
2095
- const l = clauses.length;
2096
- clauses.forEach((c, i) => {
2097
- if (c.type === "DefaultClause") {
2098
- prev.push(c.block);
2099
- return;
2356
+ return exp;
2357
+ }
2358
+ if (exp.type === "Literal") {
2359
+ if (pre.length === 1) {
2360
+ const { token } = pre[0];
2361
+ if (token === "-" || token === "+") {
2362
+ const children = [pre[0], ...exp.children];
2363
+ if (post)
2364
+ exp.children.push(post);
2365
+ return {
2366
+ type: "Literal",
2367
+ children,
2368
+ raw: `${token}${exp.raw}`
2369
+ };
2100
2370
  }
2101
- let { patterns, block } = c;
2102
- let pattern = patterns[0];
2103
- const indent = block.expressions?.[0]?.[0] || "";
2104
- const alternativeConditions = patterns.map((pattern2, i2) => {
2105
- const conditions = [];
2106
- getPatternConditions(pattern2, ref, conditions);
2107
- return conditions;
2108
- });
2109
- const conditionExpression = alternativeConditions.map((conditions, i2) => {
2110
- const conditionArray = conditions.map((c2, i3) => {
2111
- if (i3 === 0)
2112
- return c2;
2113
- return [" && ", ...c2];
2114
- });
2115
- if (i2 === 0)
2116
- return conditionArray;
2117
- return [" || ", ...conditionArray];
2118
- });
2119
- const condition2 = {
2120
- type: "ParenthesizedExpression",
2121
- children: ["(", ...refAssignment, conditionExpression, ")"],
2122
- expression: conditionExpression
2123
- };
2124
- const prefix = [];
2125
- switch (pattern.type) {
2126
- case "ArrayBindingPattern":
2127
- if (pattern.length === 0)
2128
- break;
2129
- case "ObjectBindingPattern": {
2130
- if (pattern.properties?.length === 0)
2131
- break;
2132
- let [splices, thisAssignments] = gatherBindingCode(pattern);
2133
- const patternBindings = nonMatcherBindings(pattern);
2134
- splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
2135
- thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
2136
- const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
2137
- prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
2138
- prefix.push(...thisAssignments);
2139
- prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
2140
- break;
2371
+ }
2372
+ }
2373
+ let ref;
2374
+ while (ref = pre.length) {
2375
+ const l = ref;
2376
+ const last = pre[l - 1];
2377
+ if (last.type === "Await") {
2378
+ if (last.op) {
2379
+ if (exp.type !== "ParenthesizedExpression") {
2380
+ exp = ["(", exp, ")"];
2141
2381
  }
2382
+ exp = {
2383
+ type: "CallExpression",
2384
+ children: [...last.children, "Promise", last.op, exp]
2385
+ };
2386
+ pre = pre.slice(0, -1);
2387
+ } else {
2388
+ exp = {
2389
+ type: "AwaitExpression",
2390
+ children: [...last.children, exp]
2391
+ };
2392
+ pre = pre.slice(0, -1);
2142
2393
  }
2143
- block.expressions.unshift(...prefix);
2144
- const next = [];
2145
- braceBlock(block);
2146
- if (i < l - 1)
2147
- next.push("\n", "else ");
2148
- prev.push(["", {
2149
- type: "IfStatement",
2150
- children: ["if", condition2, block, next],
2151
- then: block,
2152
- else: next,
2153
- hoistDec
2154
- }]);
2155
- hoistDec = void 0;
2156
- refAssignment = [];
2157
- return prev = next;
2158
- });
2159
- s.type = "PatternMatchingStatement";
2160
- s.children = [root];
2161
- return addParentPointers(s, s.parent);
2162
- });
2163
- }
2164
- function getPatternConditions(pattern, ref, conditions) {
2165
- if (pattern.rest)
2166
- return;
2167
- switch (pattern.type) {
2168
- case "ArrayBindingPattern": {
2169
- const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), comparator = hasRest ? " >= " : " === ", l = [comparator, (length - hasRest).toString()];
2170
- conditions.push(
2171
- ["Array.isArray(", ref, ")"],
2172
- [ref, ".length", l]
2173
- );
2174
- elements.forEach(({ children: [, e] }, i) => {
2175
- const subRef = [ref, "[", i.toString(), "]"];
2176
- return getPatternConditions(e, subRef, conditions);
2177
- });
2178
- const { blockPrefix } = pattern;
2179
- if (blockPrefix) {
2180
- const postElements = blockPrefix.children[1], { length: postLength } = postElements;
2181
- postElements.forEach(({ children: [, e] }, i) => {
2182
- const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
2183
- return getPatternConditions(e, subRef, conditions);
2184
- });
2185
- }
2186
- break;
2187
- }
2188
- case "ObjectBindingPattern": {
2189
- conditions.push(
2190
- ["typeof ", ref, " === 'object'"],
2191
- [ref, " != null"]
2192
- );
2193
- pattern.properties.forEach((p) => {
2194
- switch (p.type) {
2195
- case "PinProperty":
2196
- case "BindingProperty": {
2197
- const { name, value } = p;
2198
- let subRef;
2199
- switch (name.type) {
2200
- case "ComputedPropertyName":
2201
- conditions.push([name.expression, " in ", ref]);
2202
- subRef = [ref, name];
2203
- break;
2204
- case "Literal":
2205
- case "StringLiteral":
2206
- case "NumericLiteral":
2207
- conditions.push([name, " in ", ref]);
2208
- subRef = [ref, "[", name, "]"];
2209
- break;
2210
- default:
2211
- conditions.push(["'", name, "' in ", ref]);
2212
- subRef = [ref, ".", name];
2213
- }
2214
- if (value) {
2215
- getPatternConditions(value, subRef, conditions);
2216
- }
2217
- break;
2218
- }
2219
- }
2220
- });
2221
- break;
2222
- }
2223
- case "ConditionFragment": {
2224
- let { children } = pattern;
2225
- if (children.length) {
2226
- let [first, ...rest] = children;
2227
- let [ws, ...op] = first;
2228
- ws = [" "].concat(ws);
2229
- first = [ws, ...op];
2230
- children = [first, ...rest];
2231
- }
2232
- conditions.push(
2233
- processBinaryOpExpression([ref, children])
2234
- );
2235
- break;
2236
- }
2237
- case "RegularExpressionLiteral": {
2238
- conditions.push(
2239
- ["typeof ", ref, " === 'string'"],
2240
- [pattern, ".test(", ref, ")"]
2241
- );
2394
+ } else {
2242
2395
  break;
2243
2396
  }
2244
- case "PinPattern":
2245
- conditions.push([
2246
- ref,
2247
- " === ",
2248
- pattern.expression
2249
- ]);
2250
- break;
2251
- case "Literal":
2252
- conditions.push([
2253
- ref,
2254
- " === ",
2255
- pattern
2256
- ]);
2257
- break;
2258
- default:
2259
- break;
2260
2397
  }
2398
+ return {
2399
+ type: "UnaryExpression",
2400
+ children: [...pre, exp, post]
2401
+ };
2261
2402
  }
2262
- function elideMatchersFromArrayBindings(elements) {
2263
- return elements.map((el) => {
2264
- if (el.type === "BindingRestElement") {
2265
- return ["", el, void 0];
2266
- }
2267
- const { children: [ws, e, delim] } = el;
2268
- switch (e.type) {
2269
- case "Literal":
2270
- case "RegularExpressionLiteral":
2271
- case "StringLiteral":
2272
- case "PinPattern":
2273
- return delim;
2274
- default:
2275
- return [ws, nonMatcherBindings(e), delim];
2276
- }
2277
- });
2403
+ var init_unary = __esm({
2404
+ "source/parser/unary.civet"() {
2405
+ "use strict";
2406
+ init_util();
2407
+ }
2408
+ });
2409
+
2410
+ // source/parser/pipe.civet
2411
+ function constructInvocation(fn, arg) {
2412
+ const fnArr = [fn.leadingComment, fn.expr, fn.trailingComment];
2413
+ let expr = fn.expr;
2414
+ while (expr.type === "ParenthesizedExpression") {
2415
+ expr = expr.expression;
2416
+ }
2417
+ if (expr.ampersandBlock) {
2418
+ const { ref, body } = expr;
2419
+ ref.type = "PipedExpression";
2420
+ ref.children = [makeLeftHandSideExpression(arg)];
2421
+ updateParentPointers(ref);
2422
+ return makeNode({
2423
+ type: "UnwrappedExpression",
2424
+ children: [skipIfOnlyWS(fn.leadingComment), body, skipIfOnlyWS(fn.trailingComment)]
2425
+ });
2426
+ }
2427
+ expr = fn.expr;
2428
+ const lhs = makeLeftHandSideExpression(expr);
2429
+ let comment = skipIfOnlyWS(fn.trailingComment);
2430
+ if (comment)
2431
+ lhs.children.splice(2, 0, comment);
2432
+ comment = skipIfOnlyWS(fn.leadingComment);
2433
+ if (comment)
2434
+ lhs.children.splice(1, 0, comment);
2435
+ switch (arg.type) {
2436
+ case "CommaExpression":
2437
+ arg = makeLeftHandSideExpression(arg);
2438
+ break;
2439
+ }
2440
+ return {
2441
+ type: "CallExpression",
2442
+ children: [lhs, "(", arg, ")"]
2443
+ };
2278
2444
  }
2279
- function elideMatchersFromPropertyBindings(properties) {
2280
- return properties.map((p) => {
2281
- switch (p.type) {
2282
- case "BindingProperty": {
2283
- const { children, name, value } = p;
2284
- const [ws] = children;
2285
- switch (value && value.type) {
2286
- case "ArrayBindingPattern":
2287
- case "ObjectBindingPattern":
2288
- return {
2289
- ...p,
2290
- children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
2291
- };
2292
- case "Identifier":
2293
- return p;
2294
- case "Literal":
2295
- case "RegularExpressionLiteral":
2296
- case "StringLiteral":
2297
- default:
2298
- return {
2299
- ...p,
2300
- children: [ws, name, p.delim]
2301
- };
2302
- }
2445
+ function constructPipeStep(fn, arg, returning) {
2446
+ let children = [[fn.leadingComment, fn.expr, fn.trailingComment].map(skipIfOnlyWS), " ", arg];
2447
+ switch (fn.expr.token) {
2448
+ case "yield":
2449
+ case "await":
2450
+ if (fn.expr.op) {
2451
+ children = processUnaryExpression([fn.expr], arg, void 0);
2303
2452
  }
2304
- case "PinProperty":
2305
- case "BindingRestProperty":
2306
- default:
2307
- return p;
2308
- }
2309
- });
2310
- }
2311
- function nonMatcherBindings(pattern) {
2312
- switch (pattern.type) {
2313
- case "ArrayBindingPattern": {
2314
- const elements = elideMatchersFromArrayBindings(pattern.elements);
2315
- const children = ["[", elements, "]"];
2316
- return {
2317
- ...pattern,
2453
+ if (returning) {
2454
+ return [
2455
+ children,
2456
+ returning
2457
+ ];
2458
+ }
2459
+ return [
2318
2460
  children,
2319
- elements
2320
- };
2321
- }
2322
- case "PostRestBindingElements": {
2323
- const els = elideMatchersFromArrayBindings(pattern.children[1]);
2324
- return {
2325
- ...pattern,
2326
- children: [
2327
- pattern.children[0],
2328
- els,
2329
- ...pattern.children.slice(2)
2330
- ]
2331
- };
2332
- }
2333
- case "ObjectBindingPattern":
2334
- return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
2335
- default:
2336
- return pattern;
2461
+ null
2462
+ ];
2463
+ case "return":
2464
+ return [{
2465
+ type: "ReturnStatement",
2466
+ children
2467
+ }, null];
2468
+ }
2469
+ if (returning) {
2470
+ return [
2471
+ constructInvocation(fn, arg),
2472
+ returning
2473
+ ];
2337
2474
  }
2475
+ return [constructInvocation(fn, arg), null];
2338
2476
  }
2339
- function aggregateDuplicateBindings(bindings, ReservedWord) {
2340
- const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
2341
- const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
2342
- arrayBindings.forEach((a) => {
2343
- const { elements } = a;
2344
- return elements.forEach((element) => {
2345
- if (Array.isArray(element)) {
2346
- const [, e] = element;
2347
- if (e.type === "Identifier") {
2348
- return props.push(e);
2349
- } else if (e.type === "BindingRestElement") {
2350
- return props.push(e);
2477
+ function processPipelineExpressions(statements) {
2478
+ gatherRecursiveAll(statements, (n) => n.type === "PipelineExpression").forEach((s) => {
2479
+ const [ws, , body] = s.children;
2480
+ let [, arg] = s.children;
2481
+ let i = 0, l = body.length;
2482
+ const children = [ws];
2483
+ let usingRef = null;
2484
+ for (i = 0; i < l; i++) {
2485
+ const step = body[i];
2486
+ const [leadingComment, pipe, trailingComment, expr] = step;
2487
+ const returns = pipe.token === "||>";
2488
+ let ref, result, returning = returns ? arg : null;
2489
+ if (pipe.token === "|>=") {
2490
+ let initRef;
2491
+ if (i === 0) {
2492
+ outer:
2493
+ switch (arg.type) {
2494
+ case "MemberExpression":
2495
+ if (arg.children.length <= 2)
2496
+ break;
2497
+ case "CallExpression":
2498
+ const access = arg.children.pop();
2499
+ switch (access.type) {
2500
+ case "PropertyAccess":
2501
+ case "SliceExpression":
2502
+ break;
2503
+ default:
2504
+ children.unshift({
2505
+ type: "Error",
2506
+ $loc: pipe.token.$loc,
2507
+ message: `Can't assign to ${access.type}`
2508
+ });
2509
+ arg.children.push(access);
2510
+ break outer;
2511
+ }
2512
+ usingRef = makeRef();
2513
+ initRef = {
2514
+ type: "AssignmentExpression",
2515
+ children: [usingRef, " = ", arg, ","]
2516
+ };
2517
+ arg = {
2518
+ type: "MemberExpression",
2519
+ children: [usingRef, access]
2520
+ };
2521
+ break;
2522
+ }
2523
+ const lhs = [[
2524
+ [initRef],
2525
+ arg,
2526
+ [],
2527
+ { token: "=", children: [" = "] }
2528
+ ]];
2529
+ Object.assign(s, {
2530
+ type: "AssignmentExpression",
2531
+ children: [lhs, children],
2532
+ names: null,
2533
+ lhs,
2534
+ assigned: arg,
2535
+ exp: children
2536
+ });
2537
+ arg = clone(arg);
2538
+ if (arg.children[0].type === "Ref") {
2539
+ arg.children[0] = usingRef;
2540
+ }
2541
+ } else {
2542
+ children.unshift({
2543
+ type: "Error",
2544
+ $loc: pipe.token.$loc,
2545
+ message: "Can't use |>= in the middle of a pipeline"
2546
+ });
2351
2547
  }
2352
- ;
2353
- return;
2548
+ } else {
2549
+ if (i === 0)
2550
+ s.children = children;
2551
+ }
2552
+ if (returns && (ref = needsRef(arg))) {
2553
+ usingRef = usingRef || ref;
2554
+ arg = {
2555
+ type: "ParenthesizedExpression",
2556
+ children: ["(", {
2557
+ type: "AssignmentExpression",
2558
+ children: [usingRef, " = ", arg]
2559
+ }, ")"]
2560
+ };
2561
+ returning = usingRef;
2354
2562
  }
2355
2563
  ;
2356
- return;
2357
- });
2358
- });
2359
- const declarations = [];
2360
- const propsGroupedByName = /* @__PURE__ */ new Map();
2361
- for (const p of props) {
2362
- const { name, value } = p;
2363
- const key = value?.name || name?.name || name;
2364
- if (propsGroupedByName.has(key)) {
2365
- propsGroupedByName.get(key).push(p);
2366
- } else {
2367
- propsGroupedByName.set(key, [p]);
2368
- }
2369
- }
2370
- propsGroupedByName.forEach((shared, key) => {
2371
- if (!key) {
2372
- return;
2373
- }
2374
- if (ReservedWord({ fail() {
2375
- } }, {
2376
- pos: 0,
2377
- input: key
2378
- })) {
2379
- shared.forEach((p) => {
2380
- return aliasBinding(p, makeRef(`_${key}`, key));
2381
- });
2382
- return;
2383
- }
2384
- if (shared.length === 1) {
2385
- return;
2386
- }
2387
- const refs = shared.map((p) => {
2388
- const ref = makeRef(key);
2389
- aliasBinding(p, ref);
2390
- return ref;
2391
- });
2392
- return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
2393
- return i === 0 ? r : [", ", r];
2394
- }), "]"]);
2395
- });
2396
- return declarations;
2397
- }
2398
- function processDeclarationCondition(condition, rootCondition, parent) {
2399
- if (!(condition.type === "DeclarationCondition")) {
2400
- return;
2401
- }
2402
- const ref = makeRef();
2403
- const { decl, bindings } = condition.declaration;
2404
- const binding = bindings[0];
2405
- const { pattern, suffix, initializer, splices, thisAssignments } = binding;
2406
- const grandparent = condition.parent?.parent;
2407
- const children = (
2408
- // Check that the declaration is a plain assignment (no pattern-matching) and the immediate grandchild of an `if` or `while`
2409
- // More complex conditions (triggered by pattern matching or `until`/`unless`) don't need double parens
2410
- // @ts-ignore Just because pattern might not have a type at runtime doesn't mean it's unsafe
2411
- pattern.type === "Identifier" && (grandparent?.type === "IfStatement" || grandparent?.type === "WhileStatement") ? ["(", ref, initializer, ")"] : [ref, initializer]
2412
- );
2413
- Object.assign(condition, {
2414
- type: "AssignmentExpression",
2415
- children,
2416
- hoistDec: {
2417
- type: "Declaration",
2418
- children: ["let ", ref, suffix],
2419
- names: []
2420
- },
2421
- pattern,
2422
- ref
2423
- });
2424
- addParentPointers(condition, parent);
2425
- Object.assign(rootCondition, {
2426
- blockPrefix: [
2427
- ["", [decl, pattern, suffix, " = ", ref, ...splices], ";"],
2428
- ...thisAssignments
2429
- ]
2430
- });
2431
- }
2432
- function processDeclarationConditions(node) {
2433
- gatherRecursiveAll(node, (n) => {
2434
- return n.type === "IfStatement" || n.type === "IterationStatement" || n.type === "SwitchStatement";
2435
- }).forEach(processDeclarationConditionStatement);
2436
- }
2437
- function processDeclarationConditionStatement(s) {
2438
- const { condition } = s;
2439
- if (!condition?.expression) {
2440
- return;
2441
- }
2442
- let { expression } = condition;
2443
- if (typeof expression === "object" && expression != null && "type" in expression && expression.type === "UnaryExpression" && "children" in expression && Array.isArray(expression.children) && expression.children.length === 2 && expression.children[0] === "!" && typeof expression.children[1] === "object" && expression.children[1] != null && "type" in expression.children[1] && expression.children[1].type === "ParenthesizedExpression" && "expression" in expression.children[1]) {
2444
- const { type: type1, children: [, { type: type2, expression: expression2 }] } = expression;
2445
- const type = [type1, type2];
2446
- expression = expression2;
2447
- }
2448
- processDeclarationCondition(expression, condition.expression, s);
2449
- const { ref, pattern } = expression;
2450
- if (pattern) {
2451
- let conditions = [];
2452
- getPatternConditions(pattern, ref, conditions);
2453
- conditions = conditions.filter((c) => {
2454
- return !(c.length === 3 && c[0] === "typeof " && c[1] === ref && c[2] === " === 'object'") && !(c.length === 2 && c[0] === ref && c[1] === " != null");
2455
- });
2456
- if (conditions.length) {
2457
- condition.children.unshift("(");
2458
- conditions.forEach(function(c) {
2459
- return condition.children.push(" && ", c);
2460
- });
2461
- condition.children.push(")");
2462
- }
2463
- }
2464
- switch (s.type) {
2465
- case "IfStatement": {
2466
- const { else: e } = s;
2467
- const block = blockWithPrefix(condition.expression.blockPrefix, s.then);
2468
- s.then = block;
2469
- if (block.bare && e && !block.semicolon) {
2470
- block.children.push(block.semicolon = ";");
2564
+ [result, returning] = constructPipeStep(
2565
+ {
2566
+ leadingComment: skipIfOnlyWS(leadingComment),
2567
+ trailingComment: skipIfOnlyWS(trailingComment),
2568
+ expr
2569
+ },
2570
+ arg,
2571
+ returning
2572
+ );
2573
+ if (result.type === "ReturnStatement") {
2574
+ if (i < l - 1) {
2575
+ result.children.push({
2576
+ type: "Error",
2577
+ message: "Can't continue a pipeline after returning"
2578
+ });
2579
+ }
2580
+ arg = result;
2581
+ if (children[children.length - 1] === ",") {
2582
+ children.pop();
2583
+ children.push(";");
2584
+ }
2585
+ break;
2586
+ }
2587
+ if (returning) {
2588
+ arg = returning;
2589
+ children.push(result, ",");
2590
+ } else {
2591
+ arg = result;
2471
2592
  }
2472
- s.children.splice(2, 1, block);
2473
- updateParentPointers(block, s);
2474
- break;
2475
- }
2476
- case "IterationStatement": {
2477
- const { children, block } = s;
2478
- const newBlock = blockWithPrefix(condition.expression.blockPrefix, block);
2479
- s.children = children.map((c) => c?.type === "BlockStatement" ? newBlock : c);
2480
- updateParentPointers(newBlock, s);
2481
- break;
2482
2593
  }
2483
- case "SwitchStatement": {
2484
- const { blockPrefix, ref: ref2 } = condition.expression;
2485
- if (!blockPrefix) {
2486
- return;
2487
- }
2488
- s.condition = {
2489
- type: "ParenthesizedExpression",
2490
- children: ["(", ref2, ")"],
2491
- expression: ref2,
2492
- parent: s
2493
- };
2494
- s.children[1] = s.condition;
2495
- updateParentPointers(s);
2496
- const block = blockWithPrefix([["", [{
2594
+ if (usingRef) {
2595
+ s.hoistDec = {
2497
2596
  type: "Declaration",
2498
- children: ["let ", ...condition.expression.children]
2499
- }], ";"], ...blockPrefix], makeEmptyBlock());
2500
- updateParentPointers(block, s.parent);
2501
- replaceBlockExpression(s.parent, s, block);
2502
- block.expressions.push(["", s]);
2503
- s.parent = block;
2504
- break;
2597
+ children: ["let ", usingRef],
2598
+ names: []
2599
+ };
2505
2600
  }
2506
- }
2507
- }
2508
- function aliasBinding(p, ref) {
2509
- if (p.type === "Identifier") {
2510
- p.children[0] = ref;
2511
- } else if (p.type === "BindingRestElement") {
2512
- aliasBinding(p.binding, ref);
2513
- } else if (p.value?.type === "Identifier") {
2514
- aliasBinding(p.value, ref);
2515
- } else {
2516
- p.value = ref;
2517
- const index = p.children.indexOf(p.name);
2518
- p.children.splice(index + 1, 0, ": ", ref);
2519
- }
2601
+ children.push(arg);
2602
+ if (!children.some(($) => $?.type === "ReturnStatement") && children.some(($1) => $1 === ",")) {
2603
+ const { parent } = s;
2604
+ const parenthesizedExpression = makeLeftHandSideExpression({ ...s });
2605
+ Object.assign(s, parenthesizedExpression, {
2606
+ parent,
2607
+ hoistDec: void 0
2608
+ });
2609
+ }
2610
+ return addParentPointers(s, s.parent);
2611
+ });
2520
2612
  }
2521
- var init_pattern_matching = __esm({
2522
- "source/parser/pattern-matching.civet"() {
2613
+ var init_pipe = __esm({
2614
+ "source/parser/pipe.civet"() {
2523
2615
  "use strict";
2524
2616
  init_traversal();
2525
2617
  init_util();
2526
- init_block();
2527
- init_binding();
2528
- init_op();
2618
+ init_unary();
2529
2619
  }
2530
2620
  });
2531
2621
 
2532
- // source/parser/unary.civet
2533
- function processUnaryExpression(pre, exp, post) {
2534
- if (!(pre.length || post))
2535
- return exp;
2536
- if (post?.token === "?") {
2537
- post = {
2538
- $loc: post.$loc,
2539
- token: " != null"
2540
- };
2541
- if (pre.length) {
2542
- const lastPre = pre[pre.length - 1];
2543
- if (lastPre.token === "!") {
2544
- post.token = " == null";
2545
- pre = pre.slice(0, -1);
2546
- } else if (lastPre.length === 2 && lastPre[0].token === "!") {
2547
- post.token = " == null";
2548
- pre = pre.slice(0, -1);
2622
+ // source/parser/for.civet
2623
+ function forRange(open, forDeclaration, range, stepExp, close) {
2624
+ const { start, end, inclusive } = range;
2625
+ const counterRef = makeRef("i");
2626
+ let stepRef;
2627
+ if (stepExp) {
2628
+ stepExp = insertTrimmingSpace(stepExp, "");
2629
+ stepRef = maybeRef(stepExp, "step");
2630
+ }
2631
+ let startRef = maybeRef(start, "start");
2632
+ let endRef = maybeRef(end, "end");
2633
+ const startRefDec = startRef !== start ? [startRef, " = ", start, ", "] : [];
2634
+ const endRefDec = endRef !== end ? [endRef, " = ", end, ", "] : [];
2635
+ let ascDec = [], ascRef, asc;
2636
+ if (stepRef) {
2637
+ if (!(stepRef === stepExp)) {
2638
+ ascDec = [", ", stepRef, " = ", stepExp];
2639
+ }
2640
+ } else if ("Literal" === start.type && start.type === end.type) {
2641
+ asc = literalValue(start) <= literalValue(end);
2642
+ if ("StringLiteral" === start.subtype && start.subtype === end.subtype) {
2643
+ startRef = literalValue(start).charCodeAt(0).toString();
2644
+ endRef = literalValue(end).charCodeAt(0).toString();
2645
+ }
2646
+ } else {
2647
+ ascRef = makeRef("asc");
2648
+ ascDec = [", ", ascRef, " = ", startRef, " <= ", endRef];
2649
+ }
2650
+ let varAssign = [], varLetAssign = varAssign, varLet = varAssign, blockPrefix;
2651
+ if (forDeclaration?.declare) {
2652
+ if (forDeclaration.declare.token === "let") {
2653
+ const varName = forDeclaration.children.splice(1);
2654
+ varAssign = [...insertTrimmingSpace(varName, ""), " = "];
2655
+ varLet = [",", ...varName, " = ", counterRef];
2656
+ } else {
2657
+ const value = "StringLiteral" === start.subtype ? ["String.fromCharCode(", counterRef, ")"] : counterRef;
2658
+ blockPrefix = [
2659
+ ["", forDeclaration, " = ", value, ";"]
2660
+ ];
2661
+ }
2662
+ } else if (forDeclaration) {
2663
+ varAssign = varLetAssign = [forDeclaration, " = "];
2664
+ }
2665
+ const declaration = {
2666
+ type: "Declaration",
2667
+ children: ["let ", ...startRefDec, ...endRefDec, counterRef, " = ", ...varLetAssign, startRef, ...varLet, ...ascDec],
2668
+ names: forDeclaration?.names
2669
+ };
2670
+ const counterPart = inclusive ? [counterRef, " <= ", endRef, " : ", counterRef, " >= ", endRef] : [counterRef, " < ", endRef, " : ", counterRef, " > ", endRef];
2671
+ const condition = stepRef ? [stepRef, " !== 0 && (", stepRef, " > 0 ? ", ...counterPart, ")"] : ascRef ? [ascRef, " ? ", ...counterPart] : asc ? counterPart.slice(0, 3) : counterPart.slice(4);
2672
+ const increment = stepRef ? [...varAssign, counterRef, " += ", stepRef] : ascRef ? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef] : [...varAssign, asc ? "++" : "--", counterRef];
2673
+ return {
2674
+ declaration,
2675
+ children: [open, declaration, "; ", ...condition, "; ", ...increment, close],
2676
+ blockPrefix
2677
+ };
2678
+ }
2679
+ function processForInOf($0, getRef) {
2680
+ let [awaits, eachOwn, open, declaration, declaration2, ws, inOf, exp, step, close] = $0;
2681
+ if (exp.type === "RangeExpression" && inOf.token === "of" && !declaration2) {
2682
+ return forRange(open, declaration, exp, step, close);
2683
+ } else if (step) {
2684
+ throw new Error("for..of/in cannot use 'by' except with range literals");
2685
+ }
2686
+ let eachOwnError;
2687
+ let hoistDec, blockPrefix = [];
2688
+ if (eachOwn && eachOwn[0].token === "each") {
2689
+ if (inOf.token === "of") {
2690
+ const counterRef = makeRef("i");
2691
+ const lenRef = makeRef("len");
2692
+ const expRef2 = maybeRef(exp);
2693
+ const increment = "++";
2694
+ let assignmentNames = [...declaration.names];
2695
+ if (declaration2) {
2696
+ const [, , ws22, decl22] = declaration2;
2697
+ blockPrefix.push(["", [
2698
+ insertTrimmingSpace(ws22, ""),
2699
+ decl22,
2700
+ " = ",
2701
+ counterRef
2702
+ ], ";"]);
2703
+ assignmentNames.push(...decl22.names);
2549
2704
  }
2705
+ const expRefDec = expRef2 !== exp ? [insertTrimmingSpace(expRef2, " "), " = ", insertTrimmingSpace(exp, ""), ", "] : [];
2706
+ blockPrefix.push(["", {
2707
+ type: "Declaration",
2708
+ children: [declaration, " = ", insertTrimmingSpace(expRef2, ""), "[", counterRef, "]"],
2709
+ names: assignmentNames
2710
+ }, ";"]);
2711
+ declaration = {
2712
+ type: "Declaration",
2713
+ children: ["let ", ...expRefDec, counterRef, " = 0, ", lenRef, " = ", insertTrimmingSpace(expRef2, ""), ".length"],
2714
+ names: []
2715
+ };
2716
+ const condition = [counterRef, " < ", lenRef, "; "];
2717
+ const children = [open, declaration, "; ", condition, counterRef, increment, close];
2718
+ return { declaration, children, blockPrefix };
2719
+ } else {
2720
+ eachOwnError = {
2721
+ type: "Error",
2722
+ message: "'each' is only meaningful in for..of loops"
2723
+ };
2550
2724
  }
2551
- const existence = {
2552
- type: "Existence",
2553
- expression: exp,
2554
- children: [exp, post]
2725
+ }
2726
+ let own = eachOwn && eachOwn[0].token === "own";
2727
+ let expRef;
2728
+ if (own && inOf.token !== "in") {
2729
+ own = false;
2730
+ eachOwnError = {
2731
+ type: "Error",
2732
+ message: "'own' is only meaningful in for..in loops"
2555
2733
  };
2556
- exp = makeLeftHandSideExpression(existence);
2557
- if (pre.length) {
2558
- return {
2559
- type: "UnaryExpression",
2560
- children: [...pre, exp]
2734
+ }
2735
+ if (!declaration2 && !own) {
2736
+ return {
2737
+ declaration,
2738
+ blockPrefix,
2739
+ children: [awaits, eachOwnError, open, declaration, ws, inOf, expRef ?? exp, step, close]
2740
+ // omit declaration2, replace eachOwn with eachOwnError, replace exp with expRef
2741
+ };
2742
+ }
2743
+ let ws2, decl2;
2744
+ if (declaration2)
2745
+ [, , ws2, decl2] = declaration2;
2746
+ switch (inOf.token) {
2747
+ case "of": {
2748
+ const counterRef = makeRef("i");
2749
+ hoistDec = {
2750
+ type: "Declaration",
2751
+ children: ["let ", counterRef, " = 0"],
2752
+ names: []
2561
2753
  };
2754
+ blockPrefix.push(["", {
2755
+ type: "Declaration",
2756
+ children: [insertTrimmingSpace(ws2, ""), decl2, " = ", counterRef, "++"],
2757
+ names: decl2.names
2758
+ }, ";"]);
2759
+ break;
2562
2760
  }
2563
- return exp;
2564
- }
2565
- if (exp.type === "Literal") {
2566
- if (pre.length === 1) {
2567
- const { token } = pre[0];
2568
- if (token === "-" || token === "+") {
2569
- const children = [pre[0], ...exp.children];
2570
- if (post)
2571
- exp.children.push(post);
2572
- return {
2573
- type: "Literal",
2574
- children,
2575
- raw: `${token}${exp.raw}`
2761
+ case "in": {
2762
+ const expRef2 = maybeRef(exp);
2763
+ if (expRef2 !== exp) {
2764
+ hoistDec = {
2765
+ type: "Declaration",
2766
+ children: ["let ", expRef2],
2767
+ names: []
2768
+ };
2769
+ exp = {
2770
+ type: "AssignmentExpression",
2771
+ children: [" ", expRef2, " =", exp]
2772
+ };
2773
+ }
2774
+ let { binding } = declaration;
2775
+ if (binding?.type !== "Identifier") {
2776
+ const keyRef = makeRef("key");
2777
+ blockPrefix.push(["", [
2778
+ declaration,
2779
+ " = ",
2780
+ keyRef
2781
+ ], ";"]);
2782
+ declaration = {
2783
+ type: "ForDeclaration",
2784
+ binding: binding = keyRef,
2785
+ children: ["const ", keyRef],
2786
+ names: []
2576
2787
  };
2577
2788
  }
2578
- }
2579
- }
2580
- const l = pre.length;
2581
- if (l) {
2582
- const last = pre[l - 1];
2583
- if (last.type === "Await" && last.op) {
2584
- if (exp.type !== "ParenthesizedExpression") {
2585
- exp = ["(", exp, ")"];
2789
+ if (own) {
2790
+ const hasPropRef = getRef("hasProp");
2791
+ blockPrefix.push(["", ["if (!", hasPropRef, "(", insertTrimmingSpace(expRef2, ""), ", ", insertTrimmingSpace(binding, ""), ")) continue"], ";"]);
2792
+ }
2793
+ if (decl2) {
2794
+ blockPrefix.push(["", {
2795
+ type: "Declaration",
2796
+ children: [insertTrimmingSpace(ws2, ""), decl2, " = ", insertTrimmingSpace(expRef2, ""), "[", insertTrimmingSpace(binding, ""), "]"],
2797
+ names: decl2.names
2798
+ }, ";"]);
2586
2799
  }
2587
- exp = {
2588
- type: "CallExpression",
2589
- children: [" Promise", last.op, exp]
2590
- };
2800
+ break;
2591
2801
  }
2802
+ default:
2803
+ (() => {
2804
+ throw new Error(`for item, index must use 'of' or 'in' instead of '${inOf.token}'`);
2805
+ })();
2592
2806
  }
2593
2807
  return {
2594
- type: "UnaryExpression",
2595
- children: [...pre, exp, post]
2808
+ declaration,
2809
+ children: [awaits, eachOwnError, open, declaration, ws, inOf, exp, step, close],
2810
+ // omit declaration2, replace each with eachOwnError
2811
+ blockPrefix,
2812
+ hoistDec
2596
2813
  };
2597
2814
  }
2598
- var init_unary = __esm({
2599
- "source/parser/unary.civet"() {
2815
+ var init_for = __esm({
2816
+ "source/parser/for.civet"() {
2600
2817
  "use strict";
2601
2818
  init_util();
2602
2819
  }
@@ -2921,7 +3138,6 @@ __export(lib_exports, {
2921
3138
  dedentBlockString: () => dedentBlockString,
2922
3139
  dedentBlockSubstitutions: () => dedentBlockSubstitutions,
2923
3140
  deepCopy: () => deepCopy,
2924
- expressionizeIfClause: () => expressionizeIfClause,
2925
3141
  expressionizeTypeIf: () => expressionizeTypeIf,
2926
3142
  forRange: () => forRange,
2927
3143
  gatherBindingCode: () => gatherBindingCode,
@@ -2956,6 +3172,7 @@ __export(lib_exports, {
2956
3172
  quoteString: () => quoteString,
2957
3173
  reorderBindingRestProperty: () => reorderBindingRestProperty,
2958
3174
  replaceNodes: () => replaceNodes,
3175
+ skipImplicitArguments: () => skipImplicitArguments,
2959
3176
  typeOfJSX: () => typeOfJSX,
2960
3177
  wrapIIFE: () => wrapIIFE
2961
3178
  });
@@ -2994,16 +3211,71 @@ function negateCondition(condition) {
2994
3211
  };
2995
3212
  return { ...condition, expression, children };
2996
3213
  }
2997
- function expressionizeIfClause(clause, b, e) {
2998
- const { condition } = clause;
3214
+ function isExpression(node) {
3215
+ if (Array.isArray(node)) {
3216
+ return node.every(isExpression);
3217
+ }
3218
+ if (typeof node === "string") {
3219
+ return true;
3220
+ }
3221
+ switch (node?.type) {
3222
+ case "BlockStatement":
3223
+ case "DebuggerStatement":
3224
+ case "Declaration":
3225
+ case "IfStatement":
3226
+ case "IterationStatement":
3227
+ case "ReturnStatement":
3228
+ case "SwitchStatement":
3229
+ case "ThrowStatement":
3230
+ case "TryStatement":
3231
+ return false;
3232
+ }
3233
+ return true;
3234
+ }
3235
+ function expressionizeBlock(blockOrExpression) {
3236
+ let ref1;
3237
+ if ((ref1 = blockOrExpression) && "expressions" in ref1) {
3238
+ const { expressions } = ref1;
3239
+ const l = expressions.length;
3240
+ const results = [];
3241
+ let i1 = 0;
3242
+ for (const [ws, s, _delim] of expressions) {
3243
+ const i = i1++;
3244
+ if (!isExpression(s))
3245
+ return;
3246
+ const wrapped = makeLeftHandSideExpression(s);
3247
+ if (i === l - 1) {
3248
+ results.push([ws, wrapped]);
3249
+ } else {
3250
+ results.push([ws, wrapped, ","]);
3251
+ }
3252
+ }
3253
+ if (results.length > 1) {
3254
+ return makeLeftHandSideExpression(results);
3255
+ }
3256
+ return results;
3257
+ } else {
3258
+ return blockOrExpression;
3259
+ }
3260
+ }
3261
+ function expressionizeIfStatement(statement) {
3262
+ const { condition, then: b, else: e } = statement;
2999
3263
  const [...condRest] = condition.children, [closeParen] = condRest.splice(-1);
3264
+ const expressionizedBlock = expressionizeBlock(b);
3265
+ if (!expressionizedBlock) {
3266
+ return wrapIIFE([["", statement]]);
3267
+ }
3000
3268
  const children = [
3001
3269
  ...condRest,
3002
3270
  "?",
3003
- b
3271
+ expressionizedBlock
3004
3272
  ];
3005
3273
  if (e) {
3006
- children.push(e[0], ":", ...e.slice(2));
3274
+ const e2 = expressionizeBlock(e[2]);
3275
+ if (!e2) {
3276
+ return wrapIIFE([["", statement]]);
3277
+ }
3278
+ children.push(e[0], ":", e2, ...e.slice(3));
3007
3279
  } else {
3008
3280
  children.push(":void 0");
3009
3281
  }
@@ -3067,17 +3339,17 @@ function processCallMemberExpression(node) {
3067
3339
  let call = children[1];
3068
3340
  const args = [...call.args];
3069
3341
  call = { ...call, args };
3070
- let ref1;
3071
- if (ref1 = isComma(args.at(-1))) {
3072
- const comma = ref1;
3342
+ let ref2;
3343
+ if (ref2 = isComma(args.at(-1))) {
3344
+ const comma = ref2;
3073
3345
  comma.token = "";
3074
3346
  }
3075
3347
  let commaCount = 0;
3076
- for (let i1 = 0, len1 = args.length; i1 < len1; i1++) {
3077
- const arg = args[i1];
3078
- let ref2;
3079
- if (ref2 = isComma(arg)) {
3080
- const comma = ref2;
3348
+ for (let i2 = 0, len1 = args.length; i2 < len1; i2++) {
3349
+ const arg = args[i2];
3350
+ let ref3;
3351
+ if (ref3 = isComma(arg)) {
3352
+ const comma = ref3;
3081
3353
  comma.token = `)${op.token}(`;
3082
3354
  commaCount++;
3083
3355
  }
@@ -3214,9 +3486,9 @@ function replaceNode(node, newNode) {
3214
3486
  throw new Error("replaceNode failed: node has no parent");
3215
3487
  }
3216
3488
  function recurse(children) {
3217
- for (let i2 = 0, len2 = children.length; i2 < len2; i2++) {
3218
- const i = i2;
3219
- const child = children[i2];
3489
+ for (let i3 = 0, len2 = children.length; i3 < len2; i3++) {
3490
+ const i = i3;
3491
+ const child = children[i3];
3220
3492
  if (child === node) {
3221
3493
  children[i] = newNode;
3222
3494
  return true;
@@ -3383,55 +3655,6 @@ function makeGetterMethod(name, ws, value, returnType, block, kind = { token: "g
3383
3655
  parameters
3384
3656
  };
3385
3657
  }
3386
- function processAssignmentDeclaration(decl, pattern, suffix, ws, assign, e) {
3387
- decl = {
3388
- ...decl,
3389
- $loc: {
3390
- pos: assign.$loc.pos - 1,
3391
- length: assign.$loc.length + 1
3392
- }
3393
- };
3394
- let [splices, assignments] = gatherBindingCode(pattern);
3395
- splices = splices.map((s) => [", ", s]);
3396
- const thisAssignments = assignments.map((a) => ["", a, ";"]);
3397
- const initializer = [ws, assign, e];
3398
- const binding = makeNode({
3399
- type: "Binding",
3400
- pattern,
3401
- initializer,
3402
- splices,
3403
- suffix,
3404
- thisAssignments,
3405
- children: [pattern, suffix, initializer]
3406
- });
3407
- const children = [decl, binding];
3408
- return makeNode({
3409
- type: "Declaration",
3410
- names: pattern.names,
3411
- decl,
3412
- bindings: [binding],
3413
- splices,
3414
- thisAssignments,
3415
- children
3416
- });
3417
- }
3418
- function processDeclarations(statements) {
3419
- gatherRecursiveAll(statements, ($) => $.type === "Declaration").forEach(({ bindings }) => {
3420
- return bindings?.forEach((binding) => {
3421
- const suffix = binding.suffix;
3422
- if (suffix && suffix.optional && suffix.t) {
3423
- convertOptionalType(suffix);
3424
- }
3425
- const { initializer } = binding;
3426
- if (initializer) {
3427
- const exp = initializer[2];
3428
- return exp;
3429
- }
3430
- ;
3431
- return;
3432
- });
3433
- });
3434
- }
3435
3658
  function processBindingPatternLHS(lhs, tail) {
3436
3659
  adjustAtBindings(lhs, true);
3437
3660
  const [splices, thisAssignments] = gatherBindingCode(lhs);
@@ -3485,8 +3708,25 @@ function processAssignments(statements) {
3485
3708
  return exp.children.push(...post);
3486
3709
  return;
3487
3710
  });
3488
- gatherRecursiveAll(statements, (n) => n.type === "AssignmentExpression" && n.names === null).forEach((exp) => {
3711
+ replaceNodesRecursive(statements, (n) => n.type === "AssignmentExpression" && n.names === null, (exp) => {
3489
3712
  let { lhs: $1, exp: $2 } = exp, tail = [], i = 0, len = $1.length;
3713
+ let block;
3714
+ if (exp.parent.type === "BlockStatement" && !$1.at(-1)?.at(-1)?.special) {
3715
+ block = makeBlockFragment();
3716
+ let ref4;
3717
+ if (ref4 = prependStatementExpressionBlock([null, null, $2], block)) {
3718
+ const ref = ref4;
3719
+ exp.children = exp.children.map(function(c) {
3720
+ if (c === $2)
3721
+ return ref;
3722
+ else
3723
+ return c;
3724
+ });
3725
+ $2 = ref;
3726
+ } else {
3727
+ block = void 0;
3728
+ }
3729
+ }
3490
3730
  if ($1.some((left) => left[left.length - 1].special)) {
3491
3731
  if ($1.length !== 1)
3492
3732
  throw new Error("Only one assignment with id= is allowed");
@@ -3501,7 +3741,7 @@ function processAssignments(statements) {
3501
3741
  exp.exp = $2 = [call, "(", lhs, ", ", $2, ")"]
3502
3742
  );
3503
3743
  if (omitLhs) {
3504
- replaceNode(exp, $2);
3744
+ return $2;
3505
3745
  }
3506
3746
  }
3507
3747
  let wrapped = false;
@@ -3546,7 +3786,7 @@ function processAssignments(statements) {
3546
3786
  }
3547
3787
  exp.children = [$1];
3548
3788
  exp.names = [];
3549
- return;
3789
+ return exp;
3550
3790
  }
3551
3791
  } else if (lhs.type === "ObjectBindingPattern" || lhs.type === "ArrayBindingPattern") {
3552
3792
  processBindingPatternLHS(lhs, tail);
@@ -3558,11 +3798,19 @@ function processAssignments(statements) {
3558
3798
  const index = exp.children.indexOf($2);
3559
3799
  if (index < 0)
3560
3800
  throw new Error("Assertion error: exp not in AssignmentExpression");
3561
- return exp.children.splice(index + 1, 0, ...tail);
3801
+ exp.children.splice(index + 1, 0, ...tail);
3802
+ if (block) {
3803
+ block.parent = exp.parent;
3804
+ block.expressions.push(["", exp]);
3805
+ exp.parent = block;
3806
+ return block;
3807
+ }
3808
+ return exp;
3562
3809
  });
3563
3810
  }
3564
3811
  function attachPostfixStatementAsExpression(exp, post) {
3565
- switch (post[1].type) {
3812
+ const postfixStatement = post[1];
3813
+ switch (postfixStatement.type) {
3566
3814
  case "ForStatement":
3567
3815
  case "IterationStatement":
3568
3816
  case "DoStatement": {
@@ -3575,9 +3823,9 @@ function attachPostfixStatementAsExpression(exp, post) {
3575
3823
  };
3576
3824
  }
3577
3825
  case "IfStatement":
3578
- return expressionizeIfClause(post[1], exp);
3826
+ return expressionizeIfStatement({ ...postfixStatement, then: exp });
3579
3827
  default:
3580
- (() => {
3828
+ return (() => {
3581
3829
  throw new Error("Unknown postfix statement");
3582
3830
  })();
3583
3831
  }
@@ -3616,6 +3864,42 @@ function processTypes(node) {
3616
3864
  }
3617
3865
  });
3618
3866
  }
3867
+ function processStatementExpressions(statements) {
3868
+ gatherRecursiveAll(statements, ($) => $.type === "StatementExpression").forEach((_exp) => {
3869
+ const exp = _exp;
3870
+ const { statement } = exp;
3871
+ let ws;
3872
+ if (!(exp.children[0] === exp.statement)) {
3873
+ ws = exp.children[0];
3874
+ }
3875
+ let ref5;
3876
+ switch (statement.type) {
3877
+ case "IfStatement": {
3878
+ if (ref5 = expressionizeIfStatement(statement)) {
3879
+ const expression = ref5;
3880
+ exp.statement = expression;
3881
+ exp.children = [exp.statement];
3882
+ } else {
3883
+ exp.children = wrapIIFE([["", statement]]);
3884
+ }
3885
+ ;
3886
+ break;
3887
+ }
3888
+ case "IterationExpression": {
3889
+ ;
3890
+ break;
3891
+ }
3892
+ default: {
3893
+ exp.children = wrapIIFE([["", statement]]);
3894
+ }
3895
+ }
3896
+ if (ws) {
3897
+ return exp.children.unshift(ws);
3898
+ }
3899
+ ;
3900
+ return;
3901
+ });
3902
+ }
3619
3903
  function processProgram(root, config, m, ReservedWord) {
3620
3904
  assert.equal(m.forbidBracedApplication.length, 1, "forbidBracedApplication");
3621
3905
  assert.equal(m.forbidClassImplicitCall.length, 1, "forbidClassImplicitCall");
@@ -3626,11 +3910,12 @@ function processProgram(root, config, m, ReservedWord) {
3626
3910
  addParentPointers(root);
3627
3911
  const { expressions: statements } = root;
3628
3912
  processTypes(statements);
3629
- processDeclarationConditions(statements);
3913
+ processDeclarationConditions(statements, m.getRef);
3630
3914
  processPipelineExpressions(statements);
3631
3915
  processDeclarations(statements);
3632
3916
  processAssignments(statements);
3633
- processPatternMatching(statements, ReservedWord);
3917
+ processStatementExpressions(statements);
3918
+ processPatternMatching(statements, ReservedWord, m.getRef);
3634
3919
  gatherRecursiveAll(statements, (n) => n.type === "IterationExpression").forEach((e) => expressionizeIteration(e));
3635
3920
  hoistRefDecs(statements);
3636
3921
  processFunctions(statements, config);
@@ -3734,9 +4019,9 @@ function replaceNodes(root, predicate, replacer) {
3734
4019
  return root;
3735
4020
  }
3736
4021
  }
3737
- for (let i3 = 0, len3 = array.length; i3 < len3; i3++) {
3738
- const i = i3;
3739
- const node = array[i3];
4022
+ for (let i4 = 0, len3 = array.length; i4 < len3; i4++) {
4023
+ const i = i4;
4024
+ const node = array[i4];
3740
4025
  if (!(node != null)) {
3741
4026
  return;
3742
4027
  }
@@ -3748,6 +4033,34 @@ function replaceNodes(root, predicate, replacer) {
3748
4033
  }
3749
4034
  return root;
3750
4035
  }
4036
+ function replaceNodesRecursive(root, predicate, replacer) {
4037
+ if (!(root != null)) {
4038
+ return root;
4039
+ }
4040
+ const array = Array.isArray(root) ? root : root.children;
4041
+ if (!array) {
4042
+ if (predicate(root)) {
4043
+ return replacer(root, root);
4044
+ } else {
4045
+ return root;
4046
+ }
4047
+ }
4048
+ for (let i5 = 0, len4 = array.length; i5 < len4; i5++) {
4049
+ const i = i5;
4050
+ const node = array[i5];
4051
+ if (!(node != null)) {
4052
+ continue;
4053
+ }
4054
+ if (predicate(node)) {
4055
+ const ret = replacer(node, root);
4056
+ replaceNodesRecursive(ret, predicate, replacer);
4057
+ array[i] = ret;
4058
+ } else {
4059
+ replaceNodesRecursive(node, predicate, replacer);
4060
+ }
4061
+ }
4062
+ return root;
4063
+ }
3751
4064
  function typeOfJSX(node, config, getRef) {
3752
4065
  switch (node.type) {
3753
4066
  case "JSXElement":
@@ -3812,13 +4125,14 @@ function typeOfJSXFragment(node, config, getRef) {
3812
4125
  ;
3813
4126
  return;
3814
4127
  }
3815
- var xor, assert;
4128
+ var xor;
3816
4129
  var init_lib = __esm({
3817
4130
  "source/parser/lib.civet"() {
3818
4131
  "use strict";
3819
4132
  init_traversal();
3820
4133
  init_util();
3821
4134
  init_block();
4135
+ init_declaration();
3822
4136
  init_pipe();
3823
4137
  init_for();
3824
4138
  init_function();
@@ -3829,19 +4143,12 @@ var init_lib = __esm({
3829
4143
  init_auto_dec();
3830
4144
  init_string();
3831
4145
  xor = (a, b) => a ? !b && a : b;
3832
- assert = {
3833
- equal(a, b, msg) {
3834
- if (a !== b) {
3835
- throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
3836
- }
3837
- }
3838
- };
3839
4146
  }
3840
4147
  });
3841
4148
 
3842
- // node_modules/@danielx/hera/dist/machine.js
4149
+ // ../Hera/dist/machine.js
3843
4150
  var require_machine = __commonJS({
3844
- "node_modules/@danielx/hera/dist/machine.js"(exports2, module2) {
4151
+ "../Hera/dist/machine.js"(exports2, module2) {
3845
4152
  "use strict";
3846
4153
  var __defProp2 = Object.defineProperty;
3847
4154
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -4312,8 +4619,6 @@ var require_parser = __commonJS({
4312
4619
  $TV,
4313
4620
  $Y,
4314
4621
  Parser,
4315
- ParserContext,
4316
- ParserOptions,
4317
4622
  Validator
4318
4623
  } = require_machine();
4319
4624
  var grammar = {
@@ -4330,7 +4635,7 @@ var require_parser = __commonJS({
4330
4635
  NestedNonAssignmentExtendedExpression,
4331
4636
  ExpressionizedStatementWithTrailingCallExpressions,
4332
4637
  ExpressionizedStatement,
4333
- _ExpressionizedStatement,
4638
+ StatementExpression,
4334
4639
  CommaExpression,
4335
4640
  Arguments,
4336
4641
  ImplicitArguments,
@@ -4592,14 +4897,6 @@ var require_parser = __commonJS({
4592
4897
  ElseClause,
4593
4898
  IfClause,
4594
4899
  UnlessClause,
4595
- IfExpression,
4596
- UnlessExpression,
4597
- ElseExpressionClause,
4598
- ExpressionBlock,
4599
- ElseExpressionBlock,
4600
- NestedBlockExpressions,
4601
- NestedBlockExpression,
4602
- BlockExpressionPart,
4603
4900
  IterationStatement,
4604
4901
  _IterationStatement,
4605
4902
  IterationExpression,
@@ -4623,7 +4920,6 @@ var require_parser = __commonJS({
4623
4920
  ForBinding,
4624
4921
  SwitchStatement,
4625
4922
  EmptyCondition,
4626
- SwitchExpression,
4627
4923
  CaseBlock,
4628
4924
  NestedCaseClauses,
4629
4925
  NestedCaseClause,
@@ -4635,7 +4931,6 @@ var require_parser = __commonJS({
4635
4931
  ImpliedColon,
4636
4932
  IgnoreColon,
4637
4933
  TryStatement,
4638
- TryExpression,
4639
4934
  CatchClause,
4640
4935
  CatchBind,
4641
4936
  FinallyClause,
@@ -4676,8 +4971,6 @@ var require_parser = __commonJS({
4676
4971
  Break,
4677
4972
  Continue,
4678
4973
  Debugger,
4679
- DebuggerExpression,
4680
- ThrowExpression,
4681
4974
  MaybeNestedExpression,
4682
4975
  ImportDeclaration,
4683
4976
  ImpliedImport,
@@ -5507,22 +5800,26 @@ var require_parser = __commonJS({
5507
5800
  function ExpressionizedStatementWithTrailingCallExpressions(ctx, state) {
5508
5801
  return $EVENT(ctx, state, "ExpressionizedStatementWithTrailingCallExpressions", ExpressionizedStatementWithTrailingCallExpressions$0);
5509
5802
  }
5510
- var ExpressionizedStatement$0 = $T($S($EXPECT($R0, "ExpressionizedStatement /(?=async|debugger|if|unless|do|for|loop|until|while|switch|throw|try)/"), _ExpressionizedStatement), function(value) {
5511
- return value[1];
5803
+ var ExpressionizedStatement$0 = $TS($S($EXPECT($R0, "ExpressionizedStatement /(?=async|debugger|if|unless|do|for|loop|until|while|switch|throw|try)/"), StatementExpression), function($skip, $loc, $0, $1, $2) {
5804
+ var statement = $2;
5805
+ return {
5806
+ type: "StatementExpression",
5807
+ statement,
5808
+ children: [statement]
5809
+ };
5512
5810
  });
5513
5811
  function ExpressionizedStatement(ctx, state) {
5514
5812
  return $EVENT(ctx, state, "ExpressionizedStatement", ExpressionizedStatement$0);
5515
5813
  }
5516
- var _ExpressionizedStatement$0 = DebuggerExpression;
5517
- var _ExpressionizedStatement$1 = IfExpression;
5518
- var _ExpressionizedStatement$2 = UnlessExpression;
5519
- var _ExpressionizedStatement$3 = IterationExpression;
5520
- var _ExpressionizedStatement$4 = SwitchExpression;
5521
- var _ExpressionizedStatement$5 = ThrowExpression;
5522
- var _ExpressionizedStatement$6 = TryExpression;
5523
- var _ExpressionizedStatement$$ = [_ExpressionizedStatement$0, _ExpressionizedStatement$1, _ExpressionizedStatement$2, _ExpressionizedStatement$3, _ExpressionizedStatement$4, _ExpressionizedStatement$5, _ExpressionizedStatement$6];
5524
- function _ExpressionizedStatement(ctx, state) {
5525
- return $EVENT_C(ctx, state, "_ExpressionizedStatement", _ExpressionizedStatement$$);
5814
+ var StatementExpression$0 = DebuggerStatement;
5815
+ var StatementExpression$1 = IfStatement;
5816
+ var StatementExpression$2 = IterationExpression;
5817
+ var StatementExpression$3 = SwitchStatement;
5818
+ var StatementExpression$4 = ThrowStatement;
5819
+ var StatementExpression$5 = TryStatement;
5820
+ var StatementExpression$$ = [StatementExpression$0, StatementExpression$1, StatementExpression$2, StatementExpression$3, StatementExpression$4, StatementExpression$5];
5821
+ function StatementExpression(ctx, state) {
5822
+ return $EVENT_C(ctx, state, "StatementExpression", StatementExpression$$);
5526
5823
  }
5527
5824
  var CommaExpression$0 = $TS($S(AssignmentExpression, $Q($S(CommaDelimiter, AssignmentExpression))), function($skip, $loc, $0, $1, $2) {
5528
5825
  if ($2.length == 0)
@@ -5548,14 +5845,8 @@ var require_parser = __commonJS({
5548
5845
  var ws = $3;
5549
5846
  var args = $4;
5550
5847
  var close = $5;
5551
- if (args.length === 1) {
5552
- let arg0 = args[0];
5553
- if (Array.isArray(arg0))
5554
- arg0 = arg0[1];
5555
- if (arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block)) {
5556
- return $skip;
5557
- }
5558
- }
5848
+ if (skipImplicitArguments(args))
5849
+ return $skip;
5559
5850
  return {
5560
5851
  type: "Call",
5561
5852
  args,
@@ -6113,8 +6404,12 @@ var require_parser = __commonJS({
6113
6404
  function PipelineHeadItem(ctx, state) {
6114
6405
  return $EVENT_C(ctx, state, "PipelineHeadItem", PipelineHeadItem$$);
6115
6406
  }
6116
- var PipelineTailItem$0 = Await;
6117
- var PipelineTailItem$1 = Yield;
6407
+ var PipelineTailItem$0 = $T($S(AwaitOp, $N(AccessStart)), function(value) {
6408
+ return value[0];
6409
+ });
6410
+ var PipelineTailItem$1 = $T($S(Yield, $N(AccessStart)), function(value) {
6411
+ return value[0];
6412
+ });
6118
6413
  var PipelineTailItem$2 = $T($S(Return, $N(AccessStart)), function(value) {
6119
6414
  return value[0];
6120
6415
  });
@@ -6150,6 +6445,9 @@ var require_parser = __commonJS({
6150
6445
  return $skip;
6151
6446
  const [exp, ws, close] = $3;
6152
6447
  switch (exp.type) {
6448
+ case "StatementExpression":
6449
+ if (exp.statement.type !== "IterationExpression")
6450
+ break;
6153
6451
  case "IterationExpression":
6154
6452
  return exp;
6155
6453
  case "ParenthesizedExpression":
@@ -7677,7 +7975,7 @@ var require_parser = __commonJS({
7677
7975
  if (prefix.length) {
7678
7976
  body = {
7679
7977
  type: "UnaryExpression",
7680
- children: [prefix, body, void 0]
7978
+ children: [processUnaryExpression(prefix, body, void 0)]
7681
7979
  };
7682
7980
  }
7683
7981
  const parameters = {
@@ -9194,8 +9492,9 @@ var require_parser = __commonJS({
9194
9492
  return $EVENT_C(ctx, state, "MethodSignature", MethodSignature$$);
9195
9493
  }
9196
9494
  var ClassElementName$0 = PropertyName;
9197
- var ClassElementName$1 = PrivateIdentifier;
9198
- var ClassElementName$$ = [ClassElementName$0, ClassElementName$1];
9495
+ var ClassElementName$1 = LengthShorthand;
9496
+ var ClassElementName$2 = PrivateIdentifier;
9497
+ var ClassElementName$$ = [ClassElementName$0, ClassElementName$1, ClassElementName$2];
9199
9498
  function ClassElementName(ctx, state) {
9200
9499
  return $EVENT_C(ctx, state, "ClassElementName", ClassElementName$$);
9201
9500
  }
@@ -9634,7 +9933,13 @@ var require_parser = __commonJS({
9634
9933
  return { $loc, token: $0 };
9635
9934
  });
9636
9935
  var UnaryOp$1 = AwaitOp;
9637
- var UnaryOp$2 = $S($C(Delete, Void, Typeof), $N($R$0($EXPECT($R21, "UnaryOp /[:.]/"))), $E(_));
9936
+ var UnaryOp$2 = $TS($S($C(Delete, Void, Typeof), $N($EXPECT($R21, "UnaryOp /[:.]/")), $E(_)), function($skip, $loc, $0, $1, $2, $3) {
9937
+ var op = $1;
9938
+ var ws = $3;
9939
+ if (!ws)
9940
+ return [op, [" "]];
9941
+ return [op, ws];
9942
+ });
9638
9943
  var UnaryOp$3 = $T($S(Not, $N($EXPECT($R21, "UnaryOp /[:.]/")), $E($EXPECT($L16, 'UnaryOp " "')), $E(_)), function(value) {
9639
9944
  return [value[0], value[3]];
9640
9945
  });
@@ -9642,18 +9947,15 @@ var require_parser = __commonJS({
9642
9947
  function UnaryOp(ctx, state) {
9643
9948
  return $EVENT_C(ctx, state, "UnaryOp", UnaryOp$$);
9644
9949
  }
9645
- var AwaitOp$0 = $TS($S(Await, $E($S(Dot, IdentifierName)), $C($Y(OpenParen), _, $Y(EOS))), function($skip, $loc, $0, $1, $2, $3) {
9950
+ var AwaitOp$0 = $TS($S(Await, $E($S(Dot, IdentifierName)), $E(_)), function($skip, $loc, $0, $1, $2, $3) {
9646
9951
  var a = $1;
9647
9952
  var op = $2;
9648
9953
  var ws = $3;
9649
- if (op) {
9650
- return {
9651
- ...a,
9652
- op,
9653
- children: [a, ...ws || []]
9654
- };
9655
- }
9656
- return [a, ...ws || []];
9954
+ return {
9955
+ ...a,
9956
+ op,
9957
+ children: [a, ...ws || [" "]]
9958
+ };
9657
9959
  });
9658
9960
  function AwaitOp(ctx, state) {
9659
9961
  return $EVENT(ctx, state, "AwaitOp", AwaitOp$0);
@@ -9866,120 +10168,6 @@ var require_parser = __commonJS({
9866
10168
  function UnlessClause(ctx, state) {
9867
10169
  return $EVENT(ctx, state, "UnlessClause", UnlessClause$0);
9868
10170
  }
9869
- var IfExpression$0 = $TS($S(IfClause, ExpressionBlock, $E(ElseExpressionClause)), function($skip, $loc, $0, $1, $2, $3) {
9870
- var clause = $1;
9871
- var b = $2;
9872
- var e = $3;
9873
- return expressionizeIfClause(clause, b, e);
9874
- });
9875
- function IfExpression(ctx, state) {
9876
- return $EVENT(ctx, state, "IfExpression", IfExpression$0);
9877
- }
9878
- var UnlessExpression$0 = $TS($S(UnlessClause, ExpressionBlock, $E(ElseExpressionClause)), function($skip, $loc, $0, $1, $2, $3) {
9879
- var clause = $1;
9880
- var b = $2;
9881
- var e = $3;
9882
- return expressionizeIfClause(clause, b, e);
9883
- });
9884
- function UnlessExpression(ctx, state) {
9885
- return $EVENT(ctx, state, "UnlessExpression", UnlessExpression$0);
9886
- }
9887
- var ElseExpressionClause$0 = $TS($S($C($S(Nested, Else), $S($E(_), Else)), ElseExpressionBlock), function($skip, $loc, $0, $1, $2) {
9888
- return [...$1, $2];
9889
- });
9890
- function ElseExpressionClause(ctx, state) {
9891
- return $EVENT(ctx, state, "ElseExpressionClause", ElseExpressionClause$0);
9892
- }
9893
- var ExpressionBlock$0 = $TS($S(InsertOpenParen, NestedBlockExpressions, InsertNewline, InsertIndent, InsertCloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
9894
- var exps = $2;
9895
- exps = exps.flat();
9896
- if (exps.length === 1) {
9897
- let [ws, exp] = exps[0];
9898
- switch (exp.type) {
9899
- case "Identifier":
9900
- case "Literal":
9901
- return [ws, exp];
9902
- }
9903
- }
9904
- exps = exps.map((e, i) => {
9905
- if (i === exps.length - 1) {
9906
- return e.slice(0, -1);
9907
- }
9908
- return e;
9909
- });
9910
- return {
9911
- type: "BlockExpressions",
9912
- expressions: exps,
9913
- children: [$1, exps, $3, $4, $5]
9914
- };
9915
- });
9916
- var ExpressionBlock$1 = $S(Then, ExtendedExpression);
9917
- var ExpressionBlock$$ = [ExpressionBlock$0, ExpressionBlock$1];
9918
- function ExpressionBlock(ctx, state) {
9919
- return $EVENT_C(ctx, state, "ExpressionBlock", ExpressionBlock$$);
9920
- }
9921
- var ElseExpressionBlock$0 = $TS($S(InsertOpenParen, NestedBlockExpressions, InsertNewline, InsertIndent, InsertCloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
9922
- var exps = $2;
9923
- exps = exps.flat();
9924
- if (exps.length === 1) {
9925
- let [ws, exp] = exps[0];
9926
- switch (exp.type) {
9927
- case "Identifier":
9928
- case "Literal":
9929
- return [ws, exp];
9930
- }
9931
- }
9932
- exps = exps.map((e, i) => {
9933
- if (i === exps.length - 1) {
9934
- return e.slice(0, -1);
9935
- }
9936
- return e;
9937
- });
9938
- return {
9939
- type: "BlockExpressions",
9940
- expressions: exps,
9941
- children: [$1, exps, $3, $4, $5]
9942
- };
9943
- });
9944
- var ElseExpressionBlock$1 = $T($S($N(EOS), ExpressionWithObjectApplicationForbidden), function(value) {
9945
- return value[1];
9946
- });
9947
- var ElseExpressionBlock$$ = [ElseExpressionBlock$0, ElseExpressionBlock$1];
9948
- function ElseExpressionBlock(ctx, state) {
9949
- return $EVENT_C(ctx, state, "ElseExpressionBlock", ElseExpressionBlock$$);
9950
- }
9951
- var NestedBlockExpressions$0 = $TS($S(PushIndent, $Q(NestedBlockExpression), PopIndent), function($skip, $loc, $0, $1, $2, $3) {
9952
- var exps = $2;
9953
- if (!exps.length)
9954
- return $skip;
9955
- return exps;
9956
- });
9957
- function NestedBlockExpressions(ctx, state) {
9958
- return $EVENT(ctx, state, "NestedBlockExpressions", NestedBlockExpressions$0);
9959
- }
9960
- var NestedBlockExpression$0 = $TS($S(Nested, $P(BlockExpressionPart)), function($skip, $loc, $0, $1, $2) {
9961
- var nested = $1;
9962
- var expressions = $2;
9963
- return [
9964
- [nested, ...expressions[0]],
9965
- ...expressions.slice(1).map((s) => ["", ...s])
9966
- ];
9967
- });
9968
- function NestedBlockExpression(ctx, state) {
9969
- return $EVENT(ctx, state, "NestedBlockExpression", NestedBlockExpression$0);
9970
- }
9971
- var BlockExpressionPart$0 = $TS($S($N(EOS), $E(_), PostfixedExpression, ExpressionDelimiter), function($skip, $loc, $0, $1, $2, $3, $4) {
9972
- var ws = $2;
9973
- var exp = $3;
9974
- var delimiter = $4;
9975
- if (ws) {
9976
- exp = { ...exp, children: [ws, ...exp.children] };
9977
- }
9978
- return [exp, delimiter];
9979
- });
9980
- function BlockExpressionPart(ctx, state) {
9981
- return $EVENT(ctx, state, "BlockExpressionPart", BlockExpressionPart$0);
9982
- }
9983
10171
  var IterationStatement$0 = $T($S($EXPECT($R23, "IterationStatement /(?=loop|do|for|until|while)/"), _IterationStatement), function(value) {
9984
10172
  return value[1];
9985
10173
  });
@@ -10396,18 +10584,6 @@ var require_parser = __commonJS({
10396
10584
  function EmptyCondition(ctx, state) {
10397
10585
  return $EVENT(ctx, state, "EmptyCondition", EmptyCondition$0);
10398
10586
  }
10399
- var SwitchExpression$0 = $TV(SwitchStatement, function($skip, $loc, $0, $1) {
10400
- var s = $0;
10401
- return {
10402
- type: "SwitchExpression",
10403
- // wrap with IIFE
10404
- children: wrapIIFE([["", s]]),
10405
- statement: s
10406
- };
10407
- });
10408
- function SwitchExpression(ctx, state) {
10409
- return $EVENT(ctx, state, "SwitchExpression", SwitchExpression$0);
10410
- }
10411
10587
  var CaseBlock$0 = $TS($S($E($C(Nested, _)), OpenBrace, NestedCaseClauses, __, CloseBrace), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
10412
10588
  var clauses = $3;
10413
10589
  return {
@@ -10589,17 +10765,6 @@ var require_parser = __commonJS({
10589
10765
  function TryStatement(ctx, state) {
10590
10766
  return $EVENT(ctx, state, "TryStatement", TryStatement$0);
10591
10767
  }
10592
- var TryExpression$0 = $TV(TryStatement, function($skip, $loc, $0, $1) {
10593
- var t = $0;
10594
- return {
10595
- type: "TryExpression",
10596
- blocks: t.blocks,
10597
- children: wrapIIFE([["", t]])
10598
- };
10599
- });
10600
- function TryExpression(ctx, state) {
10601
- return $EVENT(ctx, state, "TryExpression", TryExpression$0);
10602
- }
10603
10768
  var CatchClause$0 = $TS($S($C(Nested, _), Catch, $E(CatchBind), $C(BracedThenClause, BracedOrEmptyBlock)), function($skip, $loc, $0, $1, $2, $3, $4) {
10604
10769
  var block = $4;
10605
10770
  return {
@@ -10934,26 +11099,6 @@ var require_parser = __commonJS({
10934
11099
  function Debugger(ctx, state) {
10935
11100
  return $EVENT(ctx, state, "Debugger", Debugger$0);
10936
11101
  }
10937
- var DebuggerExpression$0 = $TV(DebuggerStatement, function($skip, $loc, $0, $1) {
10938
- var s = $0;
10939
- return {
10940
- type: "DebuggerExpression",
10941
- children: wrapIIFE([["", s]])
10942
- };
10943
- });
10944
- function DebuggerExpression(ctx, state) {
10945
- return $EVENT(ctx, state, "DebuggerExpression", DebuggerExpression$0);
10946
- }
10947
- var ThrowExpression$0 = $TV(ThrowStatement, function($skip, $loc, $0, $1) {
10948
- var s = $0;
10949
- return {
10950
- type: "ThrowExpression",
10951
- children: wrapIIFE([["", s]])
10952
- };
10953
- });
10954
- function ThrowExpression(ctx, state) {
10955
- return $EVENT(ctx, state, "ThrowExpression", ThrowExpression$0);
10956
- }
10957
11102
  var MaybeNestedExpression$0 = $TS($S($N(EOS), ExtendedExpression), function($skip, $loc, $0, $1, $2) {
10958
11103
  return $2;
10959
11104
  });
@@ -10975,27 +11120,26 @@ var require_parser = __commonJS({
10975
11120
  children: [imp, $0.slice(1)]
10976
11121
  };
10977
11122
  });
10978
- var ImportDeclaration$1 = $T($S(Import, __, TypeKeyword, __, ImportClause, __, FromClause, $E(ImportAssertion)), function(value) {
11123
+ var ImportDeclaration$1 = $T($S(Import, __, TypeKeyword, __, ImportClause, __, FromClause), function(value) {
10979
11124
  return { "type": "ImportDeclaration", "ts": true, "children": value };
10980
11125
  });
10981
- var ImportDeclaration$2 = $T($S(Import, __, ImportClause, __, FromClause, $E(ImportAssertion)), function(value) {
11126
+ var ImportDeclaration$2 = $T($S(Import, __, ImportClause, __, FromClause), function(value) {
10982
11127
  return { "type": "ImportDeclaration", "children": value };
10983
11128
  });
10984
- var ImportDeclaration$3 = $T($S(Import, __, ModuleSpecifier, $E(ImportAssertion)), function(value) {
11129
+ var ImportDeclaration$3 = $T($S(Import, __, ModuleSpecifier), function(value) {
10985
11130
  return { "type": "ImportDeclaration", "children": value };
10986
11131
  });
10987
- var ImportDeclaration$4 = $TS($S(ImpliedImport, $E($S(TypeKeyword, __)), ImportClause, __, FromClause, $E(ImportAssertion)), function($skip, $loc, $0, $1, $2, $3, $4, $5, $6) {
11132
+ var ImportDeclaration$4 = $TS($S(ImpliedImport, $E($S(TypeKeyword, __)), ImportClause, __, FromClause), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
10988
11133
  var i = $1;
10989
11134
  var t = $2;
10990
11135
  var c = $3;
10991
11136
  var w = $4;
10992
11137
  var f = $5;
10993
- var a = $6;
10994
11138
  i.$loc = {
10995
11139
  pos: f[0].$loc.pos - 1,
10996
11140
  length: f[0].$loc.length + 1
10997
11141
  };
10998
- const children = [i, t, c, w, f, a];
11142
+ const children = [i, t, c, w, f];
10999
11143
  if (!t)
11000
11144
  return children;
11001
11145
  return { type: "ImportDeclaration", ts: true, children };
@@ -11154,7 +11298,8 @@ var require_parser = __commonJS({
11154
11298
  function ModuleExportName(ctx, state) {
11155
11299
  return $EVENT_C(ctx, state, "ModuleExportName", ModuleExportName$$);
11156
11300
  }
11157
- var ModuleSpecifier$0 = $TS($S(UnprocessedModuleSpecifier), function($skip, $loc, $0, $1) {
11301
+ var ModuleSpecifier$0 = $TS($S(UnprocessedModuleSpecifier, $E(ImportAssertion)), function($skip, $loc, $0, $1, $2) {
11302
+ var a = $2;
11158
11303
  let { token } = $1;
11159
11304
  if (module2.config.rewriteTsImports) {
11160
11305
  token = token.replace(/\.([mc])?ts(['"])$/, ".$1js$2");
@@ -11165,6 +11310,8 @@ var require_parser = __commonJS({
11165
11310
  `${module2.config.rewriteCivetImports.replace(/\$/g, "$$")}$1`
11166
11311
  );
11167
11312
  }
11313
+ if (a)
11314
+ return [{ ...$1, token }, a];
11168
11315
  return { ...$1, token };
11169
11316
  });
11170
11317
  function ModuleSpecifier(ctx, state) {
@@ -11529,7 +11676,11 @@ var require_parser = __commonJS({
11529
11676
  function TripleSingleStringCharacters(ctx, state) {
11530
11677
  return $EVENT(ctx, state, "TripleSingleStringCharacters", TripleSingleStringCharacters$0);
11531
11678
  }
11532
- var CoffeeStringSubstitution$0 = $S(CoffeeSubstitutionStart, PostfixedExpression, __, CloseBrace);
11679
+ var CoffeeStringSubstitution$0 = $TS($S(CoffeeSubstitutionStart, AllowAll, $E($S(PostfixedExpression, __, CloseBrace)), RestoreAll), function($skip, $loc, $0, $1, $2, $3, $4) {
11680
+ if (!$3)
11681
+ return $skip;
11682
+ return [$1, ...$3];
11683
+ });
11533
11684
  function CoffeeStringSubstitution(ctx, state) {
11534
11685
  return $EVENT(ctx, state, "CoffeeStringSubstitution", CoffeeStringSubstitution$0);
11535
11686
  }
@@ -11706,7 +11857,11 @@ var require_parser = __commonJS({
11706
11857
  function _TemplateLiteral(ctx, state) {
11707
11858
  return $EVENT_C(ctx, state, "_TemplateLiteral", _TemplateLiteral$$);
11708
11859
  }
11709
- var TemplateSubstitution$0 = $S(SubstitutionStart, PostfixedExpression, __, CloseBrace);
11860
+ var TemplateSubstitution$0 = $TS($S(SubstitutionStart, AllowAll, $E($S(PostfixedExpression, __, CloseBrace)), RestoreAll), function($skip, $loc, $0, $1, $2, $3, $4) {
11861
+ if (!$3)
11862
+ return $skip;
11863
+ return [$1, ...$3];
11864
+ });
11710
11865
  function TemplateSubstitution(ctx, state) {
11711
11866
  return $EVENT(ctx, state, "TemplateSubstitution", TemplateSubstitution$0);
11712
11867
  }
@@ -14071,7 +14226,9 @@ var require_parser = __commonJS({
14071
14226
  function TripleSlashDirective(ctx, state) {
14072
14227
  return $EVENT(ctx, state, "TripleSlashDirective", TripleSlashDirective$0);
14073
14228
  }
14074
- var DirectivePrologue$0 = PrologueString;
14229
+ var DirectivePrologue$0 = $T($S(PrologueString, $N($S(__, $C(AccessStart, Pipe)))), function(value) {
14230
+ return value[0];
14231
+ });
14075
14232
  function DirectivePrologue(ctx, state) {
14076
14233
  return $EVENT(ctx, state, "DirectivePrologue", DirectivePrologue$0);
14077
14234
  }
@@ -14455,6 +14612,19 @@ var require_parser = __commonJS({
14455
14612
  };
14456
14613
  module2.prelude.push(["", [preludeVar, isRef, typeSuffix, " = Object.is", asAny, ";\n"]]);
14457
14614
  },
14615
+ /**
14616
+ * Array length check with type guard.
14617
+ * From tlgreg https://discord.com/channels/933472021310996512/1012166187196629113/1157386582546976873
14618
+ */
14619
+ len(lenRef) {
14620
+ module2.prelude.push(["", [{
14621
+ ts: true,
14622
+ children: ["function ", lenRef, "<T extends readonly unknown[], N extends number>(arr: T, length: N): arr is T & { length: N } { return arr.length === length }"]
14623
+ }, {
14624
+ js: true,
14625
+ children: ["function ", lenRef, "(arr, length) { return arr.length === length }"]
14626
+ }], "\n"]);
14627
+ },
14458
14628
  modulo(moduloRef) {
14459
14629
  const typeSuffix = {
14460
14630
  ts: true,
@@ -14606,9 +14776,9 @@ var require_parser = __commonJS({
14606
14776
  }
14607
14777
  }
14608
14778
  });
14609
- if (typeof parse !== "undefined") {
14610
- Object.assign(module2.config, parse.config);
14611
- parse.config = module2.config;
14779
+ if (typeof parse2 !== "undefined") {
14780
+ Object.assign(module2.config, parse2.config);
14781
+ parse2.config = module2.config;
14612
14782
  } else {
14613
14783
  Object.assign(module2.config, exports2.parse.config);
14614
14784
  exports2.parse.config = module2.config;
@@ -14759,7 +14929,7 @@ var require_parser = __commonJS({
14759
14929
  };
14760
14930
  }();
14761
14931
  exports2.default = parser;
14762
- exports2.parse = parser.parse;
14932
+ var parse2 = exports2.parse = parser.parse;
14763
14933
  exports2.Program = Program;
14764
14934
  exports2.TopLevelStatements = TopLevelStatements;
14765
14935
  exports2.NestedTopLevelStatements = NestedTopLevelStatements;
@@ -14773,7 +14943,7 @@ var require_parser = __commonJS({
14773
14943
  exports2.NestedNonAssignmentExtendedExpression = NestedNonAssignmentExtendedExpression;
14774
14944
  exports2.ExpressionizedStatementWithTrailingCallExpressions = ExpressionizedStatementWithTrailingCallExpressions;
14775
14945
  exports2.ExpressionizedStatement = ExpressionizedStatement;
14776
- exports2._ExpressionizedStatement = _ExpressionizedStatement;
14946
+ exports2.StatementExpression = StatementExpression;
14777
14947
  exports2.CommaExpression = CommaExpression;
14778
14948
  exports2.Arguments = Arguments;
14779
14949
  exports2.ImplicitArguments = ImplicitArguments;
@@ -15035,14 +15205,6 @@ var require_parser = __commonJS({
15035
15205
  exports2.ElseClause = ElseClause;
15036
15206
  exports2.IfClause = IfClause;
15037
15207
  exports2.UnlessClause = UnlessClause;
15038
- exports2.IfExpression = IfExpression;
15039
- exports2.UnlessExpression = UnlessExpression;
15040
- exports2.ElseExpressionClause = ElseExpressionClause;
15041
- exports2.ExpressionBlock = ExpressionBlock;
15042
- exports2.ElseExpressionBlock = ElseExpressionBlock;
15043
- exports2.NestedBlockExpressions = NestedBlockExpressions;
15044
- exports2.NestedBlockExpression = NestedBlockExpression;
15045
- exports2.BlockExpressionPart = BlockExpressionPart;
15046
15208
  exports2.IterationStatement = IterationStatement;
15047
15209
  exports2._IterationStatement = _IterationStatement;
15048
15210
  exports2.IterationExpression = IterationExpression;
@@ -15066,7 +15228,6 @@ var require_parser = __commonJS({
15066
15228
  exports2.ForBinding = ForBinding;
15067
15229
  exports2.SwitchStatement = SwitchStatement;
15068
15230
  exports2.EmptyCondition = EmptyCondition;
15069
- exports2.SwitchExpression = SwitchExpression;
15070
15231
  exports2.CaseBlock = CaseBlock;
15071
15232
  exports2.NestedCaseClauses = NestedCaseClauses;
15072
15233
  exports2.NestedCaseClause = NestedCaseClause;
@@ -15078,7 +15239,6 @@ var require_parser = __commonJS({
15078
15239
  exports2.ImpliedColon = ImpliedColon;
15079
15240
  exports2.IgnoreColon = IgnoreColon;
15080
15241
  exports2.TryStatement = TryStatement;
15081
- exports2.TryExpression = TryExpression;
15082
15242
  exports2.CatchClause = CatchClause;
15083
15243
  exports2.CatchBind = CatchBind;
15084
15244
  exports2.FinallyClause = FinallyClause;
@@ -15119,8 +15279,6 @@ var require_parser = __commonJS({
15119
15279
  exports2.Break = Break;
15120
15280
  exports2.Continue = Continue;
15121
15281
  exports2.Debugger = Debugger;
15122
- exports2.DebuggerExpression = DebuggerExpression;
15123
- exports2.ThrowExpression = ThrowExpression;
15124
15282
  exports2.MaybeNestedExpression = MaybeNestedExpression;
15125
15283
  exports2.ImportDeclaration = ImportDeclaration;
15126
15284
  exports2.ImpliedImport = ImpliedImport;