parseman 0.58.2 → 0.59.0

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 (90) hide show
  1. package/dist/analysis/diagnostics.js +344 -130
  2. package/dist/analysis/diagnostics.js.map +3 -3
  3. package/dist/cli/index.js +346 -131
  4. package/dist/cli/index.js.map +3 -3
  5. package/dist/combinators/dispatch.d.ts.map +1 -1
  6. package/dist/combinators/field-trivia.d.ts.map +1 -1
  7. package/dist/combinators/first-set.d.ts.map +1 -1
  8. package/dist/combinators/keywords.d.ts.map +1 -1
  9. package/dist/combinators/literal.d.ts.map +1 -1
  10. package/dist/combinators/node.d.ts.map +1 -1
  11. package/dist/combinators/regex.d.ts.map +1 -1
  12. package/dist/combinators/scanTo.d.ts.map +1 -1
  13. package/dist/combinators/token.d.ts.map +1 -1
  14. package/dist/compiler/linker.d.ts.map +1 -1
  15. package/dist/compiler/token-capability.js +28 -4
  16. package/dist/compiler/token-capability.js.map +2 -2
  17. package/dist/compiler/token-scanner.d.ts.map +1 -1
  18. package/dist/cst/capture-buffer.d.ts.map +1 -1
  19. package/dist/cst/plain.js +69 -0
  20. package/dist/cst/plain.js.map +6 -0
  21. package/dist/index.js +350 -138
  22. package/dist/index.js.map +3 -3
  23. package/dist/language-service/index.js +29 -5
  24. package/dist/language-service/index.js.map +3 -3
  25. package/dist/lead-ranges.d.ts +26 -0
  26. package/dist/lead-ranges.d.ts.map +1 -0
  27. package/dist/line-index.d.ts +13 -0
  28. package/dist/line-index.d.ts.map +1 -1
  29. package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
  30. package/dist/plugin/index.js +352 -140
  31. package/dist/plugin/index.js.map +3 -3
  32. package/dist/recovery/scan.d.ts.map +1 -1
  33. package/dist/regex/classes.d.ts +5 -3
  34. package/dist/regex/classes.d.ts.map +1 -1
  35. package/dist/regex/first-set.d.ts +7 -1
  36. package/dist/regex/first-set.d.ts.map +1 -1
  37. package/dist/run/index.js +14 -4
  38. package/dist/run/index.js.map +3 -3
  39. package/dist/spec/index.js +18 -1
  40. package/dist/spec/index.js.map +2 -2
  41. package/dist/table/assemble.d.ts.map +1 -1
  42. package/dist/table/compile-rule-map.d.ts.map +1 -1
  43. package/dist/table/emit-assembly.d.ts +9 -2
  44. package/dist/table/emit-assembly.d.ts.map +1 -1
  45. package/dist/table/emit.d.ts +6 -0
  46. package/dist/table/emit.d.ts.map +1 -1
  47. package/dist/table/encode-baseline.d.ts.map +1 -1
  48. package/dist/table/index.js +330 -129
  49. package/dist/table/index.js.map +3 -3
  50. package/dist/table/program.d.ts.map +1 -1
  51. package/dist/table/run-support.d.ts.map +1 -1
  52. package/dist/table/scan-shapes.d.ts +1 -1
  53. package/dist/table/scan-shapes.d.ts.map +1 -1
  54. package/dist/table/site-labels.d.ts.map +1 -1
  55. package/dist/table/trivia-gap.d.ts +11 -1
  56. package/dist/table/trivia-gap.d.ts.map +1 -1
  57. package/dist/version.d.ts +1 -1
  58. package/package.json +2 -1
  59. package/src/combinators/choice.ts +4 -0
  60. package/src/combinators/dispatch.ts +2 -1
  61. package/src/combinators/field-trivia.ts +6 -5
  62. package/src/combinators/first-set.ts +13 -4
  63. package/src/combinators/keywords.ts +3 -2
  64. package/src/combinators/literal.ts +5 -4
  65. package/src/combinators/node.ts +3 -1
  66. package/src/combinators/regex.ts +33 -13
  67. package/src/combinators/scanTo.ts +2 -1
  68. package/src/combinators/token.ts +3 -6
  69. package/src/compiler/linker.ts +4 -2
  70. package/src/compiler/token-scanner.ts +4 -1
  71. package/src/cst/capture-buffer.ts +13 -5
  72. package/src/cst/plain.d.ts +35 -0
  73. package/src/cst/plain.js +74 -0
  74. package/src/lead-ranges.ts +53 -0
  75. package/src/line-index.ts +37 -0
  76. package/src/plugin/entry-supercompiler.ts +3 -2
  77. package/src/recovery/scan.ts +4 -4
  78. package/src/regex/classes.ts +22 -7
  79. package/src/regex/first-set.ts +67 -12
  80. package/src/table/assemble.ts +75 -38
  81. package/src/table/compile-rule-map.ts +5 -3
  82. package/src/table/emit-assembly.ts +69 -32
  83. package/src/table/emit.ts +9 -1
  84. package/src/table/encode-baseline.ts +2 -1
  85. package/src/table/program.ts +2 -1
  86. package/src/table/run-support.ts +4 -7
  87. package/src/table/scan-shapes.ts +5 -2
  88. package/src/table/site-labels.ts +2 -1
  89. package/src/table/trivia-gap.ts +19 -0
  90. package/src/version.ts +1 -1
package/dist/index.js CHANGED
@@ -1,3 +1,32 @@
1
+ // src/lead-ranges.ts
2
+ function rangesHaveLead(ranges, code) {
3
+ for (const r of ranges) if (code >= r.lo && code <= r.hi) return true;
4
+ if (code <= 65535) return false;
5
+ const high = 55296 + (code - 65536 >> 10);
6
+ for (const r of ranges) if (high >= r.lo && high <= r.hi) return true;
7
+ return false;
8
+ }
9
+ function leadRanges(ranges) {
10
+ let out;
11
+ for (const r of ranges) {
12
+ const lo = Math.max(r.lo, 55296), hi = Math.min(r.hi, 56319);
13
+ if (lo <= hi) (out ??= [...ranges]).push({ lo: 65536 + (lo - 55296 << 10), hi: 65536 + (hi - 55296 << 10) + 1023 });
14
+ }
15
+ return out ?? ranges;
16
+ }
17
+ function implicitLeadsDropped(ranges) {
18
+ const implied = leadRanges(ranges.filter((r) => r.lo <= 65535)).filter((r) => r.lo > 65535);
19
+ const out = [];
20
+ for (const r of ranges) {
21
+ let pieces = [{ lo: r.lo, hi: r.hi }];
22
+ if (r.hi > 65535) for (const c of implied) {
23
+ pieces = pieces.flatMap((q2) => q2.hi < c.lo || q2.lo > c.hi ? [q2] : [...q2.lo < c.lo ? [{ lo: q2.lo, hi: c.lo - 1 }] : [], ...q2.hi > c.hi ? [{ lo: c.hi + 1, hi: q2.hi }] : []]);
24
+ }
25
+ out.push(...pieces);
26
+ }
27
+ return out;
28
+ }
29
+
1
30
  // src/combinators/first-set.ts
2
31
  function classifyFinalChoice(arms, resolve, activeTrivia) {
3
32
  const firstSets = [];
@@ -59,8 +88,9 @@ function union(a, b) {
59
88
  function intersects(a, b) {
60
89
  if (a.kind === "any" || b.kind === "any") return true;
61
90
  if (a.kind === "empty" || b.kind === "empty") return false;
62
- for (const ra of a.ranges) {
63
- for (const rb of b.ranges) {
91
+ const bs = leadRanges(b.ranges);
92
+ for (const ra of leadRanges(a.ranges)) {
93
+ for (const rb of bs) {
64
94
  if (ra.lo <= rb.hi && rb.lo <= ra.hi) return true;
65
95
  }
66
96
  }
@@ -76,6 +106,9 @@ function startsFirstSet(combinator, input, pos) {
76
106
  const code = input.codePointAt(pos);
77
107
  if (code === void 0) return false;
78
108
  for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
109
+ if (code <= 65535) return false;
110
+ const high = 55296 + (code - 65536 >> 10);
111
+ for (const r of fs.ranges) if (high >= r.lo && high <= r.hi) return true;
79
112
  return false;
80
113
  }
81
114
  function fromRange(lo, hi) {
@@ -176,12 +209,13 @@ function narrowBy(acc, constraint) {
176
209
  if (acc.kind === "any") return constraint;
177
210
  if (acc.kind === "empty" || constraint.kind === "empty") return { kind: "empty" };
178
211
  const ranges = [];
179
- for (const a of acc.ranges) for (const b of constraint.ranges) {
212
+ const bs = leadRanges(constraint.ranges);
213
+ for (const a of leadRanges(acc.ranges)) for (const b of bs) {
180
214
  const lo = Math.max(a.lo, b.lo);
181
215
  const hi = Math.min(a.hi, b.hi);
182
216
  if (lo <= hi) ranges.push({ lo, hi });
183
217
  }
184
- return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges };
218
+ return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges: implicitLeadsDropped(ranges) };
185
219
  }
186
220
  function applyAssertion(fs, assertion) {
187
221
  return assertion === null ? fs : fs.kind === "empty" ? assertion : narrowBy(fs, assertion);
@@ -315,6 +349,7 @@ function failAt(ctx, expected, pos) {
315
349
  }
316
350
 
317
351
  // src/line-index.ts
352
+ import { PlainLineSpan, PlainSpan } from "./cst/plain.js";
318
353
  function createLineIndex() {
319
354
  return { lineStarts: [0] };
320
355
  }
@@ -374,6 +409,27 @@ function annotateSpan(span, index) {
374
409
  endColumn: e.col
375
410
  };
376
411
  }
412
+ var SPAN_KEYS = ["start", "end", "startLine", "startColumn", "endLine", "endColumn"];
413
+ function copySpan(span) {
414
+ let n = 0;
415
+ for (const key in span) {
416
+ if (key !== SPAN_KEYS[n]) return { ...span };
417
+ n++;
418
+ }
419
+ if (n === 2) return new PlainSpan(span.start, span.end);
420
+ if (n === 6 && span.startLine !== void 0 && span.startColumn !== void 0 && span.endLine !== void 0 && span.endColumn !== void 0) {
421
+ return new PlainLineSpan(span.start, span.end, span.startLine, span.startColumn, span.endLine, span.endColumn);
422
+ }
423
+ return { ...span };
424
+ }
425
+ function lineSpanFromContext(span, ctx) {
426
+ if (!ctx.trackLines) return span;
427
+ const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
428
+ if (!index) return span;
429
+ const s = offsetToLineCol(index, span.start);
430
+ const e = offsetToLineCol(index, span.end);
431
+ return new PlainLineSpan(span.start, span.end, s.line, s.col, e.line, e.col);
432
+ }
377
433
  function annotateSpanFromLineContext(span, ctx) {
378
434
  if (!ctx.trackLines) return span;
379
435
  const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
@@ -396,6 +452,7 @@ function annotateTreeSpans(value, index, seen = /* @__PURE__ */ new WeakSet()) {
396
452
  }
397
453
 
398
454
  // src/cst/capture-buffer.ts
455
+ import { PlainBuf, PlainLeaf } from "./cst/plain.js";
399
456
  var EMPTY = [];
400
457
  var EMPTY_TL = [];
401
458
  function cstCaptureActive(ctx) {
@@ -410,7 +467,7 @@ function beginCstNodeCapture(ctx) {
410
467
  cap: ctx.captureTrivia,
411
468
  buf: ctx._cstBuf
412
469
  };
413
- ctx._cstBuf = {};
470
+ ctx._cstBuf = new PlainBuf(void 0, void 0, 0);
414
471
  ctx._cstChildren = void 0;
415
472
  ctx._cstLeaves = void 0;
416
473
  ctx._cstRawChildren = void 0;
@@ -435,12 +492,15 @@ function endCstNodeCapture(ctx, saved) {
435
492
  ctx.captureTrivia = saved.cap;
436
493
  return materialized;
437
494
  }
495
+ function isLeaf(v) {
496
+ return typeof v === "object" && v !== null && v._tag === "leaf";
497
+ }
438
498
  function pushCstLeaf(ctx, leaf2) {
439
499
  if (!ctx.trackLines) {
440
500
  pushCstChild(ctx, leaf2, leaf2);
441
501
  return;
442
502
  }
443
- const annotated = leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
503
+ const annotated = isLeaf(leaf2) ? new PlainLeaf(leaf2.value, lineSpanFromContext(leaf2.span, ctx)) : leaf2 && typeof leaf2 === "object" && leaf2.span ? { ...leaf2, span: annotateSpanFromLineContext(leaf2.span, ctx) } : leaf2;
444
504
  pushCstChild(ctx, annotated, annotated);
445
505
  }
446
506
  function pushCstChild(ctx, built, rawEntry2) {
@@ -629,6 +689,7 @@ function assertionFailureExpected(positive, childTag) {
629
689
  }
630
690
 
631
691
  // src/combinators/literal.ts
692
+ import { PlainLeaf as PlainLeaf2, PlainSpan as PlainSpan2 } from "./cst/plain.js";
632
693
  function asciiFoldEq(a, b) {
633
694
  if (a.length !== b.length) return false;
634
695
  for (let i = 0; i < a.length; i++) {
@@ -686,9 +747,9 @@ function literal(value, opts = {}) {
686
747
  const code = value.charCodeAt(0);
687
748
  return function parse3(input, pos, ctx) {
688
749
  if (input.charCodeAt(pos) === code) {
689
- const span = { start: pos, end: pos + 1 };
750
+ const span = new PlainSpan2(pos, pos + 1);
690
751
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
691
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
752
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf2(value, span));
692
753
  return { ok: true, value, span };
693
754
  }
694
755
  return failAt(ctx, expected, pos);
@@ -700,9 +761,9 @@ function literal(value, opts = {}) {
700
761
  }
701
762
  const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
702
763
  if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
703
- const span = { start: pos, end };
764
+ const span = new PlainSpan2(pos, end);
704
765
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
705
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
766
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf2(matchedValue, span));
706
767
  return { ok: true, value: matchedValue, span };
707
768
  }
708
769
  return failAt(ctx, expected, pos);
@@ -736,11 +797,17 @@ function shorthandRanges(ch2) {
736
797
  if (ch2 === "s") return SPACE_RANGES;
737
798
  return [[48, 57], [65, 90], [97, 122], [95, 95]];
738
799
  }
739
- function readUnicodeEscape(body, i) {
800
+ function readUnicodeEscape(body, i, unicode = false) {
740
801
  if (body[i] !== "\\" || body[i + 1] !== "u") return null;
741
802
  const hex = body.slice(i + 2, i + 6);
742
803
  if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
743
- return { cp: Number.parseInt(hex, 16), next: i + 6 };
804
+ const cp = Number.parseInt(hex, 16);
805
+ if (unicode && cp >= 55296 && cp <= 56319 && body[i + 6] === "\\" && body[i + 7] === "u") {
806
+ const lowHex = body.slice(i + 8, i + 12);
807
+ const low = /^[0-9a-fA-F]{4}$/.test(lowHex) ? Number.parseInt(lowHex, 16) : -1;
808
+ if (low >= 56320 && low <= 57343) return { cp: 65536 + (cp - 55296 << 10) + (low - 56320), next: i + 12 };
809
+ }
810
+ return { cp, next: i + 6 };
744
811
  }
745
812
  var META = new Set("()[]{}*+?|^$.".split(""));
746
813
  function literalCodePoints(frag) {
@@ -752,6 +819,7 @@ function literalCodePoints(frag) {
752
819
  const e = frag[i + 1];
753
820
  if (e === void 0) return null;
754
821
  if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
822
+ if (e === "0" && frag[i + 2] !== void 0 && frag[i + 2] >= "0" && frag[i + 2] <= "9") return null;
755
823
  out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
756
824
  i += 2;
757
825
  continue;
@@ -792,14 +860,14 @@ function parseClassOperand(body) {
792
860
  if (cps && cps.length === 1) return { ranges: [[cps[0], cps[0]]], negated: false };
793
861
  return null;
794
862
  }
795
- function parseClassRanges(body) {
863
+ function parseClassRanges(body, unicode = false) {
796
864
  const ranges = [];
797
865
  let i = 0;
798
866
  const readAtom = () => {
799
867
  const ch2 = body[i];
800
868
  if (ch2 === void 0) return null;
801
869
  if (ch2 === "\\") {
802
- const uni = readUnicodeEscape(body, i);
870
+ const uni = readUnicodeEscape(body, i, unicode);
803
871
  if (uni) {
804
872
  i = uni.next;
805
873
  return { cp: uni.cp };
@@ -807,13 +875,15 @@ function parseClassRanges(body) {
807
875
  const e = body[i + 1];
808
876
  if (e === void 0) return null;
809
877
  i += 2;
878
+ if (e === "0" && body[i] !== void 0 && body[i] >= "0" && body[i] <= "9" || e >= "1" && e <= "9") return null;
810
879
  if (e in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[e] };
811
880
  if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges(e) };
812
881
  if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
813
882
  return { cp: e.codePointAt(0) };
814
883
  }
815
- i += ch2.length;
816
- return { cp: ch2.codePointAt(0) };
884
+ const cp = unicode ? body.codePointAt(i) : body.charCodeAt(i);
885
+ i += cp > 65535 ? 2 : 1;
886
+ return { cp };
817
887
  };
818
888
  while (i < body.length) {
819
889
  const lo = readAtom();
@@ -849,7 +919,7 @@ function rangesHaveNewline(ranges) {
849
919
  return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
850
920
  }
851
921
  var BAIL = /* @__PURE__ */ Symbol("regex-bail");
852
- function parseRegex(src) {
922
+ function parseRegex(src, unicode = false, sets = false) {
853
923
  let i = 0;
854
924
  const parseAlt = () => {
855
925
  const arms = [parseSeq()];
@@ -919,9 +989,11 @@ function parseRegex(src) {
919
989
  i++;
920
990
  return charNode(fromRange(123, 123), false);
921
991
  // a `{` with nothing to quantify is a literal brace
922
- default:
923
- i += ch2.length;
924
- return charNode(fromRange(ch2.codePointAt(0), ch2.codePointAt(0)), ch2 === "\n");
992
+ default: {
993
+ const cp = unicode ? src.codePointAt(i) : src.charCodeAt(i);
994
+ i += cp > 65535 ? 2 : 1;
995
+ return charNode(fromRange(cp, cp), ch2 === "\n");
996
+ }
925
997
  }
926
998
  };
927
999
  const parseGroup = () => {
@@ -954,6 +1026,32 @@ function parseRegex(src) {
954
1026
  let k = i + 1;
955
1027
  const negated = src[k] === "^";
956
1028
  if (negated) k++;
1029
+ if (sets) {
1030
+ let depth = 1;
1031
+ let nested = false;
1032
+ while (k < src.length && depth > 0) {
1033
+ const c = src[k];
1034
+ if (c === "\\") {
1035
+ if (src[k + 1] === "q") nested = true;
1036
+ k += 2;
1037
+ continue;
1038
+ }
1039
+ if (c === "[") {
1040
+ depth++;
1041
+ nested = true;
1042
+ } else if (c === "]") {
1043
+ depth--;
1044
+ if (depth === 0) break;
1045
+ } else if ((c === "-" || c === "&") && src[k + 1] === c) nested = true;
1046
+ k++;
1047
+ }
1048
+ if (src[k] !== "]") throw BAIL;
1049
+ if (nested) {
1050
+ i = k + 1;
1051
+ return charNode(any(), true);
1052
+ }
1053
+ k = i + 1 + (negated ? 1 : 0);
1054
+ }
957
1055
  let body = "";
958
1056
  while (k < src.length && src[k] !== "]") {
959
1057
  if (src[k] === "\\") {
@@ -966,7 +1064,7 @@ function parseRegex(src) {
966
1064
  }
967
1065
  if (src[k] !== "]") throw BAIL;
968
1066
  i = k + 1;
969
- const ranges = parseClassRanges(body);
1067
+ const ranges = parseClassRanges(body, unicode);
970
1068
  if (negated) return charNode(any(), !ranges || !rangesHaveNewline(ranges));
971
1069
  if (!ranges) return charNode(any(), true);
972
1070
  return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
@@ -974,9 +1072,20 @@ function parseRegex(src) {
974
1072
  const parseEscape = () => {
975
1073
  const e = src[i + 1];
976
1074
  if (e === void 0) throw BAIL;
977
- if (e === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(i + 2, i + 6))) {
978
- const cp = Number.parseInt(src.slice(i + 2, i + 6), 16);
979
- i += 6;
1075
+ const uni = readUnicodeEscape(src, i, unicode);
1076
+ if (uni !== null) {
1077
+ i = uni.next;
1078
+ return charNode(fromRange(uni.cp, uni.cp), uni.cp === 10);
1079
+ }
1080
+ if (e === "u" && src[i + 2] === "{") {
1081
+ const close = src.indexOf("}", i + 3);
1082
+ const hex = close < 0 ? "" : src.slice(i + 3, close);
1083
+ if (!unicode || !/^[0-9a-fA-F]{1,6}$/.test(hex)) {
1084
+ i += 2;
1085
+ return ANY;
1086
+ }
1087
+ const cp = Number.parseInt(hex, 16);
1088
+ i = close + 1;
980
1089
  return charNode(fromRange(cp, cp), cp === 10);
981
1090
  }
982
1091
  if (e === "x" && /^[0-9a-fA-F]{2}$/.test(src.slice(i + 2, i + 4))) {
@@ -984,6 +1093,16 @@ function parseRegex(src) {
984
1093
  i += 4;
985
1094
  return charNode(fromRange(cp, cp), cp === 10);
986
1095
  }
1096
+ if (e === "c") {
1097
+ const x = src[i + 2];
1098
+ if (x !== void 0 && /^[A-Za-z]$/.test(x)) {
1099
+ const cp = x.charCodeAt(0) % 32;
1100
+ i += 3;
1101
+ return charNode(fromRange(cp, cp), cp === 10);
1102
+ }
1103
+ i += 2;
1104
+ return ANY;
1105
+ }
987
1106
  i += 2;
988
1107
  switch (e) {
989
1108
  case "d":
@@ -1011,8 +1130,16 @@ function parseRegex(src) {
1011
1130
  return charNode(fromRange(12, 12), false);
1012
1131
  case "v":
1013
1132
  return charNode(fromRange(11, 11), false);
1133
+ // `\0` then a digit is a legacy octal escape (`\012` is a newline), not NUL.
1014
1134
  case "0":
1015
- return charNode(fromRange(0, 0), false);
1135
+ return src[i] !== void 0 && src[i] >= "0" && src[i] <= "9" ? ANY : charNode(fromRange(0, 0), false);
1136
+ // A property escape (`\p{…}`/`\P{…}`) matches one character of a class this
1137
+ // analyzer does not enumerate; `\k<name>` is a backreference, which may match empty.
1138
+ case "p":
1139
+ case "P":
1140
+ return charNode(any(), true);
1141
+ case "k":
1142
+ return ANY;
1016
1143
  default:
1017
1144
  if (e >= "1" && e <= "9") return ANY;
1018
1145
  return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
@@ -1086,10 +1213,10 @@ function regexCanMatchEmpty(source) {
1086
1213
  return true;
1087
1214
  }
1088
1215
  }
1089
- function firstSetFromRegex(source) {
1216
+ function firstSetFromRegex(source, flags = "") {
1090
1217
  let ast;
1091
1218
  try {
1092
- ast = parseRegex(source);
1219
+ ast = parseRegex(source, flags.includes("u") || flags.includes("v"), flags.includes("v"));
1093
1220
  } catch {
1094
1221
  return { firstSet: any(), canMatchNewline: true };
1095
1222
  }
@@ -1098,6 +1225,7 @@ function firstSetFromRegex(source) {
1098
1225
  }
1099
1226
 
1100
1227
  // src/combinators/regex.ts
1228
+ import { PlainLeaf as PlainLeaf3, PlainSpan as PlainSpan3 } from "./cst/plain.js";
1101
1229
  var SCAN_BAIL_AT = 64;
1102
1230
  function inRanges(cp, ranges) {
1103
1231
  for (let i = 0; i < ranges.length; i++) {
@@ -1138,8 +1266,18 @@ function shortScanner(source, flags) {
1138
1266
  return minOne && end === pos ? null : end;
1139
1267
  };
1140
1268
  }
1269
+ function coversNonAscii(ranges) {
1270
+ let next = 128;
1271
+ for (const r of [...ranges].sort((a, b) => a.lo - b.lo)) {
1272
+ if (r.lo > next) return false;
1273
+ if (r.hi >= next) next = r.hi + 1;
1274
+ if (next > 65535) return true;
1275
+ }
1276
+ return false;
1277
+ }
1141
1278
  function asciiCaseFold(fs) {
1142
1279
  if (fs.kind !== "ranges") return fs;
1280
+ if (fs.ranges.some((r) => r.hi >= 128) && !coversNonAscii(fs.ranges)) return any();
1143
1281
  const ranges = fs.ranges.map((r) => ({ lo: r.lo, hi: r.hi }));
1144
1282
  const add = (lo, hi) => {
1145
1283
  if (lo <= hi) ranges.push({ lo, hi });
@@ -1164,7 +1302,7 @@ function regex(pattern, flags = "") {
1164
1302
  const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
1165
1303
  const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
1166
1304
  const scan = shortScanner(source, resolvedFlags);
1167
- const raw = firstSetFromRegex(source);
1305
+ const raw = firstSetFromRegex(source, resolvedFlags);
1168
1306
  const firstSet2 = !resolvedFlags.includes("i") ? raw.firstSet : resolvedFlags.includes("u") || resolvedFlags.includes("v") ? any() : asciiCaseFold(raw.firstSet);
1169
1307
  const canMatchNewline = raw.canMatchNewline;
1170
1308
  const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
@@ -1200,9 +1338,9 @@ function regex(pattern, flags = "") {
1200
1338
  if (scanEnd !== void 0) {
1201
1339
  if (scanEnd === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
1202
1340
  const value = input.slice(pos, scanEnd);
1203
- const span2 = { start: pos, end: scanEnd };
1341
+ const span2 = new PlainSpan3(pos, scanEnd);
1204
1342
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, scanEnd);
1205
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
1343
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf3(value, span2));
1206
1344
  return { ok: true, value, span: span2 };
1207
1345
  }
1208
1346
  anchored.lastIndex = pos;
@@ -1210,9 +1348,9 @@ function regex(pattern, flags = "") {
1210
1348
  if (m === null) {
1211
1349
  return failAt(ctx, directTerminalFailureExpected(def), pos);
1212
1350
  }
1213
- const span = { start: pos, end: pos + m[0].length };
1351
+ const span = new PlainSpan3(pos, pos + m[0].length);
1214
1352
  if (canMatchNewline && ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, span.end);
1215
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
1353
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf3(m[0], span));
1216
1354
  return { ok: true, value: m[0], span };
1217
1355
  }
1218
1356
  };
@@ -1254,6 +1392,7 @@ function caseFoldVariants(cp) {
1254
1392
  }
1255
1393
 
1256
1394
  // src/combinators/keywords.ts
1395
+ import { PlainLeaf as PlainLeaf4, PlainSpan as PlainSpan4 } from "./cst/plain.js";
1257
1396
  function word(str, boundaryOrOpts, opts) {
1258
1397
  const boundary = typeof boundaryOrOpts === "string" ? boundaryOrOpts : "_0-9A-Za-z";
1259
1398
  const rest = typeof boundaryOrOpts === "object" && boundaryOrOpts !== null ? boundaryOrOpts : opts;
@@ -1312,8 +1451,8 @@ function keywords(words, opts = {}) {
1312
1451
  const m = re.exec(input);
1313
1452
  if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
1314
1453
  const value = m[0];
1315
- const span = { start: pos, end: pos + value.length };
1316
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
1454
+ const span = new PlainSpan4(pos, pos + value.length);
1455
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf4(value, span));
1317
1456
  return { ok: true, value, span };
1318
1457
  }
1319
1458
  };
@@ -2601,6 +2740,7 @@ function altStarSource(source) {
2601
2740
  }
2602
2741
 
2603
2742
  // src/recovery/scan.ts
2743
+ import { PlainSpan as PlainSpan5 } from "./cst/plain.js";
2604
2744
  function probeAt(sentinel, input, pos, ctx) {
2605
2745
  const s = {
2606
2746
  _probe: ctx._probe,
@@ -2668,9 +2808,7 @@ function firstSetSentinel(fs) {
2668
2808
  parse(input, pos) {
2669
2809
  const code = pos < input.length ? input.codePointAt(pos) : void 0;
2670
2810
  if (code !== void 0) {
2671
- for (const r of ranges) {
2672
- if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
2673
- }
2811
+ if (rangesHaveLead(ranges, code)) return { ok: true, value: null, span: { start: pos, end: pos } };
2674
2812
  }
2675
2813
  return { ok: false, expected: [], span: { start: pos, end: pos } };
2676
2814
  }
@@ -2679,7 +2817,7 @@ function firstSetSentinel(fs) {
2679
2817
  function recoverScan(input, from, ctx, sync, expected) {
2680
2818
  let scanPos = from;
2681
2819
  while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
2682
- const span = { start: from, end: scanPos };
2820
+ const span = new PlainSpan5(from, scanPos);
2683
2821
  if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
2684
2822
  const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
2685
2823
  ctx._errors?.push(error);
@@ -2781,17 +2919,18 @@ function scalarRootOf(combinator) {
2781
2919
  }
2782
2920
 
2783
2921
  // src/combinators/field-trivia.ts
2922
+ import { PlainSpan as PlainSpan6, PlainTriviaField } from "./cst/plain.js";
2784
2923
  var LEAD = { at: -1 };
2785
2924
  var FIELD_LEADING_TRIVIA = 1;
2786
2925
  var FIELD_TRAILING_TRIVIA = 2;
2787
2926
  function triviaFieldCapture(name, value, input, start, end, leadFrom, trailEnd) {
2788
- return {
2927
+ return new PlainTriviaField(
2789
2928
  name,
2790
2929
  value,
2791
- span: { start, end },
2792
- leading: leadFrom >= 0 && leadFrom < start ? input.slice(leadFrom, start) : "",
2793
- trailing: trailEnd > end ? input.slice(end, trailEnd) : ""
2794
- };
2930
+ new PlainSpan6(start, end),
2931
+ leadFrom >= 0 && leadFrom < start ? input.slice(leadFrom, start) : "",
2932
+ trailEnd > end ? input.slice(end, trailEnd) : ""
2933
+ );
2795
2934
  }
2796
2935
  function leadsTrivia(p) {
2797
2936
  return p._def.tag === "field" && p._def.leadingTrivia === true;
@@ -3346,6 +3485,9 @@ function inFirstSet(code, fs) {
3346
3485
  if (fs.kind === "any") return true;
3347
3486
  if (fs.kind === "empty") return false;
3348
3487
  for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
3488
+ if (code <= 65535) return false;
3489
+ const high = 55296 + (code - 65536 >> 10);
3490
+ for (const r of fs.ranges) if (high >= r.lo && high <= r.hi) return true;
3349
3491
  return false;
3350
3492
  }
3351
3493
  function areDisjoint(sets) {
@@ -3370,6 +3512,7 @@ function buildAsciiDispatch(parsers) {
3370
3512
  }
3371
3513
 
3372
3514
  // src/combinators/dispatch.ts
3515
+ import { PlainLeaf as PlainLeaf5 } from "./cst/plain.js";
3373
3516
  function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
3374
3517
  if (seen.has(parser2)) return false;
3375
3518
  seen.add(parser2);
@@ -3509,7 +3652,7 @@ function routed(fallback) {
3509
3652
  return { ok: false, expected: ["routed()"], span: { start: pos, end: pos } };
3510
3653
  }
3511
3654
  if (cstCaptureActive(ctx)) {
3512
- pushCstLeaf(ctx, { _tag: "leaf", value: item.value, span: item.span });
3655
+ pushCstLeaf(ctx, new PlainLeaf5(item.value, item.span));
3513
3656
  }
3514
3657
  return { ok: true, value: item.value, span: item.span };
3515
3658
  }
@@ -5021,6 +5164,7 @@ function buildFieldMap(captures) {
5021
5164
  }
5022
5165
 
5023
5166
  // src/combinators/node.ts
5167
+ import { PlainNode, PlainSpan as PlainSpan7 } from "./cst/plain.js";
5024
5168
  function unwrapChild(child) {
5025
5169
  return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
5026
5170
  }
@@ -5126,7 +5270,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
5126
5270
  const nodeType = def.type ?? missingInferredType();
5127
5271
  const cstOutput2 = cstOutputHost(ctx.build);
5128
5272
  const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
5129
- const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput2 || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children2, project, nodeType) : build ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
5273
+ const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput2 || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children2, project, nodeType) : build ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : new PlainNode(nodeType, ctx.trackLines ? copySpan(span) : new PlainSpan7(r.span.start, r.span.end), st ?? null, [...children2]);
5130
5274
  const rawEntry2 = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
5131
5275
  if (saved.buf !== void 0 || saved.ch !== void 0) {
5132
5276
  pushCstChild(ctx, built, rawEntry2);
@@ -5282,6 +5426,7 @@ function field(name, combinator, opts) {
5282
5426
  }
5283
5427
 
5284
5428
  // src/combinators/token.ts
5429
+ import { PlainLeaf as PlainLeaf6 } from "./cst/plain.js";
5285
5430
  function semanticLeafValue(_ctx, _input, _start, _end, value) {
5286
5431
  return value;
5287
5432
  }
@@ -5335,7 +5480,7 @@ function token(root) {
5335
5480
  if (!result.ok) return result;
5336
5481
  const span = result.span;
5337
5482
  const value = input.slice(pos, span.end);
5338
- if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
5483
+ if (wasCapturing) pushCstLeaf(ctx, new PlainLeaf6(value, span));
5339
5484
  return { ok: true, value, span };
5340
5485
  }
5341
5486
  };
@@ -5383,11 +5528,7 @@ function makeLeaf(root, fn, sourceCstValue) {
5383
5528
  }
5384
5529
  if (!result.ok) return result;
5385
5530
  const value = fn(result.value, result.span);
5386
- if (wasCapturing) pushCstLeaf(ctx, {
5387
- _tag: "leaf",
5388
- value: cstValue(ctx, input, pos, result.span.end, value),
5389
- span: result.span
5390
- });
5531
+ if (wasCapturing) pushCstLeaf(ctx, new PlainLeaf6(cstValue(ctx, input, pos, result.span.end, value), result.span));
5391
5532
  return { ok: true, value, span: result.span };
5392
5533
  }
5393
5534
  };
@@ -5420,6 +5561,7 @@ function buildLexBodyRecognizer(spec, constants) {
5420
5561
  }
5421
5562
 
5422
5563
  // src/table/run-support.ts
5564
+ import { PlainLeaf as PlainLeaf7, PlainLineSpan as PlainLineSpan2, PlainSpan as PlainSpan8 } from "./cst/plain.js";
5423
5565
  function lineCol(ctx, offset) {
5424
5566
  const starts = ctx._lineStarts ?? [0];
5425
5567
  let lo = 0, hi = starts.length - 1;
@@ -5432,18 +5574,14 @@ function lineCol(ctx, offset) {
5432
5574
  }
5433
5575
  function spanLines(ctx, start, end) {
5434
5576
  const s = lineCol(ctx, start), e = lineCol(ctx, end);
5435
- return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
5577
+ return new PlainLineSpan2(start, end, s[0], s[1], e[0], e[1]);
5436
5578
  }
5437
5579
  function rawEntry(v, input, s, e) {
5438
5580
  if (typeof v === "object" && v !== null) {
5439
5581
  const tg = v._tag;
5440
5582
  if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
5441
5583
  }
5442
- return {
5443
- _tag: "leaf",
5444
- value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
5445
- span: { start: s, end: e }
5446
- };
5584
+ return new PlainLeaf7(typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "", new PlainSpan8(s, e));
5447
5585
  }
5448
5586
  function lead(input, pos) {
5449
5587
  if (pos >= input.length) return -1;
@@ -5457,7 +5595,7 @@ function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
5457
5595
  const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
5458
5596
  if (collected) popCstChild(ctx);
5459
5597
  const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
5460
- const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
5598
+ const nd = build(EMPTY_KIDS, void 0, new PlainSpan8(pos, end), raw, EMPTY_TRIVIA, void 0);
5461
5599
  if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
5462
5600
  return nd;
5463
5601
  }
@@ -6127,7 +6265,7 @@ function decodeClassSpec(spec) {
6127
6265
  function resolveClass(spec) {
6128
6266
  const ascii = new Uint8Array(128);
6129
6267
  const hi = [];
6130
- for (const { lo, hi: up } of decodeClassSpec(spec)) {
6268
+ for (const { lo, hi: up } of leadRanges(decodeClassSpec(spec))) {
6131
6269
  if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
6132
6270
  if (up >= 128) hi.push(Math.max(lo, 128), up);
6133
6271
  }
@@ -9227,6 +9365,7 @@ function parseSeqParts(source) {
9227
9365
  cp2 = uni.cp;
9228
9366
  i = uni.next;
9229
9367
  } else if (e === void 0) return null;
9368
+ else if (e >= "0" && e <= "9" && (e !== "0" || source[i + 2] !== void 0 && source[i + 2] >= "0" && source[i + 2] <= "9")) return null;
9230
9369
  else if (e in CLASS_ESCAPES) {
9231
9370
  cp2 = CLASS_ESCAPES[e];
9232
9371
  i += 2;
@@ -9776,7 +9915,7 @@ function parseScanShapeCore(source) {
9776
9915
  return null;
9777
9916
  }
9778
9917
  function scanShapeFromRegex(source, flags) {
9779
- if (/[msu]/.test(flags)) return null;
9918
+ if (/[msuv]/.test(flags)) return null;
9780
9919
  if (/i/.test(flags)) return caseFoldShape(source);
9781
9920
  return parseScanShape(source);
9782
9921
  }
@@ -10381,7 +10520,7 @@ function triviaLeadRanges(tri, trivia2) {
10381
10520
  const fs = trivia2[tri]?._meta.firstSet;
10382
10521
  if (fs === void 0) return void 0;
10383
10522
  if (fs.kind === "empty") return [];
10384
- return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
10523
+ return fs.kind === "ranges" && fs.ranges !== void 0 ? leadRanges(fs.ranges) : void 0;
10385
10524
  }
10386
10525
 
10387
10526
  // src/table/scalar-terminal.ts
@@ -10739,7 +10878,14 @@ var EMITTED_PARAMS = [
10739
10878
  "skipDeferredTrivia",
10740
10879
  // Appended for the pass-through collapse (`run-support.ts`); old factories
10741
10880
  // ignore it.
10742
- "collapseEmpty"
10881
+ "collapseEmpty",
10882
+ // Appended for constructor-built tree objects (`cst/plain.d.ts`): a `new` call has
10883
+ // no allocation site, so V8 cannot pretenure them. Old factories ignore them.
10884
+ "_SP",
10885
+ "_LF",
10886
+ "_ND",
10887
+ "_FC",
10888
+ "_BUF"
10743
10889
  ];
10744
10890
  var RUNTIME_PRELUDE = `
10745
10891
  let _pfScan=null
@@ -10763,9 +10909,9 @@ if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
10763
10909
  if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
10764
10910
  return advanceTrivia(input,cur,ctx)
10765
10911
  }
10766
- function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
10912
+ function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,new _LF(value,new _SP(s,e)))}
10767
10913
  function _pushLeafBuf(ctx,value,s,e){
10768
- const l={_tag:'leaf',value,span:{start:s,end:e}}
10914
+ const l=new _LF(value,new _SP(s,e))
10769
10915
  const b=ctx._cstBuf
10770
10916
  if(b.ch!==undefined)b.ch.push(l)
10771
10917
  else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
@@ -10823,7 +10969,7 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
10823
10969
  `;
10824
10970
  var NO_RAW_RUNTIME_PRELUDE = `
10825
10971
  function _pushLeafNoRawBuf(ctx,value,s,e){
10826
- const l={_tag:'leaf',value,span:{start:s,end:e}}
10972
+ const l=new _LF(value,new _SP(s,e))
10827
10973
  const b=ctx._cstBuf
10828
10974
  if(b.ch!==undefined)b.ch.push(l)
10829
10975
  else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
@@ -10911,7 +11057,7 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}e
10911
11057
  if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,undefined,undefined,${t}lg,${t}rt)`;
10912
11058
  return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
10913
11059
  }
10914
- function emitTerm(callee, dst, t, l, skip) {
11060
+ function emitTerm(callee, dst, t, l, skip, miss) {
10915
11061
  const fast = `const ${t}v=${callee}(input,cur,ctx)
10916
11062
  if(${t}v===FAIL)return FAIL
10917
11063
  ${dst}=${t}v
@@ -10929,7 +11075,12 @@ if(${t}v===FAIL)return FAIL
10929
11075
  ${dst}=${t}v
10930
11076
  if(EC.e>${t}s)cur=EC.e
10931
11077
  else{rollbackScannedTriviaAt(ctx,${t}tl,${t}stl,${t}lg,${t}slg,${t}rt,${t}srt)}`;
10932
- if (l.tri !== TRI_UNKNOWN) return scanned;
11078
+ if (l.tri !== TRI_UNKNOWN) return miss === void 0 ? scanned : `const ${t}c=input.charCodeAt(cur)
11079
+ if(${miss(`${t}c`)}){
11080
+ ${fast}
11081
+ }else{
11082
+ ${scanned}
11083
+ }`;
10933
11084
  return `if(ctx.trivia===undefined){
10934
11085
  ${fast}
10935
11086
  }else{
@@ -10985,7 +11136,7 @@ function rebuildPools(cc, fx, disp, plan) {
10985
11136
  })
10986
11137
  };
10987
11138
  }
10988
- function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select) {
11139
+ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select, scanSinkNeutral = false) {
10989
11140
  const { code, k, fx, disp, dsp, triviaLabelled } = t;
10990
11141
  const swapLegal = !cfg.trackLines;
10991
11142
  const hostCst = cfg.hostCst;
@@ -11061,7 +11212,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, se
11061
11212
  const op = code[ip];
11062
11213
  sinkBits.set(
11063
11214
  ip,
11064
- op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
11215
+ op === OP_SCAN || !scanSinkNeutral && op === OP_LEX_PROGRAM && t.lexPrograms[code[ip + 1]].scan !== void 0 ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
11065
11216
  );
11066
11217
  }
11067
11218
  const sinkKids = [];
@@ -11234,6 +11385,12 @@ return 1
11234
11385
  return `if(${gateMissTest(child)}){${miss}}
11235
11386
  `;
11236
11387
  }
11388
+ function triviaMiss(ki) {
11389
+ const leads = triviaLeadRanges(ki, t.trivia);
11390
+ if (leads === void 0 || leads.length > 16) return void 0;
11391
+ if (leads.length === 0) return (c) => `${c}<55296`;
11392
+ return (c) => `${c}<55296&&!(${leads.map((r) => r.lo === r.hi ? `${c}===${r.lo}` : `(${c}>=${r.lo}&&${c}<=${r.hi})`).join("||")})`;
11393
+ }
11237
11394
  function skipFor(l) {
11238
11395
  if (l.tri < 0) return "_skipTrivia";
11239
11396
  const ki = l.tri;
@@ -11244,8 +11401,13 @@ return 1
11244
11401
  const nm = `_sk${skipPool.size}`;
11245
11402
  skipPool.set(key, nm);
11246
11403
  if (!hasScan) {
11247
- skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
11248
- if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
11404
+ const miss = triviaMiss(ki);
11405
+ const pre = miss === void 0 ? "" : `const c=input.charCodeAt(cur)
11406
+ if(${miss("c")})return cur
11407
+ `;
11408
+ skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){${pre === "" ? "" : `
11409
+ ${pre}`}return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
11410
+ ${pre}if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
11249
11411
  return advanceTrivia(input,cur,ctx)}`);
11250
11412
  return nm;
11251
11413
  }
@@ -11484,7 +11646,7 @@ try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
11484
11646
  return `${head}
11485
11647
  const v=${child}(input,pos,ctx)
11486
11648
  if(v===FAIL)return FAIL
11487
- return ${fn}(v,{start:pos,end:EC.e})
11649
+ return ${fn}(v,new _SP(pos,EC.e))
11488
11650
  }`;
11489
11651
  }
11490
11652
  case OP_LABEL: {
@@ -11505,7 +11667,7 @@ return v
11505
11667
  const v=${child}(input,pos,ctx)
11506
11668
  if(v===FAIL)return FAIL
11507
11669
  const f=ctx._fields
11508
- if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
11670
+ if(f!==undefined)f.push(new _FC(${name},v,new _SP(pos,EC.e)))
11509
11671
  return v
11510
11672
  }`;
11511
11673
  }
@@ -11530,7 +11692,7 @@ return v
11530
11692
  return `${head}
11531
11693
  const v=${child}(input,pos,ctx)
11532
11694
  if(v!==FAIL)return v
11533
- const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
11695
+ const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "new _SP(pos,pos)"},expected:${xf}}
11534
11696
  const es=ctx._errors
11535
11697
  if(es!==undefined)es.push(err)
11536
11698
  ${REC2 ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
@@ -11541,7 +11703,7 @@ return err
11541
11703
  case OP_ROUTED: {
11542
11704
  const fb = code[ip + 1];
11543
11705
  const fallback = fb >= 0 ? link(fb) : void 0;
11544
- const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
11706
+ const push = `pushCstLeaf(ctx,new _LF(it.value,it.span))`;
11545
11707
  return `${head}
11546
11708
  const it=ctx._routed
11547
11709
  if(it===undefined||pos!==it.span.start){
@@ -11622,8 +11784,8 @@ ctx._triviaLog=sOtl
11622
11784
  }
11623
11785
  if(v===FAIL)return FAIL
11624
11786
  const e=EC.e
11625
- const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
11626
- if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:${capturesSource ? "input.slice(pos,e)" : "out"},span:{start:pos,end:e}})
11787
+ const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,new _SP(pos,e))`}
11788
+ if(wasCap)pushCstLeaf(ctx,new _LF(${capturesSource ? "input.slice(pos,e)" : "out"},new _SP(pos,e)))
11627
11789
  EC.e=e
11628
11790
  return out
11629
11791
  }`;
@@ -11647,7 +11809,7 @@ ${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
11647
11809
  ${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
11648
11810
  const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
11649
11811
  ${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
11650
- if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
11812
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,new _LF(v,new _SP(pos,e)))
11651
11813
  EC.e=e
11652
11814
  return v
11653
11815
  }`;
@@ -11686,7 +11848,7 @@ ctx._rootTriviaLog=sRtl
11686
11848
  }
11687
11849
  if(e<0)return FAIL
11688
11850
  const v=input.slice(pos,e)
11689
- if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
11851
+ if(wasCap)pushCstLeaf(ctx,new _LF(v,new _SP(pos,e)))
11690
11852
  EC.e=e
11691
11853
  return v
11692
11854
  }`;
@@ -11694,7 +11856,7 @@ return v
11694
11856
  const e=${run3}(input,pos,ctx)
11695
11857
  if(e<0)return FAIL
11696
11858
  const v=input.slice(pos,e)
11697
- if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
11859
+ if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,new _LF(v,new _SP(pos,e)))
11698
11860
  EC.e=e
11699
11861
  return v
11700
11862
  }`;
@@ -11808,7 +11970,7 @@ return v
11808
11970
  }` : `${parts.join("\n")}
11809
11971
  }`;
11810
11972
  if (n === 1) {
11811
- parts.push(fused ? projection === 0 ? "return v0" : `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
11973
+ parts.push(fused ? projection === 0 ? "return v0" : `return ${fn}([v0],new _SP(pos,EC.e))` : wantValues ? "return [v0]" : "return undefined");
11812
11974
  return close();
11813
11975
  }
11814
11976
  parts.push("let cur=EC.e");
@@ -11829,12 +11991,12 @@ return v
11829
11991
  );
11830
11992
  } else {
11831
11993
  const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
11832
- parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
11994
+ parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L), L.tri >= 0 ? triviaMiss(L.tri) : void 0));
11833
11995
  }
11834
11996
  names.push(vn);
11835
11997
  }
11836
11998
  parts.push("EC.e=cur");
11837
- parts.push(fused ? projection >= 0 ? `return ${names[projection]}` : `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
11999
+ parts.push(fused ? projection >= 0 ? `return ${names[projection]}` : `return ${fn}([${names.join(",")}],new _SP(pos,cur))` : wantValues ? `return [${names.join(",")}]` : "return undefined");
11838
12000
  return close();
11839
12001
  }
11840
12002
  case OP_CHOICE: {
@@ -12093,7 +12255,7 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=
12093
12255
  const routedCall = (target) => `{const savedRouted=ctx._routed
12094
12256
  ${emitRollback(m1, L.buf, L.raw, sinks)}
12095
12257
  ${emitMark(m2, L.buf, L.raw, sinks, false)}
12096
- ctx._routed={value:key,span:{start:pos,end:selEnd}}
12258
+ ctx._routed={value:key,span:new _SP(pos,selEnd)}
12097
12259
  try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
12098
12260
  break}`;
12099
12261
  const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
@@ -12288,8 +12450,8 @@ return out
12288
12450
  const end=${recognize}(input,pos)
12289
12451
  if(end<0){ctx._fe=pos;ctx._fx=${xf};return FAIL}
12290
12452
  const value=${value2}
12291
- const leaf={_tag:'leaf',value,span:{start:pos,end}}
12292
- const kids=[leaf],rawKids=[leaf],span={start:pos,end}
12453
+ const leaf=new _LF(value,new _SP(pos,end))
12454
+ const kids=[leaf],rawKids=[leaf],span=new _SP(pos,end)
12293
12455
  EC.e=end
12294
12456
  const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
12295
12457
  ${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,ctx._cstBuf!==undefined&&ctx._cstBuf.noRaw===true?undefined:ctx._cstBuf!==undefined||ctx._cstRawChildren!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
@@ -12388,7 +12550,7 @@ ctx._cstTriviaLog=sTl
12388
12550
  ctx.captureTrivia=sCap
12389
12551
  if(v===FAIL)return FAIL
12390
12552
  const end=EC.e
12391
- ${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)`}
12553
+ ${collapseChildren ? `const nd=captured.length===1?captured[0]:${build}(captured,undefined,new _SP(pos,end),EMPTY_CH,EMPTY_TL,undefined)` : `const nd=${build}(captured,${fields ? "fieldMap" : "undefined"},new _SP(pos,end),EMPTY_CH,EMPTY_TL,undefined)`}
12392
12554
  ${publish}
12393
12555
  EC.e=end
12394
12556
  return nd
@@ -12411,20 +12573,20 @@ return nd
12411
12573
  const direct = `${build}(kids,fieldMap,span,rawKids,${captureWide ? "tlog" : "EMPTY_TL"},st)`;
12412
12574
  value = hostCst ? `nd=_pfHost!==undefined?${hostCall}:${direct}` : `nd=${direct}`;
12413
12575
  } else {
12414
- value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
12576
+ value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):new _ND(${ty},span,st??null,kids===EMPTY_CH?kids:[...kids])`;
12415
12577
  }
12416
12578
  const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
12417
- const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
12579
+ const openCapture = omitsRaw ? `const buf=new _BUF(undefined,true,0)
12418
12580
  ctx._cstBuf=buf
12419
12581
  ctx._cstChildren=undefined
12420
12582
  ctx._cstLeaves=undefined
12421
12583
  ctx._cstRawChildren=undefined
12422
- ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
12584
+ ctx._cstTriviaLog=undefined` : keepChildren ? `const buf=new _BUF(undefined,undefined,0)
12423
12585
  ctx._cstBuf=buf
12424
12586
  ctx._cstChildren=undefined
12425
12587
  ctx._cstLeaves=undefined
12426
12588
  ctx._cstRawChildren=undefined
12427
- ctx._cstTriviaLog=undefined` : `const buf={rawOnly:true}
12589
+ ctx._cstTriviaLog=undefined` : `const buf=new _BUF(true,undefined,0)
12428
12590
  ctx._cstBuf=buf
12429
12591
  ctx._cstChildren=undefined
12430
12592
  ctx._cstLeaves=undefined
@@ -12462,7 +12624,7 @@ ctx._cstTriviaLog=sTl
12462
12624
  ctx.captureTrivia=sCap
12463
12625
  if(v===FAIL)return FAIL
12464
12626
  const end=EC.e
12465
- const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
12627
+ const span=${tracked ? "spanLines(ctx,pos,end)" : "new _SP(pos,end)"}
12466
12628
  const st=${readsState ? "ctx.state" : "undefined"}
12467
12629
  let nd
12468
12630
  ${unwrap ? "if(kids.length===1)nd=unwrapChild(kids[0])\nelse " : ""}${collapse ? "if(kids.length===1)nd=kids[0]\nelse " : ""}${collapsible ? `if(_pfHost!==undefined&&_pfHost._parsemanCstCollapse!==undefined&&kids.length===1&&rawKids.length===1&&_pfHost._parsemanCstCollapse(${ty},kids[0],kids,rawKids))nd=kids[0]
@@ -12749,6 +12911,7 @@ function rebuildLineScan(s, subtree) {
12749
12911
  }
12750
12912
 
12751
12913
  // src/combinators/scanTo.ts
12914
+ import { PlainLeaf as PlainLeaf8, PlainSpan as PlainSpan9 } from "./cst/plain.js";
12752
12915
  function resolveScanSkip(explicitSkip, raw, ctx) {
12753
12916
  if (raw) return [];
12754
12917
  const trivia2 = ctx.trivia;
@@ -12786,7 +12949,7 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false, recoverAt, stopAt
12786
12949
  probeCtx._errors = ctx._errors;
12787
12950
  const emit = (end) => {
12788
12951
  if (end > pos && cstCaptureActive(ctx)) {
12789
- const leaf2 = { _tag: "leaf", value: input.slice(pos, end), span: { start: pos, end } };
12952
+ const leaf2 = new PlainLeaf8(input.slice(pos, end), new PlainSpan9(pos, end));
12790
12953
  pushCstLeaf(ctx, leaf2);
12791
12954
  }
12792
12955
  };
@@ -13008,6 +13171,15 @@ function skipDeferredTrivia(input, cur, ctx) {
13008
13171
  if (plain) remember(cur, scan, ctx, input, triviaP);
13009
13172
  return scan;
13010
13173
  }
13174
+ function triviaLeadTable(triviaP) {
13175
+ const fs = triviaP._meta.firstSet;
13176
+ if (fs.kind === "any") return null;
13177
+ const table = new Uint8Array(128);
13178
+ if (fs.kind === "ranges") {
13179
+ for (const r of fs.ranges) for (let c = Math.max(0, r.lo); c <= Math.min(127, r.hi); c++) table[c] = 1;
13180
+ }
13181
+ return table;
13182
+ }
13011
13183
  function clearRunEnd(input, cur, ctx, triviaP, plain) {
13012
13184
  const rootKinds = ctx._rootTriviaKindIndex;
13013
13185
  const spec = triviaP?._meta.labeledTriviaSpec;
@@ -13056,6 +13228,9 @@ function clearOf(ranges, input, from, to) {
13056
13228
  return true;
13057
13229
  }
13058
13230
 
13231
+ // src/table/assemble.ts
13232
+ import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "./cst/plain.js";
13233
+
13059
13234
  // src/table/fail-clean.ts
13060
13235
  function passChild(code, ip) {
13061
13236
  switch (code[ip]) {
@@ -13383,7 +13558,7 @@ function assemble(t, prog, cfg) {
13383
13558
  const NULLABLE = /* @__PURE__ */ new Map();
13384
13559
  const CLEAN = REC2 ? () => false : failCleanAnalysis(code);
13385
13560
  function pushLeaf(ctx, value, s, e) {
13386
- const lf = { _tag: "leaf", value, span: { start: s, end: e } };
13561
+ const lf = new PlainLeaf9(value, new PlainSpan10(s, e));
13387
13562
  pushCstLeaf(ctx, lf);
13388
13563
  }
13389
13564
  function plainBuildNode(child, build, trailing) {
@@ -13416,7 +13591,7 @@ function assemble(t, prog, cfg) {
13416
13591
  ctx.captureTrivia = sCap;
13417
13592
  if (value === FAIL) return FAIL;
13418
13593
  const end = EC.e;
13419
- const span = { start: pos, end };
13594
+ const span = new PlainSpan10(pos, end);
13420
13595
  const node2 = build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
13421
13596
  if (sBuf !== void 0 || sCh !== void 0) {
13422
13597
  pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
@@ -13461,7 +13636,7 @@ function assemble(t, prog, cfg) {
13461
13636
  ctx.captureTrivia = sCap;
13462
13637
  if (value === FAIL) return FAIL;
13463
13638
  const end = EC.e;
13464
- const node2 = build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
13639
+ const node2 = build(captured, void 0, new PlainSpan10(pos, end), EMPTY_CH, EMPTY_TL2, void 0);
13465
13640
  if (sBuf !== void 0 || sCh !== void 0) {
13466
13641
  pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
13467
13642
  }
@@ -13498,7 +13673,7 @@ function assemble(t, prog, cfg) {
13498
13673
  ctx.captureTrivia = sCap;
13499
13674
  if (value === FAIL) return FAIL;
13500
13675
  const end = EC.e;
13501
- const node2 = build(captured, fieldMap, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
13676
+ const node2 = build(captured, fieldMap, new PlainSpan10(pos, end), EMPTY_CH, EMPTY_TL2, void 0);
13502
13677
  if (sBuf !== void 0 || sCh !== void 0) {
13503
13678
  pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
13504
13679
  }
@@ -13535,7 +13710,7 @@ function assemble(t, prog, cfg) {
13535
13710
  ctx.captureTrivia = sCap;
13536
13711
  if (value === FAIL) return FAIL;
13537
13712
  const end = EC.e;
13538
- const span = { start: pos, end };
13713
+ const span = new PlainSpan10(pos, end);
13539
13714
  const node2 = kids.length === 1 ? kids[0] : build(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
13540
13715
  if (sBuf !== void 0 || sCh !== void 0) {
13541
13716
  pushCstChild(ctx, node2, rawEntry(node2, input, pos, end));
@@ -13572,7 +13747,7 @@ function assemble(t, prog, cfg) {
13572
13747
  ctx.captureTrivia = sCap;
13573
13748
  if (value === FAIL) return FAIL;
13574
13749
  const end = EC.e;
13575
- const node2 = captured.length === 1 ? captured[0] : build(captured, void 0, { start: pos, end }, EMPTY_CH, EMPTY_TL2, void 0);
13750
+ const node2 = captured.length === 1 ? captured[0] : build(captured, void 0, new PlainSpan10(pos, end), EMPTY_CH, EMPTY_TL2, void 0);
13576
13751
  if (sBuf !== void 0 || sCh !== void 0) {
13577
13752
  pushCstChild(ctx, node2, sBuf !== void 0 || sRaw !== void 0 ? rawEntry(node2, input, pos, end) : void 0);
13578
13753
  }
@@ -13681,7 +13856,23 @@ function assemble(t, prog, cfg) {
13681
13856
  }
13682
13857
  return out;
13683
13858
  }
13859
+ const LEAD_TABLES = trivia2.map((tp) => tp === void 0 ? null : triviaLeadTable(tp));
13860
+ let LEAD_OF;
13861
+ let LEAD_TABLE = null;
13862
+ function cannotStartTrivia(input, cur, triviaP) {
13863
+ if (triviaP !== LEAD_OF) {
13864
+ LEAD_OF = triviaP;
13865
+ const slot = trivia2.indexOf(triviaP);
13866
+ LEAD_TABLE = slot >= 0 ? LEAD_TABLES[slot] : triviaLeadTable(triviaP);
13867
+ }
13868
+ const table = LEAD_TABLE;
13869
+ if (table === null) return false;
13870
+ const c = input.charCodeAt(cur);
13871
+ return c < 128 && table[c] === 0;
13872
+ }
13684
13873
  function skipTrivia(input, cur, ctx) {
13874
+ const t2 = ctx.trivia;
13875
+ if (t2 !== void 0 && cannotStartTrivia(input, cur, t2)) return cur;
13685
13876
  const s = SCAN;
13686
13877
  if (s !== null && ctx._triviaLog === void 0 && !(ctx.captureTrivia === true && (ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0))) {
13687
13878
  return s(input, cur);
@@ -13696,7 +13887,8 @@ function assemble(t, prog, cfg) {
13696
13887
  const frames = [];
13697
13888
  let depth = 0;
13698
13889
  function nextTerm(child, input, cur, ctx) {
13699
- if (ctx.trivia === void 0) {
13890
+ const t2 = ctx.trivia;
13891
+ if (t2 === void 0 || cannotStartTrivia(input, cur, t2)) {
13700
13892
  const v2 = child(input, cur, ctx);
13701
13893
  if (v2 === FAIL) return -1;
13702
13894
  TERMV = v2;
@@ -13725,7 +13917,8 @@ function assemble(t, prog, cfg) {
13725
13917
  return cur;
13726
13918
  }
13727
13919
  function nextTermBuffered(child, input, cur, ctx) {
13728
- if (ctx.trivia === void 0) {
13920
+ const t2 = ctx.trivia;
13921
+ if (t2 === void 0 || cannotStartTrivia(input, cur, t2)) {
13729
13922
  const v2 = child(input, cur, ctx);
13730
13923
  if (v2 === FAIL) return -1;
13731
13924
  TERMV = v2;
@@ -13987,7 +14180,7 @@ function assemble(t, prog, cfg) {
13987
14180
  return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
13988
14181
  const savedRouted = ctx._routed;
13989
14182
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
13990
- ctx._routed = { value: key, span: { start: pos, end: selEnd } };
14183
+ ctx._routed = { value: key, span: new PlainSpan10(pos, selEnd) };
13991
14184
  let v;
13992
14185
  try {
13993
14186
  v = child(input, pos, ctx);
@@ -14420,7 +14613,7 @@ function assemble(t, prog, cfg) {
14420
14613
  case OP_EXPECT: {
14421
14614
  const child = link(code[ip + 1]);
14422
14615
  const xf = fx[code[ip + 2]];
14423
- const expectSpan = (ctx, pos) => prog.lines === 1 ? spanLines(ctx, pos, pos) : { start: pos, end: pos };
14616
+ const expectSpan = (ctx, pos) => prog.lines === 1 ? spanLines(ctx, pos, pos) : new PlainSpan10(pos, pos);
14424
14617
  if (REC2) {
14425
14618
  return (input, pos, ctx) => {
14426
14619
  const v = child(input, pos, ctx);
@@ -14452,7 +14645,7 @@ function assemble(t, prog, cfg) {
14452
14645
  return (input, pos, ctx) => {
14453
14646
  const v = child(input, pos, ctx);
14454
14647
  if (v === FAIL) return FAIL;
14455
- ctx._fields?.push({ name, value: v, span: { start: pos, end: EC.e } });
14648
+ ctx._fields?.push(new PlainField(name, v, new PlainSpan10(pos, EC.e)));
14456
14649
  return v;
14457
14650
  };
14458
14651
  }
@@ -14476,7 +14669,7 @@ function assemble(t, prog, cfg) {
14476
14669
  return (input, pos, ctx) => {
14477
14670
  const v = child(input, pos, ctx);
14478
14671
  if (v === FAIL) return FAIL;
14479
- return fn(v, { start: pos, end: EC.e });
14672
+ return fn(v, new PlainSpan10(pos, EC.e));
14480
14673
  };
14481
14674
  }
14482
14675
  case OP_SCAN: {
@@ -14527,6 +14720,7 @@ function assemble(t, prog, cfg) {
14527
14720
  const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
14528
14721
  const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
14529
14722
  const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? triviaScan[ki] : null;
14723
+ const scopeLead = ki < 0 ? null : LEAD_TABLES[ki];
14530
14724
  const child = link(code[ip + 2]);
14531
14725
  const scopePiece = code[ip] === OP_SCOPE_CAP ? (input, pos, ctx) => {
14532
14726
  const saved = ctx.trivia;
@@ -14534,6 +14728,9 @@ function assemble(t, prog, cfg) {
14534
14728
  const savedScan = SCAN;
14535
14729
  const savedCap = ctx.captureTrivia;
14536
14730
  SCAN = scanFor;
14731
+ const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
14732
+ LEAD_OF = scopeTrivia;
14733
+ LEAD_TABLE = scopeLead;
14537
14734
  ctx.trivia = scopeTrivia;
14538
14735
  ctx.triviaKindLabels = scopeLabels;
14539
14736
  ctx.captureTrivia = true;
@@ -14542,18 +14739,25 @@ function assemble(t, prog, cfg) {
14542
14739
  ctx.trivia = saved;
14543
14740
  ctx.triviaKindLabels = savedLabels;
14544
14741
  SCAN = savedScan;
14742
+ LEAD_OF = savedLeadOf;
14743
+ LEAD_TABLE = savedLead;
14545
14744
  return v;
14546
14745
  } : (input, pos, ctx) => {
14547
14746
  const saved = ctx.trivia;
14548
14747
  const savedLabels = ctx.triviaKindLabels;
14549
14748
  const savedScan = SCAN;
14550
14749
  SCAN = scanFor;
14750
+ const savedLeadOf = LEAD_OF, savedLead = LEAD_TABLE;
14751
+ LEAD_OF = scopeTrivia;
14752
+ LEAD_TABLE = scopeLead;
14551
14753
  ctx.trivia = scopeTrivia;
14552
14754
  ctx.triviaKindLabels = scopeLabels;
14553
14755
  const v = child(input, pos, ctx);
14554
14756
  ctx.trivia = saved;
14555
14757
  ctx.triviaKindLabels = savedLabels;
14556
14758
  SCAN = savedScan;
14759
+ LEAD_OF = savedLeadOf;
14760
+ LEAD_TABLE = savedLead;
14557
14761
  return v;
14558
14762
  };
14559
14763
  return scopeRootPolicy(scopePiece, code[ip] === OP_SCOPE_PLAIN ? 0 : code[ip + 3]);
@@ -14569,7 +14773,7 @@ function assemble(t, prog, cfg) {
14569
14773
  ctx._fx = ROUTED_FX;
14570
14774
  return FAIL;
14571
14775
  }
14572
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: item.value, span: item.span });
14776
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf9(item.value, item.span));
14573
14777
  EC.e = item.span.end;
14574
14778
  return item.value;
14575
14779
  };
@@ -14755,7 +14959,7 @@ function assemble(t, prog, cfg) {
14755
14959
  if (v === FAIL) return FAIL;
14756
14960
  const end = EC.e;
14757
14961
  const value = input.slice(pos, end);
14758
- if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
14962
+ if (wasCapturing) pushCstLeaf(ctx, new PlainLeaf9(value, new PlainSpan10(pos, end)));
14759
14963
  EC.e = end;
14760
14964
  return value;
14761
14965
  };
@@ -14789,7 +14993,7 @@ function assemble(t, prog, cfg) {
14789
14993
  if (ctx._probe !== void 0) failAt(ctx, suffixExpected, end);
14790
14994
  }
14791
14995
  const value = input.slice(pos, end);
14792
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
14996
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf9(value, new PlainSpan10(pos, end)));
14793
14997
  EC.e = end;
14794
14998
  return value;
14795
14999
  };
@@ -14832,7 +15036,7 @@ function assemble(t, prog, cfg) {
14832
15036
  }
14833
15037
  if (end < 0) return FAIL;
14834
15038
  const value = input.slice(pos, end);
14835
- if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
15039
+ if (wasCapturing) pushCstLeaf(ctx, new PlainLeaf9(value, new PlainSpan10(pos, end)));
14836
15040
  EC.e = end;
14837
15041
  return value;
14838
15042
  };
@@ -14841,7 +15045,7 @@ function assemble(t, prog, cfg) {
14841
15045
  const end = run3(input, pos, ctx);
14842
15046
  if (end < 0) return FAIL;
14843
15047
  const value = input.slice(pos, end);
14844
- if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
15048
+ if (cstCaptureActive(ctx)) pushCstLeaf(ctx, new PlainLeaf9(value, new PlainSpan10(pos, end)));
14845
15049
  EC.e = end;
14846
15050
  return value;
14847
15051
  };
@@ -14874,12 +15078,8 @@ function assemble(t, prog, cfg) {
14874
15078
  }
14875
15079
  if (v === FAIL) return FAIL;
14876
15080
  const end = EC.e;
14877
- const out = fn(v, { start: pos, end });
14878
- if (wasCapturing) pushCstLeaf(ctx, {
14879
- _tag: "leaf",
14880
- value: op === OP_SOURCE_LEAF && hostCst ? input.slice(pos, end) : out,
14881
- span: { start: pos, end }
14882
- });
15081
+ const out = fn(v, new PlainSpan10(pos, end));
15082
+ if (wasCapturing) pushCstLeaf(ctx, new PlainLeaf9(op === OP_SOURCE_LEAF && hostCst ? input.slice(pos, end) : out, new PlainSpan10(pos, end)));
14883
15083
  EC.e = end;
14884
15084
  return out;
14885
15085
  };
@@ -15014,7 +15214,7 @@ function assemble(t, prog, cfg) {
15014
15214
  const cur = runSyncTerms(input, pos, ctx, values);
15015
15215
  if (cur < 0) return FAIL;
15016
15216
  EC.e = cur;
15017
- return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
15217
+ return projection >= 0 ? values[projection] : fn(values, new PlainSpan10(pos, cur));
15018
15218
  };
15019
15219
  }
15020
15220
  if (wantValues) {
@@ -15108,7 +15308,7 @@ function assemble(t, prog, cfg) {
15108
15308
  const cur = runAdjTerms(input, pos, ctx, values);
15109
15309
  if (cur < 0) return FAIL;
15110
15310
  EC.e = cur;
15111
- return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
15311
+ return projection >= 0 ? values[projection] : fn(values, new PlainSpan10(pos, cur));
15112
15312
  };
15113
15313
  }
15114
15314
  if (wantValues) {
@@ -15133,7 +15333,7 @@ function assemble(t, prog, cfg) {
15133
15333
  return (input, pos, ctx) => {
15134
15334
  const v = k0(input, pos, ctx);
15135
15335
  if (v === FAIL) return FAIL;
15136
- return projection === 0 ? v : fn([v], { start: pos, end: EC.e });
15336
+ return projection === 0 ? v : fn([v], new PlainSpan10(pos, EC.e));
15137
15337
  };
15138
15338
  }
15139
15339
  if (wantValues) {
@@ -15158,7 +15358,7 @@ function assemble(t, prog, cfg) {
15158
15358
  const cur = step(k1, input, EC.e, ctx);
15159
15359
  if (cur < 0) return FAIL;
15160
15360
  EC.e = cur;
15161
- return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
15361
+ return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], new PlainSpan10(pos, cur));
15162
15362
  };
15163
15363
  }
15164
15364
  if (wantValues) {
@@ -15192,7 +15392,7 @@ function assemble(t, prog, cfg) {
15192
15392
  cur = step(k2, input, cur, ctx);
15193
15393
  if (cur < 0) return FAIL;
15194
15394
  EC.e = cur;
15195
- return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
15395
+ return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], new PlainSpan10(pos, cur));
15196
15396
  };
15197
15397
  }
15198
15398
  if (wantValues) {
@@ -15289,7 +15489,7 @@ function assemble(t, prog, cfg) {
15289
15489
  const cur = runDirectTerms(input, pos, ctx, values);
15290
15490
  if (cur < 0) return FAIL;
15291
15491
  EC.e = cur;
15292
- return projection >= 0 ? values[projection] : fn(values, { start: pos, end: cur });
15492
+ return projection >= 0 ? values[projection] : fn(values, new PlainSpan10(pos, cur));
15293
15493
  };
15294
15494
  }
15295
15495
  if (wantValues) {
@@ -16187,10 +16387,10 @@ function assemble(t, prog, cfg) {
16187
16387
  return FAIL;
16188
16388
  }
16189
16389
  const value = regexValue ? input.slice(pos, end) : spec;
16190
- const leaf2 = { _tag: "leaf", value, span: { start: pos, end } };
16390
+ const leaf2 = new PlainLeaf9(value, new PlainSpan10(pos, end));
16191
16391
  const kids = [leaf2];
16192
16392
  const rawKids = [leaf2];
16193
- const span = { start: pos, end };
16393
+ const span = new PlainSpan10(pos, end);
16194
16394
  EC.e = end;
16195
16395
  const nd = build2(kids, void 0, span, rawKids, EMPTY_TL2, void 0);
16196
16396
  if (ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0) {
@@ -16272,7 +16472,7 @@ function assemble(t, prog, cfg) {
16272
16472
  const sCh = ctx._cstChildren;
16273
16473
  const sCap = ctx.captureTrivia;
16274
16474
  const sBuf = ctx._cstBuf;
16275
- const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
16475
+ const buf = rawOnly ? new PlainBuf2(true, void 0, 0) : omitsRaw ? new PlainBuf2(void 0, true, 0) : new PlainBuf2(void 0, void 0, 0);
16276
16476
  ctx._cstBuf = buf;
16277
16477
  ctx.captureTrivia = captureWide;
16278
16478
  const savedFields = ctx._fields;
@@ -16294,7 +16494,7 @@ function assemble(t, prog, cfg) {
16294
16494
  ctx.captureTrivia = sCap;
16295
16495
  if (v === FAIL) return FAIL;
16296
16496
  const end = EC.e;
16297
- const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
16497
+ const span = tracked ? spanLines(ctx, pos, end) : new PlainSpan10(pos, end);
16298
16498
  const st = readsState ? ctx.state : void 0;
16299
16499
  let nd;
16300
16500
  if (unwrap && kids.length === 1) {
@@ -16318,7 +16518,7 @@ function assemble(t, prog, cfg) {
16318
16518
  } else if (host !== void 0) {
16319
16519
  nd = host(type, hostKids, fieldMap, span, rawKids, tlog, st, tags);
16320
16520
  } else {
16321
- nd = { _tag: "node", type, span, state: st ?? null, children: kids };
16521
+ nd = new PlainNode2(type, span, st ?? null, kids === EMPTY_CH ? kids : [...kids]);
16322
16522
  }
16323
16523
  if (sBuf !== void 0 || sCh !== void 0) {
16324
16524
  pushCstChild(ctx, nd, rawEntry(nd, input, pos, end));
@@ -16344,7 +16544,7 @@ function assemble(t, prog, cfg) {
16344
16544
  const at = fe === void 0 || fe < 0 ? pos : fe;
16345
16545
  return { ok: false, expected: ctx._fx ?? EMPTY_FX2, span: { start: at, end: at } };
16346
16546
  }
16347
- return { ok: true, value: v, span: { start: pos, end: EC.e } };
16547
+ return { ok: true, value: v, span: new PlainSpan10(pos, EC.e) };
16348
16548
  }
16349
16549
  };
16350
16550
  }
@@ -16459,7 +16659,12 @@ function assemble(t, prog, cfg) {
16459
16659
  LEAD,
16460
16660
  triviaFieldCapture,
16461
16661
  skipDeferredTrivia,
16462
- collapseEmpty
16662
+ collapseEmpty,
16663
+ PlainSpan10,
16664
+ PlainLeaf9,
16665
+ PlainNode2,
16666
+ PlainField,
16667
+ PlainBuf2
16463
16668
  );
16464
16669
  emitReached = new Set(pre.reached);
16465
16670
  if (emitted.ext !== void 0) HYBRID = emitted;
@@ -16546,7 +16751,12 @@ function assemble(t, prog, cfg) {
16546
16751
  LEAD,
16547
16752
  triviaFieldCapture,
16548
16753
  skipDeferredTrivia,
16549
- collapseEmpty
16754
+ collapseEmpty,
16755
+ PlainSpan10,
16756
+ PlainLeaf9,
16757
+ PlainNode2,
16758
+ PlainField,
16759
+ PlainBuf2
16550
16760
  );
16551
16761
  emitReached = em.reached;
16552
16762
  } catch (e) {
@@ -16804,7 +17014,11 @@ function tableRules(source, metadataOrEntry = {}) {
16804
17014
  return map[entry];
16805
17015
  }
16806
17016
 
17017
+ // src/version.ts
17018
+ var PARSEMAN_VERSION = "0.59.0";
17019
+
16807
17020
  // src/table/emit.ts
17021
+ var FACTORY_ARITY_GUARD = `if(arguments.length<${EMITTED_PARAMS.length})throw new Error(${JSON.stringify(`parseman: this parser was printed by parseman ${PARSEMAN_VERSION}; upgrade the parseman runtime to at least that version`)});`;
16808
17022
  function jsString(s) {
16809
17023
  return JSON.stringify(s);
16810
17024
  }
@@ -16890,7 +17104,7 @@ function emitAssemblies(prog, cfgs) {
16890
17104
  throw e;
16891
17105
  }
16892
17106
  const plan = em.plan;
16893
- out.push(`{key:${key},factory:function(${EMITTED_PARAMS.join(",")}){${em.source}
17107
+ out.push(`{key:${key},factory:function(${EMITTED_PARAMS.join(",")}){${FACTORY_ARITY_GUARD}${em.source}
16894
17108
  },plan:{classes:[${plan.classes.map((r) => `[${r.join(",")}]`).join(",")}],armExpected:[${plan.armExpected.map((r) => `[${r.join(",")}]`).join(",")}],masks:[${plan.masks.join(",")}]},reached:[${[...em.reached].join(",")}]}`);
16895
17109
  }
16896
17110
  return [`a:[${out.join(",")}],`];
@@ -18589,8 +18803,8 @@ function compileRuleMap(ruleMap, opts = {}) {
18589
18803
  const roots = assemblyExtraIps(artifact);
18590
18804
  let siteBytes, fixed;
18591
18805
  try {
18592
- siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes;
18593
- fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set()).source.length;
18806
+ siteBytes = emitAssemblySource(table, artifact, cfg, roots, true, void 0, true).siteBytes;
18807
+ fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set(), true).source.length;
18594
18808
  } catch (e) {
18595
18809
  if (e instanceof Unemittable) return { ...none, refusal: e.construct };
18596
18810
  throw e;
@@ -18606,7 +18820,7 @@ function compileRuleMap(ruleMap, opts = {}) {
18606
18820
  refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
18607
18821
  };
18608
18822
  }
18609
- const bytes2 = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
18823
+ const bytes2 = emitAssemblySource(table, artifact, cfg, roots, true, sites, true).source.length;
18610
18824
  if (bytes2 <= ceiling) return { sites, bytes: Math.ceil(bytes2 * SUPERCOMPILE_GROWTH) };
18611
18825
  target *= Math.min(ceiling / bytes2, 0.99);
18612
18826
  }
@@ -19247,9 +19461,6 @@ function fieldOptionsSrc(def) {
19247
19461
  return `, { ${[def.leadingTrivia === true ? "leadingTrivia: true" : "", def.trailingTrivia === true ? "trailingTrivia: true" : ""].filter(Boolean).join(", ")} }`;
19248
19462
  }
19249
19463
 
19250
- // src/version.ts
19251
- var PARSEMAN_VERSION = "0.58.2";
19252
-
19253
19464
  // src/compiler/compile-linkable-table.ts
19254
19465
  function isLocal(rule) {
19255
19466
  const d = rule._def;
@@ -19316,6 +19527,7 @@ function compileLinkableTable(ruleMapArg, ns, opts = {}) {
19316
19527
  }
19317
19528
 
19318
19529
  // src/compiler/linker.ts
19530
+ import { PlainNode as PlainNode3, PlainTaggedNode } from "./cst/plain.js";
19319
19531
  function normalizeCstCollapse(collapse) {
19320
19532
  if (collapse === true) return () => true;
19321
19533
  if (Array.isArray(collapse)) {
@@ -19325,7 +19537,7 @@ function normalizeCstCollapse(collapse) {
19325
19537
  return typeof collapse === "function" ? collapse : void 0;
19326
19538
  }
19327
19539
  function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
19328
- return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
19540
+ return tags !== void 0 && tags.length > 0 ? new PlainTaggedNode(type, tags, copySpan(span), state ?? null, [...children2]) : new PlainNode3(type, copySpan(span), state ?? null, [...children2]);
19329
19541
  }
19330
19542
  function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
19331
19543
  if (typeof typeOrOptions === "string") {