parseman 0.47.1 → 0.48.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +27 -21
  2. package/dist/analysis/diagnostics.js +2964 -347
  3. package/dist/analysis/diagnostics.js.map +3 -3
  4. package/dist/cli/index.js +2960 -343
  5. package/dist/cli/index.js.map +3 -3
  6. package/dist/combinators/choice.d.ts.map +1 -1
  7. package/dist/combinators/expect.d.ts +1 -0
  8. package/dist/combinators/expect.d.ts.map +1 -1
  9. package/dist/combinators/expected.d.ts +8 -0
  10. package/dist/combinators/expected.d.ts.map +1 -0
  11. package/dist/combinators/first-set.d.ts +8 -0
  12. package/dist/combinators/first-set.d.ts.map +1 -1
  13. package/dist/combinators/grammar.d.ts.map +1 -1
  14. package/dist/combinators/keywords.d.ts +4 -0
  15. package/dist/combinators/keywords.d.ts.map +1 -1
  16. package/dist/combinators/literal.d.ts.map +1 -1
  17. package/dist/combinators/not.d.ts.map +1 -1
  18. package/dist/combinators/peek.d.ts.map +1 -1
  19. package/dist/combinators/regex.d.ts.map +1 -1
  20. package/dist/combinators/repeat.d.ts.map +1 -1
  21. package/dist/combinators/sequence.d.ts.map +1 -1
  22. package/dist/combinators/trivia-skip.d.ts +16 -3
  23. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  24. package/dist/compiler/direct-projection.d.ts +12 -0
  25. package/dist/compiler/direct-projection.d.ts.map +1 -0
  26. package/dist/compiler/token-alphabet.d.ts +845 -5
  27. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  28. package/dist/compiler/token-capability.d.ts +3 -0
  29. package/dist/compiler/token-capability.d.ts.map +1 -0
  30. package/dist/compiler/token-capability.js +3192 -0
  31. package/dist/compiler/token-capability.js.map +6 -0
  32. package/dist/cst/trivia-charscan.d.ts +3 -0
  33. package/dist/cst/trivia-charscan.d.ts.map +1 -1
  34. package/dist/cst/trivia-css-scanner.d.ts +5 -0
  35. package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
  36. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  37. package/dist/index.js +2973 -343
  38. package/dist/index.js.map +3 -3
  39. package/dist/language-service/index.js +5 -1
  40. package/dist/language-service/index.js.map +1 -1
  41. package/dist/plugin/index.js +2982 -352
  42. package/dist/plugin/index.js.map +3 -3
  43. package/dist/spec/index.js +325 -47
  44. package/dist/spec/index.js.map +3 -3
  45. package/dist/table/assemble.d.ts.map +1 -1
  46. package/dist/table/child-slots.d.ts.map +1 -1
  47. package/dist/table/compile-rule-map.d.ts +3 -1
  48. package/dist/table/compile-rule-map.d.ts.map +1 -1
  49. package/dist/table/emit-assembly.d.ts +12 -13
  50. package/dist/table/emit-assembly.d.ts.map +1 -1
  51. package/dist/table/emit.d.ts.map +1 -1
  52. package/dist/table/encode.d.ts.map +1 -1
  53. package/dist/table/exec-baseline.d.ts.map +1 -1
  54. package/dist/table/exec.d.ts.map +1 -1
  55. package/dist/table/index.js +2937 -311
  56. package/dist/table/index.js.map +3 -3
  57. package/dist/table/lex-body.d.ts +9 -0
  58. package/dist/table/lex-body.d.ts.map +1 -0
  59. package/dist/table/lex-program.d.ts +25 -0
  60. package/dist/table/lex-program.d.ts.map +1 -0
  61. package/dist/table/ops.d.ts +47 -11
  62. package/dist/table/ops.d.ts.map +1 -1
  63. package/dist/table/program.d.ts +50 -2
  64. package/dist/table/program.d.ts.map +1 -1
  65. package/dist/table/scalar-terminal.d.ts +13 -0
  66. package/dist/table/scalar-terminal.d.ts.map +1 -0
  67. package/dist/table/site-labels.d.ts.map +1 -1
  68. package/dist/types.d.ts +2 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/version.d.ts +1 -1
  71. package/package.json +11 -11
  72. package/src/combinators/choice.ts +10 -1
  73. package/src/combinators/expect.ts +1 -0
  74. package/src/combinators/expected.ts +17 -0
  75. package/src/combinators/first-set.ts +58 -5
  76. package/src/combinators/grammar.ts +8 -3
  77. package/src/combinators/keywords.ts +22 -6
  78. package/src/combinators/literal.ts +2 -1
  79. package/src/combinators/not.ts +5 -1
  80. package/src/combinators/peek.ts +5 -1
  81. package/src/combinators/regex.ts +5 -3
  82. package/src/combinators/repeat.ts +4 -10
  83. package/src/combinators/sequence.ts +17 -14
  84. package/src/combinators/trivia-skip.ts +46 -13
  85. package/src/compiler/direct-projection.ts +43 -0
  86. package/src/compiler/token-alphabet.ts +4316 -12
  87. package/src/compiler/token-capability.ts +6 -0
  88. package/src/cst/trivia-charscan.ts +34 -0
  89. package/src/cst/trivia-css-scanner.ts +142 -0
  90. package/src/cst/trivia-kinds.ts +3 -1
  91. package/src/plugin/index.ts +4 -4
  92. package/src/table/assemble.ts +1253 -240
  93. package/src/table/child-slots.ts +2 -1
  94. package/src/table/compile-rule-map.ts +21 -3
  95. package/src/table/emit-assembly.ts +335 -87
  96. package/src/table/emit.ts +16 -2
  97. package/src/table/encode.ts +248 -60
  98. package/src/table/exec-baseline.ts +3 -7
  99. package/src/table/exec.ts +134 -25
  100. package/src/table/lex-body.ts +30 -0
  101. package/src/table/lex-program.ts +431 -0
  102. package/src/table/ops.ts +49 -11
  103. package/src/table/program.ts +46 -2
  104. package/src/table/scalar-terminal.ts +51 -0
  105. package/src/table/site-labels.ts +11 -1
  106. package/src/table/stamp.ts +1 -1
  107. package/src/types.ts +1 -1
  108. package/src/version.ts +1 -1
  109. package/dist/analysis/diagnostics.cjs +0 -13824
  110. package/dist/analysis/diagnostics.cjs.map +0 -6
  111. package/dist/cli/index.cjs +0 -14925
  112. package/dist/cli/index.cjs.map +0 -6
  113. package/dist/index.cjs +0 -16391
  114. package/dist/index.cjs.map +0 -6
  115. package/dist/language-service/index.cjs +0 -1304
  116. package/dist/language-service/index.cjs.map +0 -6
  117. package/dist/oracle/index.cjs +0 -254
  118. package/dist/oracle/index.cjs.map +0 -6
  119. package/dist/plugin/index.cjs +0 -16097
  120. package/dist/plugin/index.cjs.map +0 -6
  121. package/dist/run/index.cjs +0 -577
  122. package/dist/run/index.cjs.map +0 -6
  123. package/dist/spec/index.cjs +0 -6236
  124. package/dist/spec/index.cjs.map +0 -6
  125. package/dist/table/index.cjs +0 -11463
  126. package/dist/table/index.cjs.map +0 -6
@@ -7,6 +7,42 @@ import { ResolverFactory } from "oxc-resolver";
7
7
  import MagicString from "magic-string";
8
8
 
9
9
  // src/combinators/first-set.ts
10
+ function classifyFinalChoice(arms, resolve3) {
11
+ const firstSets = [];
12
+ const nullable2 = [];
13
+ let exclusive = true;
14
+ for (const arm of arms) {
15
+ const empty2 = matchesEmpty(arm, /* @__PURE__ */ new Set(), resolve3);
16
+ nullable2.push(empty2);
17
+ firstSets.push(empty2 ? { kind: "any" } : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve3));
18
+ if (empty2) exclusive = false;
19
+ }
20
+ if (exclusive) {
21
+ const ascii = new Uint8Array(128);
22
+ let highOwners = 0;
23
+ for (let arm = 0; arm < firstSets.length && exclusive; arm++) {
24
+ const first = firstSets[arm];
25
+ if (first.kind !== "ranges" || first.ranges.length === 0) {
26
+ exclusive = false;
27
+ break;
28
+ }
29
+ let ownsHigh = false;
30
+ for (const range of first.ranges) {
31
+ if (range.hi >= 128) ownsHigh = true;
32
+ for (let code = Math.max(0, range.lo); code <= Math.min(127, range.hi); code++) {
33
+ if (ascii[code] !== 0) {
34
+ exclusive = false;
35
+ break;
36
+ }
37
+ ascii[code] = 1;
38
+ }
39
+ if (!exclusive) break;
40
+ }
41
+ if (ownsHigh && ++highOwners > 1) exclusive = false;
42
+ }
43
+ }
44
+ return { exclusive, firstSets, nullable: nullable2 };
45
+ }
10
46
  function resolveNamedRef(p, resolve3) {
11
47
  if (resolve3 === void 0) return void 0;
12
48
  const name = p._ruleName;
@@ -825,6 +861,179 @@ function parseClassRanges(body) {
825
861
  return ranges.length ? ranges : null;
826
862
  }
827
863
 
864
+ // src/cst/trivia-css-scanner.ts
865
+ var CSS_WS_SOURCE = "[ \\t\\n\\r\\f]+";
866
+ var CSS_LINE_COMMENT_SOURCE = "\\/\\/[^\\n\\r]*";
867
+ var CSS_BLOCK_COMMENT_SOURCE = "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/";
868
+ function scanWhitespace(input, cur) {
869
+ let pos = cur;
870
+ while (pos < input.length) {
871
+ const c = input.charCodeAt(pos);
872
+ if (c !== 32 && c !== 9 && c !== 10 && c !== 13 && c !== 12) break;
873
+ pos++;
874
+ }
875
+ return pos;
876
+ }
877
+ function scanLineComment(input, cur) {
878
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 47) return cur;
879
+ let pos = cur + 2;
880
+ while (pos < input.length) {
881
+ const c = input.charCodeAt(pos);
882
+ if (c === 10 || c === 13) break;
883
+ pos++;
884
+ }
885
+ return pos;
886
+ }
887
+ function scanBlockComment(input, cur) {
888
+ if (input.charCodeAt(cur) !== 47 || input.charCodeAt(cur + 1) !== 42) return cur;
889
+ const close = input.indexOf("*/", cur + 2);
890
+ return close < 0 ? cur : close + 2;
891
+ }
892
+ function scanWsLineBlockTrivia(input, cur) {
893
+ let pos = cur;
894
+ for (; ; ) {
895
+ const ws = scanWhitespace(input, pos);
896
+ if (ws !== pos) {
897
+ pos = ws;
898
+ continue;
899
+ }
900
+ const line = scanLineComment(input, pos);
901
+ if (line !== pos) {
902
+ pos = line;
903
+ continue;
904
+ }
905
+ const block = scanBlockComment(input, pos);
906
+ if (block !== pos) {
907
+ pos = block;
908
+ continue;
909
+ }
910
+ return pos;
911
+ }
912
+ }
913
+ function scanWsBlockTrivia(input, cur) {
914
+ let pos = cur;
915
+ for (; ; ) {
916
+ const ws = scanWhitespace(input, pos);
917
+ if (ws !== pos) {
918
+ pos = ws;
919
+ continue;
920
+ }
921
+ const block = scanBlockComment(input, pos);
922
+ if (block !== pos) {
923
+ pos = block;
924
+ continue;
925
+ }
926
+ return pos;
927
+ }
928
+ }
929
+ function scanLineBlockTrivia(input, cur) {
930
+ let pos = cur;
931
+ for (; ; ) {
932
+ const line = scanLineComment(input, pos);
933
+ if (line !== pos) {
934
+ pos = line;
935
+ continue;
936
+ }
937
+ const block = scanBlockComment(input, pos);
938
+ if (block !== pos) {
939
+ pos = block;
940
+ continue;
941
+ }
942
+ return pos;
943
+ }
944
+ }
945
+ function scanBlockTrivia(input, cur) {
946
+ let pos = cur;
947
+ for (; ; ) {
948
+ const block = scanBlockComment(input, pos);
949
+ if (block === pos) return pos;
950
+ pos = block;
951
+ }
952
+ }
953
+ function visitWsLineBlock(input, cur, visit) {
954
+ let pos = cur;
955
+ for (; ; ) {
956
+ let end = scanWhitespace(input, pos);
957
+ if (end !== pos) {
958
+ visit(pos, end, 0);
959
+ pos = end;
960
+ continue;
961
+ }
962
+ end = scanLineComment(input, pos);
963
+ if (end !== pos) {
964
+ visit(pos, end, 1);
965
+ pos = end;
966
+ continue;
967
+ }
968
+ end = scanBlockComment(input, pos);
969
+ if (end !== pos) {
970
+ visit(pos, end, 2);
971
+ pos = end;
972
+ continue;
973
+ }
974
+ return pos;
975
+ }
976
+ }
977
+ function visitWsBlock(input, cur, visit) {
978
+ let pos = cur;
979
+ for (; ; ) {
980
+ let end = scanWhitespace(input, pos);
981
+ if (end !== pos) {
982
+ visit(pos, end, 0);
983
+ pos = end;
984
+ continue;
985
+ }
986
+ end = scanBlockComment(input, pos);
987
+ if (end !== pos) {
988
+ visit(pos, end, 1);
989
+ pos = end;
990
+ continue;
991
+ }
992
+ return pos;
993
+ }
994
+ }
995
+ function visitLineBlock(input, cur, visit) {
996
+ let pos = cur;
997
+ for (; ; ) {
998
+ let end = scanLineComment(input, pos);
999
+ if (end !== pos) {
1000
+ visit(pos, end, 0);
1001
+ pos = end;
1002
+ continue;
1003
+ }
1004
+ end = scanBlockComment(input, pos);
1005
+ if (end !== pos) {
1006
+ visit(pos, end, 1);
1007
+ pos = end;
1008
+ continue;
1009
+ }
1010
+ return pos;
1011
+ }
1012
+ }
1013
+ function visitBlock(input, cur, visit) {
1014
+ let pos = cur;
1015
+ for (; ; ) {
1016
+ const end = scanBlockComment(input, pos);
1017
+ if (end === pos) return pos;
1018
+ visit(pos, end, 0);
1019
+ pos = end;
1020
+ }
1021
+ }
1022
+ function commonCssTriviaScanner(sources) {
1023
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return scanWsLineBlockTrivia;
1024
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanWsBlockTrivia;
1025
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return scanLineBlockTrivia;
1026
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return scanBlockTrivia;
1027
+ return null;
1028
+ }
1029
+ function commonCssTriviaVisitor(sources) {
1030
+ if (sources.length === 3 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_LINE_COMMENT_SOURCE && sources[2] === CSS_BLOCK_COMMENT_SOURCE) return visitWsLineBlock;
1031
+ if (sources.length === 2 && sources[0] === CSS_WS_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitWsBlock;
1032
+ if (sources.length === 2 && sources[0] === CSS_LINE_COMMENT_SOURCE && sources[1] === CSS_BLOCK_COMMENT_SOURCE) return visitLineBlock;
1033
+ if (sources.length === 1 && sources[0] === CSS_BLOCK_COMMENT_SOURCE) return visitBlock;
1034
+ return null;
1035
+ }
1036
+
828
1037
  // src/cst/trivia-charscan.ts
829
1038
  function inRanges(cp, ranges) {
830
1039
  for (let i = 0; i < ranges.length; i++) {
@@ -978,6 +1187,35 @@ function classifyParser(p) {
978
1187
  if (d.tag !== "regex" || d.flags) return null;
979
1188
  return classifyArm(d.source);
980
1189
  }
1190
+ function plainRegexSource(p) {
1191
+ const d = p._def;
1192
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
1193
+ }
1194
+ var visitSpec0;
1195
+ var visitSpec1;
1196
+ var visitSpec2;
1197
+ var visitSpec3;
1198
+ var visitValue0;
1199
+ var visitValue1;
1200
+ var visitValue2;
1201
+ var visitValue3;
1202
+ function commonLabeledTriviaVisitor(spec) {
1203
+ if (spec === visitSpec0) return visitValue0;
1204
+ if (spec === visitSpec1) return visitValue1;
1205
+ if (spec === visitSpec2) return visitValue2;
1206
+ if (spec === visitSpec3) return visitValue3;
1207
+ const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
1208
+ const visitor = commonCssTriviaVisitor(sources);
1209
+ visitSpec3 = visitSpec2;
1210
+ visitValue3 = visitValue2;
1211
+ visitSpec2 = visitSpec1;
1212
+ visitValue2 = visitValue1;
1213
+ visitSpec1 = visitSpec0;
1214
+ visitValue1 = visitValue0;
1215
+ visitSpec0 = spec;
1216
+ visitValue0 = visitor;
1217
+ return visitor;
1218
+ }
981
1219
  var armSpec0;
982
1220
  var armSpec1;
983
1221
  var armSpec2;
@@ -1176,6 +1414,8 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
1176
1414
  }
1177
1415
  function visitLabeledTrivia(input, cur, spec, state, visit) {
1178
1416
  if (spec.minRepeats > 1) return void 0;
1417
+ const common = commonLabeledTriviaVisitor(spec);
1418
+ if (common !== null) return common(input, cur, visit);
1179
1419
  const chars = charArmsFor(spec);
1180
1420
  if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
1181
1421
  let pos = cur;
@@ -1309,11 +1549,12 @@ function parser(opts, root) {
1309
1549
  const scopeLabels = scopeTrivia?._meta?.triviaKindLabels;
1310
1550
  const refuseUnclassified = scopeTrivia !== void 0 && !scopeTrivia._meta?.rootTriviaClassified && !opaqueRootCapture;
1311
1551
  const forceCaptureTrivia = opts.captureTrivia === true;
1312
- const trackLinesOf = opts.trackLines === true ? TRACK_LINES_ON : opts.trackLines === false ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
1552
+ const trackLinesPolicy = opts.trackLines === true ? "on" : opts.trackLines === false ? "off" : "inherit";
1553
+ const trackLinesOf = trackLinesPolicy === "on" ? TRACK_LINES_ON : trackLinesPolicy === "off" ? TRACK_LINES_OFF : TRACK_LINES_INHERIT;
1313
1554
  const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
1314
1555
  const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
1315
1556
  const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
1316
- return {
1557
+ const grammar = {
1317
1558
  _tag: "grammar",
1318
1559
  _meta: {
1319
1560
  ...root._meta,
@@ -1332,7 +1573,9 @@ function parser(opts, root) {
1332
1573
  clearTrivia,
1333
1574
  ...opaqueRootCapture ? { rootCapture: "opaque" } : {},
1334
1575
  ...opts.captureTrivia ? { captureTrivia: true } : {},
1335
- trackLines: opts.trackLines ?? false
1576
+ trackLines: opts.trackLines ?? false,
1577
+ constructionTrackLines: trackLinesPolicy,
1578
+ ...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
1336
1579
  },
1337
1580
  parse(input, pos, _ctx) {
1338
1581
  if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
@@ -1361,6 +1604,7 @@ function parser(opts, root) {
1361
1604
  return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
1362
1605
  }
1363
1606
  };
1607
+ return grammar;
1364
1608
  }
1365
1609
  function noTrivia(root) {
1366
1610
  return parser({ trivia: null }, root);
@@ -1589,6 +1833,21 @@ function failAt(ctx, expected, pos) {
1589
1833
  return r;
1590
1834
  }
1591
1835
 
1836
+ // src/combinators/expected.ts
1837
+ function directTerminalFailureExpected(def) {
1838
+ switch (def.tag) {
1839
+ case "literal":
1840
+ return [JSON.stringify(def.value)];
1841
+ case "regex":
1842
+ return [`/${def.source}/`];
1843
+ case "keywords":
1844
+ return ["keyword"];
1845
+ }
1846
+ }
1847
+ function assertionFailureExpected(positive, childTag) {
1848
+ return [`${positive ? "peek" : "not"}(${childTag})`];
1849
+ }
1850
+
1592
1851
  // src/combinators/literal.ts
1593
1852
  function asciiFoldEq(a, b) {
1594
1853
  if (a.length !== b.length) return false;
@@ -1620,7 +1879,7 @@ function literal(value, opts = {}) {
1620
1879
  { lo: firstUpper, hi: firstUpper }
1621
1880
  ] } : firstSet2;
1622
1881
  }
1623
- const expected = [JSON.stringify(value)];
1882
+ const expected = directTerminalFailureExpected({ tag: "literal", value, caseInsensitive });
1624
1883
  const parse2 = !caseInsensitive && value.length === 1 ? (() => {
1625
1884
  const code = value.charCodeAt(0);
1626
1885
  return function parse3(input, pos, ctx) {
@@ -1981,14 +2240,15 @@ function regex(pattern, flags = "") {
1981
2240
  const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
1982
2241
  const canMatchNewline = raw.canMatchNewline;
1983
2242
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
2243
+ const def = { tag: "regex", source, flags: resolvedFlags };
1984
2244
  return {
1985
2245
  _tag: "regex",
1986
2246
  _meta: meta,
1987
- _def: { tag: "regex", source, flags: resolvedFlags },
2247
+ _def: def,
1988
2248
  parse(input, pos, ctx) {
1989
2249
  const scanEnd = scan?.(input, pos);
1990
2250
  if (scanEnd !== void 0) {
1991
- if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
2251
+ if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
1992
2252
  const value = input.slice(pos, scanEnd);
1993
2253
  const span2 = { start: pos, end: scanEnd };
1994
2254
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
@@ -1998,7 +2258,7 @@ function regex(pattern, flags = "") {
1998
2258
  anchored.lastIndex = pos;
1999
2259
  const m = anchored.exec(input);
2000
2260
  if (m === null) {
2001
- return failAt(ctx, [`/${source}/`], pos);
2261
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
2002
2262
  }
2003
2263
  const span = { start: pos, end: pos + m[0].length };
2004
2264
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
@@ -2052,12 +2312,14 @@ function word(str, boundaryOrOpts, opts) {
2052
2312
  function escapeRe(s) {
2053
2313
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2054
2314
  }
2315
+ function keywordsRegExp(words, boundary, caseInsensitive) {
2316
+ const alt = words.map(escapeRe).join("|");
2317
+ const boundarySource = boundary ? `(?![${boundary}])` : "";
2318
+ return new RegExp(`(?:${alt})${boundarySource}`, caseInsensitive ? "iy" : "uy");
2319
+ }
2055
2320
  function keywords(words, opts = {}) {
2056
2321
  const sorted = [...new Set(words)].sort((a, b) => b.length - a.length);
2057
- const alt = sorted.map(escapeRe).join("|");
2058
- const boundary = opts.boundary ? `(?![${opts.boundary}])` : "";
2059
- const flags = opts.caseInsensitive ? "iy" : "uy";
2060
- const re = new RegExp(`(?:${alt})${boundary}`, flags);
2322
+ const re = keywordsRegExp(sorted, opts.boundary, opts.caseInsensitive ?? false);
2061
2323
  let firstSet2 = empty();
2062
2324
  for (const w of sorted) {
2063
2325
  if (w.length === 0) continue;
@@ -2068,15 +2330,21 @@ function keywords(words, opts = {}) {
2068
2330
  }
2069
2331
  }
2070
2332
  const meta = { firstSet: firstSet2, canMatchNewline: false, isTrivia: false };
2333
+ const def = {
2334
+ tag: "keywords",
2335
+ words: sorted,
2336
+ caseInsensitive: opts.caseInsensitive ?? false,
2337
+ boundary: opts.boundary
2338
+ };
2071
2339
  return {
2072
2340
  _tag: "keywords",
2073
2341
  _meta: meta,
2074
- _def: { tag: "keywords", words: sorted, caseInsensitive: opts.caseInsensitive ?? false, boundary: opts.boundary },
2342
+ _def: def,
2075
2343
  parse(input, pos, ctx) {
2076
2344
  re.lastIndex = pos;
2077
2345
  const m = re.exec(input);
2078
2346
  if (m === null || m.index !== pos) {
2079
- return failAt(ctx, ["keyword"], pos);
2347
+ return failAt(ctx, directTerminalFailureExpected(def), pos);
2080
2348
  }
2081
2349
  const value = m[0];
2082
2350
  const span = { start: pos, end: pos + value.length };
@@ -2089,6 +2357,14 @@ function keywords(words, opts = {}) {
2089
2357
  // src/combinators/trivia-skip.ts
2090
2358
  var NOOP_COMMIT = () => {
2091
2359
  };
2360
+ function triviaScanEnd(scan) {
2361
+ return typeof scan === "number" ? scan : scan.end;
2362
+ }
2363
+ function commitTriviaScan(scan) {
2364
+ if (typeof scan === "number") return scan;
2365
+ scan.commit();
2366
+ return scan.end;
2367
+ }
2092
2368
  var fastTrivia0;
2093
2369
  var fastTrivia1;
2094
2370
  var fastTrivia2;
@@ -2158,7 +2434,7 @@ function rollbackLookahead(ctx, mark) {
2158
2434
  function scanWithLabels(input, cur, ctx) {
2159
2435
  const triviaP = ctx.trivia;
2160
2436
  const spec = analyzeLabeledTrivia(triviaP);
2161
- if (!spec) return { end: cur, commit: NOOP_COMMIT };
2437
+ if (!spec) return cur;
2162
2438
  const log = ctx._triviaLog;
2163
2439
  const rootLog = ctx._rootTriviaLog;
2164
2440
  const rootKinds = ctx._rootTriviaKindIndex;
@@ -2176,7 +2452,8 @@ function scanWithLabels(input, cur, ctx) {
2176
2452
  }
2177
2453
  });
2178
2454
  if (visitedEnd !== void 0) {
2179
- if (visitedEnd === cur) return { end: cur, commit: NOOP_COMMIT };
2455
+ if (visitedEnd === cur) return cur;
2456
+ if (fullRows === void 0 && rootRows === void 0 && cstRows === void 0) return visitedEnd;
2180
2457
  return {
2181
2458
  end: visitedEnd,
2182
2459
  commit: () => {
@@ -2195,7 +2472,7 @@ function scanWithLabels(input, cur, ctx) {
2195
2472
  };
2196
2473
  }
2197
2474
  const { end, chunks } = scanLabeledTriviaChunks(input, cur, spec, ctx.state);
2198
- if (end === cur) return { end: cur, commit: NOOP_COMMIT };
2475
+ if (end === cur) return cur;
2199
2476
  return {
2200
2477
  end,
2201
2478
  commit: () => recordTriviaChunks(ctx, chunks)
@@ -2236,7 +2513,7 @@ function advanceTrivia(input, cur, ctx) {
2236
2513
  const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
2237
2514
  return tr.ok && tr.span.end > cur ? tr.span.end : cur;
2238
2515
  }
2239
- function scanTrivia(input, cur, ctx) {
2516
+ function scanTriviaCompact(input, cur, ctx) {
2240
2517
  const triviaP = ctx.trivia;
2241
2518
  if (!triviaP) return { end: cur, commit: NOOP_COMMIT };
2242
2519
  const log = ctx._triviaLog;
@@ -2277,7 +2554,7 @@ function scanTrivia(input, cur, ctx) {
2277
2554
  }
2278
2555
  if (ctx.triviaKindLabels && (log !== void 0 || rootLog !== void 0 || captureTl)) {
2279
2556
  const scan = scanWithLabels(input, cur, ctx);
2280
- if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, scan.end);
2557
+ if (trackTriviaLines) recordLineRangeFromContext(ctx, input, cur, triviaScanEnd(scan));
2281
2558
  return scan;
2282
2559
  }
2283
2560
  if (ctx.triviaKindLabels) {
@@ -2307,6 +2584,10 @@ function scanTrivia(input, cur, ctx) {
2307
2584
  const tr = parseTriviaNoCapture(triviaP, input, cur, ctx);
2308
2585
  return { end: tr.ok ? tr.span.end : cur, commit: NOOP_COMMIT };
2309
2586
  }
2587
+ function scanTrivia(input, cur, ctx) {
2588
+ const scan = scanTriviaCompact(input, cur, ctx);
2589
+ return typeof scan === "number" ? { end: scan, commit: NOOP_COMMIT } : scan;
2590
+ }
2310
2591
  function skipTriviaScanned(s, input, cur, ctx) {
2311
2592
  const end = s(input, cur);
2312
2593
  if (end !== cur) {
@@ -2319,14 +2600,12 @@ function skipTriviaScanned(s, input, cur, ctx) {
2319
2600
  }
2320
2601
  function consumeTrivia(input, cur, ctx) {
2321
2602
  if (!needsDeferredTriviaCommit(ctx)) return advanceTrivia(input, cur, ctx);
2322
- const scan = scanTrivia(input, cur, ctx);
2323
- scan.commit();
2324
- return scan.end;
2603
+ return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2325
2604
  }
2326
2605
  function probeTriviaEnd(input, cur, ctx) {
2327
2606
  if (!ctx.trivia) return cur;
2328
2607
  const probeCtx = { ...ctx, trackLines: false };
2329
- if (needsDeferredTriviaCommit(probeCtx)) return scanTrivia(input, cur, probeCtx).end;
2608
+ if (needsDeferredTriviaCommit(probeCtx)) return triviaScanEnd(scanTriviaCompact(input, cur, probeCtx));
2330
2609
  return advanceTrivia(input, cur, probeCtx);
2331
2610
  }
2332
2611
  function fastTriviaScanner(trivia2) {
@@ -2354,10 +2633,16 @@ function buildFastTriviaScanner(trivia2) {
2354
2633
  const one = regexTriviaScanner(repeat);
2355
2634
  if (one) return loopScanner([one]);
2356
2635
  if (repeat._def.tag !== "choice") return null;
2636
+ const fused = commonCssTriviaScanner(repeat._def.parsers.map(triviaRegexSource));
2637
+ if (fused !== null) return fused;
2357
2638
  const arms = repeat._def.parsers.map(regexTriviaScanner);
2358
2639
  if (arms.some((s) => s === null)) return null;
2359
2640
  return loopScanner(arms);
2360
2641
  }
2642
+ function triviaRegexSource(parser2) {
2643
+ const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
2644
+ return d.tag === "regex" && d.flags === "" ? d.source : null;
2645
+ }
2361
2646
  function loopScanner(arms) {
2362
2647
  return (input, cur) => {
2363
2648
  let pos = cur;
@@ -2847,9 +3132,7 @@ function sequence(...parsers) {
2847
3132
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2848
3133
  let scanEnd;
2849
3134
  if (needsDeferredTriviaCommit(ctx)) {
2850
- const scan = scanTrivia(input, cur, ctx);
2851
- scan.commit();
2852
- scanEnd = scan.end;
3135
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2853
3136
  } else {
2854
3137
  scanEnd = advanceTrivia(input, cur, ctx);
2855
3138
  }
@@ -2859,7 +3142,15 @@ function sequence(...parsers) {
2859
3142
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2860
3143
  if (!result2.ok) return result2;
2861
3144
  if (result2.span.end > scanEnd) cur = result2.span.end;
2862
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3145
+ else rollbackScannedTriviaAt(
3146
+ ctx,
3147
+ mTlog,
3148
+ scanTlog,
3149
+ mLog,
3150
+ scanLog,
3151
+ mRootLog,
3152
+ scanRootLog
3153
+ );
2863
3154
  if (values !== void 0) values.push(result2.value);
2864
3155
  continue;
2865
3156
  }
@@ -2894,9 +3185,7 @@ function sequence(...parsers) {
2894
3185
  const mLog = ctx._triviaLog?.length ?? 0;
2895
3186
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2896
3187
  if (needsDeferredTriviaCommit(ctx)) {
2897
- const scan = scanTrivia(input, cur, ctx);
2898
- scan.commit();
2899
- scanEnd = scan.end;
3188
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2900
3189
  } else {
2901
3190
  scanEnd = advanceTrivia(input, cur, ctx);
2902
3191
  }
@@ -2906,7 +3195,15 @@ function sequence(...parsers) {
2906
3195
  const result2 = parsers[i].parse(input, scanEnd, ctx);
2907
3196
  if (!result2.ok) return result2;
2908
3197
  if (result2.span.end > scanEnd) cur = result2.span.end;
2909
- else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3198
+ else rollbackScannedTriviaAt(
3199
+ ctx,
3200
+ mTlog,
3201
+ scanTlog,
3202
+ mLog,
3203
+ scanLog,
3204
+ mRootLog,
3205
+ scanRootLog
3206
+ );
2910
3207
  if (values !== void 0) values.push(result2.value);
2911
3208
  continue;
2912
3209
  }
@@ -2938,9 +3235,7 @@ function sequence(...parsers) {
2938
3235
  const mLog = ctx._triviaLog?.length ?? 0;
2939
3236
  const mRootLog = ctx._rootTriviaLog?.length ?? 0;
2940
3237
  if (needsDeferredTriviaCommit(ctx)) {
2941
- const scan = scanTrivia(input, cur, ctx);
2942
- scan.commit();
2943
- scanEnd = scan.end;
3238
+ scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
2944
3239
  } else {
2945
3240
  scanEnd = advanceTrivia(input, cur, ctx);
2946
3241
  }
@@ -2952,7 +3247,15 @@ function sequence(...parsers) {
2952
3247
  if (result2.span.end > scanEnd) {
2953
3248
  cur = result2.span.end;
2954
3249
  } else {
2955
- rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
3250
+ rollbackScannedTriviaAt(
3251
+ ctx,
3252
+ mTlog,
3253
+ scanTlog,
3254
+ mLog,
3255
+ scanLog,
3256
+ mRootLog,
3257
+ scanRootLog
3258
+ );
2956
3259
  }
2957
3260
  if (values !== void 0) values.push(result2.value);
2958
3261
  continue;
@@ -3119,6 +3422,7 @@ function choice(...args) {
3119
3422
  },
3120
3423
  parse(input, pos, ctx) {
3121
3424
  const expected = [];
3425
+ let expectedAt = pos;
3122
3426
  if (disjoint) {
3123
3427
  const code = pos < input.length ? input.codePointAt(pos) : -1;
3124
3428
  let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
@@ -3176,7 +3480,12 @@ function choice(...args) {
3176
3480
  const result = parsers[i].parse(input, pos, ctx);
3177
3481
  if (!result.ok) {
3178
3482
  rollbackTrivia(ctx, mark);
3179
- expected.push(...result.expected);
3483
+ const at = result.span.start;
3484
+ if (at > expectedAt) {
3485
+ expectedAt = at;
3486
+ expected.length = 0;
3487
+ }
3488
+ if (at === expectedAt) expected.push(...result.expected);
3180
3489
  if (result.committed) return { ok: false, expected, span: result.span, committed: true };
3181
3490
  continue;
3182
3491
  }
@@ -3187,6 +3496,9 @@ function choice(...args) {
3187
3496
  }
3188
3497
  return result;
3189
3498
  }
3499
+ if (expected.length === 0) {
3500
+ for (const parser2 of parsers) expected.push(...deriveExpected(parser2));
3501
+ }
3190
3502
  return { ok: false, expected, span: { start: pos, end: pos } };
3191
3503
  }
3192
3504
  };
@@ -3644,9 +3956,7 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
3644
3956
  let pos = cur;
3645
3957
  if (ctx.trivia) {
3646
3958
  if (needsDeferredTriviaCommit(ctx)) {
3647
- const scan = scanTrivia(input, cur, ctx);
3648
- scan.commit();
3649
- pos = scan.end;
3959
+ pos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3650
3960
  } else {
3651
3961
  pos = advanceTrivia(input, cur, ctx);
3652
3962
  }
@@ -3872,9 +4182,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3872
4182
  let sepPos = cur;
3873
4183
  if (ctx.trivia) {
3874
4184
  if (needsDeferredTriviaCommit(ctx)) {
3875
- const scan = scanTrivia(input, cur, ctx);
3876
- scan.commit();
3877
- sepPos = scan.end;
4185
+ sepPos = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
3878
4186
  } else {
3879
4187
  sepPos = advanceTrivia(input, cur, ctx);
3880
4188
  }
@@ -3890,9 +4198,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
3890
4198
  let nextPos = sep2.span.end;
3891
4199
  if (ctx.trivia) {
3892
4200
  if (needsDeferredTriviaCommit(ctx)) {
3893
- const scan = scanTrivia(input, sep2.span.end, ctx);
3894
- scan.commit();
3895
- nextPos = scan.end;
4201
+ nextPos = commitTriviaScan(scanTriviaCompact(input, sep2.span.end, ctx));
3896
4202
  } else {
3897
4203
  nextPos = advanceTrivia(input, sep2.span.end, ctx);
3898
4204
  }
@@ -3943,7 +4249,11 @@ function not(combinator) {
3943
4249
  const result = combinator.parse(input, pos, ctx);
3944
4250
  rollbackLookahead(ctx, mark);
3945
4251
  if (result.ok) {
3946
- return { ok: false, expected: [`not(${combinator._tag})`], span: { start: pos, end: pos } };
4252
+ return {
4253
+ ok: false,
4254
+ expected: assertionFailureExpected(false, combinator._tag),
4255
+ span: { start: pos, end: pos }
4256
+ };
3947
4257
  }
3948
4258
  return { ok: true, value: null, span: { start: pos, end: pos } };
3949
4259
  }
@@ -3967,7 +4277,11 @@ function peek(combinator) {
3967
4277
  const result = combinator.parse(input, pos, ctx);
3968
4278
  rollbackLookahead(ctx, mark);
3969
4279
  if (result.ok) return { ok: true, value: null, span: { start: pos, end: pos } };
3970
- return { ok: false, expected: [`peek(${combinator._tag})`], span: { start: pos, end: pos } };
4280
+ return {
4281
+ ok: false,
4282
+ expected: assertionFailureExpected(true, combinator._tag),
4283
+ span: { start: pos, end: pos }
4284
+ };
3971
4285
  }
3972
4286
  };
3973
4287
  }
@@ -4221,6 +4535,12 @@ function confirmedArityForDef(def) {
4221
4535
  });
4222
4536
  return null;
4223
4537
  }
4538
+ function buildReadsRaw(def) {
4539
+ if (!def.build) return true;
4540
+ const arity = confirmedArityForDef(def);
4541
+ if (arity === null) return true;
4542
+ return arity >= 4;
4543
+ }
4224
4544
  function buildReadsTrivia(def) {
4225
4545
  if (!def.build) return true;
4226
4546
  const arity = confirmedArityForDef(def);
@@ -4677,6 +4997,8 @@ var OP_ATTEMPT = 38;
4677
4997
  var OP_LABEL = 39;
4678
4998
  var OP_COV = 40;
4679
4999
  var OP_SCOPE_PLAIN = 41;
5000
+ var OP_LEX_BODY = 42;
5001
+ var OP_LEX_PROGRAM = 43;
4680
5002
  var OP_DISPATCH = 25;
4681
5003
  var OP_ROUTED = 26;
4682
5004
  var OP_NAMES = {
@@ -4720,9 +5042,409 @@ var OP_NAMES = {
4720
5042
  [OP_ATTEMPT]: "ATTEMPT",
4721
5043
  [OP_LABEL]: "LABEL",
4722
5044
  [OP_COV]: "COV",
4723
- [OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
5045
+ [OP_SCOPE_PLAIN]: "SCOPE_PLAIN",
5046
+ [OP_LEX_BODY]: "LEX_BODY",
5047
+ [OP_LEX_PROGRAM]: "LEX_PROGRAM"
4724
5048
  };
4725
5049
 
5050
+ // src/table/lex-program.ts
5051
+ var LEX_NODE_TERMINAL = 0;
5052
+ var LEX_NODE_SEQUENCE2 = 1;
5053
+ var LEX_NODE_SEQUENCE3 = 2;
5054
+ var LEX_NODE_SEQUENCE4 = 3;
5055
+ var LEX_NODE_SEQUENCE5 = 4;
5056
+ var LEX_NODE_CHOICE2 = 5;
5057
+ var LEX_NODE_CHOICE4 = 6;
5058
+ var LEX_NODE_CHOICE8 = 7;
5059
+ var LEX_NODE_NOT = 8;
5060
+ var LEX_NODE_OPTIONAL = 9;
5061
+ function lexProgramDigest(words) {
5062
+ let hash = 2166136261;
5063
+ for (const word2 of words) {
5064
+ hash ^= word2 | 0;
5065
+ hash = Math.imul(hash, 16777619);
5066
+ }
5067
+ return hash | 0;
5068
+ }
5069
+ function classHas(cls, code) {
5070
+ if (code < 0) return false;
5071
+ if (code < 128) return cls.ascii[code] === 1;
5072
+ for (let i = 0; i < cls.hi.length; i += 2) {
5073
+ if (code >= cls.hi[i] && code <= cls.hi[i + 1]) return true;
5074
+ }
5075
+ return false;
5076
+ }
5077
+ var committed = (ctx) => ctx._fc === true;
5078
+ function trackLexLines(ctx, input, end) {
5079
+ let at = ctx._lineScannedTo ?? 0;
5080
+ const starts = ctx._lineStarts;
5081
+ if (starts === void 0 || end <= at) return;
5082
+ while (at < end) {
5083
+ if (input.charCodeAt(at) === 10) starts.push(at + 1);
5084
+ at++;
5085
+ }
5086
+ ctx._lineScannedTo = end;
5087
+ }
5088
+ function terminalNode(matcher, failure, tracksLines) {
5089
+ const match = (input, pos) => {
5090
+ const result = matcher(input, pos);
5091
+ return result < 0 ? -1 : result / 2;
5092
+ };
5093
+ return {
5094
+ match,
5095
+ run: (input, pos, ctx) => {
5096
+ const end = match(input, pos);
5097
+ if (end < 0) {
5098
+ ctx._fe = pos;
5099
+ ctx._fx = failure;
5100
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5101
+ return -1;
5102
+ }
5103
+ if (tracksLines) trackLexLines(ctx, input, end);
5104
+ return end;
5105
+ }
5106
+ };
5107
+ }
5108
+ function sequence2(a, b) {
5109
+ return {
5110
+ match: (input, pos) => {
5111
+ const e0 = a.match(input, pos);
5112
+ return e0 < 0 ? -1 : b.match(input, e0);
5113
+ },
5114
+ run: (input, pos, ctx) => {
5115
+ const e0 = a.run(input, pos, ctx);
5116
+ if (e0 < 0) return -1;
5117
+ ctx._fc = false;
5118
+ return b.run(input, e0, ctx);
5119
+ }
5120
+ };
5121
+ }
5122
+ function sequence3(a, b, c) {
5123
+ return {
5124
+ match: (input, pos) => {
5125
+ const e0 = a.match(input, pos);
5126
+ if (e0 < 0) return -1;
5127
+ const e1 = b.match(input, e0);
5128
+ return e1 < 0 ? -1 : c.match(input, e1);
5129
+ },
5130
+ run: (input, pos, ctx) => {
5131
+ const e0 = a.run(input, pos, ctx);
5132
+ if (e0 < 0) return -1;
5133
+ ctx._fc = false;
5134
+ const e1 = b.run(input, e0, ctx);
5135
+ if (e1 < 0) return -1;
5136
+ ctx._fc = false;
5137
+ return c.run(input, e1, ctx);
5138
+ }
5139
+ };
5140
+ }
5141
+ function sequence4(a, b, c, d) {
5142
+ const abc = sequence3(a, b, c);
5143
+ return {
5144
+ match: (input, pos) => {
5145
+ const end = abc.match(input, pos);
5146
+ return end < 0 ? -1 : d.match(input, end);
5147
+ },
5148
+ run: (input, pos, ctx) => {
5149
+ const end = abc.run(input, pos, ctx);
5150
+ if (end < 0) return -1;
5151
+ ctx._fc = false;
5152
+ return d.run(input, end, ctx);
5153
+ }
5154
+ };
5155
+ }
5156
+ function sequence5(a, b, c, d, e) {
5157
+ const abcd = sequence4(a, b, c, d);
5158
+ return {
5159
+ match: (input, pos) => {
5160
+ const end = abcd.match(input, pos);
5161
+ return end < 0 ? -1 : e.match(input, end);
5162
+ },
5163
+ run: (input, pos, ctx) => {
5164
+ const end = abcd.run(input, pos, ctx);
5165
+ if (end < 0) return -1;
5166
+ ctx._fc = false;
5167
+ return e.run(input, end, ctx);
5168
+ }
5169
+ };
5170
+ }
5171
+ function appendExpected(acc, values) {
5172
+ if (values === void 0 || values.length === 0) return acc;
5173
+ if (acc === void 0) return values.slice();
5174
+ acc.push(...values);
5175
+ return acc;
5176
+ }
5177
+ function choiceNode(arms, classes, armExpected, choiceExpected) {
5178
+ let matchTail = () => -1;
5179
+ for (let i = arms.length - 1; i >= 0; i--) {
5180
+ const arm = arms[i], next = matchTail;
5181
+ matchTail = (input, pos) => {
5182
+ const end = arm.match(input, pos);
5183
+ return end < 0 ? next(input, pos) : end;
5184
+ };
5185
+ }
5186
+ let tail = (_input, pos, ctx, _lead, acc) => {
5187
+ ctx._fe = pos;
5188
+ ctx._fx = acc ?? choiceExpected;
5189
+ return -1;
5190
+ };
5191
+ for (let i = arms.length - 1; i >= 0; i--) {
5192
+ const arm = arms[i], cls = classes[i], staticExpected = armExpected[i], next = tail;
5193
+ tail = (input, pos, ctx, lead2, acc, best) => {
5194
+ if (cls !== void 0 && !classHas(cls, lead2)) {
5195
+ return next(
5196
+ input,
5197
+ pos,
5198
+ ctx,
5199
+ lead2,
5200
+ best === pos ? appendExpected(acc, staticExpected) : acc,
5201
+ best
5202
+ );
5203
+ }
5204
+ ctx._fc = false;
5205
+ const end = arm.run(input, pos, ctx);
5206
+ if (end >= 0) return end;
5207
+ const at = ctx._fe ?? pos;
5208
+ if (at > best) {
5209
+ best = at;
5210
+ acc = void 0;
5211
+ }
5212
+ const nextAcc = at === best ? appendExpected(acc, ctx._fx) : acc;
5213
+ if (committed(ctx)) {
5214
+ if (nextAcc !== void 0) ctx._fx = nextAcc;
5215
+ return -1;
5216
+ }
5217
+ return next(input, pos, ctx, lead2, nextAcc, best);
5218
+ };
5219
+ }
5220
+ return {
5221
+ match: matchTail,
5222
+ run: (input, pos, ctx) => tail(
5223
+ input,
5224
+ pos,
5225
+ ctx,
5226
+ pos < input.length ? input.codePointAt(pos) : -1,
5227
+ void 0,
5228
+ pos
5229
+ )
5230
+ };
5231
+ }
5232
+ function notNode(body, failure) {
5233
+ return {
5234
+ match: (input, pos) => body.match(input, pos) < 0 ? pos : -1,
5235
+ run: (input, pos, ctx) => {
5236
+ if (body.match(input, pos) < 0) return pos;
5237
+ ctx._fe = pos;
5238
+ ctx._fx = failure;
5239
+ return -1;
5240
+ }
5241
+ };
5242
+ }
5243
+ function optionalNode(body) {
5244
+ return {
5245
+ match: (input, pos) => {
5246
+ const end = body.match(input, pos);
5247
+ return end < 0 ? pos : end;
5248
+ },
5249
+ run: (input, pos, ctx) => {
5250
+ ctx._fc = false;
5251
+ const end = body.run(input, pos, ctx);
5252
+ return end < 0 && !committed(ctx) ? pos : end;
5253
+ }
5254
+ };
5255
+ }
5256
+ function fixedTreeRunner(words, matchers, classes, expected) {
5257
+ const stack = [];
5258
+ const pop = () => {
5259
+ const value = stack.pop();
5260
+ if (value === void 0) throw new TypeError("table lexical tree has an incomplete fixed body");
5261
+ return value;
5262
+ };
5263
+ for (let at = 0; at < words.length; ) {
5264
+ const op = words[at++];
5265
+ if (op === LEX_NODE_TERMINAL) {
5266
+ const matcher = matchers[words[at++]], failure = expected[words[at++]];
5267
+ const tracks = words[at++];
5268
+ if (matcher === void 0 || failure === void 0 || tracks !== 0 && tracks !== 1) {
5269
+ throw new TypeError("table lexical tree terminal references an invalid pool entry");
5270
+ }
5271
+ stack.push(terminalNode(matcher, failure, tracks === 1));
5272
+ continue;
5273
+ }
5274
+ if (op >= LEX_NODE_SEQUENCE2 && op <= LEX_NODE_SEQUENCE5) {
5275
+ const count = op - LEX_NODE_SEQUENCE2 + 2;
5276
+ const nodes = Array.from({ length: count }, pop).reverse();
5277
+ if (count === 2) stack.push(sequence2(nodes[0], nodes[1]));
5278
+ else if (count === 3) stack.push(sequence3(nodes[0], nodes[1], nodes[2]));
5279
+ else if (count === 4) stack.push(sequence4(nodes[0], nodes[1], nodes[2], nodes[3]));
5280
+ else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
5281
+ continue;
5282
+ }
5283
+ if (op >= LEX_NODE_CHOICE2 && op <= LEX_NODE_CHOICE8) {
5284
+ const count = op === LEX_NODE_CHOICE2 ? 2 : op === LEX_NODE_CHOICE4 ? 4 : 8;
5285
+ const choiceFx = expected[words[at++]];
5286
+ if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
5287
+ const armClasses = [];
5288
+ const armFx = [];
5289
+ for (let i = 0; i < count; i++) {
5290
+ const cls = words[at++], fx = expected[words[at++]];
5291
+ if (cls < -1 || cls >= 0 && classes[cls] === void 0 || fx === void 0) {
5292
+ throw new TypeError("table lexical tree choice references an invalid pool entry");
5293
+ }
5294
+ armClasses.push(cls < 0 ? void 0 : classes[cls]);
5295
+ armFx.push(fx);
5296
+ }
5297
+ const arms = Array.from({ length: count }, pop).reverse();
5298
+ stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
5299
+ continue;
5300
+ }
5301
+ if (op === LEX_NODE_NOT) {
5302
+ const failure = expected[words[at++]];
5303
+ if (failure === void 0) throw new TypeError("table lexical tree assertion has an invalid expected set");
5304
+ stack.push(notNode(pop(), failure));
5305
+ continue;
5306
+ }
5307
+ if (op === LEX_NODE_OPTIONAL) {
5308
+ stack.push(optionalNode(pop()));
5309
+ continue;
5310
+ }
5311
+ throw new TypeError("table lexical tree has an unknown fixed body");
5312
+ }
5313
+ if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
5314
+ return stack[0].run;
5315
+ }
5316
+ function buildLexProgramRunner(spec, matchers, classes, expected) {
5317
+ if (spec[0] !== 0 && spec[0] !== 1 && spec[0] !== 2 && spec[0] !== 3 || spec[0] === 0 && spec.length !== 13 || spec[0] === 1 && spec.length !== 12 || spec[0] === 2 && spec.length < 6 || spec[0] === 3 && spec.length !== 3) {
5318
+ throw new TypeError("table lexical program has an invalid fixed body width");
5319
+ }
5320
+ if (spec[1] !== lexProgramDigest(spec.slice(2))) {
5321
+ throw new TypeError("table lexical program semantic digest is inconsistent");
5322
+ }
5323
+ if (spec[0] === 3) {
5324
+ if (!Number.isInteger(spec[2]) || spec[2] < 0) {
5325
+ throw new TypeError("table balanced lexical program has an invalid scan reference");
5326
+ }
5327
+ const run3 = (_input, _pos, ctx, scan) => {
5328
+ if (scan === void 0) throw new TypeError("table balanced lexical program lost its scan body");
5329
+ const result = scan.parse(_input, _pos, ctx);
5330
+ if (!result.ok) {
5331
+ ctx._fe = result.span.start;
5332
+ ctx._fx = result.expected ?? [];
5333
+ return -1;
5334
+ }
5335
+ return result.span.end;
5336
+ };
5337
+ return Object.assign(run3, { scan: spec[2] });
5338
+ }
5339
+ if (spec[0] === 2) return fixedTreeRunner(spec.slice(2), matchers, classes, expected);
5340
+ if (spec[0] === 1) {
5341
+ const g00 = matchers[spec[2]], g01 = matchers[spec[3]];
5342
+ const g02 = matchers[spec[4]], g03 = matchers[spec[5]];
5343
+ const guard0Fx = expected[spec[6]];
5344
+ const g1 = matchers[spec[7]], guard1Fx = expected[spec[8]];
5345
+ const terminal = matchers[spec[9]], terminalFx = expected[spec[10]];
5346
+ const tracks2 = spec[11];
5347
+ if (g00 === void 0 || g01 === void 0 || g02 === void 0 || g03 === void 0 || guard0Fx === void 0 || g1 === void 0 || guard1Fx === void 0 || terminal === void 0 || terminalFx === void 0 || tracks2 !== 0 && tracks2 !== 1) {
5348
+ throw new TypeError("table lexical program references an invalid pool entry");
5349
+ }
5350
+ return (input, pos, ctx) => {
5351
+ ctx._fc = false;
5352
+ if (g00(input, pos) >= 0 || g01(input, pos) >= 0 || g02(input, pos) >= 0 || g03(input, pos) >= 0) {
5353
+ ctx._fe = pos;
5354
+ ctx._fx = guard0Fx;
5355
+ return -1;
5356
+ }
5357
+ ctx._fc = false;
5358
+ if (g1(input, pos) >= 0) {
5359
+ ctx._fe = pos;
5360
+ ctx._fx = guard1Fx;
5361
+ return -1;
5362
+ }
5363
+ ctx._fc = false;
5364
+ const result = terminal(input, pos);
5365
+ if (result < 0) {
5366
+ ctx._fe = pos;
5367
+ ctx._fx = terminalFx;
5368
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5369
+ return -1;
5370
+ }
5371
+ const end = result / 2;
5372
+ if (tracks2 === 1) trackLexLines(ctx, input, end);
5373
+ return end;
5374
+ };
5375
+ }
5376
+ const cls = classes[spec[2]];
5377
+ const choiceFx = expected[spec[3]];
5378
+ const m0 = matchers[spec[4]], x0 = expected[spec[5]];
5379
+ const m1 = matchers[spec[6]], x1 = expected[spec[7]];
5380
+ const m2 = matchers[spec[8]], x2 = expected[spec[9]];
5381
+ const m3 = matchers[spec[10]], x3 = expected[spec[11]];
5382
+ const tracks = spec[12];
5383
+ if (cls === void 0 || choiceFx === void 0 || m0 === void 0 || x0 === void 0 || m1 === void 0 || x1 === void 0 || m2 === void 0 || x2 === void 0 || m3 === void 0 || x3 === void 0 || tracks !== 0 && tracks !== 1) {
5384
+ throw new TypeError("table lexical program references an invalid pool entry");
5385
+ }
5386
+ return (input, pos, ctx) => {
5387
+ const lead2 = pos < input.length ? input.codePointAt(pos) : -1;
5388
+ if (!classHas(cls, lead2)) {
5389
+ ctx._fe = pos;
5390
+ ctx._fx = choiceFx.slice();
5391
+ return -1;
5392
+ }
5393
+ let acc;
5394
+ const failed = (fx) => {
5395
+ ctx._fe = pos;
5396
+ ctx._fx = fx;
5397
+ if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
5398
+ if (acc === void 0) acc = fx.slice();
5399
+ else acc.push(...fx);
5400
+ };
5401
+ ctx._fc = false;
5402
+ const success = (result2) => {
5403
+ const end = result2 / 2;
5404
+ if (tracks === 1) trackLexLines(ctx, input, end);
5405
+ return end;
5406
+ };
5407
+ let result = m0(input, pos);
5408
+ if (result >= 0) return success(result);
5409
+ failed(x0);
5410
+ ctx._fc = false;
5411
+ result = m1(input, pos);
5412
+ if (result >= 0) return success(result);
5413
+ failed(x1);
5414
+ ctx._fc = false;
5415
+ result = m2(input, pos);
5416
+ if (result >= 0) return success(result);
5417
+ failed(x2);
5418
+ ctx._fc = false;
5419
+ result = m3(input, pos);
5420
+ if (result >= 0) return success(result);
5421
+ failed(x3);
5422
+ ctx._fe = pos;
5423
+ ctx._fx = acc ?? choiceFx;
5424
+ return -1;
5425
+ };
5426
+ }
5427
+
5428
+ // src/table/lex-body.ts
5429
+ function buildLexBodyRecognizer(spec, constants) {
5430
+ const raw = constants[spec[0]];
5431
+ if (!(raw instanceof RegExp)) {
5432
+ throw new TypeError("table lexical body does not reference a RegExp constant");
5433
+ }
5434
+ if (!Number.isInteger(spec[1]) || spec[1] < -1 || spec[1] > 65535) {
5435
+ throw new TypeError("table lexical body suffix is not absent or one UTF-16 code unit");
5436
+ }
5437
+ const re = raw.sticky ? new RegExp(raw.source, raw.flags) : new RegExp(raw.source, `${raw.flags.replace(/[gy]/g, "")}y`);
5438
+ const suffix = spec[1];
5439
+ return (input, pos) => {
5440
+ re.lastIndex = pos;
5441
+ if (!re.test(input)) return -1;
5442
+ const end = re.lastIndex;
5443
+ if (suffix < 0) return end * 2;
5444
+ return input.charCodeAt(end) === suffix ? (end + 1) * 2 + 1 : end * 2;
5445
+ };
5446
+ }
5447
+
4726
5448
  // src/table/program.ts
4727
5449
  function closureArtifact(prog) {
4728
5450
  return { ...prog, asm: [] };
@@ -4766,6 +5488,8 @@ function expandCompact(p) {
4766
5488
  fns: p.f,
4767
5489
  lines: p.l ?? 0,
4768
5490
  dsp: p.p ?? [],
5491
+ ...p.lx === void 0 ? {} : { lex: p.lx },
5492
+ ...p.lp === void 0 ? {} : { lexPrograms: p.lp },
4769
5493
  ...p.lb === void 0 ? {} : { labels: p.lb },
4770
5494
  ...p.rc === void 0 ? {} : { classified: p.rc },
4771
5495
  ...p.h === void 0 ? {} : { hostMode: p.h },
@@ -4857,7 +5581,7 @@ function resolveClass(spec) {
4857
5581
  }
4858
5582
  return { ascii, hi };
4859
5583
  }
4860
- function classHas(cls, code) {
5584
+ function classHas2(cls, code) {
4861
5585
  if (code < 0) return false;
4862
5586
  if (code < 128) return cls.ascii[code] === 1;
4863
5587
  const hi = cls.hi;
@@ -4910,6 +5634,7 @@ function resolveTable(prog) {
4910
5634
  if (hit !== void 0) return hit;
4911
5635
  const cc = prog.cc.map(resolveClass);
4912
5636
  const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
5637
+ const lex = (prog.lex ?? []).map((spec) => buildLexBodyRecognizer(spec, prog.k));
4913
5638
  const built = {
4914
5639
  prog,
4915
5640
  code: Int32Array.from(prog.code),
@@ -4928,31 +5653,385 @@ function resolveTable(prog) {
4928
5653
  routed: d.routed,
4929
5654
  expected: d.expected
4930
5655
  })),
5656
+ lex,
5657
+ lexPrograms: (prog.lexPrograms ?? []).map((spec) => buildLexProgramRunner(spec, lex, cc, prog.fx)),
4931
5658
  rules: prog.rules
4932
5659
  };
4933
5660
  if (owner !== void 0) owner.resolved = built;
4934
5661
  return built;
4935
5662
  }
4936
5663
 
5664
+ // src/compiler/direct-projection.ts
5665
+ function directArrayProjection(fn, fnSrc, arity) {
5666
+ let source = fnSrc;
5667
+ if (source === void 0) {
5668
+ source = Function.prototype.toString.call(fn);
5669
+ if (source.includes("[native code]")) return null;
5670
+ }
5671
+ const match = /^\s*\(\s*\[([^\]]*)\]\s*\)\s*=>\s*([A-Za-z_$][\w$]*)\s*$/.exec(source);
5672
+ if (match === null) return null;
5673
+ const slots = match[1].split(",").map((slot) => slot.trim());
5674
+ if (slots.length > arity) return null;
5675
+ const result = match[2];
5676
+ let selected = -1;
5677
+ for (let i = 0; i < slots.length; i++) {
5678
+ const slot = slots[i];
5679
+ if (slot === "") continue;
5680
+ if (!/^[A-Za-z_$][\w$]*$/.test(slot)) return null;
5681
+ if (slot === result) {
5682
+ if (selected >= 0) return null;
5683
+ selected = i;
5684
+ }
5685
+ }
5686
+ return selected >= 0 ? selected : null;
5687
+ }
5688
+
4937
5689
  // src/table/encode.ts
4938
- function emittableConst(v) {
4939
- const scalar = (x) => x === null || typeof x === "string" || typeof x === "number" || typeof x === "boolean";
4940
- if (scalar(v) || v instanceof RegExp) return true;
4941
- if (Array.isArray(v)) return v.every(scalar);
4942
- if (typeof v === "object" && v !== null) {
4943
- const proto = Object.getPrototypeOf(v);
4944
- if (proto !== Object.prototype && proto !== null) return false;
4945
- return Object.values(v).every((x) => scalar(x) || Array.isArray(x) && x.every(scalar));
4946
- }
4947
- return false;
5690
+ import {
5691
+ assertLexicalCapabilityClosure,
5692
+ collectLexicalCapabilities,
5693
+ winnerWrapsReference as winnerWrapsReference2
5694
+ } from "../compiler/token-capability.js";
5695
+
5696
+ // src/compiler/token-alphabet.ts
5697
+ function optionalSuffixLexBody(ir) {
5698
+ if (ir.kind !== "sequence" || ir.parts.length !== 2) return void 0;
5699
+ const [base, suffix] = ir.parts;
5700
+ if (base?.kind !== "regex" || suffix?.kind !== "repeat" || suffix.min !== 0 || suffix.max !== 1 || !suffix.greedy || suffix.mode !== "possessive" || suffix.body.kind !== "literal" || suffix.body.caseInsensitive || suffix.body.value.length !== 1) return void 0;
5701
+ return {
5702
+ kind: "regex-optional-code-unit",
5703
+ source: base.source,
5704
+ flags: base.flags,
5705
+ suffix: suffix.body.value
5706
+ };
4948
5707
  }
4949
- function wrapsRef(winner, p) {
4950
- let cur = winner;
4951
- for (let n = 0; n < 16; n++) {
4952
- if (cur === p) return true;
4953
- const d = cur._def;
4954
- if (d.tag !== "grammar" && d.tag !== "trivia") return false;
4955
- cur = d.parser;
5708
+ function selectOptionalSuffixLexBody(ir) {
5709
+ const body = optionalSuffixLexBody(ir);
5710
+ const character = { strategy: "character", estimatedOps: 5 };
5711
+ if (body === void 0) return character;
5712
+ const token2 = { strategy: "token", estimatedOps: 2, body };
5713
+ return token2.estimatedOps < character.estimatedOps ? token2 : character;
5714
+ }
5715
+ function directTokenBodyParser(parser2, resolve3) {
5716
+ const outer = parser2._def;
5717
+ if (outer.tag !== "token") return void 0;
5718
+ let body = outer.parser;
5719
+ const seen = /* @__PURE__ */ new Set();
5720
+ while (!seen.has(body)) {
5721
+ seen.add(body);
5722
+ const wrapper = body._def;
5723
+ if (wrapper.tag === "grammar") {
5724
+ if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
5725
+ body = wrapper.parser;
5726
+ continue;
5727
+ }
5728
+ if (wrapper.tag === "lazy") {
5729
+ const target = resolvedLazyTarget(body, resolve3);
5730
+ if (target === void 0) return void 0;
5731
+ body = target;
5732
+ continue;
5733
+ }
5734
+ return body;
5735
+ }
5736
+ return void 0;
5737
+ }
5738
+ function directOptionalSuffixTokenBody(parser2, resolve3) {
5739
+ const inner = directTokenBodyParser(parser2, resolve3);
5740
+ if (inner === void 0) return void 0;
5741
+ const sequence6 = inner._def;
5742
+ if (sequence6.tag !== "sequence" || sequence6.parsers.length !== 2) return void 0;
5743
+ let baseParser = sequence6.parsers[0];
5744
+ const seenBase = /* @__PURE__ */ new Set();
5745
+ while (baseParser !== void 0 && baseParser._def.tag === "lazy" && !seenBase.has(baseParser)) {
5746
+ seenBase.add(baseParser);
5747
+ baseParser = resolvedLazyTarget(baseParser, resolve3);
5748
+ }
5749
+ const base = baseParser?._def;
5750
+ const optional2 = sequence6.parsers[1]?._def;
5751
+ if (base?.tag !== "regex" || optional2?.tag !== "optional") return void 0;
5752
+ const suffix = optional2.parser._def;
5753
+ if (suffix.tag !== "literal" || suffix.caseInsensitive || suffix.value.length !== 1) return void 0;
5754
+ const selected = selectOptionalSuffixLexBody({
5755
+ kind: "sequence",
5756
+ parts: [
5757
+ { kind: "regex", source: base.source, flags: base.flags },
5758
+ {
5759
+ kind: "repeat",
5760
+ body: { kind: "literal", value: suffix.value, caseInsensitive: false },
5761
+ min: 0,
5762
+ max: 1,
5763
+ greedy: true,
5764
+ mode: "possessive"
5765
+ }
5766
+ ]
5767
+ });
5768
+ return selected.strategy === "token" ? {
5769
+ ...selected.body,
5770
+ baseCanMatchNewline: baseParser._meta.canMatchNewline,
5771
+ suffixCanMatchNewline: optional2.parser._meta.canMatchNewline,
5772
+ expected: directTerminalFailureExpected(base)
5773
+ } : void 0;
5774
+ }
5775
+ function directTerminalTokenBody(parser2, resolve3) {
5776
+ const outer = parser2._def;
5777
+ if (outer.tag !== "token") return void 0;
5778
+ const body = directTokenBodyParser(parser2, resolve3);
5779
+ if (body === void 0) return void 0;
5780
+ const def = body._def;
5781
+ if (def.tag === "regex") return {
5782
+ kind: "regex-terminal",
5783
+ source: def.source,
5784
+ flags: def.flags,
5785
+ canMatchNewline: body._meta.canMatchNewline,
5786
+ expected: directTerminalFailureExpected(def)
5787
+ };
5788
+ if (def.tag !== "keywords") return void 0;
5789
+ const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
5790
+ return {
5791
+ kind: "regex-terminal",
5792
+ source: re.source,
5793
+ flags: re.flags,
5794
+ canMatchNewline: body._meta.canMatchNewline,
5795
+ expected: directTerminalFailureExpected(def)
5796
+ };
5797
+ }
5798
+ function directTerminalParser(parser2, resolve3) {
5799
+ const seen = /* @__PURE__ */ new Set();
5800
+ while (!seen.has(parser2)) {
5801
+ seen.add(parser2);
5802
+ const def = parser2._def;
5803
+ if (def.tag === "lazy") {
5804
+ const target = resolvedLazyTarget(parser2, resolve3);
5805
+ if (target === void 0) return void 0;
5806
+ parser2 = target;
5807
+ continue;
5808
+ }
5809
+ if (def.tag === "token") {
5810
+ parser2 = def.parser;
5811
+ continue;
5812
+ }
5813
+ if (def.tag === "grammar") return void 0;
5814
+ return parser2;
5815
+ }
5816
+ return void 0;
5817
+ }
5818
+ function directTerminalLexBody(parser2, resolve3) {
5819
+ const terminal = directTerminalParser(parser2, resolve3);
5820
+ if (terminal === void 0) return void 0;
5821
+ const def = terminal._def;
5822
+ if (def.tag === "literal") {
5823
+ if (def.caseInsensitive) return void 0;
5824
+ const source = def.value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5825
+ return {
5826
+ kind: "regex-terminal",
5827
+ source,
5828
+ flags: "",
5829
+ canMatchNewline: terminal._meta.canMatchNewline,
5830
+ expected: directTerminalFailureExpected(def)
5831
+ };
5832
+ }
5833
+ if (def.tag === "regex") return {
5834
+ kind: "regex-terminal",
5835
+ source: def.source,
5836
+ flags: def.flags,
5837
+ canMatchNewline: terminal._meta.canMatchNewline,
5838
+ expected: directTerminalFailureExpected(def)
5839
+ };
5840
+ if (def.tag !== "keywords") return void 0;
5841
+ const re = keywordsRegExp(def.words, def.boundary, def.caseInsensitive);
5842
+ return {
5843
+ kind: "regex-terminal",
5844
+ source: re.source,
5845
+ flags: re.flags,
5846
+ canMatchNewline: terminal._meta.canMatchNewline,
5847
+ expected: directTerminalFailureExpected(def)
5848
+ };
5849
+ }
5850
+ function directOrdered4TokenBody(parser2, resolve3) {
5851
+ const body = directTokenBodyParser(parser2, resolve3);
5852
+ return body === void 0 ? void 0 : directOrdered4Body(body, resolve3);
5853
+ }
5854
+ function directOrdered4Body(body, resolve3) {
5855
+ if (body === void 0) return void 0;
5856
+ const choice2 = body._def;
5857
+ if (choice2.tag !== "choice" || choice2.parsers.length !== 4 || choice2.strategy.tag !== "firstMatch" || choice2.gates.some((gate2) => gate2 !== null) || choice2.autoNot.some((check) => check !== null)) return void 0;
5858
+ const arms = [];
5859
+ let common;
5860
+ for (const arm of choice2.parsers) {
5861
+ const selected = directTerminalLexBody(arm, resolve3);
5862
+ if (selected === void 0) return void 0;
5863
+ if (selected.canMatchNewline) return void 0;
5864
+ const terminal = directTerminalParser(arm, resolve3);
5865
+ const first = firstSetOf(terminal, /* @__PURE__ */ new Set(), resolve3);
5866
+ if (first.kind !== "ranges" || first.ranges.length === 0) return void 0;
5867
+ if (common === void 0) common = first;
5868
+ else if (JSON.stringify(common) !== JSON.stringify(first)) return void 0;
5869
+ arms.push(selected);
5870
+ }
5871
+ return {
5872
+ kind: "ordered4-terminals",
5873
+ commonFirstSet: common,
5874
+ commonMissExpected: deriveExpected(body),
5875
+ expected: arms.flatMap((arm) => arm.expected),
5876
+ arms
5877
+ };
5878
+ }
5879
+ function directNot2TokenBody(parser2, resolve3) {
5880
+ const body = directTokenBodyParser(parser2, resolve3);
5881
+ const sequence6 = body?._def;
5882
+ if (sequence6?.tag !== "sequence" || sequence6.parsers.length !== 3) return void 0;
5883
+ const [guard0Parser, guard1Parser, terminalParser] = sequence6.parsers;
5884
+ const guard0Def = guard0Parser?._def;
5885
+ const guard1Def = guard1Parser?._def;
5886
+ if (guard0Def?.tag !== "not" || guard1Def?.tag !== "not") return void 0;
5887
+ const ordered = directTokenBodyParser(guard0Def.parser, resolve3) ?? directTerminalParser(guard0Def.parser, resolve3);
5888
+ const guard0Body = ordered === void 0 ? void 0 : directOrdered4Body(ordered, resolve3);
5889
+ const guard1 = directTerminalLexBody(guard1Def.parser, resolve3);
5890
+ const terminal = terminalParser === void 0 ? void 0 : directTerminalLexBody(terminalParser, resolve3);
5891
+ if (guard0Body === void 0 || guard1 === void 0 || terminal === void 0 || guard1.canMatchNewline || terminal.canMatchNewline) return void 0;
5892
+ return {
5893
+ kind: "not2-ordered4-terminal",
5894
+ guard0Expected: assertionFailureExpected(false, guard0Def.parser._tag),
5895
+ guard1Expected: assertionFailureExpected(false, guard1Def.parser._tag),
5896
+ terminalExpected: terminal.expected,
5897
+ guard0: guard0Body.arms,
5898
+ guard1,
5899
+ terminal
5900
+ };
5901
+ }
5902
+ function directFixedLexNode(parser2, resolve3, active, pureOnly = false) {
5903
+ let current = parser2;
5904
+ const wrappers = /* @__PURE__ */ new Set();
5905
+ while (!wrappers.has(current)) {
5906
+ wrappers.add(current);
5907
+ const def = current._def;
5908
+ if (def.tag === "lazy") {
5909
+ const target = resolvedLazyTarget(current, resolve3);
5910
+ if (target === void 0) return void 0;
5911
+ current = target;
5912
+ continue;
5913
+ }
5914
+ if (def.tag === "token") {
5915
+ current = def.parser;
5916
+ continue;
5917
+ }
5918
+ break;
5919
+ }
5920
+ if (wrappers.has(current) && current !== parser2 && current._def.tag === "lazy") return void 0;
5921
+ if (active.has(current)) return void 0;
5922
+ active.add(current);
5923
+ try {
5924
+ const terminal = directTerminalLexBody(current, resolve3);
5925
+ if (terminal !== void 0) return { kind: "terminal", terminal };
5926
+ const def = current._def;
5927
+ if (def.tag === "grammar") {
5928
+ if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
5929
+ return directFixedLexNode(def.parser, resolve3, active, true);
5930
+ }
5931
+ if (def.tag === "sequence") {
5932
+ if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
5933
+ const parts = def.parsers.map((part) => directFixedLexNode(part, resolve3, active, pureOnly));
5934
+ if (parts.some((part) => part === void 0)) return void 0;
5935
+ return { kind: "sequence", parts };
5936
+ }
5937
+ if (def.tag === "choice") {
5938
+ if (def.parsers.length !== 2 && def.parsers.length !== 4 && def.parsers.length !== 8 || def.strategy.tag !== "firstMatch" || def.gates.some((gate2) => gate2 !== null) || def.autoNot.some((check) => check !== null)) return void 0;
5939
+ const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve3, active, pureOnly));
5940
+ if (arms.some((arm) => arm === void 0)) return void 0;
5941
+ const final = classifyFinalChoice(def.parsers, resolve3);
5942
+ return {
5943
+ kind: "choice",
5944
+ arms,
5945
+ firstSets: final.firstSets,
5946
+ armExpected: def.parsers.map(deriveExpected),
5947
+ expected: def.parsers.flatMap(deriveExpected)
5948
+ };
5949
+ }
5950
+ if (def.tag === "not") {
5951
+ const body = directFixedLexNode(def.parser, resolve3, active, true);
5952
+ return body === void 0 ? void 0 : {
5953
+ kind: "not",
5954
+ body,
5955
+ expected: assertionFailureExpected(false, def.parser._tag)
5956
+ };
5957
+ }
5958
+ if (def.tag === "optional") {
5959
+ const body = directFixedLexNode(def.parser, resolve3, active, pureOnly);
5960
+ return body === void 0 ? void 0 : { kind: "optional", body };
5961
+ }
5962
+ return void 0;
5963
+ } finally {
5964
+ active.delete(current);
5965
+ }
5966
+ }
5967
+ function directFixedTokenBody(parser2, resolve3) {
5968
+ const body = directTokenBodyParser(parser2, resolve3);
5969
+ if (body === void 0) return void 0;
5970
+ const root = directFixedLexNode(body, resolve3, /* @__PURE__ */ new Set());
5971
+ return root === void 0 ? void 0 : { kind: "fixed-tree", root };
5972
+ }
5973
+ function directBalancedTokenBody(parser2, resolve3) {
5974
+ if (directTokenBodyParser(parser2, resolve3) === void 0) return void 0;
5975
+ const spec = balancedSpecOf(parser2);
5976
+ return spec === void 0 ? void 0 : {
5977
+ kind: "balanced-scan",
5978
+ open: spec.open,
5979
+ close: spec.close,
5980
+ raw: spec.raw,
5981
+ strict: spec.strict,
5982
+ ownSkip: spec.ownSkip
5983
+ };
5984
+ }
5985
+ function directExecutableTokenBody(parser2, resolve3) {
5986
+ return directOptionalSuffixTokenBody(parser2, resolve3) ?? directTerminalTokenBody(parser2, resolve3) ?? directOrdered4TokenBody(parser2, resolve3) ?? directNot2TokenBody(parser2, resolve3) ?? directBalancedTokenBody(parser2, resolve3) ?? directFixedTokenBody(parser2, resolve3);
5987
+ }
5988
+ function winnerWrapsReference(winner, reference) {
5989
+ let current = winner;
5990
+ const seen = /* @__PURE__ */ new Set();
5991
+ while (!seen.has(current)) {
5992
+ if (current === reference) return true;
5993
+ seen.add(current);
5994
+ const def = current._def;
5995
+ if (def.tag !== "grammar" && def.tag !== "trivia") return false;
5996
+ current = def.parser;
5997
+ }
5998
+ return false;
5999
+ }
6000
+ function resolvedLazyTarget(parser2, resolve3) {
6001
+ const def = parser2._def;
6002
+ if (def.tag !== "lazy") return void 0;
6003
+ const name = parser2._ruleName;
6004
+ if (name !== void 0 && resolve3 !== void 0) {
6005
+ const winner = resolve3(name);
6006
+ if (winner !== void 0 && !winnerWrapsReference(winner, parser2)) return winner;
6007
+ }
6008
+ try {
6009
+ return def.thunk();
6010
+ } catch {
6011
+ return void 0;
6012
+ }
6013
+ }
6014
+ function balancedSpecOf(parser2) {
6015
+ let current = parser2;
6016
+ let spec = current._balancedSpec;
6017
+ const seen = /* @__PURE__ */ new Set();
6018
+ while (spec === void 0 && current._def.tag === "token" && !seen.has(current)) {
6019
+ seen.add(current);
6020
+ current = current._def.parser;
6021
+ spec = current._balancedSpec;
6022
+ }
6023
+ return spec;
6024
+ }
6025
+
6026
+ // src/table/encode.ts
6027
+ function emittableConst(v) {
6028
+ const scalar = (x) => x === null || typeof x === "string" || typeof x === "number" || typeof x === "boolean";
6029
+ if (scalar(v) || v instanceof RegExp) return true;
6030
+ if (Array.isArray(v)) return v.every(scalar);
6031
+ if (typeof v === "object" && v !== null) {
6032
+ const proto = Object.getPrototypeOf(v);
6033
+ if (proto !== Object.prototype && proto !== null) return false;
6034
+ return Object.values(v).every((x) => scalar(x) || Array.isArray(x) && x.every(scalar));
4956
6035
  }
4957
6036
  return false;
4958
6037
  }
@@ -4987,6 +6066,10 @@ var Encoder = class {
4987
6066
  fx = [];
4988
6067
  disp = [];
4989
6068
  dsp = [];
6069
+ lex = [];
6070
+ lexIndex = /* @__PURE__ */ new Map();
6071
+ lexPrograms = [];
6072
+ lexProgramIndex = /* @__PURE__ */ new Map();
4990
6073
  labels = void 0;
4991
6074
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
4992
6075
  activeTrivia = void 0;
@@ -5057,6 +6140,146 @@ var Encoder = class {
5057
6140
  this.triviaSpecs.push(this.triviaSpecOf(t));
5058
6141
  return idx;
5059
6142
  }
6143
+ lexicalBodySlot(p) {
6144
+ if (!this.selectLexicalBodies) return void 0;
6145
+ const body = directExecutableTokenBody(p, (name) => this.winners?.[name]);
6146
+ if (body === void 0) return void 0;
6147
+ const tokenDef = p._def;
6148
+ if (tokenDef.tag !== "token") throw new Error("parseman: selected lexical body lost token boundary");
6149
+ const matcher = (arm) => {
6150
+ const flags2 = arm.flags.includes("y") ? arm.flags : `${arm.flags.replace(/g/g, "")}y`;
6151
+ const regex3 = this.constant(new RegExp(arm.source, flags2));
6152
+ const key2 = `${regex3}:-1`;
6153
+ const prior2 = this.lexIndex.get(key2);
6154
+ if (prior2 !== void 0) return prior2;
6155
+ const id2 = this.lex.length;
6156
+ this.lexIndex.set(key2, id2);
6157
+ this.lex.push([regex3, -1]);
6158
+ return id2;
6159
+ };
6160
+ if (body.kind === "balanced-scan") {
6161
+ const scan = this.scanSlot({
6162
+ kind: 1,
6163
+ flags: (body.raw ? 1 : 0) | (body.strict ? 4 : 0),
6164
+ skip: body.ownSkip.map((combinator) => this.subtree(combinator)),
6165
+ open: body.open,
6166
+ close: body.close
6167
+ });
6168
+ const words = [scan];
6169
+ const spec = [3, lexProgramDigest(words), scan];
6170
+ const key2 = spec.join(",");
6171
+ const prior2 = this.lexProgramIndex.get(key2);
6172
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6173
+ const id2 = this.lexPrograms.length;
6174
+ this.lexProgramIndex.set(key2, id2);
6175
+ this.lexPrograms.push(spec);
6176
+ return { kind: "program", program: id2 };
6177
+ }
6178
+ if (body.kind === "fixed-tree") {
6179
+ const words = [];
6180
+ const emitNode = (node2) => {
6181
+ switch (node2.kind) {
6182
+ case "terminal":
6183
+ words.push(
6184
+ LEX_NODE_TERMINAL,
6185
+ matcher(node2.terminal),
6186
+ this.expected(node2.terminal.expected),
6187
+ this.track ? 1 : 0
6188
+ );
6189
+ return true;
6190
+ case "sequence": {
6191
+ for (const part of node2.parts) if (!emitNode(part)) return false;
6192
+ const op = node2.parts.length === 2 ? LEX_NODE_SEQUENCE2 : node2.parts.length === 3 ? LEX_NODE_SEQUENCE3 : node2.parts.length === 4 ? LEX_NODE_SEQUENCE4 : node2.parts.length === 5 ? LEX_NODE_SEQUENCE5 : -1;
6193
+ if (op < 0) return false;
6194
+ words.push(op);
6195
+ return true;
6196
+ }
6197
+ case "choice": {
6198
+ for (const arm of node2.arms) if (!emitNode(arm)) return false;
6199
+ const op = node2.arms.length === 2 ? LEX_NODE_CHOICE2 : node2.arms.length === 4 ? LEX_NODE_CHOICE4 : node2.arms.length === 8 ? LEX_NODE_CHOICE8 : -1;
6200
+ if (op < 0) return false;
6201
+ words.push(op, this.expected(node2.expected));
6202
+ for (let i = 0; i < node2.arms.length; i++) {
6203
+ const first = node2.firstSets[i];
6204
+ words.push(first.kind === "ranges" ? this.charClass(first) : -1);
6205
+ words.push(this.expected(node2.armExpected[i]));
6206
+ }
6207
+ return true;
6208
+ }
6209
+ case "not":
6210
+ if (!emitNode(node2.body)) return false;
6211
+ words.push(LEX_NODE_NOT, this.expected(node2.expected));
6212
+ return true;
6213
+ case "optional":
6214
+ if (!emitNode(node2.body)) return false;
6215
+ words.push(LEX_NODE_OPTIONAL);
6216
+ return true;
6217
+ }
6218
+ };
6219
+ if (!emitNode(body.root)) return void 0;
6220
+ const spec = [2, lexProgramDigest(words), ...words];
6221
+ const key2 = spec.join(",");
6222
+ const prior2 = this.lexProgramIndex.get(key2);
6223
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6224
+ const id2 = this.lexPrograms.length;
6225
+ this.lexProgramIndex.set(key2, id2);
6226
+ this.lexPrograms.push(spec);
6227
+ return { kind: "program", program: id2 };
6228
+ }
6229
+ if (body.kind === "not2-ordered4-terminal") {
6230
+ const words = [
6231
+ ...body.guard0.map(matcher),
6232
+ this.expected(body.guard0Expected),
6233
+ matcher(body.guard1),
6234
+ this.expected(body.guard1Expected),
6235
+ matcher(body.terminal),
6236
+ this.expected(body.terminalExpected),
6237
+ this.track ? 1 : 0
6238
+ ];
6239
+ const spec = [1, lexProgramDigest(words), ...words];
6240
+ const key2 = spec.join(",");
6241
+ const prior2 = this.lexProgramIndex.get(key2);
6242
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6243
+ const id2 = this.lexPrograms.length;
6244
+ this.lexProgramIndex.set(key2, id2);
6245
+ this.lexPrograms.push(spec);
6246
+ return { kind: "program", program: id2 };
6247
+ }
6248
+ if (body.kind === "ordered4-terminals") {
6249
+ const commonClass = this.charClass(body.commonFirstSet);
6250
+ if (commonClass < 0) return void 0;
6251
+ const words = [commonClass, this.expected(body.commonMissExpected)];
6252
+ for (const arm of body.arms) {
6253
+ words.push(matcher(arm), this.expected(arm.expected));
6254
+ }
6255
+ words.push(this.track ? 1 : 0);
6256
+ const spec = [0, lexProgramDigest(words), ...words];
6257
+ const key2 = spec.join(",");
6258
+ const prior2 = this.lexProgramIndex.get(key2);
6259
+ if (prior2 !== void 0) return { kind: "program", program: prior2 };
6260
+ const id2 = this.lexPrograms.length;
6261
+ this.lexProgramIndex.set(key2, id2);
6262
+ this.lexPrograms.push(spec);
6263
+ return { kind: "program", program: id2 };
6264
+ }
6265
+ const expectedFx = this.expected(body.expected);
6266
+ const flags = body.flags.includes("y") ? body.flags : `${body.flags.replace(/g/g, "")}y`;
6267
+ const regex2 = this.constant(new RegExp(body.source, flags));
6268
+ const suffix = body.kind === "regex-terminal" ? -1 : body.suffix.charCodeAt(0);
6269
+ const key = `${regex2}:${suffix}`;
6270
+ const prior = this.lexIndex.get(key);
6271
+ const suffixFx = this.expected(body.kind === "regex-terminal" ? [] : directTerminalFailureExpected({
6272
+ tag: "literal",
6273
+ value: body.suffix,
6274
+ caseInsensitive: false
6275
+ }));
6276
+ const lineFlags = this.track ? body.kind === "regex-terminal" ? 1 : 1 | 2 | 4 : body.kind === "regex-terminal" ? 0 : 4;
6277
+ if (prior !== void 0) return { kind: "body", body: prior, expectedFx, suffixFx, lineFlags };
6278
+ const id = this.lex.length;
6279
+ this.lexIndex.set(key, id);
6280
+ this.lex.push([regex2, suffix]);
6281
+ return { kind: "body", body: id, expectedFx, suffixFx, lineFlags };
6282
+ }
5060
6283
  triviaSpecOf(t) {
5061
6284
  const unlowered = (why) => {
5062
6285
  this.runtimeOnly.add(`rules({ trivia }) \u2014 ${why}`);
@@ -5140,6 +6363,9 @@ var Encoder = class {
5140
6363
  settings;
5141
6364
  /** Resolved once, HERE, at table-build time — never consulted at run time. */
5142
6365
  track;
6366
+ /** TOKEN bodies are an all-program decision. A complete occurrence inside an
6367
+ * otherwise incomplete final graph stays on CHARACTER with every sibling. */
6368
+ selectLexicalBodies;
5143
6369
  /**
5144
6370
  * Decides the extra operands laid down below. ALWAYS TRUE — see
5145
6371
  * `TableSettings.recovery`. Kept as a field rather than folded away because it
@@ -5147,9 +6373,10 @@ var Encoder = class {
5147
6373
  * row is stated.
5148
6374
  */
5149
6375
  rec;
5150
- constructor(settings) {
6376
+ constructor(settings, selectLexicalBodies) {
5151
6377
  this.settings = settings;
5152
6378
  this.track = settings.trackLines === true;
6379
+ this.selectLexicalBodies = selectLexicalBodies;
5153
6380
  this.rec = true;
5154
6381
  this.plan = settings.coverage;
5155
6382
  this.cov = settings.coverage === void 0 ? void 0 : settings.coverage.definitions.map((d) => [d.id, covKindCode(d.kind)]);
@@ -5264,6 +6491,13 @@ var Encoder = class {
5264
6491
  this.ccIndex.set(spec, i);
5265
6492
  return i;
5266
6493
  }
6494
+ /** Bind a guard only when its class is already part of the program. Repeat
6495
+ * gating must not grow the compact artifact merely to avoid a failed call. */
6496
+ existingCharClass(fs3) {
6497
+ if (fs3.kind !== "ranges" || fs3.ranges.length === 0) return -1;
6498
+ const hit = this.ccIndex.get(encodeClassSpec(fs3.ranges));
6499
+ return hit !== void 0 && hit < 100 ? hit : -1;
6500
+ }
5267
6501
  /**
5268
6502
  * Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
5269
6503
  *
@@ -5352,7 +6586,7 @@ var Encoder = class {
5352
6586
  * in the target rule's own ambient trivia when that differs from the trivia
5353
6587
  * lexically active at the reference.
5354
6588
  *
5355
- * `encodeRule` wraps a rule ENTRY in `OP_SCOPE`, but only the entry: a `g.X`
6589
+ * `encodeRule` wraps a rule ENTRY in `OP_SCOPE_PLAIN`, but only the entry: a `g.X`
5356
6590
  * reference resolves straight to the body's offset and jumps past it (the note
5357
6591
  * at `encodeRule`). So a rule referenced from inside a `noTrivia(...)` region ran
5358
6592
  * with NO ambient trivia of its own — the table scoped trivia DYNAMICALLY, by
@@ -5429,6 +6663,19 @@ var Encoder = class {
5429
6663
  }
5430
6664
  encodeDef(p) {
5431
6665
  const d = p._def;
6666
+ if (d.tag === "token") {
6667
+ const selected = this.lexicalBodySlot(p);
6668
+ if (selected !== void 0) {
6669
+ if (selected.kind === "program") return this.emit(OP_LEX_PROGRAM, selected.program);
6670
+ return this.emit(
6671
+ OP_LEX_BODY,
6672
+ selected.body,
6673
+ selected.expectedFx,
6674
+ selected.suffixFx,
6675
+ selected.lineFlags
6676
+ );
6677
+ }
6678
+ }
5432
6679
  const bal = p._balancedSpec;
5433
6680
  if (bal !== void 0) return this.emit(OP_SCAN, this.scanSlot({
5434
6681
  kind: 1,
@@ -5450,13 +6697,13 @@ var Encoder = class {
5450
6697
  switch (d.tag) {
5451
6698
  case "literal": {
5452
6699
  if (d.caseInsensitive) {
5453
- return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(deriveExpected(p)));
6700
+ return this.emit(this.track ? OP_LIT_CI_TRACK : OP_LIT_CI, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
5454
6701
  }
5455
- return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(deriveExpected(p)));
6702
+ return this.emit(this.track ? OP_LIT_TRACK : OP_LIT, this.constant(d.value), this.expected(directTerminalFailureExpected(d)));
5456
6703
  }
5457
6704
  case "regex": {
5458
6705
  const flags = d.flags.includes("y") ? d.flags : `${d.flags}y`;
5459
- return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(deriveExpected(p)));
6706
+ return this.emit(this.track ? OP_RX_TRACK : OP_RX, this.constant(new RegExp(d.source, flags)), this.expected(directTerminalFailureExpected(d)));
5460
6707
  }
5461
6708
  case "keywords": {
5462
6709
  const alt = d.words.map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
@@ -5470,7 +6717,7 @@ var Encoder = class {
5470
6717
  // failing keyword arm names the CATEGORY rather than reciting every
5471
6718
  // literal in the family. `deriveExpected` reports the literals, so the
5472
6719
  // table said `'"media"'` where both other engines say `'keyword'`.
5473
- this.expected(["keyword"])
6720
+ this.expected(directTerminalFailureExpected(d))
5474
6721
  );
5475
6722
  }
5476
6723
  case "expect": {
@@ -5517,7 +6764,8 @@ var Encoder = class {
5517
6764
  return this.covWrap(gated, armCovIds?.[src], 1);
5518
6765
  });
5519
6766
  const rr = this.refResolver();
5520
- const classes = arms.map((a) => matchesEmpty(a, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(a, /* @__PURE__ */ new Set(), rr)));
6767
+ const finalChoice = classifyFinalChoice(arms, rr);
6768
+ const classes = arms.map((_, i) => finalChoice.nullable[i] ? -1 : this.charClass(finalChoice.firstSets[i]));
5521
6769
  const dispIdx = this.disp.length;
5522
6770
  this.disp.push(classes);
5523
6771
  const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
@@ -5533,9 +6781,11 @@ var Encoder = class {
5533
6781
  case "many":
5534
6782
  case "oneOrMore": {
5535
6783
  const child = this.node(d.parser).ip;
6784
+ const rr = this.refResolver();
6785
+ const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
5536
6786
  const op = d.valueUnused ? OP_REPV : OP_REP;
5537
6787
  const min = d.tag === "many" ? 0 : d.min;
5538
- return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), -1) : this.emit(op, child, min, d.max ?? -1, -1, 0);
6788
+ return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
5539
6789
  }
5540
6790
  case "sepBy": {
5541
6791
  const child = this.node(d.parser).ip;
@@ -5562,7 +6812,8 @@ var Encoder = class {
5562
6812
  if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
5563
6813
  const kids = inner.parsers.map((c) => this.node(c).ip);
5564
6814
  const head = this.emitHead(OP_SEQX, 2 + kids.length + (this.rec ? kids.length : 0));
5565
- this.code[head + 1] = this.fn(d.fn, d.fnSrc ?? null);
6815
+ const projection = directArrayProjection(d.fn, d.fnSrc, kids.length);
6816
+ this.code[head + 1] = projection === null ? this.fn(d.fn, d.fnSrc ?? null) : ~projection;
5566
6817
  this.code[head + 2] = kids.length;
5567
6818
  for (let i = 0; i < kids.length; i++) this.code[head + 3 + i] = kids[i];
5568
6819
  if (this.rec) {
@@ -5583,10 +6834,11 @@ var Encoder = class {
5583
6834
  const cstOut = this.settings.hostMode === "cst";
5584
6835
  const noBuildCaptures = d.project === void 0;
5585
6836
  const derivedTrivia = d.build !== void 0 ? buildReadsTrivia(d) : noBuildCaptures;
6837
+ const omitsRaw = d.build !== void 0 && !buildReadsRaw(d);
5586
6838
  const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
5587
6839
  const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
5588
6840
  const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
5589
- const flags = (cstOut || d.captureTrivia === true || d.trailingTrivia === true || derivedTrivia ? 4 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
6841
+ const flags = (cstOut || d.captureTrivia === true || d.trailingTrivia === true || derivedTrivia ? 4 : 0) | (!cstOut && omitsRaw ? 2 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
5590
6842
  const body = this.emit(
5591
6843
  this.track ? OP_NODE_TRACK : OP_NODE,
5592
6844
  d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
@@ -5607,8 +6859,9 @@ var Encoder = class {
5607
6859
  const e = deriveExpected(d.parser);
5608
6860
  return this.emit(OP_GATE, cls, body, this.expected(e.length > 0 ? e : [d.parser._tag]));
5609
6861
  }
5610
- case "token":
6862
+ case "token": {
5611
6863
  return this.emit(OP_TOKEN, this.node(d.parser).ip);
6864
+ }
5612
6865
  case "routed":
5613
6866
  return this.emit(OP_ROUTED, d.fallback === void 0 ? -1 : this.node(d.fallback).ip);
5614
6867
  case "dispatch": {
@@ -5673,7 +6926,7 @@ var Encoder = class {
5673
6926
  case "lazy": {
5674
6927
  const refName = p._ruleName;
5675
6928
  const winner = refName === void 0 ? void 0 : this.winners?.[refName];
5676
- if (winner !== void 0 && !wrapsRef(winner, p)) return this.scopedRef(p, winner);
6929
+ if (winner !== void 0 && !winnerWrapsReference2(winner, p)) return this.scopedRef(p, winner);
5677
6930
  let resolved;
5678
6931
  try {
5679
6932
  resolved = d.thunk();
@@ -5689,7 +6942,7 @@ var Encoder = class {
5689
6942
  // other engine reported `['not(literal)']`. It hid because `expected` is a
5690
6943
  // TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
5691
6944
  case "not":
5692
- return this.emit(OP_NOT, this.node(d.parser).ip, this.expected([`not(${d.parser._tag})`]));
6945
+ return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
5693
6946
  case "guard":
5694
6947
  return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
5695
6948
  case "adjacency":
@@ -5707,7 +6960,7 @@ var Encoder = class {
5707
6960
  return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
5708
6961
  }
5709
6962
  case "peek":
5710
- return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected([`peek(${d.parser._tag})`]));
6963
+ return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
5711
6964
  // A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
5712
6965
  // lowering was correct only for a choice arm.
5713
6966
  case "attempt": {
@@ -5868,6 +7121,8 @@ var Encoder = class {
5868
7121
  disp: this.disp,
5869
7122
  dsp: this.dsp,
5870
7123
  rules: this.rules,
7124
+ ...this.lex.length === 0 ? {} : { lex: this.lex },
7125
+ ...this.lexPrograms.length === 0 ? {} : { lexPrograms: this.lexPrograms },
5871
7126
  ...this.labels === void 0 ? {} : { labels: this.labels },
5872
7127
  ...this.classified ? { classified: 1 } : {},
5873
7128
  ...this.scanSkipSets.length === 0 ? {} : { scanSkip: this.scanSkipSets, scanSkipOf: this.scanSkipOf },
@@ -5919,7 +7174,11 @@ function encodeTableProgram(ruleMap, settings = {}) {
5919
7174
  ...hostMode === void 0 ? {} : { hostMode },
5920
7175
  ...track ? { trackLines: true } : {}
5921
7176
  };
5922
- const enc = new Encoder(resolvedSettings);
7177
+ const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
7178
+ const resolveLexical = (name) => ruleMap[name];
7179
+ const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
7180
+ assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
7181
+ const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
5923
7182
  enc.winners = ruleMap;
5924
7183
  for (const name of names) enc.encodeRule(name, ruleMap[name]);
5925
7184
  const prog = enc.finish();
@@ -6964,6 +8223,8 @@ function childSlots(code, ip, out) {
6964
8223
  case OP_GUARD:
6965
8224
  case OP_ADJ:
6966
8225
  case OP_LIVE:
8226
+ case OP_LEX_BODY:
8227
+ case OP_LEX_PROGRAM:
6967
8228
  return true;
6968
8229
  // Single child at `ip + 1`. `OP_COV` is a wrapper on the same footing as the
6969
8230
  // rest — a coverage-encoded program is a program, and omitting it made
@@ -7081,7 +8342,12 @@ function transfer(code, ip, at, hostCst) {
7081
8342
  return { tri, buf: at.buf, cap };
7082
8343
  }
7083
8344
  if (op === OP_NODE || op === OP_NODE_TRACK) {
7084
- const cap = (code[ip + 3] & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
8345
+ const flags = code[ip + 3];
8346
+ const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
8347
+ if (directChildren) {
8348
+ return { tri: at.tri, buf: false, cap: CAP_OFF };
8349
+ }
8350
+ const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
7085
8351
  if (at.buf && cap === at.cap) return at;
7086
8352
  return { tri: at.tri, buf: true, cap };
7087
8353
  }
@@ -7122,6 +8388,43 @@ function computeSiteLabels(code, roots, hostCst) {
7122
8388
  return { at: (ip) => labels.get(ip) ?? TOP };
7123
8389
  }
7124
8390
 
8391
+ // src/table/scalar-terminal.ts
8392
+ function makeScalarRecognizer(op, spec) {
8393
+ if (op === OP_RX && spec instanceof RegExp) {
8394
+ return (input, pos) => {
8395
+ spec.lastIndex = pos;
8396
+ return spec.test(input) ? spec.lastIndex : -1;
8397
+ };
8398
+ }
8399
+ if (op !== OP_LIT || typeof spec !== "string") return void 0;
8400
+ const len = spec.length;
8401
+ if (len === 1) {
8402
+ const c0 = spec.charCodeAt(0);
8403
+ return (input, pos) => input.charCodeAt(pos) === c0 ? pos + 1 : -1;
8404
+ }
8405
+ if (len === 2) {
8406
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1);
8407
+ return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 ? pos + 2 : -1;
8408
+ }
8409
+ if (len === 3) {
8410
+ const c0 = spec.charCodeAt(0), c1 = spec.charCodeAt(1), c2 = spec.charCodeAt(2);
8411
+ return (input, pos) => input.charCodeAt(pos) === c0 && input.charCodeAt(pos + 1) === c1 && input.charCodeAt(pos + 2) === c2 ? pos + 3 : -1;
8412
+ }
8413
+ return (input, pos) => input.startsWith(spec, pos) ? pos + len : -1;
8414
+ }
8415
+ function scalarTerminalNodeChild(code, ip) {
8416
+ if (code[ip + 1] < 0 || code[ip + 3] !== 0 || code[ip + 4] !== -1) return -1;
8417
+ const child = code[ip + 2];
8418
+ const op = code[child];
8419
+ return op === OP_RX || op === OP_LIT ? child : -1;
8420
+ }
8421
+ function scalarTerminalNotChild(code, ip) {
8422
+ if (code[ip] !== OP_NOT) return -1;
8423
+ const child = code[ip + 1];
8424
+ const op = code[child];
8425
+ return op === OP_RX || op === OP_LIT ? child : -1;
8426
+ }
8427
+
7125
8428
  // src/table/emit-assembly.ts
7126
8429
  var Unemittable = class extends Error {
7127
8430
  construct;
@@ -7183,7 +8486,19 @@ var EMITTED_PARAMS = [
7183
8486
  "matchesAt",
7184
8487
  "recoverScan",
7185
8488
  "orSentinel",
7186
- "captureError"
8489
+ "captureError",
8490
+ // Pure scalar terminal recognizers, indexed by the terminal's existing const
8491
+ // operand. Appended for compatibility with older precompiled factories.
8492
+ "RECOG",
8493
+ // Appended so precompiled factories produced by earlier runtimes keep every
8494
+ // positional helper binding. Older factories ignore this trailing argument.
8495
+ "commitTriviaScan",
8496
+ "scanTriviaCompact",
8497
+ "LEX",
8498
+ // Appended for old precompiled-factory ABI: old factories ignore it.
8499
+ "adjacencyHolds",
8500
+ // Appended for selected composite lexical programs; old factories ignore it.
8501
+ "LEXPROG"
7187
8502
  ];
7188
8503
  var RUNTIME_PRELUDE = `
7189
8504
  let _pfScan=null
@@ -7194,7 +8509,7 @@ function _skipTrivia(input,cur,ctx){
7194
8509
  const s=_pfScan
7195
8510
  if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
7196
8511
  if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
7197
- if(needsDeferredTriviaCommit(ctx)){const sc=scanTrivia(input,cur,ctx);sc.commit();return sc.end}
8512
+ if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
7198
8513
  return advanceTrivia(input,cur,ctx)
7199
8514
  }
7200
8515
  function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
@@ -7208,6 +8523,13 @@ if(b.raw!==undefined)b.raw.push(l)
7208
8523
  else if(b.rawSingle!==undefined){b.raw=[b.rawSingle,l];b.rawSingle=undefined}
7209
8524
  else b.rawSingle=l
7210
8525
  }
8526
+ function _capturedFlatChildren(children){
8527
+ if(children.length===0)return EMPTY_CH
8528
+ if(children[0]!==undefined)return children
8529
+ let first=1
8530
+ while(first<children.length&&children[first]===undefined)first++
8531
+ return first===children.length?EMPTY_CH:children.slice(first)
8532
+ }
7211
8533
  function _accSet(ax,acc){
7212
8534
  if(ax===undefined||ax.length===0)return acc
7213
8535
  if(acc===undefined)return ax.slice()
@@ -7342,12 +8664,16 @@ function maskForClassRow(gates) {
7342
8664
  }
7343
8665
  return m;
7344
8666
  }
7345
- function rebuildPools(cc, fx, plan) {
8667
+ function rebuildPools(cc, fx, disp, plan) {
7346
8668
  const classes = plan.classes.map((row) => row.map((i) => i < 0 ? null : cc[i] ?? null));
7347
8669
  return {
7348
8670
  classes,
7349
8671
  armExpected: plan.armExpected.map((row) => row.map((i) => fx[i] ?? [])),
7350
- masks: plan.masks.map((ci) => maskForClassRow(classes[ci]))
8672
+ masks: plan.masks.map((source) => {
8673
+ const row = source >= 0 ? classes[source] : disp[~source]?.armCls;
8674
+ if (row === void 0) throw new TypeError(`table emitter: invalid MASK plan source ${source}`);
8675
+ return maskForClassRow(row);
8676
+ })
7351
8677
  };
7352
8678
  }
7353
8679
  function emitAssemblySource(t, prog, cfg, extraIps = []) {
@@ -7358,6 +8684,14 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7358
8684
  if (cfg.coverage) throw new Unemittable("a coverage assembly");
7359
8685
  const roots = [...Object.values(prog.rules), ...extraIps];
7360
8686
  const labels = computeSiteLabels(code, roots, hostCst);
8687
+ const scalarSpecs = /* @__PURE__ */ new Set();
8688
+ if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
8689
+ for (const ip of reachableSites(code, roots)) {
8690
+ if (code[ip] !== OP_NODE) continue;
8691
+ const child = scalarTerminalNodeChild(code, ip);
8692
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
8693
+ }
8694
+ }
7361
8695
  const sinks = (() => {
7362
8696
  let fd = false;
7363
8697
  let er = REC2;
@@ -7378,6 +8712,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7378
8712
  const reached = /* @__PURE__ */ new Set();
7379
8713
  const prelude = [];
7380
8714
  const skipDefs = [];
8715
+ const choiceDefs = [];
7381
8716
  const skipPool = /* @__PURE__ */ new Map();
7382
8717
  const pool = /* @__PURE__ */ new Map();
7383
8718
  const masks = [];
@@ -7397,6 +8732,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7397
8732
  const kRef = (i) => hoist("k", `K[${i}]`);
7398
8733
  const fxRef = (i) => hoist("fx", `FX[${i}]`);
7399
8734
  const fnRef = (i) => hoist("fn", `FNS[${i}]`);
8735
+ const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
7400
8736
  const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
7401
8737
  let uid = 0;
7402
8738
  const tmp = () => `_t${uid++}_`;
@@ -7410,8 +8746,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
7410
8746
  const nm = `_sk${skipPool.size}`;
7411
8747
  skipPool.set(key, nm);
7412
8748
  if (!hasScan) {
7413
- skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){const s=scanTrivia(input,cur,ctx);s.commit();return s.end}` : `function ${nm}(input,cur,ctx){
7414
- if(needsDeferredTriviaCommit(ctx)){const s=scanTrivia(input,cur,ctx);s.commit();return s.end}
8749
+ skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return commitTriviaScan(scanTriviaCompact(input,cur,ctx))}` : `function ${nm}(input,cur,ctx){
8750
+ if(needsDeferredTriviaCommit(ctx))return commitTriviaScan(scanTriviaCompact(input,cur,ctx))
7415
8751
  return advanceTrivia(input,cur,ctx)}`);
7416
8752
  return nm;
7417
8753
  }
@@ -7498,6 +8834,19 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
7498
8834
  const s = k[code[ip + 1]];
7499
8835
  const xf = fxRef(code[ip + 2]);
7500
8836
  const track = op === OP_LIT_TRACK;
8837
+ if (!track && scalarSpecs.has(code[ip + 1])) {
8838
+ const recognize = recognizerRef(code[ip + 1]);
8839
+ return `${head}
8840
+ const e=${recognize}(input,pos)
8841
+ if(e>=0){
8842
+ ${captureLeaf(q(s))}
8843
+ EC.e=e
8844
+ return ${q(s)}
8845
+ }
8846
+ ctx._fe=pos;ctx._fx=${xf}
8847
+ return FAIL
8848
+ }`;
8849
+ }
7501
8850
  const test = s.length === 1 ? `input.charCodeAt(pos)===${s.charCodeAt(0)}` : s.length === 2 ? `input.charCodeAt(pos)===${s.charCodeAt(0)}&&input.charCodeAt(pos+1)===${s.charCodeAt(1)}` : `input.startsWith(${q(s)},pos)`;
7502
8851
  return `${head}
7503
8852
  if(${test}){
@@ -7547,6 +8896,20 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
7547
8896
  case OP_RX_TRACK: {
7548
8897
  const xf = fxRef(code[ip + 2]);
7549
8898
  const track = op === OP_RX_TRACK;
8899
+ if (!track && scalarSpecs.has(code[ip + 1])) {
8900
+ const recognize = recognizerRef(code[ip + 1]);
8901
+ return `${head}
8902
+ const e=${recognize}(input,pos)
8903
+ if(e>=0){
8904
+ const v=input.slice(pos,e)
8905
+ ${captureLeaf("v")}
8906
+ EC.e=e
8907
+ return v
8908
+ }
8909
+ ctx._fe=pos;ctx._fx=${xf}
8910
+ return FAIL
8911
+ }`;
8912
+ }
7550
8913
  const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
7551
8914
  if (scanned !== void 0) return `${head}${scanned}}`;
7552
8915
  const rxk = k[code[ip + 1]];
@@ -7708,6 +9071,73 @@ const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
7708
9071
  if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
7709
9072
  EC.e=e
7710
9073
  return out
9074
+ }`;
9075
+ }
9076
+ case OP_LEX_BODY: {
9077
+ const recognize = hoist("lex", `LEX[${code[ip + 1]}]`);
9078
+ const expected = fxRef(code[ip + 2]);
9079
+ const suffixExpected = fxRef(code[ip + 3]);
9080
+ const lineFlags = code[ip + 4];
9081
+ const hasSuffix = (lineFlags & 4) !== 0;
9082
+ return `${head}
9083
+ const r=${recognize}(input,pos)
9084
+ if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
9085
+ const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
9086
+ ${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
9087
+ ${hasSuffix ? "ctx._fc=false" : ""}
9088
+ ${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
9089
+ ${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
9090
+ const v=input.slice(pos,e)
9091
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9092
+ EC.e=e
9093
+ return v
9094
+ }`;
9095
+ }
9096
+ case OP_LEX_PROGRAM: {
9097
+ const programId = code[ip + 1];
9098
+ const run3 = hoist("lexProgram", `LEXPROG[${programId}]`);
9099
+ const scanId = t.lexPrograms[programId].scan;
9100
+ if (scanId !== void 0) return `${head}
9101
+ const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan
9102
+ const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
9103
+ const sOtl=ctx._triviaLog,sRtl=ctx._rootTriviaLog
9104
+ const wasCap=ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined
9105
+ _pfScan=null
9106
+ ctx.trivia=undefined
9107
+ ctx.triviaKindLabels=undefined
9108
+ ctx._cstBuf=undefined
9109
+ ctx._cstChildren=undefined
9110
+ ctx._cstLeaves=undefined
9111
+ ctx._cstRawChildren=undefined
9112
+ ctx._cstTriviaLog=undefined
9113
+ ctx._triviaLog=undefined
9114
+ ctx._rootTriviaLog=undefined
9115
+ let e
9116
+ try{e=${run3}(input,pos,ctx,SCANS[${scanId}])}finally{
9117
+ _pfScan=sScan
9118
+ ctx.trivia=sTri
9119
+ ctx.triviaKindLabels=sKinds
9120
+ ctx._cstBuf=sBuf
9121
+ ctx._cstChildren=sCh
9122
+ ctx._cstLeaves=sLv
9123
+ ctx._cstRawChildren=sRaw
9124
+ ctx._cstTriviaLog=sTl
9125
+ ctx._triviaLog=sOtl
9126
+ ctx._rootTriviaLog=sRtl
9127
+ }
9128
+ if(e<0)return FAIL
9129
+ const v=input.slice(pos,e)
9130
+ if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9131
+ EC.e=e
9132
+ return v
9133
+ }`;
9134
+ return `${head}
9135
+ const e=${run3}(input,pos,ctx)
9136
+ if(e<0)return FAIL
9137
+ const v=input.slice(pos,e)
9138
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9139
+ EC.e=e
9140
+ return v
7711
9141
  }`;
7712
9142
  }
7713
9143
  /* ── transaction ─────────────────────────────────────────────────────── */
@@ -7725,6 +9155,18 @@ return FAIL
7725
9155
  }`;
7726
9156
  }
7727
9157
  case OP_NOT: {
9158
+ const scalarChild = scalarTerminalNotChild(code, ip);
9159
+ if (scalarChild >= 0) {
9160
+ const recognize = recognizerRef(code[scalarChild + 1]);
9161
+ const xf2 = fxRef(code[ip + 2]);
9162
+ return `${head}
9163
+ if(${recognize}(input,pos)<0){EC.e=pos;return null}
9164
+ ctx._fe=pos
9165
+ ctx._fx=${xf2}
9166
+ EC.e=pos
9167
+ return FAIL
9168
+ }`;
9169
+ }
7728
9170
  const child = link(code[ip + 1]);
7729
9171
  const xf = fxRef(code[ip + 2]);
7730
9172
  const p = tmp();
@@ -7774,14 +9216,14 @@ return v
7774
9216
  const base = fused ? ip + 3 : ip + 2;
7775
9217
  const n = code[fused ? ip + 2 : ip + 1];
7776
9218
  const wantValues = op !== OP_SEQV;
7777
- for (let i = 1; i < n; i++) {
7778
- if (code[code[base + i]] === OP_ADJ) {
7779
- throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
7780
- }
7781
- }
7782
- const fn = fused ? fnRef(code[ip + 1]) : void 0;
9219
+ const reducer = fused ? code[ip + 1] : -1;
9220
+ const projection = reducer < 0 ? ~reducer : -1;
9221
+ const fn = fused && projection < 0 ? fnRef(reducer) : void 0;
7783
9222
  const kids = [];
7784
- for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
9223
+ for (let i = 0; i < n; i++) {
9224
+ const childIp = code[base + i];
9225
+ kids.push(code[childIp] === OP_ADJ ? "" : link(childIp));
9226
+ }
7785
9227
  const sy = REC2 ? `${tmp()}sy` : "";
7786
9228
  const pub = (i) => {
7787
9229
  const s = sentRef(code[base + n + i]);
@@ -7795,7 +9237,7 @@ return v
7795
9237
  }` : `${parts.join("\n")}
7796
9238
  }`;
7797
9239
  if (n === 1) {
7798
- parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
9240
+ parts.push(fused ? projection === 0 ? "return v0" : `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
7799
9241
  return close();
7800
9242
  }
7801
9243
  parts.push("let cur=EC.e");
@@ -7804,11 +9246,21 @@ return v
7804
9246
  const vn = `v${i}`;
7805
9247
  parts.push(`let ${vn}`);
7806
9248
  if (REC2) parts.push(pub(i));
7807
- parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
9249
+ const childIp = code[base + i];
9250
+ if (code[childIp] === OP_ADJ) {
9251
+ const negated = code[childIp + 1] === 1;
9252
+ const ki = code[childIp + 2];
9253
+ const kinds = ki < 0 ? "undefined" : `K[${ki}]`;
9254
+ const expected = fxRef(code[childIp + 3]);
9255
+ parts.push(
9256
+ `if(!adjacencyHolds(input,cur,ctx,${negated ? "true" : "false"},${kinds})){ctx._fe=cur;ctx._fx=${expected};return FAIL}`,
9257
+ `${vn}=null`
9258
+ );
9259
+ } else parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
7808
9260
  names.push(vn);
7809
9261
  }
7810
9262
  parts.push("EC.e=cur");
7811
- parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
9263
+ parts.push(fused ? projection >= 0 ? `return ${names[projection]}` : `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
7812
9264
  return close();
7813
9265
  }
7814
9266
  case OP_CHOICE: {
@@ -7818,11 +9270,6 @@ return v
7818
9270
  const base = ip + 4;
7819
9271
  const arms = [];
7820
9272
  for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
7821
- const axi = armExpected.push(
7822
- Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
7823
- ) - 1;
7824
- armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
7825
- const afx = hoist("afx", `AFX[${axi}]`);
7826
9273
  if (table.exclusive) {
7827
9274
  const di = code[ip + 1];
7828
9275
  const asc = hoist("as", `DISP[${di}].ascii`);
@@ -7849,53 +9296,65 @@ ctx._fe=pos;ctx._fx=${choiceFx}
7849
9296
  return FAIL
7850
9297
  }`;
7851
9298
  }
7852
- const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
7853
- classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
7854
- const gates = classes[ci];
7855
- const gRef = hoist("g", `CLS[${ci}]`);
7856
- const maskable = n <= 32;
7857
- let maskName = "";
7858
- if (maskable) {
7859
- maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
7860
- maskPlan.push(ci);
7861
- }
7862
- const p = tmp();
7863
- const maskArms = arms.map((a, i) => `
7864
- if((bits&${1 << i})!==0){
9299
+ {
9300
+ const di = code[ip + 1];
9301
+ const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
9302
+ const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
9303
+ const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
9304
+ const maskable = n <= 32;
9305
+ const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
9306
+ if (maskable) maskPlan.push(~di);
9307
+ const p = tmp();
9308
+ const catchName = maskable ? `_cx${uid++}_` : "";
9309
+ if (maskable) {
9310
+ const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
9311
+ choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
9312
+ ${catchCases}
9313
+ }return acc}`);
9314
+ }
9315
+ const maskArms = maskable ? arms.map((arm, i) => {
9316
+ return `if((bits&${1 << i})!==0){
7865
9317
  ctx._fc=false
7866
- {const v=${a}(input,pos,ctx)
9318
+ {const v=${arm}(input,pos,ctx)
7867
9319
  if(v!==FAIL)return v}
7868
- for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
9320
+ if(best===pos)acc=${catchName}(${i},prev,acc)
7869
9321
  prev=${i + 1}
7870
- acc=_accSet(ctx._fx,acc)
9322
+ {const at=ctx._fe??pos
9323
+ if(at>best){best=at;acc=undefined}
9324
+ if(at===best)acc=_accSet(ctx._fx,acc)}
7871
9325
  if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
7872
9326
  ${emitRollback(p, L.buf, sinks)}
7873
- }`).join("");
7874
- const generalArms = arms.map((a, i) => `
7875
- if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
9327
+ }`;
9328
+ }).join("\n") : "";
9329
+ const generalArms = arms.map((arm, i) => `if(${gateRefs[i]}===null||classHas(${gateRefs[i]},c)){
7876
9330
  ctx._fc=false
7877
- {const v=${a}(input,pos,ctx)
9331
+ {const v=${arm}(input,pos,ctx)
7878
9332
  if(v!==FAIL)return v}
7879
- acc=_accSet(ctx._fx,acc)
9333
+ {const at=ctx._fe??pos
9334
+ if(at>best){best=at;acc=undefined}
9335
+ if(at===best)acc=_accSet(ctx._fx,acc)}
7880
9336
  if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
7881
9337
  ${emitRollback(p, L.buf, sinks)}
7882
- }else acc=_accSet(${afx}[${i}],acc)`).join("");
7883
- return `${head}
9338
+ }else if(best===pos)acc=_accSet(${expected[i]},acc)`).join("\n");
9339
+ return `${head}
7884
9340
  const c=lead(input,pos)
7885
9341
  ${emitMark(p, L.buf, sinks)}
7886
9342
  let acc
9343
+ let best=pos
7887
9344
  ${maskable ? `if(c<128){
7888
9345
  const bits=${maskName}[c<0?128:c]
7889
9346
  let prev=0
7890
9347
  ${maskArms}
7891
- for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
9348
+ if(best===pos)acc=${catchName}(${n},prev,acc)
7892
9349
  ctx._fe=pos;ctx._fx=acc??${choiceFx}
7893
9350
  return FAIL
7894
9351
  }
7895
- ` : ""}${generalArms}
9352
+ ` : ""}
9353
+ ${generalArms}
7896
9354
  ctx._fe=pos;ctx._fx=acc??${choiceFx}
7897
9355
  return FAIL
7898
9356
  }`;
9357
+ }
7899
9358
  }
7900
9359
  case OP_DISPATCH: {
7901
9360
  const di = code[ip + 2];
@@ -7921,8 +9380,16 @@ return FAIL
7921
9380
  return `asciiFoldKey(key).startsWith(${q(m[1])})`;
7922
9381
  case 4:
7923
9382
  return `asciiFoldKey(key).endsWith(${q(m[1])})`;
7924
- default:
9383
+ default: {
9384
+ if (!m[2].includes("g") && !m[2].includes("y")) {
9385
+ try {
9386
+ new RegExp(m[1], m[2]);
9387
+ return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
9388
+ } catch {
9389
+ }
9390
+ }
7925
9391
  return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
9392
+ }
7926
9393
  }
7927
9394
  };
7928
9395
  const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
@@ -7980,6 +9447,15 @@ return [key,v]
7980
9447
  const reportItem = (flags & 4) !== 0;
7981
9448
  const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
7982
9449
  const collect = op === OP_REP;
9450
+ let itemCls;
9451
+ if (!REC2) {
9452
+ const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
9453
+ if (itemClassIndex >= 0) {
9454
+ const ci = classes.push([t.cc[itemClassIndex]]) - 1;
9455
+ classPlan.push([itemClassIndex]);
9456
+ itemCls = hoist("ri", `CLS[${ci}][0]`);
9457
+ }
9458
+ }
7983
9459
  const skipBeforeFirst = sepIp < 0 && min === 0;
7984
9460
  const p = tmp();
7985
9461
  const via = sep2 !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
@@ -7987,7 +9463,6 @@ return [key,v]
7987
9463
  const skip = skipFor(L);
7988
9464
  const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
7989
9465
  const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
7990
- const needMark = L.buf ? "true" : "needMark";
7991
9466
  const pfd = sinks.fd ? `${p}fd` : "0";
7992
9467
  const per = sinks.er ? `${p}er` : "undefined";
7993
9468
  const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
@@ -8032,11 +9507,13 @@ continue
8032
9507
  return `${head}
8033
9508
  const out=${collect ? "[]" : "undefined"}
8034
9509
  ${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC2 ? `const ${my}=ctx._sync
8035
- ` : ""}let cur=pos
9510
+ ` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
9511
+ `}let cur=pos
8036
9512
  let count=0
8037
9513
  for(;;){
8038
9514
  ${max >= 0 ? `if(count>=${max})break
8039
9515
  ` : ""}${sep2 !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
9516
+ ` : ""}${itemCls !== void 0 && sep2 === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&!classHas(${itemCls},lead(input,cur)))break
8040
9517
  ` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
8041
9518
  ${markBody}
8042
9519
  let itemStart=cur
@@ -8061,7 +9538,11 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
8061
9538
  ${rb}
8062
9539
  ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
8063
9540
  }
8064
- ctx._fc=false
9541
+ ${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&!classHas(${itemCls},lead(input,itemStart))){
9542
+ ${rb}
9543
+ ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
9544
+ }
9545
+ `}ctx._fc=false
8065
9546
  const v=${child}(input,itemStart,ctx)
8066
9547
  if(v===FAIL){
8067
9548
  ${REC2 ? `if(ctx._fc===true){
@@ -8090,6 +9571,26 @@ return out
8090
9571
  case OP_NODE:
8091
9572
  case OP_NODE_TRACK: {
8092
9573
  const flags = code[ip + 3];
9574
+ const scalarChild = scalarTerminalNodeChild(code, ip);
9575
+ if (scalarChild >= 0 && scalarSpecs.has(code[scalarChild + 1])) {
9576
+ const recognize = recognizerRef(code[scalarChild + 1]);
9577
+ const spec = code[scalarChild] === OP_RX ? null : k[code[scalarChild + 1]];
9578
+ const value2 = spec === null ? "input.slice(pos,end)" : q(spec);
9579
+ const xf = fxRef(code[scalarChild + 2]);
9580
+ const build2 = fnRef(code[ip + 1]);
9581
+ return `${head}
9582
+ const end=${recognize}(input,pos)
9583
+ if(end<0){ctx._fe=pos;ctx._fx=${xf};return FAIL}
9584
+ const value=${value2}
9585
+ const leaf={_tag:'leaf',value,span:{start:pos,end}}
9586
+ const kids=[leaf],rawKids=[leaf],span={start:pos,end}
9587
+ EC.e=end
9588
+ const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
9589
+ ${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
9590
+ EC.e=end
9591
+ return nd
9592
+ }`;
9593
+ }
8093
9594
  const child = link(code[ip + 2]);
8094
9595
  const proj = code[ip + 4];
8095
9596
  const buildIdx = code[ip + 1];
@@ -8104,6 +9605,51 @@ return out
8104
9605
  const unwrap = (flags & 64) !== 0;
8105
9606
  const trailingTrivia = (flags & 128) !== 0;
8106
9607
  const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
9608
+ if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
9609
+ const fields = flags === 18;
9610
+ const collapseChildren = flags === 34;
9611
+ const publish = `if(sBuf!==undefined){
9612
+ if(sBuf.rawOnly!==true){
9613
+ if(sBuf.ch!==undefined)sBuf.ch.push(nd)
9614
+ else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
9615
+ else sBuf.single=nd
9616
+ }
9617
+ const rawNd=rawEntry(nd,input,pos,end)
9618
+ if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
9619
+ else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
9620
+ else sBuf.rawSingle=rawNd
9621
+ }else if(sCh!==undefined){
9622
+ sCh.push(nd)
9623
+ if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
9624
+ }`;
9625
+ return `${head}
9626
+ const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
9627
+ const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
9628
+ const flat=[]
9629
+ ctx._cstBuf=undefined
9630
+ ctx._cstChildren=flat
9631
+ ctx._cstLeaves=flat
9632
+ ctx._cstRawChildren=undefined
9633
+ ctx._cstTriviaLog=undefined
9634
+ ctx.captureTrivia=false
9635
+ ctx._fields=${fields ? "[]" : "undefined"}
9636
+ const v=${child}(input,pos,ctx)
9637
+ const captured=_capturedFlatChildren(flat)
9638
+ ${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
9639
+ ctx._cstBuf=sBuf
9640
+ ctx._cstChildren=sCh
9641
+ ctx._cstLeaves=sLv
9642
+ ctx._cstRawChildren=sRaw
9643
+ ctx._cstTriviaLog=sTl
9644
+ ctx.captureTrivia=sCap
9645
+ if(v===FAIL)return FAIL
9646
+ const end=EC.e
9647
+ ${collapseChildren ? `const nd=captured.length===1?captured[0]:${build}(captured,undefined,{start:pos,end},EMPTY_CH,EMPTY_TL,undefined)` : `const nd=${build}(captured,${fields ? "fieldMap" : "undefined"},{start:pos,end},EMPTY_CH,EMPTY_TL,undefined)`}
9648
+ ${publish}
9649
+ EC.e=end
9650
+ return nd
9651
+ }`;
9652
+ }
8107
9653
  const structural = build === void 0 && proj < 0;
8108
9654
  const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
8109
9655
  const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
@@ -8189,6 +9735,7 @@ return nd
8189
9735
  const source = `${RUNTIME_PRELUDE}
8190
9736
  ${prelude.join("\n")}
8191
9737
  ${skipDefs.join("\n")}
9738
+ ${choiceDefs.join("\n")}
8192
9739
  ${bodies.join("\n")}
8193
9740
  function _begin(ctx){
8194
9741
  const host=ctx.build
@@ -8416,7 +9963,7 @@ function reachableIps(prog) {
8416
9963
 
8417
9964
  // src/table/stamp.ts
8418
9965
  var EMPTY_FX = [];
8419
- function committed(c) {
9966
+ function committed2(c) {
8420
9967
  return c._fc === true;
8421
9968
  }
8422
9969
  function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(prog)) {
@@ -8466,7 +10013,7 @@ function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(pr
8466
10013
  const fe = ctx._fe;
8467
10014
  const at = fe === void 0 || fe < 0 ? pos : fe;
8468
10015
  const fspan = lines ? spanLines(ctx, at, at) : { start: at, end: at };
8469
- return committed(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
10016
+ return committed2(ctx) ? { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan, committed: true } : { ok: false, expected: ctx._fx ?? EMPTY_FX, span: fspan };
8470
10017
  }
8471
10018
  return { ok: true, value: d.lastValue(), span: lines ? spanLines(ctx, pos, end) : { start: pos, end } };
8472
10019
  };
@@ -8512,11 +10059,15 @@ function linkMatcher(m) {
8512
10059
  return (key) => asciiFoldKey(key).startsWith(value);
8513
10060
  case 4:
8514
10061
  return (key) => asciiFoldKey(key).endsWith(value);
8515
- // A fresh RegExp per test, as `matchesDispatchMatcher` builds — a cached one
8516
- // would carry `lastIndex` across parses whenever the author's pattern was
8517
- // sticky or global.
8518
10062
  default: {
8519
10063
  const flags = m[2];
10064
+ if (!flags.includes("g") && !flags.includes("y")) {
10065
+ try {
10066
+ const pattern = new RegExp(value, flags);
10067
+ return (key) => pattern.test(key);
10068
+ } catch {
10069
+ }
10070
+ }
8520
10071
  return (key) => new RegExp(value, flags).test(key);
8521
10072
  }
8522
10073
  }
@@ -8547,6 +10098,17 @@ function assemble(t, prog, cfg) {
8547
10098
  return made;
8548
10099
  }
8549
10100
  const EC = newEndCell();
10101
+ const scalarRecognizers = [];
10102
+ const rawScalarSpecs = /* @__PURE__ */ new Set();
10103
+ function scalarFor(child) {
10104
+ const spec = code[child + 1];
10105
+ let recognize = scalarRecognizers[spec];
10106
+ if (recognize === void 0) {
10107
+ recognize = makeScalarRecognizer(code[child], k[spec]);
10108
+ scalarRecognizers[spec] = recognize;
10109
+ }
10110
+ return recognize;
10111
+ }
8550
10112
  let SCAN = null;
8551
10113
  const memo = /* @__PURE__ */ new Map();
8552
10114
  const reached = /* @__PURE__ */ new Set();
@@ -8554,26 +10116,254 @@ function assemble(t, prog, cfg) {
8554
10116
  const lf = { _tag: "leaf", value, span: { start: s, end: e } };
8555
10117
  pushCstLeaf(ctx, lf);
8556
10118
  }
8557
- function rollbackNeeded(ctx) {
8558
- return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0;
10119
+ function plainBuildNode(child, build) {
10120
+ return (input, pos, ctx) => {
10121
+ const sCh = ctx._cstChildren;
10122
+ const sLv = ctx._cstLeaves;
10123
+ const sRaw = ctx._cstRawChildren;
10124
+ const sTl = ctx._cstTriviaLog;
10125
+ const sCap = ctx.captureTrivia;
10126
+ const sBuf = ctx._cstBuf;
10127
+ const savedFields = ctx._fields;
10128
+ const buf = {};
10129
+ ctx._cstBuf = buf;
10130
+ ctx._cstChildren = void 0;
10131
+ ctx._cstLeaves = void 0;
10132
+ ctx._cstRawChildren = void 0;
10133
+ ctx._cstTriviaLog = void 0;
10134
+ ctx.captureTrivia = false;
10135
+ ctx._fields = void 0;
10136
+ const value = child(input, pos, ctx);
10137
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10138
+ const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
10139
+ ctx._fields = savedFields;
10140
+ ctx._cstBuf = sBuf;
10141
+ ctx._cstChildren = sCh;
10142
+ ctx._cstLeaves = sLv;
10143
+ ctx._cstRawChildren = sRaw;
10144
+ ctx._cstTriviaLog = sTl;
10145
+ ctx.captureTrivia = sCap;
10146
+ if (value === FAIL) return FAIL;
10147
+ const end = EC.e;
10148
+ const span = { start: pos, end };
10149
+ const node2 = build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
10150
+ if (sBuf !== void 0 || sCh !== void 0) {
10151
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10152
+ }
10153
+ EC.e = end;
10154
+ return node2;
10155
+ };
8559
10156
  }
8560
- let MRAW = 0;
8561
- let MTL = 0;
8562
- let MLV = 0;
8563
- function markCst(ctx) {
8564
- const b = ctx._cstBuf;
8565
- if (b !== void 0) {
8566
- const raw = b.raw;
8567
- MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
8568
- const ch2 = b.ch;
8569
- MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
8570
- const tl = b.tl;
8571
- MTL = tl !== void 0 ? tl.length : 0;
8572
- return true;
8573
- }
8574
- if (ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0) {
8575
- MRAW = ctx._cstRawChildren?.length ?? 0;
8576
- MTL = ctx._cstTriviaLog?.length ?? 0;
10157
+ function capturedFlatChildren(children2) {
10158
+ if (children2.length === 0) return EMPTY_CH;
10159
+ if (children2[0] !== void 0) return children2;
10160
+ let first = 1;
10161
+ while (first < children2.length && children2[first] === void 0) first++;
10162
+ return first === children2.length ? EMPTY_CH : children2.slice(first);
10163
+ }
10164
+ function childrenOnlyBuildNode(child, build) {
10165
+ return (input, pos, ctx) => {
10166
+ const sCh = ctx._cstChildren;
10167
+ const sLv = ctx._cstLeaves;
10168
+ const sRaw = ctx._cstRawChildren;
10169
+ const sTl = ctx._cstTriviaLog;
10170
+ const sCap = ctx.captureTrivia;
10171
+ const sBuf = ctx._cstBuf;
10172
+ const savedFields = ctx._fields;
10173
+ const kids = [];
10174
+ ctx._cstBuf = void 0;
10175
+ ctx._cstChildren = kids;
10176
+ ctx._cstLeaves = kids;
10177
+ ctx._cstRawChildren = void 0;
10178
+ ctx._cstTriviaLog = void 0;
10179
+ ctx.captureTrivia = false;
10180
+ ctx._fields = void 0;
10181
+ const value = child(input, pos, ctx);
10182
+ const captured = capturedFlatChildren(kids);
10183
+ ctx._fields = savedFields;
10184
+ ctx._cstBuf = sBuf;
10185
+ ctx._cstChildren = sCh;
10186
+ ctx._cstLeaves = sLv;
10187
+ ctx._cstRawChildren = sRaw;
10188
+ ctx._cstTriviaLog = sTl;
10189
+ ctx.captureTrivia = sCap;
10190
+ if (value === FAIL) return FAIL;
10191
+ const end = EC.e;
10192
+ const node2 = build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10193
+ if (sBuf !== void 0 || sCh !== void 0) {
10194
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10195
+ }
10196
+ EC.e = end;
10197
+ return node2;
10198
+ };
10199
+ }
10200
+ function childrenOnlyFieldsBuildNode(child, build) {
10201
+ return (input, pos, ctx) => {
10202
+ const sCh = ctx._cstChildren;
10203
+ const sLv = ctx._cstLeaves;
10204
+ const sRaw = ctx._cstRawChildren;
10205
+ const sTl = ctx._cstTriviaLog;
10206
+ const sCap = ctx.captureTrivia;
10207
+ const sBuf = ctx._cstBuf;
10208
+ const savedFields = ctx._fields;
10209
+ const kids = [];
10210
+ ctx._cstBuf = void 0;
10211
+ ctx._cstChildren = kids;
10212
+ ctx._cstLeaves = kids;
10213
+ ctx._cstRawChildren = void 0;
10214
+ ctx._cstTriviaLog = void 0;
10215
+ ctx.captureTrivia = false;
10216
+ ctx._fields = [];
10217
+ const value = child(input, pos, ctx);
10218
+ const captured = capturedFlatChildren(kids);
10219
+ const fieldMap = buildFieldMap(ctx._fields);
10220
+ ctx._fields = savedFields;
10221
+ ctx._cstBuf = sBuf;
10222
+ ctx._cstChildren = sCh;
10223
+ ctx._cstLeaves = sLv;
10224
+ ctx._cstRawChildren = sRaw;
10225
+ ctx._cstTriviaLog = sTl;
10226
+ ctx.captureTrivia = sCap;
10227
+ if (value === FAIL) return FAIL;
10228
+ const end = EC.e;
10229
+ const node2 = build(captured, fieldMap, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10230
+ if (sBuf !== void 0 || sCh !== void 0) {
10231
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10232
+ }
10233
+ EC.e = end;
10234
+ return node2;
10235
+ };
10236
+ }
10237
+ function collapseBuildNode(child, build) {
10238
+ return (input, pos, ctx) => {
10239
+ const sCh = ctx._cstChildren;
10240
+ const sLv = ctx._cstLeaves;
10241
+ const sRaw = ctx._cstRawChildren;
10242
+ const sTl = ctx._cstTriviaLog;
10243
+ const sCap = ctx.captureTrivia;
10244
+ const sBuf = ctx._cstBuf;
10245
+ const savedFields = ctx._fields;
10246
+ const buf = {};
10247
+ ctx._cstBuf = buf;
10248
+ ctx._cstChildren = void 0;
10249
+ ctx._cstLeaves = void 0;
10250
+ ctx._cstRawChildren = void 0;
10251
+ ctx._cstTriviaLog = void 0;
10252
+ ctx.captureTrivia = false;
10253
+ ctx._fields = void 0;
10254
+ const value = child(input, pos, ctx);
10255
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10256
+ const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
10257
+ ctx._fields = savedFields;
10258
+ ctx._cstBuf = sBuf;
10259
+ ctx._cstChildren = sCh;
10260
+ ctx._cstLeaves = sLv;
10261
+ ctx._cstRawChildren = sRaw;
10262
+ ctx._cstTriviaLog = sTl;
10263
+ ctx.captureTrivia = sCap;
10264
+ if (value === FAIL) return FAIL;
10265
+ const end = EC.e;
10266
+ const span = { start: pos, end };
10267
+ const node2 = kids.length === 1 ? kids[0] : build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
10268
+ if (sBuf !== void 0 || sCh !== void 0) {
10269
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10270
+ }
10271
+ EC.e = end;
10272
+ return node2;
10273
+ };
10274
+ }
10275
+ function childrenOnlyCollapseBuildNode(child, build) {
10276
+ return (input, pos, ctx) => {
10277
+ const sCh = ctx._cstChildren;
10278
+ const sLv = ctx._cstLeaves;
10279
+ const sRaw = ctx._cstRawChildren;
10280
+ const sTl = ctx._cstTriviaLog;
10281
+ const sCap = ctx.captureTrivia;
10282
+ const sBuf = ctx._cstBuf;
10283
+ const savedFields = ctx._fields;
10284
+ const kids = [];
10285
+ ctx._cstBuf = void 0;
10286
+ ctx._cstChildren = kids;
10287
+ ctx._cstLeaves = kids;
10288
+ ctx._cstRawChildren = void 0;
10289
+ ctx._cstTriviaLog = void 0;
10290
+ ctx.captureTrivia = false;
10291
+ ctx._fields = void 0;
10292
+ const value = child(input, pos, ctx);
10293
+ const captured = capturedFlatChildren(kids);
10294
+ ctx._fields = savedFields;
10295
+ ctx._cstBuf = sBuf;
10296
+ ctx._cstChildren = sCh;
10297
+ ctx._cstLeaves = sLv;
10298
+ ctx._cstRawChildren = sRaw;
10299
+ ctx._cstTriviaLog = sTl;
10300
+ ctx.captureTrivia = sCap;
10301
+ if (value === FAIL) return FAIL;
10302
+ const end = EC.e;
10303
+ const node2 = captured.length === 1 ? captured[0] : build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
10304
+ if (sBuf !== void 0 || sCh !== void 0) {
10305
+ pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
10306
+ }
10307
+ EC.e = end;
10308
+ return node2;
10309
+ };
10310
+ }
10311
+ function plainProjectNode(child, projection, type) {
10312
+ return (input, pos, ctx) => {
10313
+ const sCh = ctx._cstChildren;
10314
+ const sLv = ctx._cstLeaves;
10315
+ const sRaw = ctx._cstRawChildren;
10316
+ const sTl = ctx._cstTriviaLog;
10317
+ const sCap = ctx.captureTrivia;
10318
+ const sBuf = ctx._cstBuf;
10319
+ const savedFields = ctx._fields;
10320
+ const buf = {};
10321
+ ctx._cstBuf = buf;
10322
+ ctx._cstChildren = void 0;
10323
+ ctx._cstLeaves = void 0;
10324
+ ctx._cstRawChildren = void 0;
10325
+ ctx._cstTriviaLog = void 0;
10326
+ ctx.captureTrivia = false;
10327
+ ctx._fields = void 0;
10328
+ const value = child(input, pos, ctx);
10329
+ const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
10330
+ ctx._fields = savedFields;
10331
+ ctx._cstBuf = sBuf;
10332
+ ctx._cstChildren = sCh;
10333
+ ctx._cstLeaves = sLv;
10334
+ ctx._cstRawChildren = sRaw;
10335
+ ctx._cstTriviaLog = sTl;
10336
+ ctx.captureTrivia = sCap;
10337
+ if (value === FAIL) return FAIL;
10338
+ const end = EC.e;
10339
+ const node2 = projectChild(kids, projection, type);
10340
+ if (sBuf !== void 0 || sCh !== void 0) {
10341
+ pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
10342
+ }
10343
+ EC.e = end;
10344
+ return node2;
10345
+ };
10346
+ }
10347
+ function rollbackNeeded(ctx) {
10348
+ return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0;
10349
+ }
10350
+ let MRAW = 0;
10351
+ let MTL = 0;
10352
+ let MLV = 0;
10353
+ function markCst(ctx) {
10354
+ const b = ctx._cstBuf;
10355
+ if (b !== void 0) {
10356
+ const raw = b.raw;
10357
+ MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
10358
+ const ch2 = b.ch;
10359
+ MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
10360
+ const tl = b.tl;
10361
+ MTL = tl !== void 0 ? tl.length : 0;
10362
+ return true;
10363
+ }
10364
+ if (ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0) {
10365
+ MRAW = ctx._cstRawChildren?.length ?? 0;
10366
+ MTL = ctx._cstTriviaLog?.length ?? 0;
8577
10367
  MLV = ctx._cstLeaves?.length ?? 0;
8578
10368
  return true;
8579
10369
  }
@@ -8610,9 +10400,7 @@ function assemble(t, prog, cfg) {
8610
10400
  }
8611
10401
  if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
8612
10402
  if (needsDeferredTriviaCommit(ctx)) {
8613
- const scan = scanTrivia(input, cur, ctx);
8614
- scan.commit();
8615
- return scan.end;
10403
+ return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
8616
10404
  }
8617
10405
  return advanceTrivia(input, cur, ctx);
8618
10406
  }
@@ -8650,7 +10438,7 @@ function assemble(t, prog, cfg) {
8650
10438
  if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
8651
10439
  return cur;
8652
10440
  }
8653
- function committed2(c) {
10441
+ function committed3(c) {
8654
10442
  return c._fc === true;
8655
10443
  }
8656
10444
  function accSet(ax, acc) {
@@ -8659,6 +10447,247 @@ function assemble(t, prog, cfg) {
8659
10447
  for (const s of ax) acc.push(s);
8660
10448
  return acc;
8661
10449
  }
10450
+ const NEVER_PIECE = () => FAIL;
10451
+ const NEVER_CLASS = { ascii: new Uint8Array(128), hi: [] };
10452
+ const EMPTY_EXPECTED_PREFIX = (_target, _prev, acc) => acc;
10453
+ function expectedBlock(start, e0, e1, e2, e3, prior) {
10454
+ return (target, prev, acc) => {
10455
+ if (prev < start) {
10456
+ acc = prior(start, prev, acc);
10457
+ prev = start;
10458
+ }
10459
+ if (target > start && prev < start + 1) acc = accSet(e0, acc);
10460
+ if (target > start + 1 && prev < start + 2) acc = accSet(e1, acc);
10461
+ if (target > start + 2 && prev < start + 3) acc = accSet(e2, acc);
10462
+ if (target > start + 3 && prev < start + 4) acc = accSet(e3, acc);
10463
+ return acc;
10464
+ };
10465
+ }
10466
+ function maskedChoiceBlock(start, a0, a1, a2, a3, through, next, total, choiceFx) {
10467
+ return (input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
10468
+ if ((bits & 1 << start) !== 0) {
10469
+ ctx._fc = false;
10470
+ const v = a0(input, pos, ctx);
10471
+ if (v !== FAIL) return v;
10472
+ if (best === pos) acc = through(start, prev, acc);
10473
+ prev = start + 1;
10474
+ const at = ctx._fe ?? pos;
10475
+ if (at > best) {
10476
+ best = at;
10477
+ acc = void 0;
10478
+ }
10479
+ if (at === best) acc = accSet(ctx._fx, acc);
10480
+ if (committed3(ctx)) {
10481
+ if (acc !== void 0) ctx._fx = acc;
10482
+ return FAIL;
10483
+ }
10484
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10485
+ }
10486
+ if ((bits & 1 << start + 1) !== 0) {
10487
+ ctx._fc = false;
10488
+ const v = a1(input, pos, ctx);
10489
+ if (v !== FAIL) return v;
10490
+ if (best === pos) acc = through(start + 1, prev, acc);
10491
+ prev = start + 2;
10492
+ const at = ctx._fe ?? pos;
10493
+ if (at > best) {
10494
+ best = at;
10495
+ acc = void 0;
10496
+ }
10497
+ if (at === best) acc = accSet(ctx._fx, acc);
10498
+ if (committed3(ctx)) {
10499
+ if (acc !== void 0) ctx._fx = acc;
10500
+ return FAIL;
10501
+ }
10502
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10503
+ }
10504
+ if ((bits & 1 << start + 2) !== 0) {
10505
+ ctx._fc = false;
10506
+ const v = a2(input, pos, ctx);
10507
+ if (v !== FAIL) return v;
10508
+ if (best === pos) acc = through(start + 2, prev, acc);
10509
+ prev = start + 3;
10510
+ const at = ctx._fe ?? pos;
10511
+ if (at > best) {
10512
+ best = at;
10513
+ acc = void 0;
10514
+ }
10515
+ if (at === best) acc = accSet(ctx._fx, acc);
10516
+ if (committed3(ctx)) {
10517
+ if (acc !== void 0) ctx._fx = acc;
10518
+ return FAIL;
10519
+ }
10520
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10521
+ }
10522
+ if ((bits & 1 << start + 3) !== 0) {
10523
+ ctx._fc = false;
10524
+ const v = a3(input, pos, ctx);
10525
+ if (v !== FAIL) return v;
10526
+ if (best === pos) acc = through(start + 3, prev, acc);
10527
+ prev = start + 4;
10528
+ const at = ctx._fe ?? pos;
10529
+ if (at > best) {
10530
+ best = at;
10531
+ acc = void 0;
10532
+ }
10533
+ if (at === best) acc = accSet(ctx._fx, acc);
10534
+ if (committed3(ctx)) {
10535
+ if (acc !== void 0) ctx._fx = acc;
10536
+ return FAIL;
10537
+ }
10538
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10539
+ }
10540
+ if (next !== void 0) {
10541
+ return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
10542
+ }
10543
+ if (best === pos) acc = through(total, prev, acc);
10544
+ ctx._fe = pos;
10545
+ ctx._fx = acc ?? choiceFx;
10546
+ return FAIL;
10547
+ };
10548
+ }
10549
+ function generalChoiceBlock(start, a0, a1, a2, a3, g0, g1, g2, g3, through, next, total, choiceFx) {
10550
+ return (input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best) => {
10551
+ if (g0 === null || classHas2(g0, c)) {
10552
+ ctx._fc = false;
10553
+ const v = a0(input, pos, ctx);
10554
+ if (v !== FAIL) return v;
10555
+ if (best === pos) acc = through(start, prev, acc);
10556
+ prev = start + 1;
10557
+ const at = ctx._fe ?? pos;
10558
+ if (at > best) {
10559
+ best = at;
10560
+ acc = void 0;
10561
+ }
10562
+ if (at === best) acc = accSet(ctx._fx, acc);
10563
+ if (committed3(ctx)) {
10564
+ if (acc !== void 0) ctx._fx = acc;
10565
+ return FAIL;
10566
+ }
10567
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10568
+ }
10569
+ if (g1 === null || classHas2(g1, c)) {
10570
+ ctx._fc = false;
10571
+ const v = a1(input, pos, ctx);
10572
+ if (v !== FAIL) return v;
10573
+ if (best === pos) acc = through(start + 1, prev, acc);
10574
+ prev = start + 2;
10575
+ const at = ctx._fe ?? pos;
10576
+ if (at > best) {
10577
+ best = at;
10578
+ acc = void 0;
10579
+ }
10580
+ if (at === best) acc = accSet(ctx._fx, acc);
10581
+ if (committed3(ctx)) {
10582
+ if (acc !== void 0) ctx._fx = acc;
10583
+ return FAIL;
10584
+ }
10585
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10586
+ }
10587
+ if (g2 === null || classHas2(g2, c)) {
10588
+ ctx._fc = false;
10589
+ const v = a2(input, pos, ctx);
10590
+ if (v !== FAIL) return v;
10591
+ if (best === pos) acc = through(start + 2, prev, acc);
10592
+ prev = start + 3;
10593
+ const at = ctx._fe ?? pos;
10594
+ if (at > best) {
10595
+ best = at;
10596
+ acc = void 0;
10597
+ }
10598
+ if (at === best) acc = accSet(ctx._fx, acc);
10599
+ if (committed3(ctx)) {
10600
+ if (acc !== void 0) ctx._fx = acc;
10601
+ return FAIL;
10602
+ }
10603
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10604
+ }
10605
+ if (g3 === null || classHas2(g3, c)) {
10606
+ ctx._fc = false;
10607
+ const v = a3(input, pos, ctx);
10608
+ if (v !== FAIL) return v;
10609
+ if (best === pos) acc = through(start + 3, prev, acc);
10610
+ prev = start + 4;
10611
+ const at = ctx._fe ?? pos;
10612
+ if (at > best) {
10613
+ best = at;
10614
+ acc = void 0;
10615
+ }
10616
+ if (at === best) acc = accSet(ctx._fx, acc);
10617
+ if (committed3(ctx)) {
10618
+ if (acc !== void 0) ctx._fx = acc;
10619
+ return FAIL;
10620
+ }
10621
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
10622
+ }
10623
+ if (next !== void 0) {
10624
+ return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
10625
+ }
10626
+ if (best === pos) acc = through(total, prev, acc);
10627
+ ctx._fe = pos;
10628
+ ctx._fx = acc ?? choiceFx;
10629
+ return FAIL;
10630
+ };
10631
+ }
10632
+ function exclusiveChoiceBlock(start, a0, a1, a2, a3, next) {
10633
+ return (arm, input, pos, ctx) => {
10634
+ if (arm === start) return a0(input, pos, ctx);
10635
+ if (arm === start + 1) return a1(input, pos, ctx);
10636
+ if (arm === start + 2) return a2(input, pos, ctx);
10637
+ if (arm === start + 3) return a3(input, pos, ctx);
10638
+ return next === void 0 ? FAIL : next(arm, input, pos, ctx);
10639
+ };
10640
+ }
10641
+ function dispatchMatcherBlock(m0, a0, m1, a1, m2, a2, m3, a3, next) {
10642
+ return (key) => {
10643
+ if (m0(key)) return a0;
10644
+ if (m1(key)) return a1;
10645
+ if (m2(key)) return a2;
10646
+ if (m3(key)) return a3;
10647
+ return next?.(key);
10648
+ };
10649
+ }
10650
+ function dispatchBranch(child, usesRouted) {
10651
+ if (!usesRouted) {
10652
+ return (input, _pos, selEnd, key, _selectorMark, ctx) => {
10653
+ const mark = saveTriviaMark(ctx);
10654
+ const v = child(input, selEnd, ctx);
10655
+ if (v === FAIL) {
10656
+ rollbackTrivia(ctx, mark);
10657
+ ctx._fc = true;
10658
+ return FAIL;
10659
+ }
10660
+ return [key, v];
10661
+ };
10662
+ }
10663
+ return (input, pos, selEnd, key, selectorMark, ctx) => {
10664
+ const savedRouted = ctx._routed;
10665
+ rollbackTrivia(ctx, selectorMark);
10666
+ const mark = saveTriviaMark(ctx);
10667
+ ctx._routed = { value: key, span: { start: pos, end: selEnd } };
10668
+ let v;
10669
+ try {
10670
+ v = child(input, pos, ctx);
10671
+ } finally {
10672
+ ctx._routed = savedRouted;
10673
+ }
10674
+ if (v === FAIL) {
10675
+ rollbackTrivia(ctx, mark);
10676
+ ctx._fc = true;
10677
+ return FAIL;
10678
+ }
10679
+ return [key, v];
10680
+ };
10681
+ }
10682
+ function dispatchArmBlock(start, a0, a1, a2, a3, next) {
10683
+ return (arm, input, pos, selEnd, key, selectorMark, ctx) => {
10684
+ if (arm === start) return a0(input, pos, selEnd, key, selectorMark, ctx);
10685
+ if (arm === start + 1) return a1(input, pos, selEnd, key, selectorMark, ctx);
10686
+ if (arm === start + 2) return a2(input, pos, selEnd, key, selectorMark, ctx);
10687
+ if (arm === start + 3) return a3(input, pos, selEnd, key, selectorMark, ctx);
10688
+ return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, selectorMark, ctx);
10689
+ };
10690
+ }
8662
10691
  function trackLinesInto(ctx, input, end) {
8663
10692
  const from = ctx._lineScannedTo ?? 0;
8664
10693
  if (end <= from) return;
@@ -8694,6 +10723,21 @@ function assemble(t, prog, cfg) {
8694
10723
  const s = k[code[ip + 1]];
8695
10724
  const len = s.length;
8696
10725
  const xf = fx[code[ip + 2]];
10726
+ const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
10727
+ if (shared !== void 0) {
10728
+ return (input, pos, ctx) => {
10729
+ const e = shared(input, pos);
10730
+ if (e >= 0) {
10731
+ if (cstCaptureActive(ctx)) pushLeaf(ctx, s, pos, e);
10732
+ EC.e = e;
10733
+ return s;
10734
+ }
10735
+ ctx._fe = pos;
10736
+ ctx._fx = xf;
10737
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
10738
+ return FAIL;
10739
+ };
10740
+ }
8697
10741
  if (len === 1) {
8698
10742
  const c0 = s.charCodeAt(0);
8699
10743
  return (input, pos, ctx) => {
@@ -8821,6 +10865,22 @@ function assemble(t, prog, cfg) {
8821
10865
  case OP_RX: {
8822
10866
  const re = k[code[ip + 1]];
8823
10867
  const xf = fx[code[ip + 2]];
10868
+ const shared = rawScalarSpecs.has(code[ip + 1]) ? scalarFor(ip) : void 0;
10869
+ if (shared !== void 0) {
10870
+ return (input, pos, ctx) => {
10871
+ const e = shared(input, pos);
10872
+ if (e >= 0) {
10873
+ const v = input.slice(pos, e);
10874
+ if (cstCaptureActive(ctx)) pushLeaf(ctx, v, pos, e);
10875
+ EC.e = e;
10876
+ return v;
10877
+ }
10878
+ ctx._fe = pos;
10879
+ ctx._fx = xf;
10880
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
10881
+ return FAIL;
10882
+ };
10883
+ }
8824
10884
  return (input, pos, ctx) => {
8825
10885
  re.lastIndex = pos;
8826
10886
  if (re.test(input)) {
@@ -8930,7 +10990,7 @@ function assemble(t, prog, cfg) {
8930
10990
  const child = link(code[ip + 2]);
8931
10991
  if (cfg.tolerant || cfg.probe) return child;
8932
10992
  return (input, pos, ctx) => {
8933
- if (!classHas(cls, lead(input, pos))) {
10993
+ if (!classHas2(cls, lead(input, pos))) {
8934
10994
  ctx._fe = pos;
8935
10995
  ctx._fx = xf;
8936
10996
  return FAIL;
@@ -9129,13 +11189,28 @@ function assemble(t, prog, cfg) {
9129
11189
  const v = child(input, pos, ctx);
9130
11190
  if (v !== FAIL) return v;
9131
11191
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9132
- if (committed2(ctx)) return FAIL;
11192
+ if (committed3(ctx)) return FAIL;
9133
11193
  ctx._fe = pos;
9134
11194
  return FAIL;
9135
11195
  };
9136
11196
  }
9137
11197
  /* ── zero-width ──────────────────────────────────────────────────────── */
9138
11198
  case OP_NOT: {
11199
+ const scalarChild = scalarTerminalNotChild(code, ip);
11200
+ if (scalarChild >= 0) {
11201
+ const recognize = scalarFor(scalarChild);
11202
+ const xf2 = fx[code[ip + 2]];
11203
+ return (input, pos, ctx) => {
11204
+ if (recognize(input, pos) < 0) {
11205
+ EC.e = pos;
11206
+ return null;
11207
+ }
11208
+ ctx._fe = pos;
11209
+ ctx._fx = xf2;
11210
+ EC.e = pos;
11211
+ return FAIL;
11212
+ };
11213
+ }
9139
11214
  const child = link(code[ip + 1]);
9140
11215
  const xf = fx[code[ip + 2]];
9141
11216
  return (input, pos, ctx) => {
@@ -9195,7 +11270,7 @@ function assemble(t, prog, cfg) {
9195
11270
  ctx._fc = false;
9196
11271
  const v = child(input, pos, ctx);
9197
11272
  if (v === FAIL) {
9198
- if (committed2(ctx)) return FAIL;
11273
+ if (committed3(ctx)) return FAIL;
9199
11274
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9200
11275
  EC.e = pos;
9201
11276
  return null;
@@ -9246,6 +11321,92 @@ function assemble(t, prog, cfg) {
9246
11321
  return value;
9247
11322
  };
9248
11323
  }
11324
+ case OP_LEX_BODY: {
11325
+ const recognize = t.lex[code[ip + 1]];
11326
+ const expected = fx[code[ip + 2]];
11327
+ return (input, pos, ctx) => {
11328
+ const recognized = recognize(input, pos);
11329
+ if (recognized < 0) {
11330
+ ctx._fe = pos;
11331
+ ctx._fx = expected;
11332
+ if (ctx._probe !== void 0) failAt(ctx, expected, pos);
11333
+ return FAIL;
11334
+ }
11335
+ const lineFlags = code[ip + 4];
11336
+ const hasSuffix = (lineFlags & 4) !== 0;
11337
+ const suffixMatched = hasSuffix && recognized % 2 === 1;
11338
+ const end = (recognized - (suffixMatched ? 1 : 0)) / 2;
11339
+ if ((lineFlags & 1) !== 0) {
11340
+ trackLinesInto(ctx, input, suffixMatched ? end - 1 : end);
11341
+ }
11342
+ if (hasSuffix) ctx._fc = false;
11343
+ if (hasSuffix && suffixMatched && (lineFlags & 2) !== 0) {
11344
+ trackLinesInto(ctx, input, end);
11345
+ }
11346
+ if (hasSuffix && !suffixMatched) {
11347
+ const suffixExpected = fx[code[ip + 3]];
11348
+ ctx._fe = end;
11349
+ ctx._fx = suffixExpected;
11350
+ if (ctx._probe !== void 0) failAt(ctx, suffixExpected, end);
11351
+ }
11352
+ const value = input.slice(pos, end);
11353
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11354
+ EC.e = end;
11355
+ return value;
11356
+ };
11357
+ }
11358
+ case OP_LEX_PROGRAM: {
11359
+ const run3 = t.lexPrograms[code[ip + 1]];
11360
+ const scanId = run3.scan;
11361
+ if (scanId !== void 0) {
11362
+ return (input, pos, ctx) => {
11363
+ const sTrivia = ctx.trivia, sKinds = ctx.triviaKindLabels;
11364
+ const sBuf = ctx._cstBuf, sChildren = ctx._cstChildren, sLeaves = ctx._cstLeaves;
11365
+ const sRaw = ctx._cstRawChildren, sTl = ctx._cstTriviaLog;
11366
+ const sOuterTl = ctx._triviaLog, sRootTl = ctx._rootTriviaLog;
11367
+ const wasCapturing = cstCaptureActive(ctx);
11368
+ const sScan = SCAN;
11369
+ SCAN = null;
11370
+ ctx.trivia = void 0;
11371
+ ctx.triviaKindLabels = void 0;
11372
+ ctx._cstBuf = void 0;
11373
+ ctx._cstChildren = void 0;
11374
+ ctx._cstLeaves = void 0;
11375
+ ctx._cstRawChildren = void 0;
11376
+ ctx._cstTriviaLog = void 0;
11377
+ ctx._triviaLog = void 0;
11378
+ ctx._rootTriviaLog = void 0;
11379
+ let end;
11380
+ try {
11381
+ end = run3(input, pos, ctx, scans[scanId]);
11382
+ } finally {
11383
+ SCAN = sScan;
11384
+ ctx.trivia = sTrivia;
11385
+ ctx.triviaKindLabels = sKinds;
11386
+ ctx._cstBuf = sBuf;
11387
+ ctx._cstChildren = sChildren;
11388
+ ctx._cstLeaves = sLeaves;
11389
+ ctx._cstRawChildren = sRaw;
11390
+ ctx._cstTriviaLog = sTl;
11391
+ ctx._triviaLog = sOuterTl;
11392
+ ctx._rootTriviaLog = sRootTl;
11393
+ }
11394
+ if (end < 0) return FAIL;
11395
+ const value = input.slice(pos, end);
11396
+ if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11397
+ EC.e = end;
11398
+ return value;
11399
+ };
11400
+ }
11401
+ return (input, pos, ctx) => {
11402
+ const end = run3(input, pos, ctx);
11403
+ if (end < 0) return FAIL;
11404
+ const value = input.slice(pos, end);
11405
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
11406
+ EC.e = end;
11407
+ return value;
11408
+ };
11409
+ }
9249
11410
  case OP_LEAF: {
9250
11411
  const fn = fns[code[ip + 1]];
9251
11412
  const child = link(code[ip + 2]);
@@ -9286,38 +11447,73 @@ function assemble(t, prog, cfg) {
9286
11447
  const fused = op === OP_SEQX;
9287
11448
  const base = fused ? ip + 3 : ip + 2;
9288
11449
  const n = code[fused ? ip + 2 : ip + 1];
9289
- const kids = new Array(n);
9290
- for (let i = 0; i < n; i++) kids[i] = link(code[base + i]);
9291
11450
  const wantValues = op !== OP_SEQV;
9292
- const fn = fused ? fns[code[ip + 1]] : void 0;
9293
- const runTerms = (input, pos, ctx, values) => {
9294
- const v0 = kids[0](input, pos, ctx);
9295
- if (v0 === FAIL) return -1;
9296
- if (values !== void 0) values.push(v0);
9297
- let cur = EC.e;
9298
- for (let i = 1; i < n; i++) {
9299
- cur = nextTerm(kids[i], input, cur, ctx);
11451
+ const reducer = fused ? code[ip + 1] : -1;
11452
+ const projection = reducer < 0 ? ~reducer : -1;
11453
+ const fn = fused && projection < 0 ? fns[reducer] : void 0;
11454
+ const runnerBlock = (count, r0, r1, r2, r3, next) => {
11455
+ if (count === 1) return (input, cur, ctx, values, inherited) => {
11456
+ cur = r0(input, cur, ctx, inherited);
9300
11457
  if (cur < 0) return -1;
9301
11458
  if (values !== void 0) values.push(TERMV);
9302
- }
9303
- return cur;
11459
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11460
+ };
11461
+ if (count === 2) return (input, cur, ctx, values, inherited) => {
11462
+ cur = r0(input, cur, ctx, inherited);
11463
+ if (cur < 0) return -1;
11464
+ if (values !== void 0) values.push(TERMV);
11465
+ cur = r1(input, cur, ctx, inherited);
11466
+ if (cur < 0) return -1;
11467
+ if (values !== void 0) values.push(TERMV);
11468
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11469
+ };
11470
+ if (count === 3) return (input, cur, ctx, values, inherited) => {
11471
+ cur = r0(input, cur, ctx, inherited);
11472
+ if (cur < 0) return -1;
11473
+ if (values !== void 0) values.push(TERMV);
11474
+ cur = r1(input, cur, ctx, inherited);
11475
+ if (cur < 0) return -1;
11476
+ if (values !== void 0) values.push(TERMV);
11477
+ cur = r2(input, cur, ctx, inherited);
11478
+ if (cur < 0) return -1;
11479
+ if (values !== void 0) values.push(TERMV);
11480
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11481
+ };
11482
+ return (input, cur, ctx, values, inherited) => {
11483
+ cur = r0(input, cur, ctx, inherited);
11484
+ if (cur < 0) return -1;
11485
+ if (values !== void 0) values.push(TERMV);
11486
+ cur = r1(input, cur, ctx, inherited);
11487
+ if (cur < 0) return -1;
11488
+ if (values !== void 0) values.push(TERMV);
11489
+ cur = r2(input, cur, ctx, inherited);
11490
+ if (cur < 0) return -1;
11491
+ if (values !== void 0) values.push(TERMV);
11492
+ cur = r3(input, cur, ctx, inherited);
11493
+ if (cur < 0) return -1;
11494
+ if (values !== void 0) values.push(TERMV);
11495
+ return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
11496
+ };
9304
11497
  };
9305
11498
  if (REC2) {
9306
- const syncs = new Array(n);
9307
- for (let i = 0; i < n; i++) syncs[i] = sentinelFor(code[base + n + i]);
9308
- const runners = new Array(n);
9309
- for (let i = 1; i < n; i++) {
11499
+ const first2 = link(code[base]);
11500
+ const firstSync = sentinelFor(code[base + n]);
11501
+ const runnerAt = (i) => {
11502
+ const sync = sentinelFor(code[base + n + i]);
9310
11503
  const kidIp = code[base + i];
9311
11504
  if (code[kidIp] !== OP_ADJ) {
9312
- const kid = kids[i];
9313
- runners[i] = (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9314
- continue;
11505
+ const kid = link(kidIp);
11506
+ return (input, cur, ctx, inherited) => {
11507
+ ctx._sync = sync ?? inherited;
11508
+ return nextTerm(kid, input, cur, ctx);
11509
+ };
9315
11510
  }
9316
11511
  const negated = code[kidIp + 1] === 1;
9317
11512
  const ki = code[kidIp + 2];
9318
11513
  const kinds = ki < 0 ? void 0 : k[ki];
9319
11514
  const xf = fx[code[kidIp + 3]];
9320
- runners[i] = (input, cur, ctx) => {
11515
+ return (input, cur, ctx, inherited) => {
11516
+ ctx._sync = sync ?? inherited;
9321
11517
  if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
9322
11518
  ctx._fe = cur;
9323
11519
  ctx._fx = xf;
@@ -9326,25 +11522,34 @@ function assemble(t, prog, cfg) {
9326
11522
  TERMV = null;
9327
11523
  return cur;
9328
11524
  };
9329
- }
11525
+ };
11526
+ const bindRunners = (start) => {
11527
+ const count = Math.min(4, n - start);
11528
+ const at = (offset) => runnerAt(start + offset);
11529
+ const never = () => -1;
11530
+ return runnerBlock(
11531
+ count,
11532
+ at(0),
11533
+ count > 1 ? at(1) : never,
11534
+ count > 2 ? at(2) : never,
11535
+ count > 3 ? at(3) : never,
11536
+ start + count < n ? bindRunners(start + count) : void 0
11537
+ );
11538
+ };
11539
+ const tail2 = n > 1 ? bindRunners(1) : void 0;
9330
11540
  const runSyncTerms = (input, pos, ctx, values) => {
9331
11541
  const inherited = ctx._sync;
9332
- ctx._sync = syncs[0] ?? inherited;
9333
- const v0 = kids[0](input, pos, ctx);
11542
+ ctx._sync = firstSync ?? inherited;
11543
+ const v0 = first2(input, pos, ctx);
9334
11544
  if (v0 === FAIL) {
9335
11545
  ctx._sync = inherited;
9336
11546
  return -1;
9337
11547
  }
9338
11548
  if (values !== void 0) values.push(v0);
9339
- let cur = EC.e;
9340
- for (let i = 1; i < n; i++) {
9341
- ctx._sync = syncs[i] ?? inherited;
9342
- cur = runners[i](input, cur, ctx);
9343
- if (cur < 0) {
9344
- ctx._sync = inherited;
9345
- return -1;
9346
- }
9347
- if (values !== void 0) values.push(TERMV);
11549
+ const cur = tail2 === void 0 ? EC.e : tail2(input, EC.e, ctx, values, inherited);
11550
+ if (cur < 0) {
11551
+ ctx._sync = inherited;
11552
+ return -1;
9348
11553
  }
9349
11554
  ctx._sync = inherited;
9350
11555
  return cur;
@@ -9355,7 +11560,7 @@ function assemble(t, prog, cfg) {
9355
11560
  const cur = runSyncTerms(input, pos, ctx, values);
9356
11561
  if (cur < 0) return FAIL;
9357
11562
  EC.e = cur;
9358
- return fn(values, { start: pos, end: cur });
11563
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9359
11564
  };
9360
11565
  }
9361
11566
  if (wantValues) {
@@ -9380,19 +11585,18 @@ function assemble(t, prog, cfg) {
9380
11585
  break;
9381
11586
  }
9382
11587
  if (hasAdj) {
9383
- const runners = new Array(n);
9384
- for (let i = 1; i < n; i++) {
11588
+ const first2 = link(code[base]);
11589
+ const runnerAt = (i) => {
9385
11590
  const kidIp = code[base + i];
9386
11591
  if (code[kidIp] !== OP_ADJ) {
9387
- const kid = kids[i];
9388
- runners[i] = (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9389
- continue;
11592
+ const kid = link(kidIp);
11593
+ return (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
9390
11594
  }
9391
11595
  const negated = code[kidIp + 1] === 1;
9392
11596
  const ki = code[kidIp + 2];
9393
11597
  const kinds = ki < 0 ? void 0 : k[ki];
9394
11598
  const xf = fx[code[kidIp + 3]];
9395
- runners[i] = (input, cur, ctx) => {
11599
+ return (input, cur, ctx) => {
9396
11600
  if (!adjacencyHolds(input, cur, ctx, negated, kinds)) {
9397
11601
  ctx._fe = cur;
9398
11602
  ctx._fx = xf;
@@ -9401,18 +11605,26 @@ function assemble(t, prog, cfg) {
9401
11605
  TERMV = null;
9402
11606
  return cur;
9403
11607
  };
9404
- }
11608
+ };
11609
+ const bindRunners = (start) => {
11610
+ const count = Math.min(4, n - start);
11611
+ const at = (offset) => runnerAt(start + offset);
11612
+ const never = () => -1;
11613
+ return runnerBlock(
11614
+ count,
11615
+ at(0),
11616
+ count > 1 ? at(1) : never,
11617
+ count > 2 ? at(2) : never,
11618
+ count > 3 ? at(3) : never,
11619
+ start + count < n ? bindRunners(start + count) : void 0
11620
+ );
11621
+ };
11622
+ const tail2 = bindRunners(1);
9405
11623
  const runAdjTerms = (input, pos, ctx, values) => {
9406
- const v0 = kids[0](input, pos, ctx);
11624
+ const v0 = first2(input, pos, ctx);
9407
11625
  if (v0 === FAIL) return -1;
9408
11626
  if (values !== void 0) values.push(v0);
9409
- let cur = EC.e;
9410
- for (let i = 1; i < n; i++) {
9411
- cur = runners[i](input, cur, ctx);
9412
- if (cur < 0) return -1;
9413
- if (values !== void 0) values.push(TERMV);
9414
- }
9415
- return cur;
11627
+ return tail2(input, EC.e, ctx, values);
9416
11628
  };
9417
11629
  if (fused) {
9418
11630
  return (input, pos, ctx) => {
@@ -9420,7 +11632,7 @@ function assemble(t, prog, cfg) {
9420
11632
  const cur = runAdjTerms(input, pos, ctx, values);
9421
11633
  if (cur < 0) return FAIL;
9422
11634
  EC.e = cur;
9423
- return fn(values, { start: pos, end: cur });
11635
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9424
11636
  };
9425
11637
  }
9426
11638
  if (wantValues) {
@@ -9440,12 +11652,12 @@ function assemble(t, prog, cfg) {
9440
11652
  };
9441
11653
  }
9442
11654
  if (n === 1) {
9443
- const k0 = kids[0];
11655
+ const k0 = link(code[base]);
9444
11656
  if (fused) {
9445
11657
  return (input, pos, ctx) => {
9446
11658
  const v = k0(input, pos, ctx);
9447
11659
  if (v === FAIL) return FAIL;
9448
- return fn([v], { start: pos, end: EC.e });
11660
+ return projection === 0 ? v : fn([v], { start: pos, end: EC.e });
9449
11661
  };
9450
11662
  }
9451
11663
  if (wantValues) {
@@ -9462,7 +11674,7 @@ function assemble(t, prog, cfg) {
9462
11674
  };
9463
11675
  }
9464
11676
  if (n === 2) {
9465
- const k0 = kids[0], k1 = kids[1];
11677
+ const k0 = link(code[base]), k1 = link(code[base + 1]);
9466
11678
  if (fused) {
9467
11679
  return (input, pos, ctx) => {
9468
11680
  const v0 = k0(input, pos, ctx);
@@ -9470,7 +11682,7 @@ function assemble(t, prog, cfg) {
9470
11682
  const cur = nextTerm(k1, input, EC.e, ctx);
9471
11683
  if (cur < 0) return FAIL;
9472
11684
  EC.e = cur;
9473
- return fn([v0, TERMV], { start: pos, end: cur });
11685
+ return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
9474
11686
  };
9475
11687
  }
9476
11688
  if (wantValues) {
@@ -9493,7 +11705,7 @@ function assemble(t, prog, cfg) {
9493
11705
  };
9494
11706
  }
9495
11707
  if (n === 3) {
9496
- const k0 = kids[0], k1 = kids[1], k2 = kids[2];
11708
+ const k0 = link(code[base]), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
9497
11709
  if (fused) {
9498
11710
  return (input, pos, ctx) => {
9499
11711
  const v0 = k0(input, pos, ctx);
@@ -9504,7 +11716,7 @@ function assemble(t, prog, cfg) {
9504
11716
  cur = nextTerm(k2, input, cur, ctx);
9505
11717
  if (cur < 0) return FAIL;
9506
11718
  EC.e = cur;
9507
- return fn([v0, v1, TERMV], { start: pos, end: cur });
11719
+ return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
9508
11720
  };
9509
11721
  }
9510
11722
  if (wantValues) {
@@ -9531,26 +11743,90 @@ function assemble(t, prog, cfg) {
9531
11743
  return void 0;
9532
11744
  };
9533
11745
  }
11746
+ const block = (count, k0, k1, k2, k3, next) => {
11747
+ if (count === 1) return (input, cur, ctx, values) => {
11748
+ cur = nextTerm(k0, input, cur, ctx);
11749
+ if (cur < 0) return -1;
11750
+ if (values !== void 0) values.push(TERMV);
11751
+ return next === void 0 ? cur : next(input, cur, ctx, values);
11752
+ };
11753
+ if (count === 2) return (input, cur, ctx, values) => {
11754
+ cur = nextTerm(k0, input, cur, ctx);
11755
+ if (cur < 0) return -1;
11756
+ if (values !== void 0) values.push(TERMV);
11757
+ cur = nextTerm(k1, input, cur, ctx);
11758
+ if (cur < 0) return -1;
11759
+ if (values !== void 0) values.push(TERMV);
11760
+ return next === void 0 ? cur : next(input, cur, ctx, values);
11761
+ };
11762
+ if (count === 3) return (input, cur, ctx, values) => {
11763
+ cur = nextTerm(k0, input, cur, ctx);
11764
+ if (cur < 0) return -1;
11765
+ if (values !== void 0) values.push(TERMV);
11766
+ cur = nextTerm(k1, input, cur, ctx);
11767
+ if (cur < 0) return -1;
11768
+ if (values !== void 0) values.push(TERMV);
11769
+ cur = nextTerm(k2, input, cur, ctx);
11770
+ if (cur < 0) return -1;
11771
+ if (values !== void 0) values.push(TERMV);
11772
+ return next === void 0 ? cur : next(input, cur, ctx, values);
11773
+ };
11774
+ return (input, cur, ctx, values) => {
11775
+ cur = nextTerm(k0, input, cur, ctx);
11776
+ if (cur < 0) return -1;
11777
+ if (values !== void 0) values.push(TERMV);
11778
+ cur = nextTerm(k1, input, cur, ctx);
11779
+ if (cur < 0) return -1;
11780
+ if (values !== void 0) values.push(TERMV);
11781
+ cur = nextTerm(k2, input, cur, ctx);
11782
+ if (cur < 0) return -1;
11783
+ if (values !== void 0) values.push(TERMV);
11784
+ cur = nextTerm(k3, input, cur, ctx);
11785
+ if (cur < 0) return -1;
11786
+ if (values !== void 0) values.push(TERMV);
11787
+ return next === void 0 ? cur : next(input, cur, ctx, values);
11788
+ };
11789
+ };
11790
+ const bind = (start) => {
11791
+ const count = Math.min(4, n - start);
11792
+ const child = (offset) => link(code[base + start + offset]);
11793
+ return block(
11794
+ count,
11795
+ child(0),
11796
+ count > 1 ? child(1) : NEVER_PIECE,
11797
+ count > 2 ? child(2) : NEVER_PIECE,
11798
+ count > 3 ? child(3) : NEVER_PIECE,
11799
+ start + count < n ? bind(start + count) : void 0
11800
+ );
11801
+ };
11802
+ const first = link(code[base]);
11803
+ const tail = bind(1);
11804
+ const runDirectTerms = (input, pos, ctx, values) => {
11805
+ const v0 = first(input, pos, ctx);
11806
+ if (v0 === FAIL) return -1;
11807
+ if (values !== void 0) values.push(v0);
11808
+ return tail(input, EC.e, ctx, values);
11809
+ };
9534
11810
  if (fused) {
9535
11811
  return (input, pos, ctx) => {
9536
11812
  const values = [];
9537
- const cur = runTerms(input, pos, ctx, values);
11813
+ const cur = runDirectTerms(input, pos, ctx, values);
9538
11814
  if (cur < 0) return FAIL;
9539
11815
  EC.e = cur;
9540
- return fn(values, { start: pos, end: cur });
11816
+ return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
9541
11817
  };
9542
11818
  }
9543
11819
  if (wantValues) {
9544
11820
  return (input, pos, ctx) => {
9545
11821
  const values = [];
9546
- const cur = runTerms(input, pos, ctx, values);
11822
+ const cur = runDirectTerms(input, pos, ctx, values);
9547
11823
  if (cur < 0) return FAIL;
9548
11824
  EC.e = cur;
9549
11825
  return values;
9550
11826
  };
9551
11827
  }
9552
11828
  return (input, pos, ctx) => {
9553
- const cur = runTerms(input, pos, ctx, void 0);
11829
+ const cur = runDirectTerms(input, pos, ctx, void 0);
9554
11830
  if (cur < 0) return FAIL;
9555
11831
  EC.e = cur;
9556
11832
  return void 0;
@@ -9562,13 +11838,86 @@ function assemble(t, prog, cfg) {
9562
11838
  const n = code[ip + 2];
9563
11839
  const choiceFx = fx[code[ip + 3]];
9564
11840
  const base = ip + 4;
9565
- const arms = new Array(n);
9566
- for (let i = 0; i < n; i++) arms[i] = link(code[base + i]);
9567
- const armFx = new Array(n);
9568
- for (let i = 0; i < n; i++) armFx[i] = fx[code[base + n + i]];
9569
11841
  if (table.exclusive) {
9570
11842
  const ascii = table.ascii;
9571
11843
  const hi = table.hi;
11844
+ if (n === 2) {
11845
+ const a0 = link(code[base]), a1 = link(code[base + 1]);
11846
+ return (input, pos, ctx) => {
11847
+ const c = lead(input, pos);
11848
+ let arm = -1;
11849
+ if (c >= 0 && c < 128) {
11850
+ const a = ascii[c];
11851
+ if (a !== 0) arm = a - 1;
11852
+ } else if (c >= 128) {
11853
+ for (let i = 0; i < hi.length; i += 3) {
11854
+ if (c >= hi[i] && c <= hi[i + 1]) {
11855
+ arm = hi[i + 2];
11856
+ break;
11857
+ }
11858
+ }
11859
+ }
11860
+ if (arm >= 0) {
11861
+ ctx._fc = false;
11862
+ const v = arm === 0 ? a0(input, pos, ctx) : a1(input, pos, ctx);
11863
+ if (v !== FAIL) return v;
11864
+ if (committed3(ctx)) return FAIL;
11865
+ const failed = ctx._fx;
11866
+ if (failed !== void 0 && failed.length > 0) {
11867
+ ctx._fe = pos;
11868
+ return FAIL;
11869
+ }
11870
+ }
11871
+ ctx._fe = pos;
11872
+ ctx._fx = choiceFx;
11873
+ return FAIL;
11874
+ };
11875
+ }
11876
+ if (n === 3) {
11877
+ const a0 = link(code[base]), a1 = link(code[base + 1]), a2 = link(code[base + 2]);
11878
+ return (input, pos, ctx) => {
11879
+ const c = lead(input, pos);
11880
+ let arm = -1;
11881
+ if (c >= 0 && c < 128) {
11882
+ const a = ascii[c];
11883
+ if (a !== 0) arm = a - 1;
11884
+ } else if (c >= 128) {
11885
+ for (let i = 0; i < hi.length; i += 3) {
11886
+ if (c >= hi[i] && c <= hi[i + 1]) {
11887
+ arm = hi[i + 2];
11888
+ break;
11889
+ }
11890
+ }
11891
+ }
11892
+ if (arm >= 0) {
11893
+ ctx._fc = false;
11894
+ const v = arm === 0 ? a0(input, pos, ctx) : arm === 1 ? a1(input, pos, ctx) : a2(input, pos, ctx);
11895
+ if (v !== FAIL) return v;
11896
+ if (committed3(ctx)) return FAIL;
11897
+ const failed = ctx._fx;
11898
+ if (failed !== void 0 && failed.length > 0) {
11899
+ ctx._fe = pos;
11900
+ return FAIL;
11901
+ }
11902
+ }
11903
+ ctx._fe = pos;
11904
+ ctx._fx = choiceFx;
11905
+ return FAIL;
11906
+ };
11907
+ }
11908
+ const bindExclusive = (start) => {
11909
+ const at = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
11910
+ const next = start + 4 < n ? bindExclusive(start + 4) : void 0;
11911
+ return exclusiveChoiceBlock(
11912
+ start,
11913
+ at(start),
11914
+ at(start + 1),
11915
+ at(start + 2),
11916
+ at(start + 3),
11917
+ next
11918
+ );
11919
+ };
11920
+ const selected = bindExclusive(0);
9572
11921
  return (input, pos, ctx) => {
9573
11922
  const c = lead(input, pos);
9574
11923
  let arm = -1;
@@ -9585,11 +11934,11 @@ function assemble(t, prog, cfg) {
9585
11934
  }
9586
11935
  if (arm >= 0) {
9587
11936
  ctx._fc = false;
9588
- const v = arms[arm](input, pos, ctx);
11937
+ const v = selected(arm, input, pos, ctx);
9589
11938
  if (v !== FAIL) return v;
9590
- if (committed2(ctx)) return FAIL;
9591
- const armFx2 = ctx._fx;
9592
- if (armFx2 !== void 0 && armFx2.length > 0) {
11939
+ if (committed3(ctx)) return FAIL;
11940
+ const armFx = ctx._fx;
11941
+ if (armFx !== void 0 && armFx.length > 0) {
9593
11942
  ctx._fe = pos;
9594
11943
  return FAIL;
9595
11944
  }
@@ -9600,25 +11949,25 @@ function assemble(t, prog, cfg) {
9600
11949
  };
9601
11950
  }
9602
11951
  const armCls = table.armCls;
9603
- const gates = new Array(n);
9604
- for (let i = 0; i < n; i++) gates[i] = armCls[i] ?? null;
9605
- const maskable = n <= 32;
9606
- let cand;
9607
- if (maskable) {
9608
- const m = new Uint32Array(129);
9609
- for (let i = 0; i < n; i++) {
9610
- const cls = gates[i];
9611
- const bit = 1 << i;
11952
+ if (n === 2 || n === 3) {
11953
+ const a0 = link(code[base]), a1 = link(code[base + 1]);
11954
+ const a2 = n === 3 ? link(code[base + 2]) : void 0;
11955
+ const e0 = fx[code[base + n]];
11956
+ const e1 = fx[code[base + n + 1]];
11957
+ const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
11958
+ const g0 = armCls[0] ?? null, g1 = armCls[1] ?? null;
11959
+ const g2 = n === 3 ? armCls[2] ?? null : null;
11960
+ const mask = new Uint32Array(129);
11961
+ const addGate = (cls, bit) => {
9612
11962
  if (cls === null) {
9613
- for (let c = 0; c < 129; c++) m[c] |= bit;
9614
- continue;
11963
+ for (let c = 0; c < 129; c++) mask[c] |= bit;
11964
+ return;
9615
11965
  }
9616
- for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) m[c] |= bit;
9617
- }
9618
- cand = m;
9619
- }
9620
- if (cand !== void 0) {
9621
- const mask = cand;
11966
+ for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
11967
+ };
11968
+ addGate(g0, 1);
11969
+ addGate(g1, 2);
11970
+ if (n === 3) addGate(g2, 4);
9622
11971
  return (input, pos, ctx) => {
9623
11972
  const c = lead(input, pos);
9624
11973
  const need = markCst(ctx);
@@ -9630,51 +11979,240 @@ function assemble(t, prog, cfg) {
9630
11979
  const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
9631
11980
  const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
9632
11981
  let acc;
11982
+ let best = pos;
9633
11983
  if (c < 128) {
9634
- const bits0 = mask[c < 0 ? 128 : c];
9635
- let bits = bits0;
11984
+ const bits = mask[c < 0 ? 128 : c];
9636
11985
  let prev = 0;
9637
- while (bits !== 0) {
9638
- const i = 31 - Math.clz32(bits & -bits);
9639
- bits &= bits - 1;
11986
+ if ((bits & 1) !== 0) {
11987
+ ctx._fc = false;
11988
+ const v = a0(input, pos, ctx);
11989
+ if (v !== FAIL) return v;
11990
+ prev = 1;
11991
+ const at = ctx._fe ?? pos;
11992
+ if (at > best) {
11993
+ best = at;
11994
+ acc = void 0;
11995
+ }
11996
+ if (at === best) acc = accSet(ctx._fx, acc);
11997
+ if (committed3(ctx)) {
11998
+ if (acc !== void 0) ctx._fx = acc;
11999
+ return FAIL;
12000
+ }
12001
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12002
+ }
12003
+ if ((bits & 2) !== 0) {
9640
12004
  ctx._fc = false;
9641
- const v = arms[i](input, pos, ctx);
12005
+ const v = a1(input, pos, ctx);
9642
12006
  if (v !== FAIL) return v;
9643
- for (let j = prev; j < i; j++) if ((bits0 & 1 << j) === 0) acc = accSet(armFx[j], acc);
9644
- prev = i + 1;
9645
- acc = accSet(ctx._fx, acc);
9646
- if (committed2(ctx)) {
12007
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12008
+ prev = 2;
12009
+ const at = ctx._fe ?? pos;
12010
+ if (at > best) {
12011
+ best = at;
12012
+ acc = void 0;
12013
+ }
12014
+ if (at === best) acc = accSet(ctx._fx, acc);
12015
+ if (committed3(ctx)) {
12016
+ if (acc !== void 0) ctx._fx = acc;
12017
+ return FAIL;
12018
+ }
12019
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12020
+ }
12021
+ if (n === 3 && (bits & 4) !== 0) {
12022
+ ctx._fc = false;
12023
+ const v = a2(input, pos, ctx);
12024
+ if (v !== FAIL) return v;
12025
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12026
+ if (best === pos && prev < 2) acc = accSet(e1, acc);
12027
+ prev = 3;
12028
+ const at = ctx._fe ?? pos;
12029
+ if (at > best) {
12030
+ best = at;
12031
+ acc = void 0;
12032
+ }
12033
+ if (at === best) acc = accSet(ctx._fx, acc);
12034
+ if (committed3(ctx)) {
9647
12035
  if (acc !== void 0) ctx._fx = acc;
9648
12036
  return FAIL;
9649
12037
  }
9650
12038
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9651
12039
  }
9652
- for (let j = prev; j < n; j++) if ((bits0 & 1 << j) === 0) acc = accSet(armFx[j], acc);
12040
+ if (best === pos && prev < 1) acc = accSet(e0, acc);
12041
+ if (best === pos && prev < 2) acc = accSet(e1, acc);
12042
+ if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
9653
12043
  ctx._fe = pos;
9654
12044
  ctx._fx = acc ?? choiceFx;
9655
12045
  return FAIL;
9656
12046
  }
9657
- for (let i = 0; i < n; i++) {
9658
- const cls = gates[i];
9659
- if (cls !== null && !classHas(cls, c)) {
9660
- acc = accSet(armFx[i], acc);
9661
- continue;
12047
+ if (g0 === null || classHas2(g0, c)) {
12048
+ ctx._fc = false;
12049
+ const v = a0(input, pos, ctx);
12050
+ if (v !== FAIL) return v;
12051
+ const at = ctx._fe ?? pos;
12052
+ if (at > best) {
12053
+ best = at;
12054
+ acc = void 0;
12055
+ }
12056
+ if (at === best) acc = accSet(ctx._fx, acc);
12057
+ if (committed3(ctx)) {
12058
+ if (acc !== void 0) ctx._fx = acc;
12059
+ return FAIL;
9662
12060
  }
12061
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12062
+ } else if (best === pos) acc = accSet(e0, acc);
12063
+ if (g1 === null || classHas2(g1, c)) {
9663
12064
  ctx._fc = false;
9664
- const v = arms[i](input, pos, ctx);
12065
+ const v = a1(input, pos, ctx);
9665
12066
  if (v !== FAIL) return v;
9666
- acc = accSet(ctx._fx, acc);
9667
- if (committed2(ctx)) {
12067
+ const at = ctx._fe ?? pos;
12068
+ if (at > best) {
12069
+ best = at;
12070
+ acc = void 0;
12071
+ }
12072
+ if (at === best) acc = accSet(ctx._fx, acc);
12073
+ if (committed3(ctx)) {
9668
12074
  if (acc !== void 0) ctx._fx = acc;
9669
12075
  return FAIL;
9670
12076
  }
9671
12077
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12078
+ } else if (best === pos) acc = accSet(e1, acc);
12079
+ if (n === 3) {
12080
+ if (g2 === null || classHas2(g2, c)) {
12081
+ ctx._fc = false;
12082
+ const v = a2(input, pos, ctx);
12083
+ if (v !== FAIL) return v;
12084
+ const at = ctx._fe ?? pos;
12085
+ if (at > best) {
12086
+ best = at;
12087
+ acc = void 0;
12088
+ }
12089
+ if (at === best) acc = accSet(ctx._fx, acc);
12090
+ if (committed3(ctx)) {
12091
+ if (acc !== void 0) ctx._fx = acc;
12092
+ return FAIL;
12093
+ }
12094
+ if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12095
+ } else if (best === pos) acc = accSet(e2, acc);
9672
12096
  }
9673
12097
  ctx._fe = pos;
9674
12098
  ctx._fx = acc ?? choiceFx;
9675
12099
  return FAIL;
9676
12100
  };
9677
12101
  }
12102
+ const bindGeneral = (start, prior) => {
12103
+ const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
12104
+ const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
12105
+ const gate2 = (i) => i < n ? armCls[i] ?? null : NEVER_CLASS;
12106
+ const through = expectedBlock(
12107
+ start,
12108
+ expected(start),
12109
+ expected(start + 1),
12110
+ expected(start + 2),
12111
+ expected(start + 3),
12112
+ prior
12113
+ );
12114
+ const next = start + 4 < n ? bindGeneral(start + 4, through) : void 0;
12115
+ return generalChoiceBlock(
12116
+ start,
12117
+ arm(start),
12118
+ arm(start + 1),
12119
+ arm(start + 2),
12120
+ arm(start + 3),
12121
+ gate2(start),
12122
+ gate2(start + 1),
12123
+ gate2(start + 2),
12124
+ gate2(start + 3),
12125
+ through,
12126
+ next,
12127
+ n,
12128
+ choiceFx
12129
+ );
12130
+ };
12131
+ const general = bindGeneral(0, EMPTY_EXPECTED_PREFIX);
12132
+ if (n <= 32) {
12133
+ const mask = new Uint32Array(129);
12134
+ for (let i = 0; i < n; i++) {
12135
+ const cls = armCls[i] ?? null;
12136
+ const bit = 1 << i;
12137
+ if (cls === null) {
12138
+ for (let c = 0; c < 129; c++) mask[c] |= bit;
12139
+ continue;
12140
+ }
12141
+ for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) mask[c] |= bit;
12142
+ }
12143
+ const bindMasked = (start, prior) => {
12144
+ const arm = (i) => i < n ? link(code[base + i]) : NEVER_PIECE;
12145
+ const expected = (i) => i < n ? fx[code[base + n + i]] : EMPTY_FX2;
12146
+ const through = expectedBlock(
12147
+ start,
12148
+ expected(start),
12149
+ expected(start + 1),
12150
+ expected(start + 2),
12151
+ expected(start + 3),
12152
+ prior
12153
+ );
12154
+ const next = start + 4 < n ? bindMasked(start + 4, through) : void 0;
12155
+ return maskedChoiceBlock(
12156
+ start,
12157
+ arm(start),
12158
+ arm(start + 1),
12159
+ arm(start + 2),
12160
+ arm(start + 3),
12161
+ through,
12162
+ next,
12163
+ n,
12164
+ choiceFx
12165
+ );
12166
+ };
12167
+ const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
12168
+ return (input, pos, ctx) => {
12169
+ const c = lead(input, pos);
12170
+ const need = markCst(ctx);
12171
+ const mRaw = MRAW;
12172
+ const mTl = MTL;
12173
+ const mLv = MLV;
12174
+ const mFl = need ? ctx._fields?.length ?? 0 : 0;
12175
+ const mEr = need ? ctx._errors?.length ?? 0 : 0;
12176
+ const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
12177
+ const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
12178
+ if (c < 128) {
12179
+ return masked(
12180
+ input,
12181
+ pos,
12182
+ ctx,
12183
+ mask[c < 0 ? 128 : c],
12184
+ need,
12185
+ mRaw,
12186
+ mTl,
12187
+ mLv,
12188
+ mFl,
12189
+ mEr,
12190
+ mLog,
12191
+ mRoot,
12192
+ void 0,
12193
+ 0,
12194
+ pos
12195
+ );
12196
+ }
12197
+ return general(
12198
+ input,
12199
+ pos,
12200
+ ctx,
12201
+ c,
12202
+ need,
12203
+ mRaw,
12204
+ mTl,
12205
+ mLv,
12206
+ mFl,
12207
+ mEr,
12208
+ mLog,
12209
+ mRoot,
12210
+ void 0,
12211
+ 0,
12212
+ pos
12213
+ );
12214
+ };
12215
+ }
9678
12216
  return (input, pos, ctx) => {
9679
12217
  const c = lead(input, pos);
9680
12218
  const need = markCst(ctx);
@@ -9685,26 +12223,23 @@ function assemble(t, prog, cfg) {
9685
12223
  const mEr = need ? ctx._errors?.length ?? 0 : 0;
9686
12224
  const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
9687
12225
  const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
9688
- let acc;
9689
- for (let i = 0; i < n; i++) {
9690
- const cls = gates[i];
9691
- if (cls !== null && !classHas(cls, c)) {
9692
- acc = accSet(armFx[i], acc);
9693
- continue;
9694
- }
9695
- ctx._fc = false;
9696
- const v = arms[i](input, pos, ctx);
9697
- if (v !== FAIL) return v;
9698
- acc = accSet(ctx._fx, acc);
9699
- if (committed2(ctx)) {
9700
- if (acc !== void 0) ctx._fx = acc;
9701
- return FAIL;
9702
- }
9703
- if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9704
- }
9705
- ctx._fe = pos;
9706
- ctx._fx = acc ?? choiceFx;
9707
- return FAIL;
12226
+ return general(
12227
+ input,
12228
+ pos,
12229
+ ctx,
12230
+ c,
12231
+ need,
12232
+ mRaw,
12233
+ mTl,
12234
+ mLv,
12235
+ mFl,
12236
+ mEr,
12237
+ mLog,
12238
+ mRoot,
12239
+ void 0,
12240
+ 0,
12241
+ pos
12242
+ );
9708
12243
  };
9709
12244
  }
9710
12245
  /* ── greedyClassify / autoNot ────────────────────────────────────────── */
@@ -9773,7 +12308,7 @@ function assemble(t, prog, cfg) {
9773
12308
  if (nc !== 0) {
9774
12309
  const c = lead(input, end);
9775
12310
  for (let i = 0; i < nc; i++) {
9776
- if (!classHas(clss[i], c)) continue;
12311
+ if (!classHas2(clss[i], c)) continue;
9777
12312
  ctx._fc = false;
9778
12313
  ctx._fx = void 0;
9779
12314
  return FAIL;
@@ -9797,6 +12332,9 @@ function assemble(t, prog, cfg) {
9797
12332
  const reportItem = (flags & 4) !== 0;
9798
12333
  const itemFx = reportItem ? fx[code[ip + 6]] : EMPTY_FX2;
9799
12334
  const collect = op === OP_REP;
12335
+ const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
12336
+ const itemClass = !REC2 && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
12337
+ const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
9800
12338
  const skipBeforeFirst = sepIp < 0 && min === 0;
9801
12339
  if (REC2) {
9802
12340
  const itemFx2 = fx[code[ip + 6]];
@@ -9830,7 +12368,7 @@ function assemble(t, prog, cfg) {
9830
12368
  const sv = sep2(input, sp, ctx);
9831
12369
  if (sv === FAIL) {
9832
12370
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9833
- if (committed2(ctx)) return FAIL;
12371
+ if (committed3(ctx)) return FAIL;
9834
12372
  break;
9835
12373
  }
9836
12374
  if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
@@ -9847,7 +12385,7 @@ function assemble(t, prog, cfg) {
9847
12385
  ctx._fc = false;
9848
12386
  const v = child(input, itemStart, ctx);
9849
12387
  if (v === FAIL) {
9850
- if (committed2(ctx)) {
12388
+ if (committed3(ctx)) {
9851
12389
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9852
12390
  return FAIL;
9853
12391
  }
@@ -9893,11 +12431,13 @@ function assemble(t, prog, cfg) {
9893
12431
  const out = collect ? [] : void 0;
9894
12432
  const hasTrivia = ctx.trivia !== void 0;
9895
12433
  const needMark = rollbackNeeded(ctx);
12434
+ const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
9896
12435
  let cur = pos;
9897
12436
  let count = 0;
9898
12437
  for (; ; ) {
9899
12438
  if (max >= 0 && count >= max) break;
9900
12439
  if (sep2 !== void 0 && count > 0 && count >= min && cur >= input.length) break;
12440
+ if (count >= min && sep2 === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
9901
12441
  if (needMark) markCst(ctx);
9902
12442
  const mRaw = needMark ? MRAW : 0;
9903
12443
  const mTl = needMark ? MTL : 0;
@@ -9917,7 +12457,7 @@ function assemble(t, prog, cfg) {
9917
12457
  const sv = sep2(input, sp, ctx);
9918
12458
  if (sv === FAIL) {
9919
12459
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9920
- if (committed2(ctx)) return FAIL;
12460
+ if (committed3(ctx)) return FAIL;
9921
12461
  break;
9922
12462
  }
9923
12463
  if (!keepSeparators) demoteCapturedToRaw(ctx, leavesBefore);
@@ -9931,11 +12471,16 @@ function assemble(t, prog, cfg) {
9931
12471
  if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
9932
12472
  break;
9933
12473
  }
12474
+ if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
12475
+ if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12476
+ if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
12477
+ break;
12478
+ }
9934
12479
  ctx._fc = false;
9935
12480
  const v = child(input, itemStart, ctx);
9936
12481
  if (v === FAIL) {
9937
12482
  if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
9938
- if (committed2(ctx)) return FAIL;
12483
+ if (committed3(ctx)) return FAIL;
9939
12484
  if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
9940
12485
  break;
9941
12486
  }
@@ -9967,78 +12512,103 @@ function assemble(t, prog, cfg) {
9967
12512
  const otherRouted = code[ip + 4] === 1;
9968
12513
  const n = code[ip + 5];
9969
12514
  const armBase = ip + 6;
9970
- const arms = new Array(n);
9971
- for (let i = 0; i < n; i++) arms[i] = link(code[armBase + i]);
9972
12515
  const byKey = spec.byKey;
9973
12516
  const byFold = spec.byFold;
9974
12517
  const hasFold = spec.byFold.size > 0;
9975
12518
  const match = spec.match;
9976
12519
  const matchN = match.length;
9977
- const matchFn = new Array(matchN);
9978
- const matchArm = new Array(matchN);
9979
- for (let i = 0; i < matchN; i++) {
9980
- matchFn[i] = linkMatcher(match[i]);
9981
- matchArm[i] = match[i][3];
9982
- }
9983
12520
  const routed2 = spec.routed;
9984
12521
  const expected = spec.expected;
12522
+ const validArm = (arm) => Number.isInteger(arm) && arm >= 0 && arm < n;
12523
+ if (routed2.length !== n) throw new TypeError("table assembler: malformed dispatch routed arity");
12524
+ for (const arm of byKey.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch exact arm");
12525
+ for (const arm of byFold.values()) if (!validArm(arm)) throw new TypeError("table assembler: malformed dispatch folded arm");
12526
+ for (const m of match) if (!validArm(m[3])) throw new TypeError("table assembler: malformed dispatch matcher arm");
12527
+ const neverMatch = () => false;
12528
+ const bindMatchers = (start) => {
12529
+ const pred = (i) => i < matchN ? linkMatcher(match[i]) : neverMatch;
12530
+ const arm = (i) => i < matchN ? match[i][3] : -1;
12531
+ const next = start + 4 < matchN ? bindMatchers(start + 4) : void 0;
12532
+ return dispatchMatcherBlock(
12533
+ pred(start),
12534
+ arm(start),
12535
+ pred(start + 1),
12536
+ arm(start + 1),
12537
+ pred(start + 2),
12538
+ arm(start + 2),
12539
+ pred(start + 3),
12540
+ arm(start + 3),
12541
+ next
12542
+ );
12543
+ };
12544
+ const matchBlock = matchN === 0 ? void 0 : bindMatchers(0);
12545
+ const classify = hasFold ? matchBlock === void 0 ? (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) : (key) => byKey.get(key) ?? byFold.get(asciiFoldKey(key)) ?? matchBlock(key) : matchBlock === void 0 ? (key) => byKey.get(key) : (key) => byKey.get(key) ?? matchBlock(key);
12546
+ const neverBranch = () => FAIL;
12547
+ const bindArms = (start) => {
12548
+ const branch = (i) => i < n ? dispatchBranch(link(code[armBase + i]), routed2[i] === 1) : neverBranch;
12549
+ const next = start + 4 < n ? bindArms(start + 4) : void 0;
12550
+ return dispatchArmBlock(
12551
+ start,
12552
+ branch(start),
12553
+ branch(start + 1),
12554
+ branch(start + 2),
12555
+ branch(start + 3),
12556
+ next
12557
+ );
12558
+ };
12559
+ const runArm = n === 0 ? void 0 : bindArms(0);
12560
+ const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
9985
12561
  return (input, pos, ctx) => {
9986
12562
  const selectorMark = saveTriviaMark(ctx);
9987
12563
  const selVal = selector(input, pos, ctx);
9988
12564
  if (selVal === FAIL) return FAIL;
9989
12565
  const selEnd = EC.e;
9990
12566
  const key = selVal;
9991
- let arm = byKey.get(key);
9992
- if (arm === void 0 && hasFold) arm = byFold.get(asciiFoldKey(key));
9993
- if (arm === void 0) {
9994
- for (let i = 0; i < matchN; i++) {
9995
- if (matchFn[i](key)) {
9996
- arm = matchArm[i];
9997
- break;
9998
- }
9999
- }
10000
- }
10001
- let target;
10002
- let usesRouted;
12567
+ const arm = classify(key);
10003
12568
  if (arm === void 0) {
10004
- if (other === void 0) {
12569
+ if (runOther === void 0) {
10005
12570
  ctx._fe = selEnd;
10006
12571
  ctx._fx = expected;
10007
12572
  return FAIL;
10008
12573
  }
10009
- target = other;
10010
- usesRouted = otherRouted;
10011
- } else {
10012
- target = arms[arm];
10013
- usesRouted = routed2[arm] === 1;
10014
- }
10015
- let mark = saveTriviaMark(ctx);
10016
- let v;
10017
- if (usesRouted) {
10018
- const savedRouted = ctx._routed;
10019
- rollbackTrivia(ctx, selectorMark);
10020
- mark = saveTriviaMark(ctx);
10021
- ctx._routed = { value: key, span: { start: pos, end: selEnd } };
10022
- try {
10023
- v = target(input, pos, ctx);
10024
- } finally {
10025
- ctx._routed = savedRouted;
10026
- }
10027
- } else {
10028
- v = target(input, selEnd, ctx);
10029
- }
10030
- if (v === FAIL) {
10031
- rollbackTrivia(ctx, mark);
10032
- ctx._fc = true;
10033
- return FAIL;
12574
+ return runOther(input, pos, selEnd, key, selectorMark, ctx);
10034
12575
  }
10035
- return [key, v];
12576
+ return runArm(arm, input, pos, selEnd, key, selectorMark, ctx);
10036
12577
  };
10037
12578
  }
10038
12579
  /* ── node ────────────────────────────────────────────────────────────── */
10039
12580
  case OP_NODE:
10040
12581
  case OP_NODE_TRACK: {
10041
12582
  const flags = code[ip + 3];
12583
+ const scalarChild = !hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines ? scalarTerminalNodeChild(code, ip) : -1;
12584
+ if (scalarChild >= 0) {
12585
+ const recognize = scalarFor(scalarChild);
12586
+ const spec = k[code[scalarChild + 1]];
12587
+ const regexValue = code[scalarChild] === OP_RX;
12588
+ const xf = fx[code[scalarChild + 2]];
12589
+ const build2 = fns[code[ip + 1]];
12590
+ return (input, pos, ctx) => {
12591
+ const end = recognize(input, pos);
12592
+ if (end < 0) {
12593
+ ctx._fe = pos;
12594
+ ctx._fx = xf;
12595
+ if (ctx._probe !== void 0) failAt(ctx, xf, pos);
12596
+ return FAIL;
12597
+ }
12598
+ const value = regexValue ? input.slice(pos, end) : spec;
12599
+ const leaf2 = { _tag: "leaf", value, span: { start: pos, end } };
12600
+ const kids = [leaf2];
12601
+ const rawKids = [leaf2];
12602
+ const span = { start: pos, end };
12603
+ EC.e = end;
12604
+ const nd = build2(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
12605
+ if (ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0) {
12606
+ pushCstChild(ctx, nd, ctx._cstRawChildren !== void 0 || ctx._cstBuf !== void 0 ? rawEntry(nd, input, pos, end) : void 0);
12607
+ }
12608
+ EC.e = end;
12609
+ return nd;
12610
+ };
12611
+ }
10042
12612
  const child = link(code[ip + 2]);
10043
12613
  const proj = code[ip + 4];
10044
12614
  const buildIdx = code[ip + 1];
@@ -10053,6 +12623,26 @@ function assemble(t, prog, cfg) {
10053
12623
  const unwrap = (flags & 64) !== 0;
10054
12624
  const trailingTrivia = (flags & 128) !== 0;
10055
12625
  const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
12626
+ if (!hostCst && !tracked) {
12627
+ if (build !== void 0 && proj < 0 && flags === 0) {
12628
+ return plainBuildNode(child, build);
12629
+ }
12630
+ if (build !== void 0 && proj < 0 && flags === 2) {
12631
+ return childrenOnlyBuildNode(child, build);
12632
+ }
12633
+ if (build !== void 0 && proj < 0 && flags === 18) {
12634
+ return childrenOnlyFieldsBuildNode(child, build);
12635
+ }
12636
+ if (build !== void 0 && proj < 0 && flags === 32) {
12637
+ return collapseBuildNode(child, build);
12638
+ }
12639
+ if (build !== void 0 && proj < 0 && flags === 34) {
12640
+ return childrenOnlyCollapseBuildNode(child, build);
12641
+ }
12642
+ if (build === void 0 && proj >= 0 && flags === 0) {
12643
+ return plainProjectNode(child, proj, type);
12644
+ }
12645
+ }
10056
12646
  const structural = build === void 0 && proj < 0;
10057
12647
  const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
10058
12648
  const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
@@ -10172,14 +12762,27 @@ function assemble(t, prog, cfg) {
10172
12762
  if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
10173
12763
  }
10174
12764
  for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
10175
- const validationRoots = [...Object.values(prog.rules), ...extraIps];
10176
- for (const ip of reachableSites(code, validationRoots)) {
10177
- if (code[ip] !== OP_DISPATCH) continue;
10178
- validateDispatchSpec(dsp[code[ip + 2]], code[ip + 5], code[ip + 4]);
12765
+ const roots = [...Object.values(prog.rules), ...extraIps];
12766
+ for (const ip of reachableSites(code, roots)) {
12767
+ if (code[ip] === OP_DISPATCH) {
12768
+ const spec = dsp[code[ip + 2]];
12769
+ validateDispatchSpec(spec, code[ip + 5], code[ip + 4]);
12770
+ }
12771
+ if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
12772
+ if (code[ip] === OP_NODE) {
12773
+ const child = scalarTerminalNodeChild(code, ip);
12774
+ if (child >= 0) {
12775
+ rawScalarSpecs.add(code[child + 1]);
12776
+ scalarFor(child);
12777
+ }
12778
+ }
12779
+ }
12780
+ const notChild = scalarTerminalNotChild(code, ip);
12781
+ if (notChild >= 0) scalarFor(notChild);
10179
12782
  }
10180
12783
  const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
10181
12784
  if (pre !== void 0) {
10182
- const pools = rebuildPools(t.cc, t.fx, pre.plan);
12785
+ const pools = rebuildPools(t.cc, t.fx, t.disp, pre.plan);
10183
12786
  emitted = pre.factory(
10184
12787
  EC,
10185
12788
  FAIL,
@@ -10205,7 +12808,7 @@ function assemble(t, prog, cfg) {
10205
12808
  rollbackTriviaAt,
10206
12809
  rollbackScannedTriviaAt,
10207
12810
  failAt,
10208
- classHas,
12811
+ classHas2,
10209
12812
  consumeTrivia,
10210
12813
  buildFieldMap,
10211
12814
  projectChild,
@@ -10226,7 +12829,13 @@ function assemble(t, prog, cfg) {
10226
12829
  matchesAt,
10227
12830
  recoverScan,
10228
12831
  orSentinel,
10229
- captureError
12832
+ captureError,
12833
+ scalarRecognizers,
12834
+ commitTriviaScan,
12835
+ scanTriviaCompact,
12836
+ t.lex,
12837
+ adjacencyHolds,
12838
+ t.lexPrograms
10230
12839
  );
10231
12840
  emitReached = new Set(pre.reached);
10232
12841
  }
@@ -10276,7 +12885,7 @@ function assemble(t, prog, cfg) {
10276
12885
  rollbackTriviaAt,
10277
12886
  rollbackScannedTriviaAt,
10278
12887
  failAt,
10279
- classHas,
12888
+ classHas2,
10280
12889
  consumeTrivia,
10281
12890
  buildFieldMap,
10282
12891
  projectChild,
@@ -10302,7 +12911,13 @@ function assemble(t, prog, cfg) {
10302
12911
  matchesAt,
10303
12912
  recoverScan,
10304
12913
  orSentinel,
10305
- captureError
12914
+ captureError,
12915
+ scalarRecognizers,
12916
+ commitTriviaScan,
12917
+ scanTriviaCompact,
12918
+ t.lex,
12919
+ adjacencyHolds,
12920
+ t.lexPrograms
10306
12921
  );
10307
12922
  emitReached = em.reached;
10308
12923
  } catch (e) {
@@ -10553,6 +13168,17 @@ function emitScanSpec(s) {
10553
13168
  function emitDispatchSpec(d) {
10554
13169
  return `{key:[${d.key.map(jsString).join(",")}],keyArm:[${d.keyArm.join(",")}],fold:[${d.fold.map(jsString).join(",")}],foldArm:[${d.foldArm.join(",")}],match:[${d.match.map((m) => `[${m[0]},${jsString(m[1])},${jsString(m[2])},${m[3]}]`).join(",")}],routed:[${d.routed.join(",")}],expected:[${d.expected.map(jsString).join(",")}]}`;
10555
13170
  }
13171
+ function defaultAssemblyCfgs(prog) {
13172
+ const hostCst = prog.hostMode === "cst";
13173
+ const trackLines = prog.lines === 1;
13174
+ return [false, true].map((tolerant) => ({
13175
+ hostCst,
13176
+ trackLines,
13177
+ tolerant,
13178
+ coverage: false,
13179
+ probe: false
13180
+ }));
13181
+ }
10556
13182
  function emitAssemblies(prog, cfgs) {
10557
13183
  if (cfgs.length === 0) return ["a:[],"];
10558
13184
  const t = resolveTable(prog);
@@ -10605,6 +13231,8 @@ function programFields(prog, fns, opts = {}) {
10605
13231
  // `run({ rootTrivia })` rejected a grammar that plainly has labels — the
10606
13232
  // exact failure the root-trivia work exists to prevent, one hop downstream.
10607
13233
  ...prog.dsp.length === 0 ? [] : [`p:[${prog.dsp.map(emitDispatchSpec).join(",")}],`],
13234
+ ...prog.lex === void 0 ? [] : [`lx:[${prog.lex.map((row) => `[${row.join(",")}]`).join(",")}],`],
13235
+ ...prog.lexPrograms === void 0 ? [] : [`lp:[${prog.lexPrograms.map((row) => `[${row.join(",")}]`).join(",")}],`],
10608
13236
  ...prog.labels === void 0 ? [] : [`lb:[${prog.labels.map(jsString).join(",")}],`],
10609
13237
  ...prog.classified === 1 ? ["rc:1,"] : [],
10610
13238
  // Without this a recovery table's MODULE loads as a strict one: the extra
@@ -12828,6 +15456,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
12828
15456
  };
12829
15457
 
12830
15458
  // src/table/compile-rule-map.ts
15459
+ var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
12831
15460
  function resolveHostMode(ruleMap, explicit) {
12832
15461
  return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
12833
15462
  }
@@ -12917,10 +15546,11 @@ function compileRuleMap(ruleMap, opts = {}) {
12917
15546
  `compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
12918
15547
  );
12919
15548
  }
12920
- const replacementWithMetadata = (metadataSource) => emitTableExpression(artifact, {
15549
+ const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
12921
15550
  entry: null,
12922
15551
  runtimeRef: opts.runtimeRef ?? "tableRules",
12923
15552
  fnSources: sources,
15553
+ ...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
12924
15554
  ...metadataSource === void 0 ? {} : { metadataSource }
12925
15555
  });
12926
15556
  const replacement = replacementWithMetadata();
@@ -12945,7 +15575,7 @@ function compileRuleMap(ruleMap, opts = {}) {
12945
15575
  }
12946
15576
 
12947
15577
  // src/version.ts
12948
- var PARSEMAN_VERSION = "0.47.1";
15578
+ var PARSEMAN_VERSION = "0.48.1";
12949
15579
 
12950
15580
  // src/compiler/compile-linkable-table.ts
12951
15581
  function isLocal(rule) {
@@ -15685,10 +18315,10 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
15685
18315
  if (compiled !== null) {
15686
18316
  usedTableRuntime = true;
15687
18317
  return {
15688
- replacement: compiled.replacementWithMetadata(staticTableMetadataSource({
15689
- reflection: compiled.reflection,
15690
- leaf: true
15691
- })),
18318
+ replacement: compiled.replacementWithMetadata(
18319
+ staticTableMetadataSource({ reflection: compiled.reflection, leaf: true }),
18320
+ { precompileDefault: true }
18321
+ ),
15692
18322
  ...importedFactories.length ? { importedFactories } : {}
15693
18323
  };
15694
18324
  }