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