@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/browser.js CHANGED
@@ -278,27 +278,25 @@ var Civet = (() => {
278
278
  return expression;
279
279
  }
280
280
  switch (expression.type) {
281
- case "Ref":
282
281
  case "AmpersandRef":
282
+ case "CallExpression":
283
283
  case "Identifier":
284
+ case "JSXElement":
285
+ case "JSXFragment":
284
286
  case "Literal":
285
- case "IterationExpression":
286
- case "CallExpression":
287
287
  case "MemberExpression":
288
288
  case "NewExpression":
289
289
  case "ParenthesizedExpression":
290
- case "IfExpression":
291
- case "DebuggerExpression":
292
- case "SwitchExpression":
293
- case "ThrowExpression":
294
- case "TryExpression":
290
+ case "Ref":
291
+ case "StatementExpression":
295
292
  return expression;
296
293
  }
297
294
  return makeNode({
298
295
  type: "ParenthesizedExpression",
299
296
  children: ["(", expression, ")"],
300
297
  expression,
301
- implicit: true
298
+ implicit: true,
299
+ parent: void 0
302
300
  });
303
301
  }
304
302
  function updateParentPointers(node, parent, depth = 1) {
@@ -413,7 +411,9 @@ var Civet = (() => {
413
411
  type: "BlockStatement",
414
412
  expressions,
415
413
  children: ["{", expressions, "}"],
416
- bare: false
414
+ bare: false,
415
+ root: false,
416
+ parent: void 0
417
417
  });
418
418
  const parameters = {
419
419
  type: "Parameters",
@@ -452,11 +452,18 @@ var Civet = (() => {
452
452
  children
453
453
  });
454
454
  }
455
- var typeNeedsNoParens;
455
+ var assert, typeNeedsNoParens;
456
456
  var init_util = __esm({
457
457
  "source/parser/util.civet"() {
458
458
  "use strict";
459
459
  init_traversal();
460
+ assert = {
461
+ equal(a, b, msg) {
462
+ if (a !== b) {
463
+ throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
464
+ }
465
+ }
466
+ };
460
467
  typeNeedsNoParens = /* @__PURE__ */ new Set([
461
468
  "IdentifierType",
462
469
  "ImportType",
@@ -616,6 +623,17 @@ var Civet = (() => {
616
623
  empty: true
617
624
  };
618
625
  }
626
+ function makeBlockFragment() {
627
+ const expressions = [];
628
+ return {
629
+ type: "BlockStatement",
630
+ children: expressions,
631
+ parent: void 0,
632
+ expressions,
633
+ bare: false,
634
+ root: false
635
+ };
636
+ }
619
637
  function replaceBlockExpression(node, child, replacement) {
620
638
  let found = false;
621
639
  const { expressions } = node;
@@ -747,816 +765,1092 @@ var Civet = (() => {
747
765
  }
748
766
  });
749
767
 
750
- // source/parser/pipe.civet
751
- function constructInvocation(fn, arg) {
752
- const fnArr = [fn.leadingComment, fn.expr, fn.trailingComment];
753
- let expr = fn.expr;
754
- while (expr.type === "ParenthesizedExpression") {
755
- expr = expr.expression;
756
- }
757
- if (expr.ampersandBlock) {
758
- const { ref, body } = expr;
759
- ref.type = "PipedExpression";
760
- ref.children = [makeLeftHandSideExpression(arg)];
761
- updateParentPointers(ref);
762
- return makeNode({
763
- type: "UnwrappedExpression",
764
- children: [skipIfOnlyWS(fn.leadingComment), body, skipIfOnlyWS(fn.trailingComment)]
765
- });
766
- }
767
- expr = fn.expr;
768
- const lhs = makeLeftHandSideExpression(expr);
769
- let comment = skipIfOnlyWS(fn.trailingComment);
770
- if (comment)
771
- lhs.children.splice(2, 0, comment);
772
- comment = skipIfOnlyWS(fn.leadingComment);
773
- if (comment)
774
- lhs.children.splice(1, 0, comment);
775
- switch (arg.type) {
776
- case "CommaExpression":
777
- arg = makeLeftHandSideExpression(arg);
778
- break;
768
+ // source/parser/binding.civet
769
+ function adjustAtBindings(statements, asThis = false) {
770
+ gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
771
+ const { ref } = binding;
772
+ if (asThis) {
773
+ const atBinding = binding.binding;
774
+ atBinding.children.pop();
775
+ atBinding.type = void 0;
776
+ binding.children.unshift(ref.id, ": this.", ref.base);
777
+ binding.type = "Property";
778
+ binding.ref = void 0;
779
+ return;
780
+ }
781
+ if (ref.names[0] !== ref.base) {
782
+ return binding.children.unshift(ref.base, ": ");
783
+ }
784
+ ;
785
+ return;
786
+ });
787
+ }
788
+ function adjustBindingElements(elements) {
789
+ const names = elements.flatMap((p) => p.names || []), { length } = elements;
790
+ let blockPrefix, restIndex = -1, restCount = 0;
791
+ elements.forEach(({ type }, i) => {
792
+ if (type === "BindingRestElement") {
793
+ if (restIndex < 0)
794
+ restIndex = i;
795
+ return restCount++;
796
+ }
797
+ ;
798
+ return;
799
+ });
800
+ if (restCount === 0) {
801
+ return {
802
+ children: elements,
803
+ names,
804
+ blockPrefix,
805
+ length
806
+ };
807
+ } else if (restCount === 1) {
808
+ const rest = elements[restIndex];
809
+ const after = elements.slice(restIndex + 1);
810
+ const restIdentifier = rest.binding.ref || rest.binding;
811
+ names.push(...rest.names || []);
812
+ let l = after.length;
813
+ if (l) {
814
+ if (arrayElementHasTrailingComma(after[l - 1]))
815
+ l++;
816
+ blockPrefix = {
817
+ type: "PostRestBindingElements",
818
+ children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
819
+ names: after.flatMap((p) => p.names)
820
+ };
821
+ }
822
+ return {
823
+ names,
824
+ children: [...elements.slice(0, restIndex), {
825
+ ...rest,
826
+ children: rest.children.slice(0, -1)
827
+ // remove trailing comma
828
+ }],
829
+ blockPrefix,
830
+ length
831
+ };
779
832
  }
833
+ const err = {
834
+ type: "Error",
835
+ children: ["Multiple rest elements in array pattern"]
836
+ };
780
837
  return {
781
- type: "CallExpression",
782
- children: [lhs, "(", arg, ")"]
838
+ names,
839
+ children: [...elements, err],
840
+ blockPrefix,
841
+ length
783
842
  };
784
843
  }
785
- function constructPipeStep(fn, arg, returning) {
786
- const children = [[fn.leadingComment, fn.expr, fn.trailingComment].map(skipIfOnlyWS), " ", arg];
787
- switch (fn.expr.token) {
788
- case "yield":
789
- case "await":
790
- if (returning) {
791
- return [
792
- children,
793
- returning
794
- ];
844
+ function gatherBindingCode(statements, opts) {
845
+ const thisAssignments = [];
846
+ const splices = [];
847
+ function insertRestSplices(s, p, thisAssignments2) {
848
+ gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
849
+ if (n.type === "AtBinding") {
850
+ const { ref } = n;
851
+ const { id } = ref;
852
+ thisAssignments2.push([`this.${id} = `, ref]);
853
+ return;
795
854
  }
796
- return [
797
- children,
798
- null
799
- ];
800
- case "return":
801
- return [{
802
- type: "ReturnStatement",
803
- children
804
- }, null];
855
+ if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
856
+ n.names.forEach((id) => ({
857
+ push: thisAssignments2.push({
858
+ type: "AssignmentExpression",
859
+ children: [`this.${id} = `, id],
860
+ js: true
861
+ })
862
+ }));
863
+ return;
864
+ }
865
+ const { blockPrefix } = n;
866
+ p.push(blockPrefix);
867
+ return insertRestSplices(blockPrefix, p, thisAssignments2);
868
+ });
805
869
  }
806
- if (returning) {
807
- return [
808
- constructInvocation(fn, arg),
809
- returning
810
- ];
870
+ insertRestSplices(statements, splices, thisAssignments);
871
+ return [splices, thisAssignments];
872
+ }
873
+ function arrayElementHasTrailingComma(elementNode) {
874
+ const lastChild = elementNode.children.at(-1);
875
+ return lastChild && lastChild[lastChild.length - 1]?.token === ",";
876
+ }
877
+ var init_binding = __esm({
878
+ "source/parser/binding.civet"() {
879
+ "use strict";
880
+ init_traversal();
881
+ init_util();
882
+ }
883
+ });
884
+
885
+ // source/parser/op.civet
886
+ function getPrecedence(op) {
887
+ if (typeof op === "string") {
888
+ return precedenceMap.get(op) ?? (() => {
889
+ throw new Error(`Unknown operator: ${op}`);
890
+ })();
891
+ } else if (typeof op.prec === "number") {
892
+ return op.prec;
893
+ } else {
894
+ return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
811
895
  }
812
- return [constructInvocation(fn, arg), null];
813
896
  }
814
- function processPipelineExpressions(statements) {
815
- gatherRecursiveAll(statements, (n) => n.type === "PipelineExpression").forEach((s) => {
816
- const [ws, , body] = s.children;
817
- let [, arg] = s.children;
818
- let i = 0, l = body.length;
819
- const children = [ws];
820
- let usingRef = null;
821
- for (i = 0; i < l; i++) {
822
- const step = body[i];
823
- const [leadingComment, pipe, trailingComment, expr] = step;
824
- const returns = pipe.token === "||>";
825
- let ref, result, returning = returns ? arg : null;
826
- if (pipe.token === "|>=") {
827
- let initRef;
828
- if (i === 0) {
829
- outer:
830
- switch (arg.type) {
831
- case "MemberExpression":
832
- if (arg.children.length <= 2)
833
- break;
834
- case "CallExpression":
835
- const access = arg.children.pop();
836
- switch (access.type) {
837
- case "PropertyAccess":
838
- case "SliceExpression":
839
- break;
840
- default:
841
- children.unshift({
842
- type: "Error",
843
- $loc: pipe.token.$loc,
844
- message: `Can't assign to ${access.type}`
845
- });
846
- arg.children.push(access);
847
- break outer;
848
- }
849
- usingRef = makeRef();
850
- initRef = {
851
- type: "AssignmentExpression",
852
- children: [usingRef, " = ", arg, ","]
853
- };
854
- arg = {
855
- type: "MemberExpression",
856
- children: [usingRef, access]
857
- };
858
- break;
897
+ function processBinaryOpExpression($0) {
898
+ return recurse(expandChainedComparisons($0));
899
+ function recurse(expandedOps) {
900
+ let i = 2;
901
+ while (i < expandedOps.length) {
902
+ let op = expandedOps[i];
903
+ if (op.special) {
904
+ let advanceLeft2 = function(allowEqual) {
905
+ while (start >= 4) {
906
+ const prevPrec = getPrecedence(expandedOps[start - 2]);
907
+ if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
908
+ return prevPrec === prec;
859
909
  }
860
- const lhs = [[
861
- [initRef],
862
- arg,
863
- [],
864
- { token: "=", children: [" = "] }
865
- ]];
866
- Object.assign(s, {
867
- type: "AssignmentExpression",
868
- children: [lhs, children],
869
- names: null,
870
- lhs,
871
- assigned: arg,
872
- exp: children
873
- });
874
- arg = clone(arg);
875
- if (arg.children[0].type === "Ref") {
876
- arg.children[0] = usingRef;
910
+ start -= 4;
911
+ }
912
+ return false;
913
+ }, advanceRight2 = function(allowEqual) {
914
+ while (end + 4 < expandedOps.length) {
915
+ const nextPrec = getPrecedence(expandedOps[end + 2]);
916
+ if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
917
+ return nextPrec === prec;
918
+ }
919
+ end += 4;
920
+ }
921
+ return false;
922
+ };
923
+ var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
924
+ let start = i - 2, end = i + 2;
925
+ const prec = getPrecedence(op);
926
+ let error;
927
+ switch (op.assoc) {
928
+ case "left":
929
+ case void 0: {
930
+ advanceLeft2(true);
931
+ advanceRight2(false);
932
+ break;
933
+ }
934
+ case "right": {
935
+ advanceLeft2(false);
936
+ advanceRight2(true);
937
+ break;
938
+ }
939
+ case "non": {
940
+ if (advanceLeft2(false) || advanceRight2(false)) {
941
+ error = {
942
+ type: "Error",
943
+ message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
944
+ };
945
+ }
946
+ ;
947
+ break;
948
+ }
949
+ case "arguments": {
950
+ if (advanceLeft2(false)) {
951
+ error = {
952
+ type: "Error",
953
+ message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
954
+ };
955
+ }
956
+ advanceRight2(true);
957
+ break;
958
+ }
959
+ default: {
960
+ throw new Error(`Unsupported associativity: ${op.assoc}`);
961
+ }
962
+ }
963
+ let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
964
+ let wsOp = expandedOps[i - 1];
965
+ let wsB = expandedOps[i + 1];
966
+ let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
967
+ if (op.assoc === "arguments") {
968
+ let i2 = 2;
969
+ while (i2 < b.length) {
970
+ if (prec === getPrecedence(b[i2])) {
971
+ if (!(b[i2].token === op.token)) {
972
+ error ??= {
973
+ type: "Error",
974
+ message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
975
+ };
976
+ }
977
+ b[i2] = ",";
978
+ }
979
+ i2 += 4;
877
980
  }
878
981
  } else {
879
- children.unshift({
880
- type: "Error",
881
- $loc: pipe.token.$loc,
882
- message: "Can't use |>= in the middle of a pipeline"
883
- });
982
+ b = recurse(b);
884
983
  }
885
- } else {
886
- if (i === 0)
887
- s.children = children;
888
- }
889
- if (returns && (ref = needsRef(arg))) {
890
- usingRef = usingRef || ref;
891
- arg = {
892
- type: "ParenthesizedExpression",
893
- children: ["(", {
894
- type: "AssignmentExpression",
895
- children: [usingRef, " = ", arg]
896
- }, ")"]
897
- };
898
- returning = usingRef;
899
- }
900
- ;
901
- [result, returning] = constructPipeStep(
902
- {
903
- leadingComment: skipIfOnlyWS(leadingComment),
904
- trailingComment: skipIfOnlyWS(trailingComment),
905
- expr
906
- },
907
- arg,
908
- returning
909
- );
910
- if (result.type === "ReturnStatement") {
911
- if (i < l - 1) {
912
- result.children.push({
913
- type: "Error",
914
- message: "Can't continue a pipeline after returning"
915
- });
984
+ if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
985
+ a = ["typeof ", makeLeftHandSideExpression(a)];
986
+ if (op.negated) {
987
+ op = { ...op, token: "!==", negated: false };
988
+ } else {
989
+ op = { ...op, token: "===" };
990
+ }
916
991
  }
917
- arg = result;
918
- if (children[children.length - 1] === ",") {
919
- children.pop();
920
- children.push(";");
992
+ if (op.asConst) {
993
+ a = makeAsConst(a);
994
+ b = makeAsConst(b);
921
995
  }
922
- break;
923
- }
924
- if (returning) {
925
- arg = returning;
926
- children.push(result, ",");
996
+ let children;
997
+ if (op.call) {
998
+ wsOp = insertTrimmingSpace(wsOp, "");
999
+ if (op.reversed) {
1000
+ wsB = insertTrimmingSpace(wsB, "");
1001
+ children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
1002
+ } else {
1003
+ children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
1004
+ }
1005
+ } else if (op.method) {
1006
+ wsOp = insertTrimmingSpace(wsOp, "");
1007
+ wsB = insertTrimmingSpace(wsB, "");
1008
+ if (op.reversed) {
1009
+ if (end !== i + 2)
1010
+ b = makeLeftHandSideExpression(b);
1011
+ b = dotNumericLiteral(b);
1012
+ children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
1013
+ } else {
1014
+ if (start !== i - 2 || a.type === "NumericLiteral") {
1015
+ a = makeLeftHandSideExpression(a);
1016
+ }
1017
+ a = dotNumericLiteral(a);
1018
+ children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
1019
+ }
1020
+ } else if (op.token) {
1021
+ children = [a, wsOp, op, wsB, b];
1022
+ if (op.negated)
1023
+ children = ["(", ...children, ")"];
1024
+ } else {
1025
+ throw new Error("Unknown operator: " + JSON.stringify(op));
1026
+ }
1027
+ if (op.negated)
1028
+ children.unshift("!");
1029
+ if (error != null) {
1030
+ children.push(error);
1031
+ }
1032
+ expandedOps.splice(start, end - start + 1, {
1033
+ children
1034
+ });
1035
+ i = start + 2;
927
1036
  } else {
928
- arg = result;
1037
+ i += 4;
929
1038
  }
930
1039
  }
931
- if (usingRef) {
932
- s.hoistDec = {
933
- type: "Declaration",
934
- children: ["let ", usingRef],
935
- names: []
936
- };
937
- }
938
- children.push(arg);
939
- if (!children.some(($) => $?.type === "ReturnStatement") && children.some(($1) => $1 === ",")) {
940
- const { parent } = s;
941
- const parenthesizedExpression = makeLeftHandSideExpression({ ...s });
942
- Object.assign(s, parenthesizedExpression, {
943
- parent,
944
- hoistDec: void 0
945
- });
946
- }
947
- return addParentPointers(s, s.parent);
948
- });
1040
+ return expandedOps;
1041
+ }
1042
+ ;
1043
+ return recurse;
949
1044
  }
950
- var init_pipe = __esm({
951
- "source/parser/pipe.civet"() {
952
- "use strict";
953
- init_traversal();
954
- init_util();
1045
+ function dotNumericLiteral(literal) {
1046
+ if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
1047
+ literal.children.push(".");
1048
+ literal.raw += ".";
955
1049
  }
956
- });
957
-
958
- // source/parser/for.civet
959
- function forRange(open, forDeclaration, range, stepExp, close) {
960
- const { start, end, inclusive } = range;
961
- const counterRef = makeRef("i");
962
- let stepRef;
963
- if (stepExp) {
964
- stepExp = insertTrimmingSpace(stepExp, "");
965
- stepRef = maybeRef(stepExp, "step");
1050
+ return literal;
1051
+ }
1052
+ function makeAsConst(node) {
1053
+ if (Array.isArray(node) && node.length === 1) {
1054
+ node = node[0];
966
1055
  }
967
- const startRef = maybeRef(start, "start");
968
- const endRef = maybeRef(end, "end");
969
- const startRefDec = startRef !== start ? [startRef, " = ", start, ", "] : [];
970
- const endRefDec = endRef !== end ? [endRef, " = ", end, ", "] : [];
971
- let ascDec = [], ascRef, asc;
972
- if (stepRef) {
973
- if (stepRef !== stepExp) {
974
- ascDec = [", ", stepRef, " = ", stepExp];
975
- }
976
- } else if (start.type === "Literal" && end.type === "Literal") {
977
- asc = literalValue(start) <= literalValue(end);
1056
+ if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
1057
+ return { ...node, children: [...node.children, asConst] };
978
1058
  } else {
979
- ascRef = makeRef("asc");
980
- ascDec = [", ", ascRef, " = ", startRef, " <= ", endRef];
981
- }
982
- let varAssign = [], varLetAssign = varAssign, varLet = varAssign, blockPrefix;
983
- if (forDeclaration?.declare) {
984
- if (forDeclaration.declare.token === "let") {
985
- const varName = forDeclaration.children.splice(1);
986
- varAssign = [...insertTrimmingSpace(varName, ""), " = "];
987
- varLet = [",", ...varName, " = ", counterRef];
988
- } else {
989
- blockPrefix = [
990
- ["", forDeclaration, " = ", counterRef, ";"]
991
- ];
992
- }
993
- } else if (forDeclaration) {
994
- varAssign = varLetAssign = [forDeclaration, " = "];
1059
+ return node;
995
1060
  }
996
- const declaration = {
997
- type: "Declaration",
998
- children: ["let ", ...startRefDec, ...endRefDec, counterRef, " = ", ...varLetAssign, startRef, ...varLet, ...ascDec],
999
- names: forDeclaration?.names
1000
- };
1001
- const counterPart = inclusive ? [counterRef, " <= ", endRef, " : ", counterRef, " >= ", endRef] : [counterRef, " < ", endRef, " : ", counterRef, " > ", endRef];
1002
- const condition = stepRef ? [stepRef, " !== 0 && (", stepRef, " > 0 ? ", ...counterPart, ")"] : ascRef ? [ascRef, " ? ", ...counterPart] : asc ? counterPart.slice(0, 3) : counterPart.slice(4);
1003
- const increment = stepRef ? [...varAssign, counterRef, " += ", stepRef] : ascRef ? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef] : [...varAssign, asc ? "++" : "--", counterRef];
1004
- return {
1005
- declaration,
1006
- children: [open, declaration, "; ", ...condition, "; ", ...increment, close],
1007
- blockPrefix
1008
- };
1009
1061
  }
1010
- function processForInOf($0, getRef) {
1011
- let [awaits, eachOwn, open, declaration, declaration2, ws, inOf, exp, step, close] = $0;
1012
- if (exp.type === "RangeExpression" && inOf.token === "of" && !declaration2) {
1013
- return forRange(open, declaration, exp, step, close);
1014
- } else if (step) {
1015
- throw new Error("for..of/in cannot use 'by' except with range literals");
1062
+ function isExistence(exp) {
1063
+ if (exp.type === "ParenthesizedExpression" && exp.implicit) {
1064
+ exp = exp.expression;
1016
1065
  }
1017
- let eachOwnError;
1018
- let hoistDec, blockPrefix = [];
1019
- if (eachOwn && eachOwn[0].token === "each") {
1020
- if (inOf.token === "of") {
1021
- const counterRef = makeRef("i");
1022
- const lenRef = makeRef("len");
1023
- const expRef2 = maybeRef(exp);
1024
- const increment = "++";
1025
- let assignmentNames = [...declaration.names];
1026
- if (declaration2) {
1027
- const [, , ws22, decl22] = declaration2;
1028
- blockPrefix.push(["", [
1029
- insertTrimmingSpace(ws22, ""),
1030
- decl22,
1031
- " = ",
1032
- counterRef
1033
- ], ";"]);
1034
- assignmentNames.push(...decl22.names);
1035
- }
1036
- const expRefDec = expRef2 !== exp ? [insertTrimmingSpace(expRef2, " "), " = ", insertTrimmingSpace(exp, ""), ", "] : [];
1037
- blockPrefix.push(["", {
1038
- type: "Declaration",
1039
- children: [declaration, " = ", insertTrimmingSpace(expRef2, ""), "[", counterRef, "]"],
1040
- names: assignmentNames
1041
- }, ";"]);
1042
- declaration = {
1043
- type: "Declaration",
1044
- children: ["let ", ...expRefDec, counterRef, " = 0, ", lenRef, " = ", insertTrimmingSpace(expRef2, ""), ".length"],
1045
- names: []
1046
- };
1047
- const condition = [counterRef, " < ", lenRef, "; "];
1048
- const children = [open, declaration, "; ", condition, counterRef, increment, close];
1049
- return { declaration, children, blockPrefix };
1050
- } else {
1051
- eachOwnError = {
1052
- type: "Error",
1053
- message: "'each' is only meaningful in for..of loops"
1054
- };
1055
- }
1066
+ if (exp.type === "Existence") {
1067
+ return exp;
1056
1068
  }
1057
- let own = eachOwn && eachOwn[0].token === "own";
1058
- let expRef;
1059
- if (own && inOf.token !== "in") {
1060
- own = false;
1061
- eachOwnError = {
1062
- type: "Error",
1063
- message: "'own' is only meaningful in for..in loops"
1064
- };
1069
+ ;
1070
+ return;
1071
+ }
1072
+ function isRelationalOp(op) {
1073
+ return op.relational || getPrecedence(op) === precedenceRelational;
1074
+ }
1075
+ function expandChainedComparisons([first, binops]) {
1076
+ const results = [];
1077
+ let i = 0;
1078
+ const l = binops.length;
1079
+ let start = 0;
1080
+ let chains = [];
1081
+ let op;
1082
+ while (i < l) {
1083
+ [, op] = binops[i];
1084
+ if (isRelationalOp(op)) {
1085
+ chains.push(i);
1086
+ } else if (getPrecedence(op) < precedenceRelational) {
1087
+ processChains(op);
1088
+ first = void 0;
1089
+ }
1090
+ i++;
1065
1091
  }
1066
- if (!declaration2 && !own) {
1067
- return {
1068
- declaration,
1069
- blockPrefix,
1070
- children: [awaits, eachOwnError, open, declaration, ws, inOf, expRef ?? exp, step, close]
1071
- // omit declaration2, replace eachOwn with eachOwnError, replace exp with expRef
1072
- };
1092
+ if (op != null) {
1093
+ processChains(op);
1073
1094
  }
1074
- let ws2, decl2;
1075
- if (declaration2)
1076
- [, , ws2, decl2] = declaration2;
1077
- switch (inOf.token) {
1078
- case "of": {
1079
- const counterRef = makeRef("i");
1080
- hoistDec = {
1081
- type: "Declaration",
1082
- children: ["let ", counterRef, " = 0"],
1083
- names: []
1084
- };
1085
- blockPrefix.push(["", {
1086
- type: "Declaration",
1087
- children: [insertTrimmingSpace(ws2, ""), decl2, " = ", counterRef, "++"],
1088
- names: decl2.names
1089
- }, ";"]);
1090
- break;
1095
+ return results;
1096
+ function processChains(op2) {
1097
+ if (first && isRelationalOp(op2)) {
1098
+ first = expandExistence(first);
1091
1099
  }
1092
- case "in": {
1093
- const expRef2 = maybeRef(exp);
1094
- if (expRef2 !== exp) {
1095
- hoistDec = {
1096
- type: "Declaration",
1097
- children: ["let ", expRef2],
1098
- names: []
1099
- };
1100
- exp = {
1101
- type: "AssignmentExpression",
1102
- children: [" ", expRef2, " =", exp]
1103
- };
1104
- }
1105
- let { binding } = declaration;
1106
- if (binding?.type !== "Identifier") {
1107
- const keyRef = makeRef("key");
1108
- blockPrefix.push(["", [
1109
- declaration,
1110
- " = ",
1111
- keyRef
1112
- ], ";"]);
1113
- declaration = {
1114
- type: "ForDeclaration",
1115
- binding: binding = keyRef,
1116
- children: ["const ", keyRef],
1117
- names: []
1118
- };
1119
- }
1120
- if (own) {
1121
- const hasPropRef = getRef("hasProp");
1122
- blockPrefix.push(["", ["if (!", hasPropRef, "(", insertTrimmingSpace(expRef2, ""), ", ", insertTrimmingSpace(binding, ""), ")) continue"], ";"]);
1123
- }
1124
- if (decl2) {
1125
- blockPrefix.push(["", {
1126
- type: "Declaration",
1127
- children: [insertTrimmingSpace(ws2, ""), decl2, " = ", insertTrimmingSpace(expRef2, ""), "[", insertTrimmingSpace(binding, ""), "]"],
1128
- names: decl2.names
1129
- }, ";"]);
1100
+ if (chains.length > 1) {
1101
+ chains.forEach((index, k) => {
1102
+ if (k > 0) {
1103
+ results.push(" ", "&&", " ");
1104
+ }
1105
+ const binop = binops[index];
1106
+ let [, , , exp] = binop;
1107
+ exp = binop[3] = expandExistence(exp);
1108
+ let endIndex;
1109
+ if (k < chains.length - 1) {
1110
+ endIndex = chains[k + 1];
1111
+ } else {
1112
+ endIndex = i + 1;
1113
+ }
1114
+ results.push(first, ...binops.slice(start, endIndex).flat());
1115
+ first = [exp].concat(binops.slice(index + 1, endIndex));
1116
+ return start = endIndex;
1117
+ });
1118
+ } else {
1119
+ if (first) {
1120
+ results.push(first);
1130
1121
  }
1131
- break;
1122
+ results.push(...binops.slice(start, i + 1).flat());
1123
+ start = i + 1;
1132
1124
  }
1133
- default:
1134
- (() => {
1135
- throw new Error(`for item, index must use 'of' or 'in' instead of '${inOf.token}'`);
1136
- })();
1125
+ chains.length = 0;
1137
1126
  }
1138
- return {
1139
- declaration,
1140
- children: [awaits, eachOwnError, open, declaration, ws, inOf, exp, step, close],
1141
- // omit declaration2, replace each with eachOwnError
1142
- blockPrefix,
1143
- hoistDec
1144
- };
1127
+ function expandExistence(exp) {
1128
+ const existence = isExistence(exp);
1129
+ if (existence) {
1130
+ results.push(existence, " ", "&&", " ");
1131
+ return existence.expression;
1132
+ }
1133
+ return exp;
1134
+ }
1135
+ ;
1145
1136
  }
1146
- var init_for = __esm({
1147
- "source/parser/for.civet"() {
1137
+ var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
1138
+ var init_op = __esm({
1139
+ "source/parser/op.civet"() {
1148
1140
  "use strict";
1149
1141
  init_util();
1142
+ precedenceOrder = [
1143
+ ["||", "??"],
1144
+ ["^^"],
1145
+ ["&&"],
1146
+ ["|"],
1147
+ ["^"],
1148
+ ["&"],
1149
+ // NOTE: Equality and inequality merged because of relational chaining
1150
+ [
1151
+ "==",
1152
+ "!=",
1153
+ "===",
1154
+ "!==",
1155
+ "<",
1156
+ "<=",
1157
+ ">",
1158
+ ">=",
1159
+ "in",
1160
+ "instanceof"
1161
+ ],
1162
+ // NOTE: Extra in-between level for default custom operators
1163
+ ["custom"],
1164
+ ["<<", ">>", ">>>"],
1165
+ ["+", "-"],
1166
+ ["*", "/", "%"],
1167
+ ["**"]
1168
+ ];
1169
+ precedenceMap = /* @__PURE__ */ new Map();
1170
+ for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
1171
+ const prec = i1;
1172
+ const ops = precedenceOrder[i1];
1173
+ for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
1174
+ const op = ops[i2];
1175
+ precedenceMap.set(op, prec);
1176
+ }
1177
+ }
1178
+ precedenceStep = 1 / 64;
1179
+ precedenceRelational = precedenceMap.get("==");
1180
+ precedenceCustomDefault = precedenceMap.get("custom");
1181
+ asConst = {
1182
+ ts: true,
1183
+ children: [" as const"]
1184
+ };
1150
1185
  }
1151
1186
  });
1152
1187
 
1153
- // source/parser/binding.civet
1154
- function adjustAtBindings(statements, asThis = false) {
1155
- gatherRecursiveAll(statements, (n) => n.type === "AtBindingProperty").forEach((binding) => {
1156
- const { ref } = binding;
1157
- if (asThis) {
1158
- const atBinding = binding.binding;
1159
- atBinding.children.pop();
1160
- atBinding.type = void 0;
1161
- binding.children.unshift(ref.id, ": this.", ref.base);
1162
- binding.type = "Property";
1163
- binding.ref = void 0;
1164
- return;
1188
+ // source/parser/pattern-matching.civet
1189
+ function processPatternMatching(statements, ReservedWord, getRef) {
1190
+ gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
1191
+ const { caseBlock } = s;
1192
+ const { clauses } = caseBlock;
1193
+ for (const c of clauses) {
1194
+ if (c.type === "WhenClause" && c.break) {
1195
+ const last = c.block?.expressions?.at(-1)?.[1];
1196
+ if (isExit(last)) {
1197
+ c.children.splice(c.children.indexOf(c.break), 1);
1198
+ c.break = void 0;
1199
+ }
1200
+ }
1165
1201
  }
1166
- if (ref.names[0] !== ref.base) {
1167
- return binding.children.unshift(ref.base, ": ");
1202
+ let errors = false;
1203
+ let isPattern = false;
1204
+ if (clauses.some(($1) => $1.type === "PatternClause")) {
1205
+ isPattern = true;
1206
+ clauses.forEach((c) => {
1207
+ if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
1208
+ errors = true;
1209
+ return c.children.push({
1210
+ type: "Error",
1211
+ message: "Can't mix pattern matching and non-pattern matching clauses"
1212
+ });
1213
+ }
1214
+ ;
1215
+ return;
1216
+ });
1168
1217
  }
1169
- ;
1170
- return;
1171
- });
1172
- }
1173
- function adjustBindingElements(elements) {
1174
- const names = elements.flatMap((p) => p.names || []), { length } = elements;
1175
- let blockPrefix, restIndex = -1, restCount = 0;
1176
- elements.forEach(({ type }, i) => {
1177
- if (type === "BindingRestElement") {
1178
- if (restIndex < 0)
1179
- restIndex = i;
1180
- return restCount++;
1218
+ if (errors || !isPattern) {
1219
+ return;
1181
1220
  }
1182
- ;
1183
- return;
1184
- });
1185
- if (restCount === 0) {
1186
- return {
1187
- children: elements,
1188
- names,
1189
- blockPrefix,
1190
- length
1191
- };
1192
- } else if (restCount === 1) {
1193
- const rest = elements[restIndex];
1194
- const after = elements.slice(restIndex + 1);
1195
- const restIdentifier = rest.binding.ref || rest.binding;
1196
- names.push(...rest.names || []);
1197
- let l = after.length;
1198
- if (l) {
1199
- if (arrayElementHasTrailingComma(after[l - 1]))
1200
- l++;
1201
- blockPrefix = {
1202
- type: "PostRestBindingElements",
1203
- children: ["[", insertTrimmingSpace(after, ""), "] = ", restIdentifier, ".splice(-", l.toString(), ")"],
1204
- names: after.flatMap((p) => p.names)
1221
+ let { condition } = s;
1222
+ if (condition.type === "ParenthesizedExpression") {
1223
+ condition = condition.expression;
1224
+ }
1225
+ let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
1226
+ if (ref !== condition) {
1227
+ hoistDec = {
1228
+ type: "Declaration",
1229
+ children: ["let ", ref],
1230
+ names: []
1205
1231
  };
1232
+ refAssignment = [{
1233
+ type: "AssignmentExpression",
1234
+ children: [ref, " = ", condition]
1235
+ }, ","];
1206
1236
  }
1207
- return {
1208
- names,
1209
- children: [...elements.slice(0, restIndex), {
1210
- ...rest,
1211
- children: rest.children.slice(0, -1)
1212
- // remove trailing comma
1213
- }],
1214
- blockPrefix,
1215
- length
1216
- };
1217
- }
1218
- const err = {
1219
- type: "Error",
1220
- children: ["Multiple rest elements in array pattern"]
1221
- };
1222
- return {
1223
- names,
1224
- children: [...elements, err],
1225
- blockPrefix,
1226
- length
1227
- };
1228
- }
1229
- function gatherBindingCode(statements, opts) {
1230
- const thisAssignments = [];
1231
- const splices = [];
1232
- function insertRestSplices(s, p, thisAssignments2) {
1233
- gatherRecursiveAll(s, (n) => n.blockPrefix || opts?.injectParamProps && n.accessModifier || n.type === "AtBinding").forEach((n) => {
1234
- if (n.type === "AtBinding") {
1235
- const { ref } = n;
1236
- const { id } = ref;
1237
- thisAssignments2.push([`this.${id} = `, ref]);
1237
+ let prev = [], root = prev;
1238
+ const l = clauses.length;
1239
+ clauses.forEach((c, i) => {
1240
+ if (c.type === "DefaultClause") {
1241
+ prev.push(c.block);
1238
1242
  return;
1239
1243
  }
1240
- if (opts?.injectParamProps && n.type === "Parameter" && n.accessModifier) {
1241
- n.names.forEach((id) => ({
1242
- push: thisAssignments2.push({
1243
- type: "AssignmentExpression",
1244
- children: [`this.${id} = `, id],
1245
- js: true
1246
- })
1247
- }));
1248
- return;
1244
+ let { patterns, block } = c;
1245
+ let pattern = patterns[0];
1246
+ const indent = block.expressions?.[0]?.[0] || "";
1247
+ const alternativeConditions = patterns.map((pattern2, i2) => {
1248
+ const conditions = [];
1249
+ getPatternConditions(pattern2, ref, conditions, getRef);
1250
+ return conditions;
1251
+ });
1252
+ const conditionExpression = alternativeConditions.map((conditions, i2) => {
1253
+ const conditionArray = conditions.map((c2, i3) => {
1254
+ if (i3 === 0)
1255
+ return c2;
1256
+ return [" && ", ...c2];
1257
+ });
1258
+ if (i2 === 0)
1259
+ return conditionArray;
1260
+ return [" || ", ...conditionArray];
1261
+ });
1262
+ const condition2 = {
1263
+ type: "ParenthesizedExpression",
1264
+ children: ["(", ...refAssignment, conditionExpression, ")"],
1265
+ expression: conditionExpression
1266
+ };
1267
+ const prefix = [];
1268
+ switch (pattern.type) {
1269
+ case "ArrayBindingPattern":
1270
+ if (pattern.length === 0)
1271
+ break;
1272
+ case "ObjectBindingPattern": {
1273
+ if (pattern.properties?.length === 0)
1274
+ break;
1275
+ let [splices, thisAssignments] = gatherBindingCode(pattern);
1276
+ const patternBindings = nonMatcherBindings(pattern);
1277
+ splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
1278
+ thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
1279
+ const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
1280
+ prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
1281
+ prefix.push(...thisAssignments);
1282
+ prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
1283
+ break;
1284
+ }
1249
1285
  }
1250
- const { blockPrefix } = n;
1251
- p.push(blockPrefix);
1252
- return insertRestSplices(blockPrefix, p, thisAssignments2);
1286
+ block.expressions.unshift(...prefix);
1287
+ const next = [];
1288
+ braceBlock(block);
1289
+ if (i < l - 1)
1290
+ next.push("\n", "else ");
1291
+ prev.push(["", {
1292
+ type: "IfStatement",
1293
+ children: ["if", condition2, block, next],
1294
+ then: block,
1295
+ else: next,
1296
+ hoistDec
1297
+ }]);
1298
+ hoistDec = void 0;
1299
+ refAssignment = [];
1300
+ return prev = next;
1253
1301
  });
1254
- }
1255
- insertRestSplices(statements, splices, thisAssignments);
1256
- return [splices, thisAssignments];
1257
- }
1258
- function arrayElementHasTrailingComma(elementNode) {
1259
- const lastChild = elementNode.children.at(-1);
1260
- return lastChild && lastChild[lastChild.length - 1]?.token === ",";
1261
- }
1262
- var init_binding = __esm({
1263
- "source/parser/binding.civet"() {
1264
- "use strict";
1265
- init_traversal();
1266
- init_util();
1267
- }
1268
- });
1269
-
1270
- // source/parser/function.civet
1271
- function isVoidType(t) {
1272
- return t?.type === "LiteralType" && t.t.type === "VoidType";
1273
- }
1274
- function isPromiseVoidType(t) {
1275
- return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
1276
- }
1277
- function isGeneratorVoidType(t) {
1278
- return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1279
- }
1280
- function isAsyncGeneratorVoidType(t) {
1281
- return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1302
+ s.type = "PatternMatchingStatement";
1303
+ s.children = [root];
1304
+ return addParentPointers(s, s.parent);
1305
+ });
1282
1306
  }
1283
- function implicitFunctionBlock(f) {
1284
- if (f.abstract || f.block || f.signature?.optional)
1285
- return;
1286
- const { name, parent } = f;
1287
- if (parent?.type === "ExportDeclaration")
1307
+ function getPatternConditions(pattern, ref, conditions, getRef) {
1308
+ if (pattern.rest)
1288
1309
  return;
1289
- const expressions = parent?.expressions ?? parent?.elements;
1290
- const currentIndex = expressions?.findIndex(([, def]) => def === f);
1291
- const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
1292
- if (f.type === following?.type && name && name === following.name) {
1293
- f.ts = true;
1294
- } else {
1295
- const block = makeEmptyBlock();
1296
- block.parent = f;
1297
- f.block = block;
1298
- f.children.push(block);
1299
- f.ts = false;
1300
- }
1301
- }
1302
- function processReturn(f, implicitReturns) {
1303
- let { returnType } = f.signature;
1304
- if (returnType && returnType.optional) {
1305
- convertOptionalType(returnType);
1306
- }
1307
- if (!processReturnValue(f) && implicitReturns) {
1308
- const { signature, block } = f;
1309
- const { modifier, name, returnType: returnType2 } = signature;
1310
- const { async, generator, set } = modifier;
1311
- const isMethod = f.type === "MethodDefinition";
1312
- const isConstructor = isMethod && name === "constructor";
1313
- const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
1314
- if (block?.type === "BlockStatement") {
1315
- if (isVoid || set || isConstructor) {
1316
- if (block.bare && block.implicitlyReturned) {
1317
- block.children = [" {", ...block.children, " }"];
1318
- block.bare = block.implicitlyReturned = false;
1319
- }
1320
- } else {
1321
- if (!block.implicitlyReturned) {
1322
- insertReturn(block);
1310
+ switch (pattern.type) {
1311
+ case "ArrayBindingPattern": {
1312
+ const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), l = (length - hasRest).toString(), lengthCheck = hasRest ? [ref, ".length >= ", l] : [getRef("len"), "(", ref, ", ", l, ")"];
1313
+ conditions.push(
1314
+ ["Array.isArray(", ref, ")"],
1315
+ lengthCheck
1316
+ );
1317
+ elements.forEach(({ children: [, e] }, i) => {
1318
+ const subRef = [ref, "[", i.toString(), "]"];
1319
+ return getPatternConditions(e, subRef, conditions, getRef);
1320
+ });
1321
+ const { blockPrefix } = pattern;
1322
+ if (blockPrefix) {
1323
+ const postElements = blockPrefix.children[1], { length: postLength } = postElements;
1324
+ postElements.forEach(({ children: [, e] }, i) => {
1325
+ const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
1326
+ return getPatternConditions(e, subRef, conditions, getRef);
1327
+ });
1328
+ }
1329
+ break;
1330
+ }
1331
+ case "ObjectBindingPattern": {
1332
+ conditions.push(
1333
+ ["typeof ", ref, " === 'object'"],
1334
+ [ref, " != null"]
1335
+ );
1336
+ pattern.properties.forEach((p) => {
1337
+ switch (p.type) {
1338
+ case "PinProperty":
1339
+ case "BindingProperty": {
1340
+ const { name, value } = p;
1341
+ let subRef;
1342
+ switch (name.type) {
1343
+ case "ComputedPropertyName":
1344
+ conditions.push([name.expression, " in ", ref]);
1345
+ subRef = [ref, name];
1346
+ break;
1347
+ case "Literal":
1348
+ case "StringLiteral":
1349
+ case "NumericLiteral":
1350
+ conditions.push([name, " in ", ref]);
1351
+ subRef = [ref, "[", name, "]"];
1352
+ break;
1353
+ default:
1354
+ conditions.push(["'", name, "' in ", ref]);
1355
+ subRef = [ref, ".", name];
1356
+ }
1357
+ if (value) {
1358
+ getPatternConditions(value, subRef, conditions, getRef);
1359
+ }
1360
+ break;
1361
+ }
1323
1362
  }
1363
+ });
1364
+ break;
1365
+ }
1366
+ case "ConditionFragment": {
1367
+ let { children } = pattern;
1368
+ if (children.length) {
1369
+ let [first, ...rest] = children;
1370
+ let [ws, ...op] = first;
1371
+ ws = [" "].concat(ws);
1372
+ first = [ws, ...op];
1373
+ children = [first, ...rest];
1324
1374
  }
1375
+ conditions.push(
1376
+ processBinaryOpExpression([ref, children])
1377
+ );
1378
+ break;
1379
+ }
1380
+ case "RegularExpressionLiteral": {
1381
+ conditions.push(
1382
+ ["typeof ", ref, " === 'string'"],
1383
+ [pattern, ".test(", ref, ")"]
1384
+ );
1385
+ break;
1325
1386
  }
1387
+ case "PinPattern":
1388
+ conditions.push([
1389
+ ref,
1390
+ " === ",
1391
+ pattern.expression
1392
+ ]);
1393
+ break;
1394
+ case "Literal":
1395
+ conditions.push([
1396
+ ref,
1397
+ " === ",
1398
+ pattern
1399
+ ]);
1400
+ break;
1401
+ default:
1402
+ break;
1326
1403
  }
1327
1404
  }
1328
- function processReturnValue(func) {
1329
- const { block } = func;
1330
- const values = gatherRecursiveWithinFunction(
1331
- block,
1332
- ({ type }) => type === "ReturnValue"
1333
- );
1334
- if (!values.length) {
1335
- return false;
1336
- }
1337
- const ref = makeRef("ret");
1338
- let declaration;
1339
- values.forEach((value) => {
1340
- value.children = [ref];
1341
- const { ancestor, child } = findAncestor(
1342
- value,
1343
- ({ type }) => type === "Declaration",
1344
- isFunction
1345
- );
1346
- if (ancestor) {
1347
- return declaration ??= child;
1348
- }
1349
- ;
1350
- return;
1351
- });
1352
- let returnType = func.returnType ?? func.signature?.returnType;
1353
- if (returnType) {
1354
- const { t } = returnType;
1355
- let m;
1356
- if (m = t.type, m === "TypePredicate") {
1357
- returnType = ": boolean";
1358
- } else if (m === "AssertsType") {
1359
- returnType = void 0;
1405
+ function elideMatchersFromArrayBindings(elements) {
1406
+ return elements.map((el) => {
1407
+ if (el.type === "BindingRestElement") {
1408
+ return ["", el, void 0];
1360
1409
  }
1361
- }
1362
- if (declaration) {
1363
- if (!(declaration.suffix != null)) {
1364
- declaration.children[1] = declaration.suffix = returnType;
1410
+ const { children: [ws, e, delim] } = el;
1411
+ switch (e.type) {
1412
+ case "Literal":
1413
+ case "RegularExpressionLiteral":
1414
+ case "StringLiteral":
1415
+ case "PinPattern":
1416
+ return delim;
1417
+ default:
1418
+ return [ws, nonMatcherBindings(e), delim];
1365
1419
  }
1366
- } else {
1367
- block.expressions.unshift([
1368
- getIndent(block.expressions[0]),
1369
- {
1370
- type: "Declaration",
1371
- children: ["let ", ref, returnType],
1372
- names: []
1373
- },
1374
- ";"
1375
- ]);
1376
- }
1377
- gatherRecursiveWithinFunction(
1378
- block,
1379
- (r) => r.type === "ReturnStatement" && !r.expression
1380
- ).forEach((r) => {
1381
- r.expression = ref;
1382
- return r.children.splice(-1, 1, " ", ref);
1383
1420
  });
1384
- if (!(block.children.at(-2)?.type === "ReturnStatement")) {
1385
- block.expressions.push([
1386
- [getIndent(block.expressions.at(-1))],
1387
- {
1388
- type: "ReturnStatement",
1389
- expression: ref,
1390
- children: ["return ", ref]
1421
+ }
1422
+ function elideMatchersFromPropertyBindings(properties) {
1423
+ return properties.map((p) => {
1424
+ switch (p.type) {
1425
+ case "BindingProperty": {
1426
+ const { children, name, value } = p;
1427
+ const [ws] = children;
1428
+ switch (value && value.type) {
1429
+ case "ArrayBindingPattern":
1430
+ case "ObjectBindingPattern":
1431
+ return {
1432
+ ...p,
1433
+ children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
1434
+ };
1435
+ case "Identifier":
1436
+ return p;
1437
+ case "Literal":
1438
+ case "RegularExpressionLiteral":
1439
+ case "StringLiteral":
1440
+ default:
1441
+ return {
1442
+ ...p,
1443
+ children: [ws, name, p.delim]
1444
+ };
1445
+ }
1391
1446
  }
1392
- ]);
1393
- }
1394
- return true;
1447
+ case "PinProperty":
1448
+ case "BindingRestProperty":
1449
+ default:
1450
+ return p;
1451
+ }
1452
+ });
1395
1453
  }
1396
- function patternAsValue(pattern) {
1454
+ function nonMatcherBindings(pattern) {
1397
1455
  switch (pattern.type) {
1398
1456
  case "ArrayBindingPattern": {
1399
- const children = [...pattern.children];
1400
- const index = children.indexOf(pattern.elements);
1401
- if (index < 0)
1402
- throw new Error("failed to find elements in ArrayBindingPattern");
1403
- children[index] = pattern.elements.map((el) => {
1404
- const [ws, e, delim] = el.children;
1405
- return { ...el, children: [ws, patternAsValue(e), delim] };
1406
- });
1407
- return { ...pattern, children };
1408
- }
1409
- case "ObjectBindingPattern": {
1410
- const children = [...pattern.children];
1411
- const index = children.indexOf(pattern.properties);
1412
- if (index < 0)
1413
- throw new Error("failed to find properties in ArrayBindingPattern");
1414
- children[index] = pattern.properties.map(patternAsValue);
1415
- return { ...pattern, children };
1457
+ const elements = elideMatchersFromArrayBindings(pattern.elements);
1458
+ const children = ["[", elements, "]"];
1459
+ return {
1460
+ ...pattern,
1461
+ children,
1462
+ elements
1463
+ };
1416
1464
  }
1417
- case "Identifier":
1418
- case "BindingProperty": {
1419
- const children = [pattern.name, pattern.delim];
1420
- if (isWhitespaceOrEmpty(pattern.children[0])) {
1421
- children.unshift(pattern.children[0]);
1422
- }
1423
- return { ...pattern, children };
1465
+ case "PostRestBindingElements": {
1466
+ const els = elideMatchersFromArrayBindings(pattern.children[1]);
1467
+ return {
1468
+ ...pattern,
1469
+ children: [
1470
+ pattern.children[0],
1471
+ els,
1472
+ ...pattern.children.slice(2)
1473
+ ]
1474
+ };
1424
1475
  }
1476
+ case "ObjectBindingPattern":
1477
+ return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
1425
1478
  default:
1426
1479
  return pattern;
1427
1480
  }
1428
1481
  }
1429
- function insertPush(node, ref) {
1430
- if (!node)
1431
- return;
1432
- switch (node.type) {
1433
- case "BlockStatement":
1434
- if (node.expressions.length) {
1435
- insertPush(node.expressions.at(-1), ref);
1436
- } else {
1437
- node.expressions.push([ref, ".push(void 0);"]);
1438
- }
1439
- return;
1440
- case "CaseBlock":
1441
- node.clauses.forEach((clause) => {
1442
- return insertPush(clause, ref);
1443
- });
1444
- return;
1445
- case "WhenClause":
1446
- insertPush(node.block, ref);
1447
- return;
1448
- case "DefaultClause":
1449
- insertPush(node.block, ref);
1450
- return;
1451
- }
1452
- if (!Array.isArray(node))
1453
- return;
1454
- let [, exp] = node;
1455
- if (!exp) {
1456
- return;
1457
- }
1458
- const indent = getIndent(node);
1459
- const outer = exp;
1460
- let { type } = exp;
1461
- if (type === "LabelledStatement") {
1462
- exp = exp.statement;
1463
- ({ type } = exp);
1464
- }
1465
- switch (exp.type) {
1466
- case "BreakStatement":
1467
- case "ContinueStatement":
1468
- case "DebuggerStatement":
1469
- case "EmptyStatement":
1470
- case "ReturnStatement":
1471
- case "ThrowStatement":
1472
- return;
1473
- case "Declaration":
1474
- exp.children.push(["", [
1475
- ";",
1476
- ref,
1477
- ".push(",
1478
- patternAsValue(exp.bindings.at(-1).pattern),
1479
- ")"
1480
- ]]);
1481
- return;
1482
- case "ForStatement":
1483
- case "IterationStatement":
1484
- case "DoStatement":
1485
- wrapIterationReturningResults(exp, outer, ref);
1486
- return;
1487
- case "BlockStatement":
1488
- insertPush(exp.expressions[exp.expressions.length - 1], ref);
1489
- return;
1490
- case "IfStatement":
1491
- insertPush(exp.then, ref);
1492
- if (exp.then.bare && !exp.then.semicolon) {
1493
- exp.then.children.push(exp.then.semicolon = ";");
1482
+ function aggregateDuplicateBindings(bindings, ReservedWord) {
1483
+ const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
1484
+ const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
1485
+ arrayBindings.forEach((a) => {
1486
+ const { elements } = a;
1487
+ return elements.forEach((element) => {
1488
+ if (Array.isArray(element)) {
1489
+ const [, e] = element;
1490
+ if (e.type === "Identifier") {
1491
+ return props.push(e);
1492
+ } else if (e.type === "BindingRestElement") {
1493
+ return props.push(e);
1494
+ }
1495
+ ;
1496
+ return;
1494
1497
  }
1495
- if (exp.else)
1496
- insertPush(exp.else[2], ref);
1497
- else
1498
- exp.children.push([" else {\n", indent, ref, ".push(undefined)\n", indent, "}"]);
1498
+ ;
1499
1499
  return;
1500
- case "PatternMatchingStatement":
1501
- insertPush(exp.children[0][0], ref);
1500
+ });
1501
+ });
1502
+ const declarations = [];
1503
+ const propsGroupedByName = /* @__PURE__ */ new Map();
1504
+ for (const p of props) {
1505
+ const { name, value } = p;
1506
+ const key = value?.name || name?.name || name;
1507
+ if (propsGroupedByName.has(key)) {
1508
+ propsGroupedByName.get(key).push(p);
1509
+ } else {
1510
+ propsGroupedByName.set(key, [p]);
1511
+ }
1512
+ }
1513
+ propsGroupedByName.forEach((shared, key) => {
1514
+ if (!key) {
1502
1515
  return;
1503
- case "SwitchStatement":
1504
- insertPush(exp.children[2], ref);
1516
+ }
1517
+ if (ReservedWord({ fail() {
1518
+ } }, {
1519
+ pos: 0,
1520
+ input: key
1521
+ })) {
1522
+ shared.forEach((p) => {
1523
+ return aliasBinding(p, makeRef(`_${key}`, key));
1524
+ });
1505
1525
  return;
1506
- case "TryStatement":
1507
- exp.blocks.forEach((block) => insertPush(block, ref));
1526
+ }
1527
+ if (shared.length === 1) {
1508
1528
  return;
1529
+ }
1530
+ const refs = shared.map((p) => {
1531
+ const ref = makeRef(key);
1532
+ aliasBinding(p, ref);
1533
+ return ref;
1534
+ });
1535
+ return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
1536
+ return i === 0 ? r : [", ", r];
1537
+ }), "]"]);
1538
+ });
1539
+ return declarations;
1540
+ }
1541
+ function aliasBinding(p, ref) {
1542
+ if (p.type === "Identifier") {
1543
+ p.children[0] = ref;
1544
+ } else if (p.type === "BindingRestElement") {
1545
+ aliasBinding(p.binding, ref);
1546
+ } else if (p.value?.type === "Identifier") {
1547
+ aliasBinding(p.value, ref);
1548
+ } else {
1549
+ p.value = ref;
1550
+ const index = p.children.indexOf(p.name);
1551
+ p.children.splice(index + 1, 0, ": ", ref);
1509
1552
  }
1510
- if (node[node.length - 1]?.type === "SemicolonDelimiter")
1511
- return;
1512
- node.splice(1, 0, ref, ".push(");
1513
- node.push(")");
1514
1553
  }
1515
- function insertReturn(node, outerNode = node) {
1516
- if (!node)
1554
+ var init_pattern_matching = __esm({
1555
+ "source/parser/pattern-matching.civet"() {
1556
+ "use strict";
1557
+ init_traversal();
1558
+ init_util();
1559
+ init_block();
1560
+ init_binding();
1561
+ init_op();
1562
+ }
1563
+ });
1564
+
1565
+ // source/parser/function.civet
1566
+ function isVoidType(t) {
1567
+ return t?.type === "LiteralType" && t.t.type === "VoidType";
1568
+ }
1569
+ function isPromiseVoidType(t) {
1570
+ return t?.type === "IdentifierType" && t.raw === "Promise" && t.args?.types?.length === 1 && isVoidType(t.args.types[0]);
1571
+ }
1572
+ function isGeneratorVoidType(t) {
1573
+ return t?.type === "IdentifierType" && (t.raw === "Iterator" || t.raw === "Generator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1574
+ }
1575
+ function isAsyncGeneratorVoidType(t) {
1576
+ return t?.type === "IdentifierType" && (t.raw === "AsyncIterator" || t.raw === "AsyncGenerator") && t.args?.types?.length >= 2 && isVoidType(t.args.types[1]);
1577
+ }
1578
+ function implicitFunctionBlock(f) {
1579
+ if (f.abstract || f.block || f.signature?.optional)
1517
1580
  return;
1518
- switch (node.type) {
1519
- case "BlockStatement":
1520
- if (node.expressions.length) {
1521
- const last = node.expressions[node.expressions.length - 1];
1522
- insertReturn(last);
1523
- } else {
1524
- if (node.parent.type === "CatchClause") {
1525
- node.expressions.push(["return"]);
1581
+ const { name, parent } = f;
1582
+ if (parent?.type === "ExportDeclaration")
1583
+ return;
1584
+ const expressions = parent?.expressions ?? parent?.elements;
1585
+ const currentIndex = expressions?.findIndex(([, def]) => def === f);
1586
+ const following = currentIndex >= 0 && expressions[currentIndex + 1]?.[1];
1587
+ if (f.type === following?.type && name && name === following.name) {
1588
+ f.ts = true;
1589
+ } else {
1590
+ const block = makeEmptyBlock();
1591
+ block.parent = f;
1592
+ f.block = block;
1593
+ f.children.push(block);
1594
+ f.ts = false;
1595
+ }
1596
+ }
1597
+ function processReturn(f, implicitReturns) {
1598
+ let { returnType } = f.signature;
1599
+ if (returnType && returnType.optional) {
1600
+ convertOptionalType(returnType);
1601
+ }
1602
+ if (!processReturnValue(f) && implicitReturns) {
1603
+ const { signature, block } = f;
1604
+ const { modifier, name, returnType: returnType2 } = signature;
1605
+ const { async, generator, set } = modifier;
1606
+ const isMethod = f.type === "MethodDefinition";
1607
+ const isConstructor = isMethod && name === "constructor";
1608
+ const isVoid = isVoidType(returnType2?.t) || async && (isPromiseVoidType(returnType2?.t) || generator && isAsyncGeneratorVoidType(returnType2?.t)) || !async && generator && isGeneratorVoidType(returnType2?.t);
1609
+ if (block?.type === "BlockStatement") {
1610
+ if (isVoid || set || isConstructor) {
1611
+ if (block.bare && block.implicitlyReturned) {
1612
+ block.children = [" {", ...block.children, " }"];
1613
+ block.bare = block.implicitlyReturned = false;
1526
1614
  }
1527
- }
1528
- return;
1529
- case "WhenClause":
1530
- if (node.break) {
1531
- node.children.splice(node.children.indexOf(node.break), 1);
1532
- }
1533
- if (node.block.expressions.length) {
1534
- insertReturn(node.block);
1535
1615
  } else {
1536
- node.block.expressions.push(wrapWithReturn());
1616
+ if (!block.implicitlyReturned) {
1617
+ insertReturn(block);
1618
+ }
1537
1619
  }
1538
- return;
1539
- case "DefaultClause":
1540
- insertReturn(node.block);
1541
- return;
1620
+ }
1542
1621
  }
1543
- if (!Array.isArray(node))
1544
- return;
1545
- let [, exp, semi] = node;
1546
- if (semi?.type === "SemicolonDelimiter") {
1547
- return;
1622
+ }
1623
+ function processReturnValue(func) {
1624
+ const { block } = func;
1625
+ const values = gatherRecursiveWithinFunction(
1626
+ block,
1627
+ ({ type }) => type === "ReturnValue"
1628
+ );
1629
+ if (!values.length) {
1630
+ return false;
1548
1631
  }
1549
- if (!exp) {
1632
+ const ref = makeRef("ret");
1633
+ let declaration;
1634
+ values.forEach((value) => {
1635
+ value.children = [ref];
1636
+ const { ancestor, child } = findAncestor(
1637
+ value,
1638
+ ({ type }) => type === "Declaration",
1639
+ isFunction
1640
+ );
1641
+ if (ancestor) {
1642
+ return declaration ??= child;
1643
+ }
1644
+ ;
1550
1645
  return;
1646
+ });
1647
+ let returnType = func.returnType ?? func.signature?.returnType;
1648
+ if (returnType) {
1649
+ const { t } = returnType;
1650
+ let m;
1651
+ if (m = t.type, m === "TypePredicate") {
1652
+ returnType = ": boolean";
1653
+ } else if (m === "AssertsType") {
1654
+ returnType = void 0;
1655
+ }
1551
1656
  }
1552
- const outer = exp;
1553
- let { type } = exp;
1554
- if (type === "LabelledStatement") {
1555
- exp = exp.statement;
1556
- ({ type } = exp);
1657
+ if (declaration) {
1658
+ if (!(declaration.suffix != null)) {
1659
+ declaration.children[1] = declaration.suffix = returnType;
1660
+ }
1661
+ } else {
1662
+ block.expressions.unshift([
1663
+ getIndent(block.expressions[0]),
1664
+ {
1665
+ type: "Declaration",
1666
+ children: ["let ", ref, returnType],
1667
+ names: []
1668
+ },
1669
+ ";"
1670
+ ]);
1557
1671
  }
1558
- switch (type) {
1559
- case "BreakStatement":
1672
+ gatherRecursiveWithinFunction(
1673
+ block,
1674
+ (r) => r.type === "ReturnStatement" && !r.expression
1675
+ ).forEach((r) => {
1676
+ r.expression = ref;
1677
+ return r.children.splice(-1, 1, " ", ref);
1678
+ });
1679
+ if (!(block.children.at(-2)?.type === "ReturnStatement")) {
1680
+ const indent = getIndent(block.expressions.at(-1)) || ";";
1681
+ block.expressions.push([
1682
+ [indent],
1683
+ {
1684
+ type: "ReturnStatement",
1685
+ expression: ref,
1686
+ children: ["return ", ref]
1687
+ }
1688
+ ]);
1689
+ }
1690
+ return true;
1691
+ }
1692
+ function patternAsValue(pattern) {
1693
+ switch (pattern.type) {
1694
+ case "ArrayBindingPattern": {
1695
+ const children = [...pattern.children];
1696
+ const index = children.indexOf(pattern.elements);
1697
+ if (index < 0)
1698
+ throw new Error("failed to find elements in ArrayBindingPattern");
1699
+ children[index] = pattern.elements.map((el) => {
1700
+ const [ws, e, delim] = el.children;
1701
+ return { ...el, children: [ws, patternAsValue(e), delim] };
1702
+ });
1703
+ return { ...pattern, children };
1704
+ }
1705
+ case "ObjectBindingPattern": {
1706
+ const children = [...pattern.children];
1707
+ const index = children.indexOf(pattern.properties);
1708
+ if (index < 0)
1709
+ throw new Error("failed to find properties in ArrayBindingPattern");
1710
+ children[index] = pattern.properties.map(patternAsValue);
1711
+ return { ...pattern, children };
1712
+ }
1713
+ case "Identifier":
1714
+ case "BindingProperty": {
1715
+ const children = [pattern.name, pattern.delim];
1716
+ if (isWhitespaceOrEmpty(pattern.children[0])) {
1717
+ children.unshift(pattern.children[0]);
1718
+ }
1719
+ return { ...pattern, children };
1720
+ }
1721
+ default:
1722
+ return pattern;
1723
+ }
1724
+ }
1725
+ function assignResults(node, collect) {
1726
+ if (!node)
1727
+ return;
1728
+ switch (node.type) {
1729
+ case "BlockStatement":
1730
+ if (node.expressions.length) {
1731
+ assignResults(node.expressions.at(-1), collect);
1732
+ } else {
1733
+ node.expressions.push(["", collect("void 0"), ";"]);
1734
+ }
1735
+ return;
1736
+ case "CaseBlock":
1737
+ node.clauses.forEach((clause) => {
1738
+ return assignResults(clause, collect);
1739
+ });
1740
+ return;
1741
+ case "WhenClause":
1742
+ case "DefaultClause":
1743
+ case "PatternClause": {
1744
+ assignResults(node.block, collect);
1745
+ return;
1746
+ }
1747
+ }
1748
+ if (!Array.isArray(node)) {
1749
+ return;
1750
+ }
1751
+ let [, exp] = node;
1752
+ if (!exp) {
1753
+ return;
1754
+ }
1755
+ const outer = exp;
1756
+ let { type } = exp;
1757
+ if (type === "LabelledStatement") {
1758
+ exp = exp.statement;
1759
+ ({ type } = exp);
1760
+ }
1761
+ switch (exp.type) {
1762
+ case "BreakStatement":
1763
+ case "ContinueStatement":
1764
+ case "DebuggerStatement":
1765
+ case "EmptyStatement":
1766
+ case "ReturnStatement":
1767
+ case "ThrowStatement":
1768
+ return;
1769
+ case "Declaration":
1770
+ exp.children.push([
1771
+ "",
1772
+ [";", collect(patternAsValue(exp.bindings.at(-1).pattern))]
1773
+ ]);
1774
+ return;
1775
+ case "ForStatement":
1776
+ case "IterationStatement":
1777
+ case "DoStatement":
1778
+ wrapIterationReturningResults(exp, outer, collect);
1779
+ return;
1780
+ case "BlockStatement":
1781
+ assignResults(exp.expressions[exp.expressions.length - 1], collect);
1782
+ return;
1783
+ case "IfStatement":
1784
+ assignResults(exp.then, collect);
1785
+ if (exp.then.bare && !exp.then.semicolon) {
1786
+ exp.then.children.push(exp.then.semicolon = ";");
1787
+ }
1788
+ if (exp.else) {
1789
+ assignResults(exp.else[2], collect);
1790
+ } else {
1791
+ exp.children.push([" else {", collect("undefined"), "}"]);
1792
+ }
1793
+ return;
1794
+ case "PatternMatchingStatement":
1795
+ assignResults(exp.children[0][0], collect);
1796
+ return;
1797
+ case "SwitchStatement":
1798
+ assignResults(exp.children[2], collect);
1799
+ return;
1800
+ case "TryStatement":
1801
+ exp.blocks.forEach((block) => assignResults(block, collect));
1802
+ return;
1803
+ }
1804
+ if (node.at(-1)?.type === "SemicolonDelimiter") {
1805
+ return;
1806
+ }
1807
+ node[1] = collect(node[1]);
1808
+ }
1809
+ function insertReturn(node, outerNode = node) {
1810
+ if (!node)
1811
+ return;
1812
+ switch (node.type) {
1813
+ case "BlockStatement":
1814
+ if (node.expressions.length) {
1815
+ const last = node.expressions[node.expressions.length - 1];
1816
+ insertReturn(last);
1817
+ } else {
1818
+ if (node.parent.type === "CatchClause") {
1819
+ node.expressions.push(["return"]);
1820
+ }
1821
+ }
1822
+ return;
1823
+ case "WhenClause":
1824
+ if (node.break) {
1825
+ node.children.splice(node.children.indexOf(node.break), 1);
1826
+ }
1827
+ if (node.block.expressions.length) {
1828
+ insertReturn(node.block);
1829
+ } else {
1830
+ node.block.expressions.push(wrapWithReturn());
1831
+ }
1832
+ return;
1833
+ case "DefaultClause":
1834
+ insertReturn(node.block);
1835
+ return;
1836
+ }
1837
+ if (!Array.isArray(node))
1838
+ return;
1839
+ let [, exp, semi] = node;
1840
+ if (semi?.type === "SemicolonDelimiter") {
1841
+ return;
1842
+ }
1843
+ if (!exp) {
1844
+ return;
1845
+ }
1846
+ const outer = exp;
1847
+ let { type } = exp;
1848
+ if (type === "LabelledStatement") {
1849
+ exp = exp.statement;
1850
+ ({ type } = exp);
1851
+ }
1852
+ switch (type) {
1853
+ case "BreakStatement":
1560
1854
  case "ContinueStatement":
1561
1855
  case "DebuggerStatement":
1562
1856
  case "EmptyStatement":
@@ -1623,24 +1917,31 @@ var Civet = (() => {
1623
1917
  return insertReturn(clause);
1624
1918
  });
1625
1919
  }
1626
- function wrapIterationReturningResults(statement, outer, outerRef) {
1920
+ function wrapIterationReturningResults(statement, outer, collect) {
1627
1921
  if (statement.type === "DoStatement") {
1628
- if (outerRef) {
1629
- insertPush(statement.block, outerRef);
1922
+ if (collect) {
1923
+ assignResults(statement.block, collect);
1630
1924
  } else {
1631
1925
  insertReturn(statement.block, outer);
1632
1926
  }
1633
1927
  return;
1634
1928
  }
1635
- const resultsRef = makeRef("results");
1929
+ assert.equal(
1930
+ statement.resultsRef,
1931
+ void 0,
1932
+ "wrapIterationReturningResults should not be called twice on the same statement"
1933
+ );
1934
+ const resultsRef = statement.resultsRef = makeRef("results");
1636
1935
  const declaration = {
1637
1936
  type: "Declaration",
1638
- children: ["const ", resultsRef, "=[];"]
1937
+ children: ["const ", resultsRef, "=[]"]
1639
1938
  };
1640
- insertPush(statement.block, resultsRef);
1641
- outer.children.unshift(declaration);
1642
- if (outerRef) {
1643
- statement.children.push(";", outerRef, ".push(", resultsRef, ");");
1939
+ outer.children.unshift(["", declaration, ";"]);
1940
+ assignResults(statement.block, (node) => {
1941
+ return [resultsRef, ".push(", node, ")"];
1942
+ });
1943
+ if (collect) {
1944
+ statement.children.push(collect(resultsRef));
1644
1945
  } else {
1645
1946
  statement.children.push(";return ", resultsRef, ";");
1646
1947
  }
@@ -1723,8 +2024,11 @@ var Civet = (() => {
1723
2024
  updateParentPointers(exp);
1724
2025
  return;
1725
2026
  }
1726
- const resultsRef = makeRef("results");
1727
- insertPush(block, resultsRef);
2027
+ exp.resultsRef ??= makeRef("results");
2028
+ const { resultsRef } = exp;
2029
+ assignResults(block, (node) => {
2030
+ return [resultsRef, ".push(", node, ")"];
2031
+ });
1728
2032
  braceBlock(block);
1729
2033
  children.splice(
1730
2034
  i,
@@ -1737,6 +2041,19 @@ var Civet = (() => {
1737
2041
  );
1738
2042
  updateParentPointers(exp);
1739
2043
  }
2044
+ function skipImplicitArguments(args) {
2045
+ if (args.length === 1) {
2046
+ let arg0 = args[0];
2047
+ if (Array.isArray(arg0)) {
2048
+ arg0 = arg0[1];
2049
+ }
2050
+ if (arg0.type === "StatementExpression") {
2051
+ arg0 = arg0.statement;
2052
+ }
2053
+ return arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block);
2054
+ }
2055
+ return false;
2056
+ }
1740
2057
  var init_function = __esm({
1741
2058
  "source/parser/function.civet"() {
1742
2059
  "use strict";
@@ -1747,864 +2064,764 @@ var Civet = (() => {
1747
2064
  }
1748
2065
  });
1749
2066
 
1750
- // source/parser/op.civet
1751
- function getPrecedence(op) {
1752
- if (typeof op === "string") {
1753
- return precedenceMap.get(op) ?? (() => {
1754
- throw new Error(`Unknown operator: ${op}`);
1755
- })();
1756
- } else if (typeof op.prec === "number") {
1757
- return op.prec;
2067
+ // source/parser/declaration.civet
2068
+ function processAssignmentDeclaration(decl, pattern, suffix, ws, assign, e) {
2069
+ decl = {
2070
+ ...decl,
2071
+ $loc: {
2072
+ pos: assign.$loc.pos - 1,
2073
+ length: assign.$loc.length + 1
2074
+ }
2075
+ };
2076
+ let [splices, assignments] = gatherBindingCode(pattern);
2077
+ splices = splices.map((s) => [", ", s]);
2078
+ const thisAssignments = assignments.map((a) => ["", a, ";"]);
2079
+ const initializer = [ws, assign, e];
2080
+ const binding = makeNode({
2081
+ type: "Binding",
2082
+ pattern,
2083
+ initializer,
2084
+ splices,
2085
+ suffix,
2086
+ thisAssignments,
2087
+ children: [pattern, suffix, initializer]
2088
+ });
2089
+ const children = [decl, binding];
2090
+ return makeNode({
2091
+ type: "Declaration",
2092
+ names: pattern.names,
2093
+ decl,
2094
+ bindings: [binding],
2095
+ splices,
2096
+ thisAssignments,
2097
+ children
2098
+ });
2099
+ }
2100
+ function processDeclarations(statements) {
2101
+ gatherRecursiveAll(statements, ($) => $.type === "Declaration").forEach((statement) => {
2102
+ const { bindings } = statement;
2103
+ return bindings?.forEach((binding) => {
2104
+ const suffix = binding.suffix;
2105
+ if (suffix && suffix.optional && suffix.t) {
2106
+ convertOptionalType(suffix);
2107
+ }
2108
+ const { initializer } = binding;
2109
+ if (initializer) {
2110
+ return prependStatementExpressionBlock(initializer, statement);
2111
+ }
2112
+ ;
2113
+ return;
2114
+ });
2115
+ });
2116
+ }
2117
+ function prependStatementExpressionBlock(initializer, statement) {
2118
+ let exp = initializer[2];
2119
+ let ws;
2120
+ if (Array.isArray(exp)) {
2121
+ ws = exp[0];
2122
+ exp = exp[1];
2123
+ }
2124
+ if (!(exp.type === "StatementExpression")) {
2125
+ return;
2126
+ }
2127
+ const pre = [];
2128
+ const statementExp = exp.statement;
2129
+ const blockStatement = ["", statementExp];
2130
+ let ref;
2131
+ if (statementExp.type === "IterationExpression") {
2132
+ if (statementExp.async) {
2133
+ return;
2134
+ }
2135
+ const statement2 = statementExp.statement;
2136
+ blockStatement[1] = statement2;
2137
+ if (statement2.type === "DoStatement") {
2138
+ ref = initializer[2] = makeRef();
2139
+ assignResults(blockStatement, (resultNode) => {
2140
+ return makeNode({
2141
+ type: "AssignmentExpression",
2142
+ children: [ref, " = ", resultNode]
2143
+ });
2144
+ });
2145
+ const refDec = {
2146
+ type: "Declaration",
2147
+ children: ["let ", ref, ";"]
2148
+ };
2149
+ pre.unshift(refDec);
2150
+ } else {
2151
+ wrapIterationReturningResults(statement2, { children: blockStatement }, function() {
2152
+ });
2153
+ ref = initializer[2] = statement2.resultsRef;
2154
+ }
1758
2155
  } else {
1759
- return precedenceMap.get(op.prec ?? op.token) ?? (op.relational ? precedenceRelational : precedenceCustomDefault);
2156
+ ref = initializer[2] = makeRef();
2157
+ assignResults(blockStatement, (resultNode) => {
2158
+ return makeNode({
2159
+ type: "AssignmentExpression",
2160
+ children: [ref, " = ", resultNode]
2161
+ });
2162
+ });
2163
+ const refDec = {
2164
+ type: "Declaration",
2165
+ children: ["let ", ref, ";"]
2166
+ };
2167
+ pre.unshift(refDec);
2168
+ if (ws) {
2169
+ pre.push(ws);
2170
+ }
1760
2171
  }
2172
+ statement.children.unshift(pre, blockStatement, ";");
2173
+ updateParentPointers(blockStatement, statement);
2174
+ return ref;
1761
2175
  }
1762
- function processBinaryOpExpression($0) {
1763
- return recurse(expandChainedComparisons($0));
1764
- function recurse(expandedOps) {
1765
- let i = 2;
1766
- while (i < expandedOps.length) {
1767
- let op = expandedOps[i];
1768
- if (op.special) {
1769
- let advanceLeft2 = function(allowEqual) {
1770
- while (start >= 4) {
1771
- const prevPrec = getPrecedence(expandedOps[start - 2]);
1772
- if (!(prevPrec > prec || allowEqual && prevPrec === prec)) {
1773
- return prevPrec === prec;
1774
- }
1775
- start -= 4;
1776
- }
1777
- return false;
1778
- }, advanceRight2 = function(allowEqual) {
1779
- while (end + 4 < expandedOps.length) {
1780
- const nextPrec = getPrecedence(expandedOps[end + 2]);
1781
- if (!(nextPrec > prec || allowEqual && nextPrec === prec)) {
1782
- return nextPrec === prec;
1783
- }
1784
- end += 4;
1785
- }
1786
- return false;
1787
- };
1788
- var advanceLeft = advanceLeft2, advanceRight = advanceRight2;
1789
- let start = i - 2, end = i + 2;
1790
- const prec = getPrecedence(op);
1791
- let error;
1792
- switch (op.assoc) {
1793
- case "left":
1794
- case void 0: {
1795
- advanceLeft2(true);
1796
- advanceRight2(false);
1797
- break;
1798
- }
1799
- case "right": {
1800
- advanceLeft2(false);
1801
- advanceRight2(true);
1802
- break;
1803
- }
1804
- case "non": {
1805
- if (advanceLeft2(false) || advanceRight2(false)) {
1806
- error = {
1807
- type: "Error",
1808
- message: `non-associative operator ${op.token} used at same precedence level without parenthesization`
1809
- };
1810
- }
1811
- ;
1812
- break;
1813
- }
1814
- case "arguments": {
1815
- if (advanceLeft2(false)) {
1816
- error = {
1817
- type: "Error",
1818
- message: `arguments operator ${op.token} used at same precedence level as ${expandedOps[start - 2].token} to the left`
1819
- };
1820
- }
1821
- advanceRight2(true);
1822
- break;
1823
- }
1824
- default: {
1825
- throw new Error(`Unsupported associativity: ${op.assoc}`);
1826
- }
1827
- }
1828
- let a = start === i - 2 ? expandedOps[start] : expandedOps.slice(start, i - 1);
1829
- let wsOp = expandedOps[i - 1];
1830
- let wsB = expandedOps[i + 1];
1831
- let b = end === i + 2 ? expandedOps[i + 2] : expandedOps.slice(i + 2, end + 1);
1832
- if (op.assoc === "arguments") {
1833
- let i2 = 2;
1834
- while (i2 < b.length) {
1835
- if (prec === getPrecedence(b[i2])) {
1836
- if (!(b[i2].token === op.token)) {
1837
- error ??= {
1838
- type: "Error",
1839
- message: `arguments operator ${op.token} used at same precedence level as ${b[i2].token} to the right`
1840
- };
1841
- }
1842
- b[i2] = ",";
1843
- }
1844
- i2 += 4;
1845
- }
1846
- } else {
1847
- b = recurse(b);
1848
- }
1849
- if (op.token === "instanceof" && b.type === "Literal" && b.children?.[0]?.type === "StringLiteral") {
1850
- a = ["typeof ", makeLeftHandSideExpression(a)];
1851
- if (op.negated) {
1852
- op = { ...op, token: "!==", negated: false };
1853
- } else {
1854
- op = { ...op, token: "===" };
1855
- }
1856
- }
1857
- if (op.asConst) {
1858
- a = makeAsConst(a);
1859
- b = makeAsConst(b);
1860
- }
1861
- let children;
1862
- if (op.call) {
1863
- wsOp = insertTrimmingSpace(wsOp, "");
1864
- if (op.reversed) {
1865
- wsB = insertTrimmingSpace(wsB, "");
1866
- children = [wsOp, op.call, "(", wsB, b, ", ", a, ")", op.suffix];
1867
- } else {
1868
- children = [wsOp, op.call, "(", a, ",", wsB, b, ")", op.suffix];
1869
- }
1870
- } else if (op.method) {
1871
- wsOp = insertTrimmingSpace(wsOp, "");
1872
- wsB = insertTrimmingSpace(wsB, "");
1873
- if (op.reversed) {
1874
- if (end !== i + 2)
1875
- b = makeLeftHandSideExpression(b);
1876
- b = dotNumericLiteral(b);
1877
- children = [wsB, b, wsOp, ".", op.method, "(", a, ")"];
1878
- } else {
1879
- if (start !== i - 2 || a.type === "NumericLiteral") {
1880
- a = makeLeftHandSideExpression(a);
1881
- }
1882
- a = dotNumericLiteral(a);
1883
- children = [a, wsOp, ".", op.method, "(", wsB, b, ")"];
1884
- }
1885
- } else if (op.token) {
1886
- children = [a, wsOp, op, wsB, b];
1887
- if (op.negated)
1888
- children = ["(", ...children, ")"];
1889
- } else {
1890
- throw new Error("Unknown operator: " + JSON.stringify(op));
1891
- }
1892
- if (op.negated)
1893
- children.unshift("!");
1894
- if (error != null) {
1895
- children.push(error);
1896
- }
1897
- expandedOps.splice(start, end - start + 1, {
1898
- children
1899
- });
1900
- i = start + 2;
1901
- } else {
1902
- i += 4;
1903
- }
1904
- }
1905
- return expandedOps;
1906
- }
1907
- ;
1908
- return recurse;
1909
- }
1910
- function dotNumericLiteral(literal) {
1911
- if (literal?.type === "Literal" && /^[+-]?(?:0|[1-9](?:_[0-9]|[0-9])*)$/.test(literal.raw)) {
1912
- literal.children.push(".");
1913
- literal.raw += ".";
1914
- }
1915
- return literal;
1916
- }
1917
- function makeAsConst(node) {
1918
- if (Array.isArray(node) && node.length === 1) {
1919
- node = node[0];
2176
+ function processDeclarationCondition(condition, rootCondition, parent) {
2177
+ if (!(condition.type === "DeclarationCondition")) {
2178
+ return;
1920
2179
  }
1921
- if (node.type === "Literal" && node.raw !== "null" || node.type === "ArrayExpression" || node.type === "ObjectExpression") {
1922
- return { ...node, children: [...node.children, asConst] };
2180
+ const { decl, bindings } = condition.declaration;
2181
+ const binding = bindings[0];
2182
+ const { pattern, suffix, initializer, splices, thisAssignments } = binding;
2183
+ let ref = prependStatementExpressionBlock(initializer, parent);
2184
+ if (ref) {
2185
+ Object.assign(condition, {
2186
+ type: "AssignmentExpression",
2187
+ children: [ref],
2188
+ pattern,
2189
+ ref,
2190
+ statementDeclaration: true
2191
+ });
1923
2192
  } else {
1924
- return node;
1925
- }
1926
- }
1927
- function isExistence(exp) {
1928
- if (exp.type === "ParenthesizedExpression" && exp.implicit) {
1929
- exp = exp.expression;
1930
- }
1931
- if (exp.type === "Existence") {
1932
- return exp;
2193
+ ref = makeRef();
2194
+ const grandparent = condition.parent?.parent;
2195
+ const children = (
2196
+ // Check that the declaration is a plain assignment (no pattern-matching) and the immediate grandchild of an `if` or `while`
2197
+ // More complex conditions (triggered by pattern matching or `until`/`unless`) don't need double parens
2198
+ // @ts-ignore Just because pattern might not have a type at runtime doesn't mean it's unsafe
2199
+ pattern.type === "Identifier" && (grandparent?.type === "IfStatement" || grandparent?.type === "WhileStatement") ? ["(", ref, initializer, ")"] : [ref, initializer]
2200
+ );
2201
+ Object.assign(condition, {
2202
+ type: "AssignmentExpression",
2203
+ children,
2204
+ hoistDec: {
2205
+ type: "Declaration",
2206
+ children: ["let ", ref, suffix],
2207
+ names: []
2208
+ },
2209
+ pattern,
2210
+ ref
2211
+ });
1933
2212
  }
1934
- ;
1935
- return;
2213
+ addParentPointers(condition, parent);
2214
+ Object.assign(rootCondition, {
2215
+ blockPrefix: [
2216
+ ["", [decl, pattern, suffix, " = ", ref, ...splices], ";"],
2217
+ ...thisAssignments
2218
+ ]
2219
+ });
1936
2220
  }
1937
- function isRelationalOp(op) {
1938
- return op.relational || getPrecedence(op) === precedenceRelational;
2221
+ function processDeclarationConditions(node, getRef) {
2222
+ gatherRecursiveAll(node, (n) => {
2223
+ return n.type === "IfStatement" || n.type === "IterationStatement" || n.type === "SwitchStatement";
2224
+ }).forEach((s) => {
2225
+ return processDeclarationConditionStatement(s, getRef);
2226
+ });
1939
2227
  }
1940
- function expandChainedComparisons([first, binops]) {
1941
- const results = [];
1942
- let i = 0;
1943
- const l = binops.length;
1944
- let start = 0;
1945
- let chains = [];
1946
- let op;
1947
- while (i < l) {
1948
- [, op] = binops[i];
1949
- if (isRelationalOp(op)) {
1950
- chains.push(i);
1951
- } else if (getPrecedence(op) < precedenceRelational) {
1952
- processChains(op);
1953
- first = void 0;
1954
- }
1955
- i++;
2228
+ function processDeclarationConditionStatement(s, getRef) {
2229
+ const { condition } = s;
2230
+ if (!condition?.expression) {
2231
+ return;
1956
2232
  }
1957
- if (op != null) {
1958
- processChains(op);
2233
+ let { expression } = condition;
2234
+ 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]) {
2235
+ const { type: type1, children: [, { type: type2, expression: expression2 }] } = expression;
2236
+ const type = [type1, type2];
2237
+ expression = expression2;
1959
2238
  }
1960
- return results;
1961
- function processChains(op2) {
1962
- if (first && isRelationalOp(op2)) {
1963
- first = expandExistence(first);
2239
+ processDeclarationCondition(expression, condition.expression, s);
2240
+ const { ref, pattern } = expression;
2241
+ if (pattern) {
2242
+ let conditions = [];
2243
+ getPatternConditions(pattern, ref, conditions, getRef);
2244
+ conditions = conditions.filter((c) => {
2245
+ return !(c.length === 3 && c[0] === "typeof " && c[1] === ref && c[2] === " === 'object'") && !(c.length === 2 && c[0] === ref && c[1] === " != null");
2246
+ });
2247
+ if (conditions.length) {
2248
+ condition.children.unshift("(");
2249
+ conditions.forEach(function(c) {
2250
+ return condition.children.push(" && ", c);
2251
+ });
2252
+ condition.children.push(")");
1964
2253
  }
1965
- if (chains.length > 1) {
1966
- chains.forEach((index, k) => {
1967
- if (k > 0) {
1968
- results.push(" ", "&&", " ");
1969
- }
1970
- const binop = binops[index];
1971
- let [, , , exp] = binop;
1972
- exp = binop[3] = expandExistence(exp);
1973
- let endIndex;
1974
- if (k < chains.length - 1) {
1975
- endIndex = chains[k + 1];
2254
+ }
2255
+ switch (s.type) {
2256
+ case "IfStatement": {
2257
+ const { else: e } = s;
2258
+ const block = blockWithPrefix(condition.expression.blockPrefix, s.then);
2259
+ if (block.bare && e && !block.semicolon) {
2260
+ block.children.push(block.semicolon = ";");
2261
+ }
2262
+ s.children = s.children.map((c) => {
2263
+ if (c === s.then) {
2264
+ return block;
1976
2265
  } else {
1977
- endIndex = i + 1;
2266
+ return c;
1978
2267
  }
1979
- results.push(first, ...binops.slice(start, endIndex).flat());
1980
- first = [exp].concat(binops.slice(index + 1, endIndex));
1981
- return start = endIndex;
1982
2268
  });
1983
- } else {
1984
- if (first) {
1985
- results.push(first);
1986
- }
1987
- results.push(...binops.slice(start, i + 1).flat());
1988
- start = i + 1;
1989
- }
1990
- chains.length = 0;
1991
- }
1992
- function expandExistence(exp) {
1993
- const existence = isExistence(exp);
1994
- if (existence) {
1995
- results.push(existence, " ", "&&", " ");
1996
- return existence.expression;
2269
+ s.then = block;
2270
+ updateParentPointers(block, s);
2271
+ break;
2272
+ }
2273
+ case "IterationStatement": {
2274
+ const { children, block } = s;
2275
+ const newBlock = blockWithPrefix(condition.expression.blockPrefix, block);
2276
+ s.children = children.map((c) => c?.type === "BlockStatement" ? newBlock : c);
2277
+ updateParentPointers(newBlock, s);
2278
+ break;
2279
+ }
2280
+ case "SwitchStatement": {
2281
+ const { blockPrefix, ref: ref2, statementDeclaration } = condition.expression;
2282
+ if (!blockPrefix) {
2283
+ return;
2284
+ }
2285
+ const newCondition = {
2286
+ type: "ParenthesizedExpression",
2287
+ children: ["(", ref2, ")"],
2288
+ expression: ref2,
2289
+ parent: s
2290
+ };
2291
+ s.children = s.children.map(function(c) {
2292
+ if (c === s.condition) {
2293
+ return newCondition;
2294
+ } else {
2295
+ return c;
2296
+ }
2297
+ });
2298
+ s.condition = newCondition;
2299
+ updateParentPointers(s);
2300
+ if (statementDeclaration) {
2301
+ const block = makeEmptyBlock();
2302
+ replaceBlockExpression(s.parent, s, block);
2303
+ block.expressions.push(["", s]);
2304
+ s.children.splice(s.children.findIndex(($1) => $1.token === "switch"), 0, blockPrefix);
2305
+ s.parent = block;
2306
+ } else {
2307
+ const block = blockWithPrefix([["", [{
2308
+ type: "Declaration",
2309
+ children: ["let ", ...condition.expression.children]
2310
+ }], ";"], ...blockPrefix], makeEmptyBlock());
2311
+ updateParentPointers(block, s.parent);
2312
+ replaceBlockExpression(s.parent, s, block);
2313
+ block.expressions.push(["", s]);
2314
+ s.parent = block;
2315
+ }
2316
+ ;
2317
+ break;
1997
2318
  }
1998
- return exp;
1999
2319
  }
2000
- ;
2001
2320
  }
2002
- var precedenceOrder, precedenceMap, precedenceStep, precedenceRelational, precedenceCustomDefault, asConst;
2003
- var init_op = __esm({
2004
- "source/parser/op.civet"() {
2321
+ var init_declaration = __esm({
2322
+ "source/parser/declaration.civet"() {
2005
2323
  "use strict";
2324
+ init_block();
2325
+ init_traversal();
2326
+ init_pattern_matching();
2006
2327
  init_util();
2007
- precedenceOrder = [
2008
- ["||", "??"],
2009
- ["^^"],
2010
- ["&&"],
2011
- ["|"],
2012
- ["^"],
2013
- ["&"],
2014
- // NOTE: Equality and inequality merged because of relational chaining
2015
- [
2016
- "==",
2017
- "!=",
2018
- "===",
2019
- "!==",
2020
- "<",
2021
- "<=",
2022
- ">",
2023
- ">=",
2024
- "in",
2025
- "instanceof"
2026
- ],
2027
- // NOTE: Extra in-between level for default custom operators
2028
- ["custom"],
2029
- ["<<", ">>", ">>>"],
2030
- ["+", "-"],
2031
- ["*", "/", "%"],
2032
- ["**"]
2033
- ];
2034
- precedenceMap = /* @__PURE__ */ new Map();
2035
- for (let i1 = 0, len = precedenceOrder.length; i1 < len; i1++) {
2036
- const prec = i1;
2037
- const ops = precedenceOrder[i1];
2038
- for (let i2 = 0, len1 = ops.length; i2 < len1; i2++) {
2039
- const op = ops[i2];
2040
- precedenceMap.set(op, prec);
2041
- }
2042
- }
2043
- precedenceStep = 1 / 64;
2044
- precedenceRelational = precedenceMap.get("==");
2045
- precedenceCustomDefault = precedenceMap.get("custom");
2046
- asConst = {
2047
- ts: true,
2048
- children: [" as const"]
2049
- };
2328
+ init_function();
2329
+ init_binding();
2050
2330
  }
2051
2331
  });
2052
2332
 
2053
- // source/parser/pattern-matching.civet
2054
- function processPatternMatching(statements, ReservedWord) {
2055
- gatherRecursiveAll(statements, ($) => $.type === "SwitchStatement").forEach((s) => {
2056
- const { caseBlock } = s;
2057
- const { clauses } = caseBlock;
2058
- for (const c of clauses) {
2059
- if (c.type === "WhenClause" && c.break) {
2060
- const last = c.block?.expressions?.at(-1)?.[1];
2061
- if (isExit(last)) {
2062
- c.children.splice(c.children.indexOf(c.break), 1);
2063
- c.break = void 0;
2064
- }
2333
+ // source/parser/unary.civet
2334
+ function processUnaryExpression(pre, exp, post) {
2335
+ if (!(pre.length || post))
2336
+ return exp;
2337
+ if (post?.token === "?") {
2338
+ post = {
2339
+ $loc: post.$loc,
2340
+ token: " != null"
2341
+ };
2342
+ if (pre.length) {
2343
+ const lastPre = pre[pre.length - 1];
2344
+ if (lastPre.token === "!") {
2345
+ post.token = " == null";
2346
+ pre = pre.slice(0, -1);
2347
+ } else if (lastPre.length === 2 && lastPre[0].token === "!") {
2348
+ post.token = " == null";
2349
+ pre = pre.slice(0, -1);
2065
2350
  }
2066
2351
  }
2067
- let errors = false;
2068
- let isPattern = false;
2069
- if (clauses.some(($1) => $1.type === "PatternClause")) {
2070
- isPattern = true;
2071
- clauses.forEach((c) => {
2072
- if (!(c.type === "PatternClause" || c.type === "DefaultClause")) {
2073
- errors = true;
2074
- return c.children.push({
2075
- type: "Error",
2076
- message: "Can't mix pattern matching and non-pattern matching clauses"
2077
- });
2078
- }
2079
- ;
2080
- return;
2081
- });
2082
- }
2083
- if (errors || !isPattern) {
2084
- return;
2085
- }
2086
- let { condition } = s;
2087
- if (condition.type === "ParenthesizedExpression") {
2088
- condition = condition.expression;
2089
- }
2090
- let hoistDec, refAssignment = [], ref = maybeRef(condition, "m");
2091
- if (ref !== condition) {
2092
- hoistDec = {
2093
- type: "Declaration",
2094
- children: ["let ", ref],
2095
- names: []
2352
+ const existence = {
2353
+ type: "Existence",
2354
+ expression: exp,
2355
+ children: [exp, post]
2356
+ };
2357
+ exp = makeLeftHandSideExpression(existence);
2358
+ if (pre.length) {
2359
+ return {
2360
+ type: "UnaryExpression",
2361
+ children: [...pre, exp]
2096
2362
  };
2097
- refAssignment = [{
2098
- type: "AssignmentExpression",
2099
- children: [ref, " = ", condition]
2100
- }, ","];
2101
2363
  }
2102
- let prev = [], root = prev;
2103
- const l = clauses.length;
2104
- clauses.forEach((c, i) => {
2105
- if (c.type === "DefaultClause") {
2106
- prev.push(c.block);
2107
- return;
2364
+ return exp;
2365
+ }
2366
+ if (exp.type === "Literal") {
2367
+ if (pre.length === 1) {
2368
+ const { token } = pre[0];
2369
+ if (token === "-" || token === "+") {
2370
+ const children = [pre[0], ...exp.children];
2371
+ if (post)
2372
+ exp.children.push(post);
2373
+ return {
2374
+ type: "Literal",
2375
+ children,
2376
+ raw: `${token}${exp.raw}`
2377
+ };
2108
2378
  }
2109
- let { patterns, block } = c;
2110
- let pattern = patterns[0];
2111
- const indent = block.expressions?.[0]?.[0] || "";
2112
- const alternativeConditions = patterns.map((pattern2, i2) => {
2113
- const conditions = [];
2114
- getPatternConditions(pattern2, ref, conditions);
2115
- return conditions;
2116
- });
2117
- const conditionExpression = alternativeConditions.map((conditions, i2) => {
2118
- const conditionArray = conditions.map((c2, i3) => {
2119
- if (i3 === 0)
2120
- return c2;
2121
- return [" && ", ...c2];
2122
- });
2123
- if (i2 === 0)
2124
- return conditionArray;
2125
- return [" || ", ...conditionArray];
2126
- });
2127
- const condition2 = {
2128
- type: "ParenthesizedExpression",
2129
- children: ["(", ...refAssignment, conditionExpression, ")"],
2130
- expression: conditionExpression
2131
- };
2132
- const prefix = [];
2133
- switch (pattern.type) {
2134
- case "ArrayBindingPattern":
2135
- if (pattern.length === 0)
2136
- break;
2137
- case "ObjectBindingPattern": {
2138
- if (pattern.properties?.length === 0)
2139
- break;
2140
- let [splices, thisAssignments] = gatherBindingCode(pattern);
2141
- const patternBindings = nonMatcherBindings(pattern);
2142
- splices = splices.map((s2) => [", ", nonMatcherBindings(s2)]);
2143
- thisAssignments = thisAssignments.map((a) => [indent, a, ";"]);
2144
- const duplicateDeclarations = aggregateDuplicateBindings([patternBindings, splices], ReservedWord);
2145
- prefix.push([indent, "const ", patternBindings, " = ", ref, splices, ";"]);
2146
- prefix.push(...thisAssignments);
2147
- prefix.push(...duplicateDeclarations.map((d) => [indent, d, ";"]));
2148
- break;
2379
+ }
2380
+ }
2381
+ let ref;
2382
+ while (ref = pre.length) {
2383
+ const l = ref;
2384
+ const last = pre[l - 1];
2385
+ if (last.type === "Await") {
2386
+ if (last.op) {
2387
+ if (exp.type !== "ParenthesizedExpression") {
2388
+ exp = ["(", exp, ")"];
2149
2389
  }
2390
+ exp = {
2391
+ type: "CallExpression",
2392
+ children: [...last.children, "Promise", last.op, exp]
2393
+ };
2394
+ pre = pre.slice(0, -1);
2395
+ } else {
2396
+ exp = {
2397
+ type: "AwaitExpression",
2398
+ children: [...last.children, exp]
2399
+ };
2400
+ pre = pre.slice(0, -1);
2150
2401
  }
2151
- block.expressions.unshift(...prefix);
2152
- const next = [];
2153
- braceBlock(block);
2154
- if (i < l - 1)
2155
- next.push("\n", "else ");
2156
- prev.push(["", {
2157
- type: "IfStatement",
2158
- children: ["if", condition2, block, next],
2159
- then: block,
2160
- else: next,
2161
- hoistDec
2162
- }]);
2163
- hoistDec = void 0;
2164
- refAssignment = [];
2165
- return prev = next;
2166
- });
2167
- s.type = "PatternMatchingStatement";
2168
- s.children = [root];
2169
- return addParentPointers(s, s.parent);
2170
- });
2171
- }
2172
- function getPatternConditions(pattern, ref, conditions) {
2173
- if (pattern.rest)
2174
- return;
2175
- switch (pattern.type) {
2176
- case "ArrayBindingPattern": {
2177
- const { elements, length } = pattern, hasRest = elements.some((e) => e.rest), comparator = hasRest ? " >= " : " === ", l = [comparator, (length - hasRest).toString()];
2178
- conditions.push(
2179
- ["Array.isArray(", ref, ")"],
2180
- [ref, ".length", l]
2181
- );
2182
- elements.forEach(({ children: [, e] }, i) => {
2183
- const subRef = [ref, "[", i.toString(), "]"];
2184
- return getPatternConditions(e, subRef, conditions);
2185
- });
2186
- const { blockPrefix } = pattern;
2187
- if (blockPrefix) {
2188
- const postElements = blockPrefix.children[1], { length: postLength } = postElements;
2189
- postElements.forEach(({ children: [, e] }, i) => {
2190
- const subRef = [ref, "[", ref, ".length - ", (postLength + i).toString(), "]"];
2191
- return getPatternConditions(e, subRef, conditions);
2192
- });
2193
- }
2194
- break;
2195
- }
2196
- case "ObjectBindingPattern": {
2197
- conditions.push(
2198
- ["typeof ", ref, " === 'object'"],
2199
- [ref, " != null"]
2200
- );
2201
- pattern.properties.forEach((p) => {
2202
- switch (p.type) {
2203
- case "PinProperty":
2204
- case "BindingProperty": {
2205
- const { name, value } = p;
2206
- let subRef;
2207
- switch (name.type) {
2208
- case "ComputedPropertyName":
2209
- conditions.push([name.expression, " in ", ref]);
2210
- subRef = [ref, name];
2211
- break;
2212
- case "Literal":
2213
- case "StringLiteral":
2214
- case "NumericLiteral":
2215
- conditions.push([name, " in ", ref]);
2216
- subRef = [ref, "[", name, "]"];
2217
- break;
2218
- default:
2219
- conditions.push(["'", name, "' in ", ref]);
2220
- subRef = [ref, ".", name];
2221
- }
2222
- if (value) {
2223
- getPatternConditions(value, subRef, conditions);
2224
- }
2225
- break;
2226
- }
2227
- }
2228
- });
2229
- break;
2230
- }
2231
- case "ConditionFragment": {
2232
- let { children } = pattern;
2233
- if (children.length) {
2234
- let [first, ...rest] = children;
2235
- let [ws, ...op] = first;
2236
- ws = [" "].concat(ws);
2237
- first = [ws, ...op];
2238
- children = [first, ...rest];
2239
- }
2240
- conditions.push(
2241
- processBinaryOpExpression([ref, children])
2242
- );
2243
- break;
2244
- }
2245
- case "RegularExpressionLiteral": {
2246
- conditions.push(
2247
- ["typeof ", ref, " === 'string'"],
2248
- [pattern, ".test(", ref, ")"]
2249
- );
2402
+ } else {
2250
2403
  break;
2251
2404
  }
2252
- case "PinPattern":
2253
- conditions.push([
2254
- ref,
2255
- " === ",
2256
- pattern.expression
2257
- ]);
2258
- break;
2259
- case "Literal":
2260
- conditions.push([
2261
- ref,
2262
- " === ",
2263
- pattern
2264
- ]);
2265
- break;
2266
- default:
2267
- break;
2268
2405
  }
2406
+ return {
2407
+ type: "UnaryExpression",
2408
+ children: [...pre, exp, post]
2409
+ };
2269
2410
  }
2270
- function elideMatchersFromArrayBindings(elements) {
2271
- return elements.map((el) => {
2272
- if (el.type === "BindingRestElement") {
2273
- return ["", el, void 0];
2274
- }
2275
- const { children: [ws, e, delim] } = el;
2276
- switch (e.type) {
2277
- case "Literal":
2278
- case "RegularExpressionLiteral":
2279
- case "StringLiteral":
2280
- case "PinPattern":
2281
- return delim;
2282
- default:
2283
- return [ws, nonMatcherBindings(e), delim];
2284
- }
2285
- });
2411
+ var init_unary = __esm({
2412
+ "source/parser/unary.civet"() {
2413
+ "use strict";
2414
+ init_util();
2415
+ }
2416
+ });
2417
+
2418
+ // source/parser/pipe.civet
2419
+ function constructInvocation(fn, arg) {
2420
+ const fnArr = [fn.leadingComment, fn.expr, fn.trailingComment];
2421
+ let expr = fn.expr;
2422
+ while (expr.type === "ParenthesizedExpression") {
2423
+ expr = expr.expression;
2424
+ }
2425
+ if (expr.ampersandBlock) {
2426
+ const { ref, body } = expr;
2427
+ ref.type = "PipedExpression";
2428
+ ref.children = [makeLeftHandSideExpression(arg)];
2429
+ updateParentPointers(ref);
2430
+ return makeNode({
2431
+ type: "UnwrappedExpression",
2432
+ children: [skipIfOnlyWS(fn.leadingComment), body, skipIfOnlyWS(fn.trailingComment)]
2433
+ });
2434
+ }
2435
+ expr = fn.expr;
2436
+ const lhs = makeLeftHandSideExpression(expr);
2437
+ let comment = skipIfOnlyWS(fn.trailingComment);
2438
+ if (comment)
2439
+ lhs.children.splice(2, 0, comment);
2440
+ comment = skipIfOnlyWS(fn.leadingComment);
2441
+ if (comment)
2442
+ lhs.children.splice(1, 0, comment);
2443
+ switch (arg.type) {
2444
+ case "CommaExpression":
2445
+ arg = makeLeftHandSideExpression(arg);
2446
+ break;
2447
+ }
2448
+ return {
2449
+ type: "CallExpression",
2450
+ children: [lhs, "(", arg, ")"]
2451
+ };
2286
2452
  }
2287
- function elideMatchersFromPropertyBindings(properties) {
2288
- return properties.map((p) => {
2289
- switch (p.type) {
2290
- case "BindingProperty": {
2291
- const { children, name, value } = p;
2292
- const [ws] = children;
2293
- switch (value && value.type) {
2294
- case "ArrayBindingPattern":
2295
- case "ObjectBindingPattern":
2296
- return {
2297
- ...p,
2298
- children: [ws, name, ": ", nonMatcherBindings(value), p.delim]
2299
- };
2300
- case "Identifier":
2301
- return p;
2302
- case "Literal":
2303
- case "RegularExpressionLiteral":
2304
- case "StringLiteral":
2305
- default:
2306
- return {
2307
- ...p,
2308
- children: [ws, name, p.delim]
2309
- };
2310
- }
2453
+ function constructPipeStep(fn, arg, returning) {
2454
+ let children = [[fn.leadingComment, fn.expr, fn.trailingComment].map(skipIfOnlyWS), " ", arg];
2455
+ switch (fn.expr.token) {
2456
+ case "yield":
2457
+ case "await":
2458
+ if (fn.expr.op) {
2459
+ children = processUnaryExpression([fn.expr], arg, void 0);
2311
2460
  }
2312
- case "PinProperty":
2313
- case "BindingRestProperty":
2314
- default:
2315
- return p;
2316
- }
2317
- });
2318
- }
2319
- function nonMatcherBindings(pattern) {
2320
- switch (pattern.type) {
2321
- case "ArrayBindingPattern": {
2322
- const elements = elideMatchersFromArrayBindings(pattern.elements);
2323
- const children = ["[", elements, "]"];
2324
- return {
2325
- ...pattern,
2461
+ if (returning) {
2462
+ return [
2463
+ children,
2464
+ returning
2465
+ ];
2466
+ }
2467
+ return [
2326
2468
  children,
2327
- elements
2328
- };
2329
- }
2330
- case "PostRestBindingElements": {
2331
- const els = elideMatchersFromArrayBindings(pattern.children[1]);
2332
- return {
2333
- ...pattern,
2334
- children: [
2335
- pattern.children[0],
2336
- els,
2337
- ...pattern.children.slice(2)
2338
- ]
2339
- };
2340
- }
2341
- case "ObjectBindingPattern":
2342
- return ["{", elideMatchersFromPropertyBindings(pattern.properties), "}"];
2343
- default:
2344
- return pattern;
2469
+ null
2470
+ ];
2471
+ case "return":
2472
+ return [{
2473
+ type: "ReturnStatement",
2474
+ children
2475
+ }, null];
2476
+ }
2477
+ if (returning) {
2478
+ return [
2479
+ constructInvocation(fn, arg),
2480
+ returning
2481
+ ];
2345
2482
  }
2483
+ return [constructInvocation(fn, arg), null];
2346
2484
  }
2347
- function aggregateDuplicateBindings(bindings, ReservedWord) {
2348
- const props = gatherRecursiveAll(bindings, ($2) => $2.type === "BindingProperty");
2349
- const arrayBindings = gatherRecursiveAll(bindings, ($3) => $3.type === "ArrayBindingPattern");
2350
- arrayBindings.forEach((a) => {
2351
- const { elements } = a;
2352
- return elements.forEach((element) => {
2353
- if (Array.isArray(element)) {
2354
- const [, e] = element;
2355
- if (e.type === "Identifier") {
2356
- return props.push(e);
2357
- } else if (e.type === "BindingRestElement") {
2358
- return props.push(e);
2485
+ function processPipelineExpressions(statements) {
2486
+ gatherRecursiveAll(statements, (n) => n.type === "PipelineExpression").forEach((s) => {
2487
+ const [ws, , body] = s.children;
2488
+ let [, arg] = s.children;
2489
+ let i = 0, l = body.length;
2490
+ const children = [ws];
2491
+ let usingRef = null;
2492
+ for (i = 0; i < l; i++) {
2493
+ const step = body[i];
2494
+ const [leadingComment, pipe, trailingComment, expr] = step;
2495
+ const returns = pipe.token === "||>";
2496
+ let ref, result, returning = returns ? arg : null;
2497
+ if (pipe.token === "|>=") {
2498
+ let initRef;
2499
+ if (i === 0) {
2500
+ outer:
2501
+ switch (arg.type) {
2502
+ case "MemberExpression":
2503
+ if (arg.children.length <= 2)
2504
+ break;
2505
+ case "CallExpression":
2506
+ const access = arg.children.pop();
2507
+ switch (access.type) {
2508
+ case "PropertyAccess":
2509
+ case "SliceExpression":
2510
+ break;
2511
+ default:
2512
+ children.unshift({
2513
+ type: "Error",
2514
+ $loc: pipe.token.$loc,
2515
+ message: `Can't assign to ${access.type}`
2516
+ });
2517
+ arg.children.push(access);
2518
+ break outer;
2519
+ }
2520
+ usingRef = makeRef();
2521
+ initRef = {
2522
+ type: "AssignmentExpression",
2523
+ children: [usingRef, " = ", arg, ","]
2524
+ };
2525
+ arg = {
2526
+ type: "MemberExpression",
2527
+ children: [usingRef, access]
2528
+ };
2529
+ break;
2530
+ }
2531
+ const lhs = [[
2532
+ [initRef],
2533
+ arg,
2534
+ [],
2535
+ { token: "=", children: [" = "] }
2536
+ ]];
2537
+ Object.assign(s, {
2538
+ type: "AssignmentExpression",
2539
+ children: [lhs, children],
2540
+ names: null,
2541
+ lhs,
2542
+ assigned: arg,
2543
+ exp: children
2544
+ });
2545
+ arg = clone(arg);
2546
+ if (arg.children[0].type === "Ref") {
2547
+ arg.children[0] = usingRef;
2548
+ }
2549
+ } else {
2550
+ children.unshift({
2551
+ type: "Error",
2552
+ $loc: pipe.token.$loc,
2553
+ message: "Can't use |>= in the middle of a pipeline"
2554
+ });
2359
2555
  }
2360
- ;
2361
- return;
2556
+ } else {
2557
+ if (i === 0)
2558
+ s.children = children;
2559
+ }
2560
+ if (returns && (ref = needsRef(arg))) {
2561
+ usingRef = usingRef || ref;
2562
+ arg = {
2563
+ type: "ParenthesizedExpression",
2564
+ children: ["(", {
2565
+ type: "AssignmentExpression",
2566
+ children: [usingRef, " = ", arg]
2567
+ }, ")"]
2568
+ };
2569
+ returning = usingRef;
2362
2570
  }
2363
2571
  ;
2364
- return;
2365
- });
2366
- });
2367
- const declarations = [];
2368
- const propsGroupedByName = /* @__PURE__ */ new Map();
2369
- for (const p of props) {
2370
- const { name, value } = p;
2371
- const key = value?.name || name?.name || name;
2372
- if (propsGroupedByName.has(key)) {
2373
- propsGroupedByName.get(key).push(p);
2374
- } else {
2375
- propsGroupedByName.set(key, [p]);
2376
- }
2377
- }
2378
- propsGroupedByName.forEach((shared, key) => {
2379
- if (!key) {
2380
- return;
2381
- }
2382
- if (ReservedWord({ fail() {
2383
- } }, {
2384
- pos: 0,
2385
- input: key
2386
- })) {
2387
- shared.forEach((p) => {
2388
- return aliasBinding(p, makeRef(`_${key}`, key));
2389
- });
2390
- return;
2391
- }
2392
- if (shared.length === 1) {
2393
- return;
2394
- }
2395
- const refs = shared.map((p) => {
2396
- const ref = makeRef(key);
2397
- aliasBinding(p, ref);
2398
- return ref;
2399
- });
2400
- return declarations.push(["const ", key, " = [", ...refs.map((r, i) => {
2401
- return i === 0 ? r : [", ", r];
2402
- }), "]"]);
2403
- });
2404
- return declarations;
2405
- }
2406
- function processDeclarationCondition(condition, rootCondition, parent) {
2407
- if (!(condition.type === "DeclarationCondition")) {
2408
- return;
2409
- }
2410
- const ref = makeRef();
2411
- const { decl, bindings } = condition.declaration;
2412
- const binding = bindings[0];
2413
- const { pattern, suffix, initializer, splices, thisAssignments } = binding;
2414
- const grandparent = condition.parent?.parent;
2415
- const children = (
2416
- // Check that the declaration is a plain assignment (no pattern-matching) and the immediate grandchild of an `if` or `while`
2417
- // More complex conditions (triggered by pattern matching or `until`/`unless`) don't need double parens
2418
- // @ts-ignore Just because pattern might not have a type at runtime doesn't mean it's unsafe
2419
- pattern.type === "Identifier" && (grandparent?.type === "IfStatement" || grandparent?.type === "WhileStatement") ? ["(", ref, initializer, ")"] : [ref, initializer]
2420
- );
2421
- Object.assign(condition, {
2422
- type: "AssignmentExpression",
2423
- children,
2424
- hoistDec: {
2425
- type: "Declaration",
2426
- children: ["let ", ref, suffix],
2427
- names: []
2428
- },
2429
- pattern,
2430
- ref
2431
- });
2432
- addParentPointers(condition, parent);
2433
- Object.assign(rootCondition, {
2434
- blockPrefix: [
2435
- ["", [decl, pattern, suffix, " = ", ref, ...splices], ";"],
2436
- ...thisAssignments
2437
- ]
2438
- });
2439
- }
2440
- function processDeclarationConditions(node) {
2441
- gatherRecursiveAll(node, (n) => {
2442
- return n.type === "IfStatement" || n.type === "IterationStatement" || n.type === "SwitchStatement";
2443
- }).forEach(processDeclarationConditionStatement);
2444
- }
2445
- function processDeclarationConditionStatement(s) {
2446
- const { condition } = s;
2447
- if (!condition?.expression) {
2448
- return;
2449
- }
2450
- let { expression } = condition;
2451
- 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]) {
2452
- const { type: type1, children: [, { type: type2, expression: expression2 }] } = expression;
2453
- const type = [type1, type2];
2454
- expression = expression2;
2455
- }
2456
- processDeclarationCondition(expression, condition.expression, s);
2457
- const { ref, pattern } = expression;
2458
- if (pattern) {
2459
- let conditions = [];
2460
- getPatternConditions(pattern, ref, conditions);
2461
- conditions = conditions.filter((c) => {
2462
- return !(c.length === 3 && c[0] === "typeof " && c[1] === ref && c[2] === " === 'object'") && !(c.length === 2 && c[0] === ref && c[1] === " != null");
2463
- });
2464
- if (conditions.length) {
2465
- condition.children.unshift("(");
2466
- conditions.forEach(function(c) {
2467
- return condition.children.push(" && ", c);
2468
- });
2469
- condition.children.push(")");
2470
- }
2471
- }
2472
- switch (s.type) {
2473
- case "IfStatement": {
2474
- const { else: e } = s;
2475
- const block = blockWithPrefix(condition.expression.blockPrefix, s.then);
2476
- s.then = block;
2477
- if (block.bare && e && !block.semicolon) {
2478
- block.children.push(block.semicolon = ";");
2572
+ [result, returning] = constructPipeStep(
2573
+ {
2574
+ leadingComment: skipIfOnlyWS(leadingComment),
2575
+ trailingComment: skipIfOnlyWS(trailingComment),
2576
+ expr
2577
+ },
2578
+ arg,
2579
+ returning
2580
+ );
2581
+ if (result.type === "ReturnStatement") {
2582
+ if (i < l - 1) {
2583
+ result.children.push({
2584
+ type: "Error",
2585
+ message: "Can't continue a pipeline after returning"
2586
+ });
2587
+ }
2588
+ arg = result;
2589
+ if (children[children.length - 1] === ",") {
2590
+ children.pop();
2591
+ children.push(";");
2592
+ }
2593
+ break;
2594
+ }
2595
+ if (returning) {
2596
+ arg = returning;
2597
+ children.push(result, ",");
2598
+ } else {
2599
+ arg = result;
2479
2600
  }
2480
- s.children.splice(2, 1, block);
2481
- updateParentPointers(block, s);
2482
- break;
2483
- }
2484
- case "IterationStatement": {
2485
- const { children, block } = s;
2486
- const newBlock = blockWithPrefix(condition.expression.blockPrefix, block);
2487
- s.children = children.map((c) => c?.type === "BlockStatement" ? newBlock : c);
2488
- updateParentPointers(newBlock, s);
2489
- break;
2490
2601
  }
2491
- case "SwitchStatement": {
2492
- const { blockPrefix, ref: ref2 } = condition.expression;
2493
- if (!blockPrefix) {
2494
- return;
2495
- }
2496
- s.condition = {
2497
- type: "ParenthesizedExpression",
2498
- children: ["(", ref2, ")"],
2499
- expression: ref2,
2500
- parent: s
2501
- };
2502
- s.children[1] = s.condition;
2503
- updateParentPointers(s);
2504
- const block = blockWithPrefix([["", [{
2602
+ if (usingRef) {
2603
+ s.hoistDec = {
2505
2604
  type: "Declaration",
2506
- children: ["let ", ...condition.expression.children]
2507
- }], ";"], ...blockPrefix], makeEmptyBlock());
2508
- updateParentPointers(block, s.parent);
2509
- replaceBlockExpression(s.parent, s, block);
2510
- block.expressions.push(["", s]);
2511
- s.parent = block;
2512
- break;
2605
+ children: ["let ", usingRef],
2606
+ names: []
2607
+ };
2513
2608
  }
2514
- }
2515
- }
2516
- function aliasBinding(p, ref) {
2517
- if (p.type === "Identifier") {
2518
- p.children[0] = ref;
2519
- } else if (p.type === "BindingRestElement") {
2520
- aliasBinding(p.binding, ref);
2521
- } else if (p.value?.type === "Identifier") {
2522
- aliasBinding(p.value, ref);
2523
- } else {
2524
- p.value = ref;
2525
- const index = p.children.indexOf(p.name);
2526
- p.children.splice(index + 1, 0, ": ", ref);
2527
- }
2609
+ children.push(arg);
2610
+ if (!children.some(($) => $?.type === "ReturnStatement") && children.some(($1) => $1 === ",")) {
2611
+ const { parent } = s;
2612
+ const parenthesizedExpression = makeLeftHandSideExpression({ ...s });
2613
+ Object.assign(s, parenthesizedExpression, {
2614
+ parent,
2615
+ hoistDec: void 0
2616
+ });
2617
+ }
2618
+ return addParentPointers(s, s.parent);
2619
+ });
2528
2620
  }
2529
- var init_pattern_matching = __esm({
2530
- "source/parser/pattern-matching.civet"() {
2621
+ var init_pipe = __esm({
2622
+ "source/parser/pipe.civet"() {
2531
2623
  "use strict";
2532
2624
  init_traversal();
2533
2625
  init_util();
2534
- init_block();
2535
- init_binding();
2536
- init_op();
2626
+ init_unary();
2537
2627
  }
2538
2628
  });
2539
2629
 
2540
- // source/parser/unary.civet
2541
- function processUnaryExpression(pre, exp, post) {
2542
- if (!(pre.length || post))
2543
- return exp;
2544
- if (post?.token === "?") {
2545
- post = {
2546
- $loc: post.$loc,
2547
- token: " != null"
2548
- };
2549
- if (pre.length) {
2550
- const lastPre = pre[pre.length - 1];
2551
- if (lastPre.token === "!") {
2552
- post.token = " == null";
2553
- pre = pre.slice(0, -1);
2554
- } else if (lastPre.length === 2 && lastPre[0].token === "!") {
2555
- post.token = " == null";
2556
- pre = pre.slice(0, -1);
2630
+ // source/parser/for.civet
2631
+ function forRange(open, forDeclaration, range, stepExp, close) {
2632
+ const { start, end, inclusive } = range;
2633
+ const counterRef = makeRef("i");
2634
+ let stepRef;
2635
+ if (stepExp) {
2636
+ stepExp = insertTrimmingSpace(stepExp, "");
2637
+ stepRef = maybeRef(stepExp, "step");
2638
+ }
2639
+ let startRef = maybeRef(start, "start");
2640
+ let endRef = maybeRef(end, "end");
2641
+ const startRefDec = startRef !== start ? [startRef, " = ", start, ", "] : [];
2642
+ const endRefDec = endRef !== end ? [endRef, " = ", end, ", "] : [];
2643
+ let ascDec = [], ascRef, asc;
2644
+ if (stepRef) {
2645
+ if (!(stepRef === stepExp)) {
2646
+ ascDec = [", ", stepRef, " = ", stepExp];
2647
+ }
2648
+ } else if ("Literal" === start.type && start.type === end.type) {
2649
+ asc = literalValue(start) <= literalValue(end);
2650
+ if ("StringLiteral" === start.subtype && start.subtype === end.subtype) {
2651
+ startRef = literalValue(start).charCodeAt(0).toString();
2652
+ endRef = literalValue(end).charCodeAt(0).toString();
2653
+ }
2654
+ } else {
2655
+ ascRef = makeRef("asc");
2656
+ ascDec = [", ", ascRef, " = ", startRef, " <= ", endRef];
2657
+ }
2658
+ let varAssign = [], varLetAssign = varAssign, varLet = varAssign, blockPrefix;
2659
+ if (forDeclaration?.declare) {
2660
+ if (forDeclaration.declare.token === "let") {
2661
+ const varName = forDeclaration.children.splice(1);
2662
+ varAssign = [...insertTrimmingSpace(varName, ""), " = "];
2663
+ varLet = [",", ...varName, " = ", counterRef];
2664
+ } else {
2665
+ const value = "StringLiteral" === start.subtype ? ["String.fromCharCode(", counterRef, ")"] : counterRef;
2666
+ blockPrefix = [
2667
+ ["", forDeclaration, " = ", value, ";"]
2668
+ ];
2669
+ }
2670
+ } else if (forDeclaration) {
2671
+ varAssign = varLetAssign = [forDeclaration, " = "];
2672
+ }
2673
+ const declaration = {
2674
+ type: "Declaration",
2675
+ children: ["let ", ...startRefDec, ...endRefDec, counterRef, " = ", ...varLetAssign, startRef, ...varLet, ...ascDec],
2676
+ names: forDeclaration?.names
2677
+ };
2678
+ const counterPart = inclusive ? [counterRef, " <= ", endRef, " : ", counterRef, " >= ", endRef] : [counterRef, " < ", endRef, " : ", counterRef, " > ", endRef];
2679
+ const condition = stepRef ? [stepRef, " !== 0 && (", stepRef, " > 0 ? ", ...counterPart, ")"] : ascRef ? [ascRef, " ? ", ...counterPart] : asc ? counterPart.slice(0, 3) : counterPart.slice(4);
2680
+ const increment = stepRef ? [...varAssign, counterRef, " += ", stepRef] : ascRef ? [...varAssign, ascRef, " ? ++", counterRef, " : --", counterRef] : [...varAssign, asc ? "++" : "--", counterRef];
2681
+ return {
2682
+ declaration,
2683
+ children: [open, declaration, "; ", ...condition, "; ", ...increment, close],
2684
+ blockPrefix
2685
+ };
2686
+ }
2687
+ function processForInOf($0, getRef) {
2688
+ let [awaits, eachOwn, open, declaration, declaration2, ws, inOf, exp, step, close] = $0;
2689
+ if (exp.type === "RangeExpression" && inOf.token === "of" && !declaration2) {
2690
+ return forRange(open, declaration, exp, step, close);
2691
+ } else if (step) {
2692
+ throw new Error("for..of/in cannot use 'by' except with range literals");
2693
+ }
2694
+ let eachOwnError;
2695
+ let hoistDec, blockPrefix = [];
2696
+ if (eachOwn && eachOwn[0].token === "each") {
2697
+ if (inOf.token === "of") {
2698
+ const counterRef = makeRef("i");
2699
+ const lenRef = makeRef("len");
2700
+ const expRef2 = maybeRef(exp);
2701
+ const increment = "++";
2702
+ let assignmentNames = [...declaration.names];
2703
+ if (declaration2) {
2704
+ const [, , ws22, decl22] = declaration2;
2705
+ blockPrefix.push(["", [
2706
+ insertTrimmingSpace(ws22, ""),
2707
+ decl22,
2708
+ " = ",
2709
+ counterRef
2710
+ ], ";"]);
2711
+ assignmentNames.push(...decl22.names);
2557
2712
  }
2713
+ const expRefDec = expRef2 !== exp ? [insertTrimmingSpace(expRef2, " "), " = ", insertTrimmingSpace(exp, ""), ", "] : [];
2714
+ blockPrefix.push(["", {
2715
+ type: "Declaration",
2716
+ children: [declaration, " = ", insertTrimmingSpace(expRef2, ""), "[", counterRef, "]"],
2717
+ names: assignmentNames
2718
+ }, ";"]);
2719
+ declaration = {
2720
+ type: "Declaration",
2721
+ children: ["let ", ...expRefDec, counterRef, " = 0, ", lenRef, " = ", insertTrimmingSpace(expRef2, ""), ".length"],
2722
+ names: []
2723
+ };
2724
+ const condition = [counterRef, " < ", lenRef, "; "];
2725
+ const children = [open, declaration, "; ", condition, counterRef, increment, close];
2726
+ return { declaration, children, blockPrefix };
2727
+ } else {
2728
+ eachOwnError = {
2729
+ type: "Error",
2730
+ message: "'each' is only meaningful in for..of loops"
2731
+ };
2558
2732
  }
2559
- const existence = {
2560
- type: "Existence",
2561
- expression: exp,
2562
- children: [exp, post]
2733
+ }
2734
+ let own = eachOwn && eachOwn[0].token === "own";
2735
+ let expRef;
2736
+ if (own && inOf.token !== "in") {
2737
+ own = false;
2738
+ eachOwnError = {
2739
+ type: "Error",
2740
+ message: "'own' is only meaningful in for..in loops"
2563
2741
  };
2564
- exp = makeLeftHandSideExpression(existence);
2565
- if (pre.length) {
2566
- return {
2567
- type: "UnaryExpression",
2568
- children: [...pre, exp]
2742
+ }
2743
+ if (!declaration2 && !own) {
2744
+ return {
2745
+ declaration,
2746
+ blockPrefix,
2747
+ children: [awaits, eachOwnError, open, declaration, ws, inOf, expRef ?? exp, step, close]
2748
+ // omit declaration2, replace eachOwn with eachOwnError, replace exp with expRef
2749
+ };
2750
+ }
2751
+ let ws2, decl2;
2752
+ if (declaration2)
2753
+ [, , ws2, decl2] = declaration2;
2754
+ switch (inOf.token) {
2755
+ case "of": {
2756
+ const counterRef = makeRef("i");
2757
+ hoistDec = {
2758
+ type: "Declaration",
2759
+ children: ["let ", counterRef, " = 0"],
2760
+ names: []
2569
2761
  };
2762
+ blockPrefix.push(["", {
2763
+ type: "Declaration",
2764
+ children: [insertTrimmingSpace(ws2, ""), decl2, " = ", counterRef, "++"],
2765
+ names: decl2.names
2766
+ }, ";"]);
2767
+ break;
2570
2768
  }
2571
- return exp;
2572
- }
2573
- if (exp.type === "Literal") {
2574
- if (pre.length === 1) {
2575
- const { token } = pre[0];
2576
- if (token === "-" || token === "+") {
2577
- const children = [pre[0], ...exp.children];
2578
- if (post)
2579
- exp.children.push(post);
2580
- return {
2581
- type: "Literal",
2582
- children,
2583
- raw: `${token}${exp.raw}`
2769
+ case "in": {
2770
+ const expRef2 = maybeRef(exp);
2771
+ if (expRef2 !== exp) {
2772
+ hoistDec = {
2773
+ type: "Declaration",
2774
+ children: ["let ", expRef2],
2775
+ names: []
2776
+ };
2777
+ exp = {
2778
+ type: "AssignmentExpression",
2779
+ children: [" ", expRef2, " =", exp]
2780
+ };
2781
+ }
2782
+ let { binding } = declaration;
2783
+ if (binding?.type !== "Identifier") {
2784
+ const keyRef = makeRef("key");
2785
+ blockPrefix.push(["", [
2786
+ declaration,
2787
+ " = ",
2788
+ keyRef
2789
+ ], ";"]);
2790
+ declaration = {
2791
+ type: "ForDeclaration",
2792
+ binding: binding = keyRef,
2793
+ children: ["const ", keyRef],
2794
+ names: []
2584
2795
  };
2585
2796
  }
2586
- }
2587
- }
2588
- const l = pre.length;
2589
- if (l) {
2590
- const last = pre[l - 1];
2591
- if (last.type === "Await" && last.op) {
2592
- if (exp.type !== "ParenthesizedExpression") {
2593
- exp = ["(", exp, ")"];
2797
+ if (own) {
2798
+ const hasPropRef = getRef("hasProp");
2799
+ blockPrefix.push(["", ["if (!", hasPropRef, "(", insertTrimmingSpace(expRef2, ""), ", ", insertTrimmingSpace(binding, ""), ")) continue"], ";"]);
2800
+ }
2801
+ if (decl2) {
2802
+ blockPrefix.push(["", {
2803
+ type: "Declaration",
2804
+ children: [insertTrimmingSpace(ws2, ""), decl2, " = ", insertTrimmingSpace(expRef2, ""), "[", insertTrimmingSpace(binding, ""), "]"],
2805
+ names: decl2.names
2806
+ }, ";"]);
2594
2807
  }
2595
- exp = {
2596
- type: "CallExpression",
2597
- children: [" Promise", last.op, exp]
2598
- };
2808
+ break;
2599
2809
  }
2810
+ default:
2811
+ (() => {
2812
+ throw new Error(`for item, index must use 'of' or 'in' instead of '${inOf.token}'`);
2813
+ })();
2600
2814
  }
2601
2815
  return {
2602
- type: "UnaryExpression",
2603
- children: [...pre, exp, post]
2816
+ declaration,
2817
+ children: [awaits, eachOwnError, open, declaration, ws, inOf, exp, step, close],
2818
+ // omit declaration2, replace each with eachOwnError
2819
+ blockPrefix,
2820
+ hoistDec
2604
2821
  };
2605
2822
  }
2606
- var init_unary = __esm({
2607
- "source/parser/unary.civet"() {
2823
+ var init_for = __esm({
2824
+ "source/parser/for.civet"() {
2608
2825
  "use strict";
2609
2826
  init_util();
2610
2827
  }
@@ -2929,7 +3146,6 @@ var Civet = (() => {
2929
3146
  dedentBlockString: () => dedentBlockString,
2930
3147
  dedentBlockSubstitutions: () => dedentBlockSubstitutions,
2931
3148
  deepCopy: () => deepCopy,
2932
- expressionizeIfClause: () => expressionizeIfClause,
2933
3149
  expressionizeTypeIf: () => expressionizeTypeIf,
2934
3150
  forRange: () => forRange,
2935
3151
  gatherBindingCode: () => gatherBindingCode,
@@ -2964,6 +3180,7 @@ var Civet = (() => {
2964
3180
  quoteString: () => quoteString,
2965
3181
  reorderBindingRestProperty: () => reorderBindingRestProperty,
2966
3182
  replaceNodes: () => replaceNodes,
3183
+ skipImplicitArguments: () => skipImplicitArguments,
2967
3184
  typeOfJSX: () => typeOfJSX,
2968
3185
  wrapIIFE: () => wrapIIFE
2969
3186
  });
@@ -3002,16 +3219,71 @@ var Civet = (() => {
3002
3219
  };
3003
3220
  return { ...condition, expression, children };
3004
3221
  }
3005
- function expressionizeIfClause(clause, b, e) {
3006
- const { condition } = clause;
3222
+ function isExpression(node) {
3223
+ if (Array.isArray(node)) {
3224
+ return node.every(isExpression);
3225
+ }
3226
+ if (typeof node === "string") {
3227
+ return true;
3228
+ }
3229
+ switch (node?.type) {
3230
+ case "BlockStatement":
3231
+ case "DebuggerStatement":
3232
+ case "Declaration":
3233
+ case "IfStatement":
3234
+ case "IterationStatement":
3235
+ case "ReturnStatement":
3236
+ case "SwitchStatement":
3237
+ case "ThrowStatement":
3238
+ case "TryStatement":
3239
+ return false;
3240
+ }
3241
+ return true;
3242
+ }
3243
+ function expressionizeBlock(blockOrExpression) {
3244
+ let ref1;
3245
+ if ((ref1 = blockOrExpression) && "expressions" in ref1) {
3246
+ const { expressions } = ref1;
3247
+ const l = expressions.length;
3248
+ const results = [];
3249
+ let i1 = 0;
3250
+ for (const [ws, s, _delim] of expressions) {
3251
+ const i = i1++;
3252
+ if (!isExpression(s))
3253
+ return;
3254
+ const wrapped = makeLeftHandSideExpression(s);
3255
+ if (i === l - 1) {
3256
+ results.push([ws, wrapped]);
3257
+ } else {
3258
+ results.push([ws, wrapped, ","]);
3259
+ }
3260
+ }
3261
+ if (results.length > 1) {
3262
+ return makeLeftHandSideExpression(results);
3263
+ }
3264
+ return results;
3265
+ } else {
3266
+ return blockOrExpression;
3267
+ }
3268
+ }
3269
+ function expressionizeIfStatement(statement) {
3270
+ const { condition, then: b, else: e } = statement;
3007
3271
  const [...condRest] = condition.children, [closeParen] = condRest.splice(-1);
3272
+ const expressionizedBlock = expressionizeBlock(b);
3273
+ if (!expressionizedBlock) {
3274
+ return wrapIIFE([["", statement]]);
3275
+ }
3008
3276
  const children = [
3009
3277
  ...condRest,
3010
3278
  "?",
3011
- b
3279
+ expressionizedBlock
3012
3280
  ];
3013
3281
  if (e) {
3014
- children.push(e[0], ":", ...e.slice(2));
3282
+ const e2 = expressionizeBlock(e[2]);
3283
+ if (!e2) {
3284
+ return wrapIIFE([["", statement]]);
3285
+ }
3286
+ children.push(e[0], ":", e2, ...e.slice(3));
3015
3287
  } else {
3016
3288
  children.push(":void 0");
3017
3289
  }
@@ -3075,17 +3347,17 @@ var Civet = (() => {
3075
3347
  let call = children[1];
3076
3348
  const args = [...call.args];
3077
3349
  call = { ...call, args };
3078
- let ref1;
3079
- if (ref1 = isComma(args.at(-1))) {
3080
- const comma = ref1;
3350
+ let ref2;
3351
+ if (ref2 = isComma(args.at(-1))) {
3352
+ const comma = ref2;
3081
3353
  comma.token = "";
3082
3354
  }
3083
3355
  let commaCount = 0;
3084
- for (let i1 = 0, len1 = args.length; i1 < len1; i1++) {
3085
- const arg = args[i1];
3086
- let ref2;
3087
- if (ref2 = isComma(arg)) {
3088
- const comma = ref2;
3356
+ for (let i2 = 0, len1 = args.length; i2 < len1; i2++) {
3357
+ const arg = args[i2];
3358
+ let ref3;
3359
+ if (ref3 = isComma(arg)) {
3360
+ const comma = ref3;
3089
3361
  comma.token = `)${op.token}(`;
3090
3362
  commaCount++;
3091
3363
  }
@@ -3222,9 +3494,9 @@ var Civet = (() => {
3222
3494
  throw new Error("replaceNode failed: node has no parent");
3223
3495
  }
3224
3496
  function recurse(children) {
3225
- for (let i2 = 0, len2 = children.length; i2 < len2; i2++) {
3226
- const i = i2;
3227
- const child = children[i2];
3497
+ for (let i3 = 0, len2 = children.length; i3 < len2; i3++) {
3498
+ const i = i3;
3499
+ const child = children[i3];
3228
3500
  if (child === node) {
3229
3501
  children[i] = newNode;
3230
3502
  return true;
@@ -3391,55 +3663,6 @@ var Civet = (() => {
3391
3663
  parameters
3392
3664
  };
3393
3665
  }
3394
- function processAssignmentDeclaration(decl, pattern, suffix, ws, assign, e) {
3395
- decl = {
3396
- ...decl,
3397
- $loc: {
3398
- pos: assign.$loc.pos - 1,
3399
- length: assign.$loc.length + 1
3400
- }
3401
- };
3402
- let [splices, assignments] = gatherBindingCode(pattern);
3403
- splices = splices.map((s) => [", ", s]);
3404
- const thisAssignments = assignments.map((a) => ["", a, ";"]);
3405
- const initializer = [ws, assign, e];
3406
- const binding = makeNode({
3407
- type: "Binding",
3408
- pattern,
3409
- initializer,
3410
- splices,
3411
- suffix,
3412
- thisAssignments,
3413
- children: [pattern, suffix, initializer]
3414
- });
3415
- const children = [decl, binding];
3416
- return makeNode({
3417
- type: "Declaration",
3418
- names: pattern.names,
3419
- decl,
3420
- bindings: [binding],
3421
- splices,
3422
- thisAssignments,
3423
- children
3424
- });
3425
- }
3426
- function processDeclarations(statements) {
3427
- gatherRecursiveAll(statements, ($) => $.type === "Declaration").forEach(({ bindings }) => {
3428
- return bindings?.forEach((binding) => {
3429
- const suffix = binding.suffix;
3430
- if (suffix && suffix.optional && suffix.t) {
3431
- convertOptionalType(suffix);
3432
- }
3433
- const { initializer } = binding;
3434
- if (initializer) {
3435
- const exp = initializer[2];
3436
- return exp;
3437
- }
3438
- ;
3439
- return;
3440
- });
3441
- });
3442
- }
3443
3666
  function processBindingPatternLHS(lhs, tail) {
3444
3667
  adjustAtBindings(lhs, true);
3445
3668
  const [splices, thisAssignments] = gatherBindingCode(lhs);
@@ -3493,8 +3716,25 @@ var Civet = (() => {
3493
3716
  return exp.children.push(...post);
3494
3717
  return;
3495
3718
  });
3496
- gatherRecursiveAll(statements, (n) => n.type === "AssignmentExpression" && n.names === null).forEach((exp) => {
3719
+ replaceNodesRecursive(statements, (n) => n.type === "AssignmentExpression" && n.names === null, (exp) => {
3497
3720
  let { lhs: $1, exp: $2 } = exp, tail = [], i = 0, len = $1.length;
3721
+ let block;
3722
+ if (exp.parent.type === "BlockStatement" && !$1.at(-1)?.at(-1)?.special) {
3723
+ block = makeBlockFragment();
3724
+ let ref4;
3725
+ if (ref4 = prependStatementExpressionBlock([null, null, $2], block)) {
3726
+ const ref = ref4;
3727
+ exp.children = exp.children.map(function(c) {
3728
+ if (c === $2)
3729
+ return ref;
3730
+ else
3731
+ return c;
3732
+ });
3733
+ $2 = ref;
3734
+ } else {
3735
+ block = void 0;
3736
+ }
3737
+ }
3498
3738
  if ($1.some((left) => left[left.length - 1].special)) {
3499
3739
  if ($1.length !== 1)
3500
3740
  throw new Error("Only one assignment with id= is allowed");
@@ -3509,7 +3749,7 @@ var Civet = (() => {
3509
3749
  exp.exp = $2 = [call, "(", lhs, ", ", $2, ")"]
3510
3750
  );
3511
3751
  if (omitLhs) {
3512
- replaceNode(exp, $2);
3752
+ return $2;
3513
3753
  }
3514
3754
  }
3515
3755
  let wrapped = false;
@@ -3554,7 +3794,7 @@ var Civet = (() => {
3554
3794
  }
3555
3795
  exp.children = [$1];
3556
3796
  exp.names = [];
3557
- return;
3797
+ return exp;
3558
3798
  }
3559
3799
  } else if (lhs.type === "ObjectBindingPattern" || lhs.type === "ArrayBindingPattern") {
3560
3800
  processBindingPatternLHS(lhs, tail);
@@ -3566,11 +3806,19 @@ var Civet = (() => {
3566
3806
  const index = exp.children.indexOf($2);
3567
3807
  if (index < 0)
3568
3808
  throw new Error("Assertion error: exp not in AssignmentExpression");
3569
- return exp.children.splice(index + 1, 0, ...tail);
3809
+ exp.children.splice(index + 1, 0, ...tail);
3810
+ if (block) {
3811
+ block.parent = exp.parent;
3812
+ block.expressions.push(["", exp]);
3813
+ exp.parent = block;
3814
+ return block;
3815
+ }
3816
+ return exp;
3570
3817
  });
3571
3818
  }
3572
3819
  function attachPostfixStatementAsExpression(exp, post) {
3573
- switch (post[1].type) {
3820
+ const postfixStatement = post[1];
3821
+ switch (postfixStatement.type) {
3574
3822
  case "ForStatement":
3575
3823
  case "IterationStatement":
3576
3824
  case "DoStatement": {
@@ -3583,9 +3831,9 @@ var Civet = (() => {
3583
3831
  };
3584
3832
  }
3585
3833
  case "IfStatement":
3586
- return expressionizeIfClause(post[1], exp);
3834
+ return expressionizeIfStatement({ ...postfixStatement, then: exp });
3587
3835
  default:
3588
- (() => {
3836
+ return (() => {
3589
3837
  throw new Error("Unknown postfix statement");
3590
3838
  })();
3591
3839
  }
@@ -3624,6 +3872,42 @@ var Civet = (() => {
3624
3872
  }
3625
3873
  });
3626
3874
  }
3875
+ function processStatementExpressions(statements) {
3876
+ gatherRecursiveAll(statements, ($) => $.type === "StatementExpression").forEach((_exp) => {
3877
+ const exp = _exp;
3878
+ const { statement } = exp;
3879
+ let ws;
3880
+ if (!(exp.children[0] === exp.statement)) {
3881
+ ws = exp.children[0];
3882
+ }
3883
+ let ref5;
3884
+ switch (statement.type) {
3885
+ case "IfStatement": {
3886
+ if (ref5 = expressionizeIfStatement(statement)) {
3887
+ const expression = ref5;
3888
+ exp.statement = expression;
3889
+ exp.children = [exp.statement];
3890
+ } else {
3891
+ exp.children = wrapIIFE([["", statement]]);
3892
+ }
3893
+ ;
3894
+ break;
3895
+ }
3896
+ case "IterationExpression": {
3897
+ ;
3898
+ break;
3899
+ }
3900
+ default: {
3901
+ exp.children = wrapIIFE([["", statement]]);
3902
+ }
3903
+ }
3904
+ if (ws) {
3905
+ return exp.children.unshift(ws);
3906
+ }
3907
+ ;
3908
+ return;
3909
+ });
3910
+ }
3627
3911
  function processProgram(root, config, m, ReservedWord) {
3628
3912
  assert.equal(m.forbidBracedApplication.length, 1, "forbidBracedApplication");
3629
3913
  assert.equal(m.forbidClassImplicitCall.length, 1, "forbidClassImplicitCall");
@@ -3634,11 +3918,12 @@ var Civet = (() => {
3634
3918
  addParentPointers(root);
3635
3919
  const { expressions: statements } = root;
3636
3920
  processTypes(statements);
3637
- processDeclarationConditions(statements);
3921
+ processDeclarationConditions(statements, m.getRef);
3638
3922
  processPipelineExpressions(statements);
3639
3923
  processDeclarations(statements);
3640
3924
  processAssignments(statements);
3641
- processPatternMatching(statements, ReservedWord);
3925
+ processStatementExpressions(statements);
3926
+ processPatternMatching(statements, ReservedWord, m.getRef);
3642
3927
  gatherRecursiveAll(statements, (n) => n.type === "IterationExpression").forEach((e) => expressionizeIteration(e));
3643
3928
  hoistRefDecs(statements);
3644
3929
  processFunctions(statements, config);
@@ -3742,9 +4027,9 @@ var Civet = (() => {
3742
4027
  return root;
3743
4028
  }
3744
4029
  }
3745
- for (let i3 = 0, len3 = array.length; i3 < len3; i3++) {
3746
- const i = i3;
3747
- const node = array[i3];
4030
+ for (let i4 = 0, len3 = array.length; i4 < len3; i4++) {
4031
+ const i = i4;
4032
+ const node = array[i4];
3748
4033
  if (!(node != null)) {
3749
4034
  return;
3750
4035
  }
@@ -3756,6 +4041,34 @@ var Civet = (() => {
3756
4041
  }
3757
4042
  return root;
3758
4043
  }
4044
+ function replaceNodesRecursive(root, predicate, replacer) {
4045
+ if (!(root != null)) {
4046
+ return root;
4047
+ }
4048
+ const array = Array.isArray(root) ? root : root.children;
4049
+ if (!array) {
4050
+ if (predicate(root)) {
4051
+ return replacer(root, root);
4052
+ } else {
4053
+ return root;
4054
+ }
4055
+ }
4056
+ for (let i5 = 0, len4 = array.length; i5 < len4; i5++) {
4057
+ const i = i5;
4058
+ const node = array[i5];
4059
+ if (!(node != null)) {
4060
+ continue;
4061
+ }
4062
+ if (predicate(node)) {
4063
+ const ret = replacer(node, root);
4064
+ replaceNodesRecursive(ret, predicate, replacer);
4065
+ array[i] = ret;
4066
+ } else {
4067
+ replaceNodesRecursive(node, predicate, replacer);
4068
+ }
4069
+ }
4070
+ return root;
4071
+ }
3759
4072
  function typeOfJSX(node, config, getRef) {
3760
4073
  switch (node.type) {
3761
4074
  case "JSXElement":
@@ -3820,13 +4133,14 @@ var Civet = (() => {
3820
4133
  ;
3821
4134
  return;
3822
4135
  }
3823
- var xor, assert;
4136
+ var xor;
3824
4137
  var init_lib = __esm({
3825
4138
  "source/parser/lib.civet"() {
3826
4139
  "use strict";
3827
4140
  init_traversal();
3828
4141
  init_util();
3829
4142
  init_block();
4143
+ init_declaration();
3830
4144
  init_pipe();
3831
4145
  init_for();
3832
4146
  init_function();
@@ -3837,19 +4151,12 @@ var Civet = (() => {
3837
4151
  init_auto_dec();
3838
4152
  init_string();
3839
4153
  xor = (a, b) => a ? !b && a : b;
3840
- assert = {
3841
- equal(a, b, msg) {
3842
- if (a !== b) {
3843
- throw new Error(`Assertion failed [${msg}]: ${a} !== ${b}`);
3844
- }
3845
- }
3846
- };
3847
4154
  }
3848
4155
  });
3849
4156
 
3850
- // node_modules/@danielx/hera/dist/machine.js
4157
+ // ../Hera/dist/machine.js
3851
4158
  var require_machine = __commonJS({
3852
- "node_modules/@danielx/hera/dist/machine.js"(exports, module) {
4159
+ "../Hera/dist/machine.js"(exports, module) {
3853
4160
  "use strict";
3854
4161
  var __defProp2 = Object.defineProperty;
3855
4162
  var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
@@ -4320,8 +4627,6 @@ ${input.slice(result.pos)}
4320
4627
  $TV,
4321
4628
  $Y,
4322
4629
  Parser,
4323
- ParserContext,
4324
- ParserOptions,
4325
4630
  Validator
4326
4631
  } = require_machine();
4327
4632
  var grammar = {
@@ -4338,7 +4643,7 @@ ${input.slice(result.pos)}
4338
4643
  NestedNonAssignmentExtendedExpression,
4339
4644
  ExpressionizedStatementWithTrailingCallExpressions,
4340
4645
  ExpressionizedStatement,
4341
- _ExpressionizedStatement,
4646
+ StatementExpression,
4342
4647
  CommaExpression,
4343
4648
  Arguments,
4344
4649
  ImplicitArguments,
@@ -4600,14 +4905,6 @@ ${input.slice(result.pos)}
4600
4905
  ElseClause,
4601
4906
  IfClause,
4602
4907
  UnlessClause,
4603
- IfExpression,
4604
- UnlessExpression,
4605
- ElseExpressionClause,
4606
- ExpressionBlock,
4607
- ElseExpressionBlock,
4608
- NestedBlockExpressions,
4609
- NestedBlockExpression,
4610
- BlockExpressionPart,
4611
4908
  IterationStatement,
4612
4909
  _IterationStatement,
4613
4910
  IterationExpression,
@@ -4631,7 +4928,6 @@ ${input.slice(result.pos)}
4631
4928
  ForBinding,
4632
4929
  SwitchStatement,
4633
4930
  EmptyCondition,
4634
- SwitchExpression,
4635
4931
  CaseBlock,
4636
4932
  NestedCaseClauses,
4637
4933
  NestedCaseClause,
@@ -4643,7 +4939,6 @@ ${input.slice(result.pos)}
4643
4939
  ImpliedColon,
4644
4940
  IgnoreColon,
4645
4941
  TryStatement,
4646
- TryExpression,
4647
4942
  CatchClause,
4648
4943
  CatchBind,
4649
4944
  FinallyClause,
@@ -4684,8 +4979,6 @@ ${input.slice(result.pos)}
4684
4979
  Break,
4685
4980
  Continue,
4686
4981
  Debugger,
4687
- DebuggerExpression,
4688
- ThrowExpression,
4689
4982
  MaybeNestedExpression,
4690
4983
  ImportDeclaration,
4691
4984
  ImpliedImport,
@@ -5515,22 +5808,26 @@ ${input.slice(result.pos)}
5515
5808
  function ExpressionizedStatementWithTrailingCallExpressions(ctx, state) {
5516
5809
  return $EVENT(ctx, state, "ExpressionizedStatementWithTrailingCallExpressions", ExpressionizedStatementWithTrailingCallExpressions$0);
5517
5810
  }
5518
- var ExpressionizedStatement$0 = $T($S($EXPECT($R0, "ExpressionizedStatement /(?=async|debugger|if|unless|do|for|loop|until|while|switch|throw|try)/"), _ExpressionizedStatement), function(value) {
5519
- return value[1];
5811
+ 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) {
5812
+ var statement = $2;
5813
+ return {
5814
+ type: "StatementExpression",
5815
+ statement,
5816
+ children: [statement]
5817
+ };
5520
5818
  });
5521
5819
  function ExpressionizedStatement(ctx, state) {
5522
5820
  return $EVENT(ctx, state, "ExpressionizedStatement", ExpressionizedStatement$0);
5523
5821
  }
5524
- var _ExpressionizedStatement$0 = DebuggerExpression;
5525
- var _ExpressionizedStatement$1 = IfExpression;
5526
- var _ExpressionizedStatement$2 = UnlessExpression;
5527
- var _ExpressionizedStatement$3 = IterationExpression;
5528
- var _ExpressionizedStatement$4 = SwitchExpression;
5529
- var _ExpressionizedStatement$5 = ThrowExpression;
5530
- var _ExpressionizedStatement$6 = TryExpression;
5531
- var _ExpressionizedStatement$$ = [_ExpressionizedStatement$0, _ExpressionizedStatement$1, _ExpressionizedStatement$2, _ExpressionizedStatement$3, _ExpressionizedStatement$4, _ExpressionizedStatement$5, _ExpressionizedStatement$6];
5532
- function _ExpressionizedStatement(ctx, state) {
5533
- return $EVENT_C(ctx, state, "_ExpressionizedStatement", _ExpressionizedStatement$$);
5822
+ var StatementExpression$0 = DebuggerStatement;
5823
+ var StatementExpression$1 = IfStatement;
5824
+ var StatementExpression$2 = IterationExpression;
5825
+ var StatementExpression$3 = SwitchStatement;
5826
+ var StatementExpression$4 = ThrowStatement;
5827
+ var StatementExpression$5 = TryStatement;
5828
+ var StatementExpression$$ = [StatementExpression$0, StatementExpression$1, StatementExpression$2, StatementExpression$3, StatementExpression$4, StatementExpression$5];
5829
+ function StatementExpression(ctx, state) {
5830
+ return $EVENT_C(ctx, state, "StatementExpression", StatementExpression$$);
5534
5831
  }
5535
5832
  var CommaExpression$0 = $TS($S(AssignmentExpression, $Q($S(CommaDelimiter, AssignmentExpression))), function($skip, $loc, $0, $1, $2) {
5536
5833
  if ($2.length == 0)
@@ -5556,14 +5853,8 @@ ${input.slice(result.pos)}
5556
5853
  var ws = $3;
5557
5854
  var args = $4;
5558
5855
  var close = $5;
5559
- if (args.length === 1) {
5560
- let arg0 = args[0];
5561
- if (Array.isArray(arg0))
5562
- arg0 = arg0[1];
5563
- if (arg0.type === "IterationExpression" && arg0.subtype !== "DoStatement" && !arg0.async && isEmptyBareBlock(arg0.block)) {
5564
- return $skip;
5565
- }
5566
- }
5856
+ if (skipImplicitArguments(args))
5857
+ return $skip;
5567
5858
  return {
5568
5859
  type: "Call",
5569
5860
  args,
@@ -6121,8 +6412,12 @@ ${input.slice(result.pos)}
6121
6412
  function PipelineHeadItem(ctx, state) {
6122
6413
  return $EVENT_C(ctx, state, "PipelineHeadItem", PipelineHeadItem$$);
6123
6414
  }
6124
- var PipelineTailItem$0 = Await;
6125
- var PipelineTailItem$1 = Yield;
6415
+ var PipelineTailItem$0 = $T($S(AwaitOp, $N(AccessStart)), function(value) {
6416
+ return value[0];
6417
+ });
6418
+ var PipelineTailItem$1 = $T($S(Yield, $N(AccessStart)), function(value) {
6419
+ return value[0];
6420
+ });
6126
6421
  var PipelineTailItem$2 = $T($S(Return, $N(AccessStart)), function(value) {
6127
6422
  return value[0];
6128
6423
  });
@@ -6158,6 +6453,9 @@ ${input.slice(result.pos)}
6158
6453
  return $skip;
6159
6454
  const [exp, ws, close] = $3;
6160
6455
  switch (exp.type) {
6456
+ case "StatementExpression":
6457
+ if (exp.statement.type !== "IterationExpression")
6458
+ break;
6161
6459
  case "IterationExpression":
6162
6460
  return exp;
6163
6461
  case "ParenthesizedExpression":
@@ -7685,7 +7983,7 @@ ${input.slice(result.pos)}
7685
7983
  if (prefix.length) {
7686
7984
  body = {
7687
7985
  type: "UnaryExpression",
7688
- children: [prefix, body, void 0]
7986
+ children: [processUnaryExpression(prefix, body, void 0)]
7689
7987
  };
7690
7988
  }
7691
7989
  const parameters = {
@@ -9202,8 +9500,9 @@ ${input.slice(result.pos)}
9202
9500
  return $EVENT_C(ctx, state, "MethodSignature", MethodSignature$$);
9203
9501
  }
9204
9502
  var ClassElementName$0 = PropertyName;
9205
- var ClassElementName$1 = PrivateIdentifier;
9206
- var ClassElementName$$ = [ClassElementName$0, ClassElementName$1];
9503
+ var ClassElementName$1 = LengthShorthand;
9504
+ var ClassElementName$2 = PrivateIdentifier;
9505
+ var ClassElementName$$ = [ClassElementName$0, ClassElementName$1, ClassElementName$2];
9207
9506
  function ClassElementName(ctx, state) {
9208
9507
  return $EVENT_C(ctx, state, "ClassElementName", ClassElementName$$);
9209
9508
  }
@@ -9642,7 +9941,13 @@ ${input.slice(result.pos)}
9642
9941
  return { $loc, token: $0 };
9643
9942
  });
9644
9943
  var UnaryOp$1 = AwaitOp;
9645
- var UnaryOp$2 = $S($C(Delete, Void, Typeof), $N($R$0($EXPECT($R21, "UnaryOp /[:.]/"))), $E(_));
9944
+ var UnaryOp$2 = $TS($S($C(Delete, Void, Typeof), $N($EXPECT($R21, "UnaryOp /[:.]/")), $E(_)), function($skip, $loc, $0, $1, $2, $3) {
9945
+ var op = $1;
9946
+ var ws = $3;
9947
+ if (!ws)
9948
+ return [op, [" "]];
9949
+ return [op, ws];
9950
+ });
9646
9951
  var UnaryOp$3 = $T($S(Not, $N($EXPECT($R21, "UnaryOp /[:.]/")), $E($EXPECT($L16, 'UnaryOp " "')), $E(_)), function(value) {
9647
9952
  return [value[0], value[3]];
9648
9953
  });
@@ -9650,18 +9955,15 @@ ${input.slice(result.pos)}
9650
9955
  function UnaryOp(ctx, state) {
9651
9956
  return $EVENT_C(ctx, state, "UnaryOp", UnaryOp$$);
9652
9957
  }
9653
- var AwaitOp$0 = $TS($S(Await, $E($S(Dot, IdentifierName)), $C($Y(OpenParen), _, $Y(EOS))), function($skip, $loc, $0, $1, $2, $3) {
9958
+ var AwaitOp$0 = $TS($S(Await, $E($S(Dot, IdentifierName)), $E(_)), function($skip, $loc, $0, $1, $2, $3) {
9654
9959
  var a = $1;
9655
9960
  var op = $2;
9656
9961
  var ws = $3;
9657
- if (op) {
9658
- return {
9659
- ...a,
9660
- op,
9661
- children: [a, ...ws || []]
9662
- };
9663
- }
9664
- return [a, ...ws || []];
9962
+ return {
9963
+ ...a,
9964
+ op,
9965
+ children: [a, ...ws || [" "]]
9966
+ };
9665
9967
  });
9666
9968
  function AwaitOp(ctx, state) {
9667
9969
  return $EVENT(ctx, state, "AwaitOp", AwaitOp$0);
@@ -9874,120 +10176,6 @@ ${input.slice(result.pos)}
9874
10176
  function UnlessClause(ctx, state) {
9875
10177
  return $EVENT(ctx, state, "UnlessClause", UnlessClause$0);
9876
10178
  }
9877
- var IfExpression$0 = $TS($S(IfClause, ExpressionBlock, $E(ElseExpressionClause)), function($skip, $loc, $0, $1, $2, $3) {
9878
- var clause = $1;
9879
- var b = $2;
9880
- var e = $3;
9881
- return expressionizeIfClause(clause, b, e);
9882
- });
9883
- function IfExpression(ctx, state) {
9884
- return $EVENT(ctx, state, "IfExpression", IfExpression$0);
9885
- }
9886
- var UnlessExpression$0 = $TS($S(UnlessClause, ExpressionBlock, $E(ElseExpressionClause)), function($skip, $loc, $0, $1, $2, $3) {
9887
- var clause = $1;
9888
- var b = $2;
9889
- var e = $3;
9890
- return expressionizeIfClause(clause, b, e);
9891
- });
9892
- function UnlessExpression(ctx, state) {
9893
- return $EVENT(ctx, state, "UnlessExpression", UnlessExpression$0);
9894
- }
9895
- var ElseExpressionClause$0 = $TS($S($C($S(Nested, Else), $S($E(_), Else)), ElseExpressionBlock), function($skip, $loc, $0, $1, $2) {
9896
- return [...$1, $2];
9897
- });
9898
- function ElseExpressionClause(ctx, state) {
9899
- return $EVENT(ctx, state, "ElseExpressionClause", ElseExpressionClause$0);
9900
- }
9901
- var ExpressionBlock$0 = $TS($S(InsertOpenParen, NestedBlockExpressions, InsertNewline, InsertIndent, InsertCloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
9902
- var exps = $2;
9903
- exps = exps.flat();
9904
- if (exps.length === 1) {
9905
- let [ws, exp] = exps[0];
9906
- switch (exp.type) {
9907
- case "Identifier":
9908
- case "Literal":
9909
- return [ws, exp];
9910
- }
9911
- }
9912
- exps = exps.map((e, i) => {
9913
- if (i === exps.length - 1) {
9914
- return e.slice(0, -1);
9915
- }
9916
- return e;
9917
- });
9918
- return {
9919
- type: "BlockExpressions",
9920
- expressions: exps,
9921
- children: [$1, exps, $3, $4, $5]
9922
- };
9923
- });
9924
- var ExpressionBlock$1 = $S(Then, ExtendedExpression);
9925
- var ExpressionBlock$$ = [ExpressionBlock$0, ExpressionBlock$1];
9926
- function ExpressionBlock(ctx, state) {
9927
- return $EVENT_C(ctx, state, "ExpressionBlock", ExpressionBlock$$);
9928
- }
9929
- var ElseExpressionBlock$0 = $TS($S(InsertOpenParen, NestedBlockExpressions, InsertNewline, InsertIndent, InsertCloseParen), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
9930
- var exps = $2;
9931
- exps = exps.flat();
9932
- if (exps.length === 1) {
9933
- let [ws, exp] = exps[0];
9934
- switch (exp.type) {
9935
- case "Identifier":
9936
- case "Literal":
9937
- return [ws, exp];
9938
- }
9939
- }
9940
- exps = exps.map((e, i) => {
9941
- if (i === exps.length - 1) {
9942
- return e.slice(0, -1);
9943
- }
9944
- return e;
9945
- });
9946
- return {
9947
- type: "BlockExpressions",
9948
- expressions: exps,
9949
- children: [$1, exps, $3, $4, $5]
9950
- };
9951
- });
9952
- var ElseExpressionBlock$1 = $T($S($N(EOS), ExpressionWithObjectApplicationForbidden), function(value) {
9953
- return value[1];
9954
- });
9955
- var ElseExpressionBlock$$ = [ElseExpressionBlock$0, ElseExpressionBlock$1];
9956
- function ElseExpressionBlock(ctx, state) {
9957
- return $EVENT_C(ctx, state, "ElseExpressionBlock", ElseExpressionBlock$$);
9958
- }
9959
- var NestedBlockExpressions$0 = $TS($S(PushIndent, $Q(NestedBlockExpression), PopIndent), function($skip, $loc, $0, $1, $2, $3) {
9960
- var exps = $2;
9961
- if (!exps.length)
9962
- return $skip;
9963
- return exps;
9964
- });
9965
- function NestedBlockExpressions(ctx, state) {
9966
- return $EVENT(ctx, state, "NestedBlockExpressions", NestedBlockExpressions$0);
9967
- }
9968
- var NestedBlockExpression$0 = $TS($S(Nested, $P(BlockExpressionPart)), function($skip, $loc, $0, $1, $2) {
9969
- var nested = $1;
9970
- var expressions = $2;
9971
- return [
9972
- [nested, ...expressions[0]],
9973
- ...expressions.slice(1).map((s) => ["", ...s])
9974
- ];
9975
- });
9976
- function NestedBlockExpression(ctx, state) {
9977
- return $EVENT(ctx, state, "NestedBlockExpression", NestedBlockExpression$0);
9978
- }
9979
- var BlockExpressionPart$0 = $TS($S($N(EOS), $E(_), PostfixedExpression, ExpressionDelimiter), function($skip, $loc, $0, $1, $2, $3, $4) {
9980
- var ws = $2;
9981
- var exp = $3;
9982
- var delimiter = $4;
9983
- if (ws) {
9984
- exp = { ...exp, children: [ws, ...exp.children] };
9985
- }
9986
- return [exp, delimiter];
9987
- });
9988
- function BlockExpressionPart(ctx, state) {
9989
- return $EVENT(ctx, state, "BlockExpressionPart", BlockExpressionPart$0);
9990
- }
9991
10179
  var IterationStatement$0 = $T($S($EXPECT($R23, "IterationStatement /(?=loop|do|for|until|while)/"), _IterationStatement), function(value) {
9992
10180
  return value[1];
9993
10181
  });
@@ -10404,18 +10592,6 @@ ${input.slice(result.pos)}
10404
10592
  function EmptyCondition(ctx, state) {
10405
10593
  return $EVENT(ctx, state, "EmptyCondition", EmptyCondition$0);
10406
10594
  }
10407
- var SwitchExpression$0 = $TV(SwitchStatement, function($skip, $loc, $0, $1) {
10408
- var s = $0;
10409
- return {
10410
- type: "SwitchExpression",
10411
- // wrap with IIFE
10412
- children: wrapIIFE([["", s]]),
10413
- statement: s
10414
- };
10415
- });
10416
- function SwitchExpression(ctx, state) {
10417
- return $EVENT(ctx, state, "SwitchExpression", SwitchExpression$0);
10418
- }
10419
10595
  var CaseBlock$0 = $TS($S($E($C(Nested, _)), OpenBrace, NestedCaseClauses, __, CloseBrace), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
10420
10596
  var clauses = $3;
10421
10597
  return {
@@ -10597,17 +10773,6 @@ ${input.slice(result.pos)}
10597
10773
  function TryStatement(ctx, state) {
10598
10774
  return $EVENT(ctx, state, "TryStatement", TryStatement$0);
10599
10775
  }
10600
- var TryExpression$0 = $TV(TryStatement, function($skip, $loc, $0, $1) {
10601
- var t = $0;
10602
- return {
10603
- type: "TryExpression",
10604
- blocks: t.blocks,
10605
- children: wrapIIFE([["", t]])
10606
- };
10607
- });
10608
- function TryExpression(ctx, state) {
10609
- return $EVENT(ctx, state, "TryExpression", TryExpression$0);
10610
- }
10611
10776
  var CatchClause$0 = $TS($S($C(Nested, _), Catch, $E(CatchBind), $C(BracedThenClause, BracedOrEmptyBlock)), function($skip, $loc, $0, $1, $2, $3, $4) {
10612
10777
  var block = $4;
10613
10778
  return {
@@ -10942,26 +11107,6 @@ ${input.slice(result.pos)}
10942
11107
  function Debugger(ctx, state) {
10943
11108
  return $EVENT(ctx, state, "Debugger", Debugger$0);
10944
11109
  }
10945
- var DebuggerExpression$0 = $TV(DebuggerStatement, function($skip, $loc, $0, $1) {
10946
- var s = $0;
10947
- return {
10948
- type: "DebuggerExpression",
10949
- children: wrapIIFE([["", s]])
10950
- };
10951
- });
10952
- function DebuggerExpression(ctx, state) {
10953
- return $EVENT(ctx, state, "DebuggerExpression", DebuggerExpression$0);
10954
- }
10955
- var ThrowExpression$0 = $TV(ThrowStatement, function($skip, $loc, $0, $1) {
10956
- var s = $0;
10957
- return {
10958
- type: "ThrowExpression",
10959
- children: wrapIIFE([["", s]])
10960
- };
10961
- });
10962
- function ThrowExpression(ctx, state) {
10963
- return $EVENT(ctx, state, "ThrowExpression", ThrowExpression$0);
10964
- }
10965
11110
  var MaybeNestedExpression$0 = $TS($S($N(EOS), ExtendedExpression), function($skip, $loc, $0, $1, $2) {
10966
11111
  return $2;
10967
11112
  });
@@ -10983,27 +11128,26 @@ ${input.slice(result.pos)}
10983
11128
  children: [imp, $0.slice(1)]
10984
11129
  };
10985
11130
  });
10986
- var ImportDeclaration$1 = $T($S(Import, __, TypeKeyword, __, ImportClause, __, FromClause, $E(ImportAssertion)), function(value) {
11131
+ var ImportDeclaration$1 = $T($S(Import, __, TypeKeyword, __, ImportClause, __, FromClause), function(value) {
10987
11132
  return { "type": "ImportDeclaration", "ts": true, "children": value };
10988
11133
  });
10989
- var ImportDeclaration$2 = $T($S(Import, __, ImportClause, __, FromClause, $E(ImportAssertion)), function(value) {
11134
+ var ImportDeclaration$2 = $T($S(Import, __, ImportClause, __, FromClause), function(value) {
10990
11135
  return { "type": "ImportDeclaration", "children": value };
10991
11136
  });
10992
- var ImportDeclaration$3 = $T($S(Import, __, ModuleSpecifier, $E(ImportAssertion)), function(value) {
11137
+ var ImportDeclaration$3 = $T($S(Import, __, ModuleSpecifier), function(value) {
10993
11138
  return { "type": "ImportDeclaration", "children": value };
10994
11139
  });
10995
- var ImportDeclaration$4 = $TS($S(ImpliedImport, $E($S(TypeKeyword, __)), ImportClause, __, FromClause, $E(ImportAssertion)), function($skip, $loc, $0, $1, $2, $3, $4, $5, $6) {
11140
+ var ImportDeclaration$4 = $TS($S(ImpliedImport, $E($S(TypeKeyword, __)), ImportClause, __, FromClause), function($skip, $loc, $0, $1, $2, $3, $4, $5) {
10996
11141
  var i = $1;
10997
11142
  var t = $2;
10998
11143
  var c = $3;
10999
11144
  var w = $4;
11000
11145
  var f = $5;
11001
- var a = $6;
11002
11146
  i.$loc = {
11003
11147
  pos: f[0].$loc.pos - 1,
11004
11148
  length: f[0].$loc.length + 1
11005
11149
  };
11006
- const children = [i, t, c, w, f, a];
11150
+ const children = [i, t, c, w, f];
11007
11151
  if (!t)
11008
11152
  return children;
11009
11153
  return { type: "ImportDeclaration", ts: true, children };
@@ -11162,7 +11306,8 @@ ${input.slice(result.pos)}
11162
11306
  function ModuleExportName(ctx, state) {
11163
11307
  return $EVENT_C(ctx, state, "ModuleExportName", ModuleExportName$$);
11164
11308
  }
11165
- var ModuleSpecifier$0 = $TS($S(UnprocessedModuleSpecifier), function($skip, $loc, $0, $1) {
11309
+ var ModuleSpecifier$0 = $TS($S(UnprocessedModuleSpecifier, $E(ImportAssertion)), function($skip, $loc, $0, $1, $2) {
11310
+ var a = $2;
11166
11311
  let { token } = $1;
11167
11312
  if (module.config.rewriteTsImports) {
11168
11313
  token = token.replace(/\.([mc])?ts(['"])$/, ".$1js$2");
@@ -11173,6 +11318,8 @@ ${input.slice(result.pos)}
11173
11318
  `${module.config.rewriteCivetImports.replace(/\$/g, "$$")}$1`
11174
11319
  );
11175
11320
  }
11321
+ if (a)
11322
+ return [{ ...$1, token }, a];
11176
11323
  return { ...$1, token };
11177
11324
  });
11178
11325
  function ModuleSpecifier(ctx, state) {
@@ -11537,7 +11684,11 @@ ${input.slice(result.pos)}
11537
11684
  function TripleSingleStringCharacters(ctx, state) {
11538
11685
  return $EVENT(ctx, state, "TripleSingleStringCharacters", TripleSingleStringCharacters$0);
11539
11686
  }
11540
- var CoffeeStringSubstitution$0 = $S(CoffeeSubstitutionStart, PostfixedExpression, __, CloseBrace);
11687
+ var CoffeeStringSubstitution$0 = $TS($S(CoffeeSubstitutionStart, AllowAll, $E($S(PostfixedExpression, __, CloseBrace)), RestoreAll), function($skip, $loc, $0, $1, $2, $3, $4) {
11688
+ if (!$3)
11689
+ return $skip;
11690
+ return [$1, ...$3];
11691
+ });
11541
11692
  function CoffeeStringSubstitution(ctx, state) {
11542
11693
  return $EVENT(ctx, state, "CoffeeStringSubstitution", CoffeeStringSubstitution$0);
11543
11694
  }
@@ -11714,7 +11865,11 @@ ${input.slice(result.pos)}
11714
11865
  function _TemplateLiteral(ctx, state) {
11715
11866
  return $EVENT_C(ctx, state, "_TemplateLiteral", _TemplateLiteral$$);
11716
11867
  }
11717
- var TemplateSubstitution$0 = $S(SubstitutionStart, PostfixedExpression, __, CloseBrace);
11868
+ var TemplateSubstitution$0 = $TS($S(SubstitutionStart, AllowAll, $E($S(PostfixedExpression, __, CloseBrace)), RestoreAll), function($skip, $loc, $0, $1, $2, $3, $4) {
11869
+ if (!$3)
11870
+ return $skip;
11871
+ return [$1, ...$3];
11872
+ });
11718
11873
  function TemplateSubstitution(ctx, state) {
11719
11874
  return $EVENT(ctx, state, "TemplateSubstitution", TemplateSubstitution$0);
11720
11875
  }
@@ -14079,7 +14234,9 @@ ${input.slice(result.pos)}
14079
14234
  function TripleSlashDirective(ctx, state) {
14080
14235
  return $EVENT(ctx, state, "TripleSlashDirective", TripleSlashDirective$0);
14081
14236
  }
14082
- var DirectivePrologue$0 = PrologueString;
14237
+ var DirectivePrologue$0 = $T($S(PrologueString, $N($S(__, $C(AccessStart, Pipe)))), function(value) {
14238
+ return value[0];
14239
+ });
14083
14240
  function DirectivePrologue(ctx, state) {
14084
14241
  return $EVENT(ctx, state, "DirectivePrologue", DirectivePrologue$0);
14085
14242
  }
@@ -14463,6 +14620,19 @@ ${input.slice(result.pos)}
14463
14620
  };
14464
14621
  module.prelude.push(["", [preludeVar, isRef, typeSuffix, " = Object.is", asAny, ";\n"]]);
14465
14622
  },
14623
+ /**
14624
+ * Array length check with type guard.
14625
+ * From tlgreg https://discord.com/channels/933472021310996512/1012166187196629113/1157386582546976873
14626
+ */
14627
+ len(lenRef) {
14628
+ module.prelude.push(["", [{
14629
+ ts: true,
14630
+ children: ["function ", lenRef, "<T extends readonly unknown[], N extends number>(arr: T, length: N): arr is T & { length: N } { return arr.length === length }"]
14631
+ }, {
14632
+ js: true,
14633
+ children: ["function ", lenRef, "(arr, length) { return arr.length === length }"]
14634
+ }], "\n"]);
14635
+ },
14466
14636
  modulo(moduloRef) {
14467
14637
  const typeSuffix = {
14468
14638
  ts: true,
@@ -14614,9 +14784,9 @@ ${input.slice(result.pos)}
14614
14784
  }
14615
14785
  }
14616
14786
  });
14617
- if (typeof parse !== "undefined") {
14618
- Object.assign(module.config, parse.config);
14619
- parse.config = module.config;
14787
+ if (typeof parse2 !== "undefined") {
14788
+ Object.assign(module.config, parse2.config);
14789
+ parse2.config = module.config;
14620
14790
  } else {
14621
14791
  Object.assign(module.config, exports.parse.config);
14622
14792
  exports.parse.config = module.config;
@@ -14767,7 +14937,7 @@ ${input.slice(result.pos)}
14767
14937
  };
14768
14938
  }();
14769
14939
  exports.default = parser;
14770
- exports.parse = parser.parse;
14940
+ var parse2 = exports.parse = parser.parse;
14771
14941
  exports.Program = Program;
14772
14942
  exports.TopLevelStatements = TopLevelStatements;
14773
14943
  exports.NestedTopLevelStatements = NestedTopLevelStatements;
@@ -14781,7 +14951,7 @@ ${input.slice(result.pos)}
14781
14951
  exports.NestedNonAssignmentExtendedExpression = NestedNonAssignmentExtendedExpression;
14782
14952
  exports.ExpressionizedStatementWithTrailingCallExpressions = ExpressionizedStatementWithTrailingCallExpressions;
14783
14953
  exports.ExpressionizedStatement = ExpressionizedStatement;
14784
- exports._ExpressionizedStatement = _ExpressionizedStatement;
14954
+ exports.StatementExpression = StatementExpression;
14785
14955
  exports.CommaExpression = CommaExpression;
14786
14956
  exports.Arguments = Arguments;
14787
14957
  exports.ImplicitArguments = ImplicitArguments;
@@ -15043,14 +15213,6 @@ ${input.slice(result.pos)}
15043
15213
  exports.ElseClause = ElseClause;
15044
15214
  exports.IfClause = IfClause;
15045
15215
  exports.UnlessClause = UnlessClause;
15046
- exports.IfExpression = IfExpression;
15047
- exports.UnlessExpression = UnlessExpression;
15048
- exports.ElseExpressionClause = ElseExpressionClause;
15049
- exports.ExpressionBlock = ExpressionBlock;
15050
- exports.ElseExpressionBlock = ElseExpressionBlock;
15051
- exports.NestedBlockExpressions = NestedBlockExpressions;
15052
- exports.NestedBlockExpression = NestedBlockExpression;
15053
- exports.BlockExpressionPart = BlockExpressionPart;
15054
15216
  exports.IterationStatement = IterationStatement;
15055
15217
  exports._IterationStatement = _IterationStatement;
15056
15218
  exports.IterationExpression = IterationExpression;
@@ -15074,7 +15236,6 @@ ${input.slice(result.pos)}
15074
15236
  exports.ForBinding = ForBinding;
15075
15237
  exports.SwitchStatement = SwitchStatement;
15076
15238
  exports.EmptyCondition = EmptyCondition;
15077
- exports.SwitchExpression = SwitchExpression;
15078
15239
  exports.CaseBlock = CaseBlock;
15079
15240
  exports.NestedCaseClauses = NestedCaseClauses;
15080
15241
  exports.NestedCaseClause = NestedCaseClause;
@@ -15086,7 +15247,6 @@ ${input.slice(result.pos)}
15086
15247
  exports.ImpliedColon = ImpliedColon;
15087
15248
  exports.IgnoreColon = IgnoreColon;
15088
15249
  exports.TryStatement = TryStatement;
15089
- exports.TryExpression = TryExpression;
15090
15250
  exports.CatchClause = CatchClause;
15091
15251
  exports.CatchBind = CatchBind;
15092
15252
  exports.FinallyClause = FinallyClause;
@@ -15127,8 +15287,6 @@ ${input.slice(result.pos)}
15127
15287
  exports.Break = Break;
15128
15288
  exports.Continue = Continue;
15129
15289
  exports.Debugger = Debugger;
15130
- exports.DebuggerExpression = DebuggerExpression;
15131
- exports.ThrowExpression = ThrowExpression;
15132
15290
  exports.MaybeNestedExpression = MaybeNestedExpression;
15133
15291
  exports.ImportDeclaration = ImportDeclaration;
15134
15292
  exports.ImpliedImport = ImpliedImport;