parseman 0.49.0 → 0.50.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 (77) hide show
  1. package/dist/analysis/commitment.d.ts +2 -1
  2. package/dist/analysis/commitment.d.ts.map +1 -1
  3. package/dist/analysis/diagnostics.js +1931 -861
  4. package/dist/analysis/diagnostics.js.map +3 -3
  5. package/dist/analysis/rebuild.d.ts.map +1 -1
  6. package/dist/cli/index.js +1235 -164
  7. package/dist/cli/index.js.map +3 -3
  8. package/dist/combinators/trivia-skip.d.ts +1 -1
  9. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  10. package/dist/compiler/build-arity.d.ts +16 -0
  11. package/dist/compiler/build-arity.d.ts.map +1 -1
  12. package/dist/compiler/degradation.d.ts +0 -2
  13. package/dist/compiler/degradation.d.ts.map +1 -1
  14. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  15. package/dist/compiler/token-alphabet.d.ts +11 -0
  16. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  17. package/dist/compiler/token-capability.js +185 -20
  18. package/dist/compiler/token-capability.js.map +1 -1
  19. package/dist/cst/capture-buffer.d.ts +5 -1
  20. package/dist/cst/capture-buffer.d.ts.map +1 -1
  21. package/dist/index.js +1348 -279
  22. package/dist/index.js.map +3 -3
  23. package/dist/language-service/index.js +2 -1
  24. package/dist/language-service/index.js.map +1 -1
  25. package/dist/plugin/entry-supercompiler.d.ts +48 -0
  26. package/dist/plugin/entry-supercompiler.d.ts.map +1 -0
  27. package/dist/plugin/evaluator.d.ts.map +1 -1
  28. package/dist/plugin/index.d.ts.map +1 -1
  29. package/dist/plugin/index.js +1940 -385
  30. package/dist/plugin/index.js.map +3 -3
  31. package/dist/run/index.js +2 -1
  32. package/dist/run/index.js.map +1 -1
  33. package/dist/spec/index.js +28 -7
  34. package/dist/spec/index.js.map +1 -1
  35. package/dist/table/assemble.d.ts.map +1 -1
  36. package/dist/table/compile-rule-map.d.ts +6 -5
  37. package/dist/table/compile-rule-map.d.ts.map +1 -1
  38. package/dist/table/emit-assembly.d.ts +6 -1
  39. package/dist/table/emit-assembly.d.ts.map +1 -1
  40. package/dist/table/encode.d.ts.map +1 -1
  41. package/dist/table/index.js +1298 -231
  42. package/dist/table/index.js.map +3 -3
  43. package/dist/table/ops.d.ts +3 -2
  44. package/dist/table/ops.d.ts.map +1 -1
  45. package/dist/table/program.d.ts +15 -1
  46. package/dist/table/program.d.ts.map +1 -1
  47. package/dist/table/scalar-terminal.d.ts +30 -0
  48. package/dist/table/scalar-terminal.d.ts.map +1 -1
  49. package/dist/table/site-labels.d.ts +8 -0
  50. package/dist/table/site-labels.d.ts.map +1 -1
  51. package/dist/types.d.ts +2 -1
  52. package/dist/types.d.ts.map +1 -1
  53. package/dist/version.d.ts +1 -1
  54. package/package.json +1 -1
  55. package/src/analysis/commitment.ts +19 -8
  56. package/src/analysis/rebuild.ts +1 -0
  57. package/src/combinators/trivia-skip.ts +2 -2
  58. package/src/compiler/build-arity.ts +50 -0
  59. package/src/compiler/degradation.ts +0 -6
  60. package/src/compiler/ir-serialize.ts +6 -4
  61. package/src/compiler/token-alphabet.ts +322 -28
  62. package/src/cst/capture-buffer.ts +34 -11
  63. package/src/plugin/entry-supercompiler.ts +567 -0
  64. package/src/plugin/evaluator.ts +10 -0
  65. package/src/plugin/index.ts +7 -3
  66. package/src/table/assemble.ts +125 -42
  67. package/src/table/compile-rule-map.ts +8 -7
  68. package/src/table/compile.ts +7 -8
  69. package/src/table/emit-assembly.ts +646 -126
  70. package/src/table/emit.ts +1 -1
  71. package/src/table/encode.ts +132 -7
  72. package/src/table/ops.ts +3 -2
  73. package/src/table/program.ts +44 -3
  74. package/src/table/scalar-terminal.ts +213 -1
  75. package/src/table/site-labels.ts +22 -9
  76. package/src/types.ts +1 -1
  77. package/src/version.ts +1 -1
package/dist/cli/index.js CHANGED
@@ -927,7 +927,7 @@ function beginCstNodeCapture(ctx) {
927
927
  function finishCstBuf(buf) {
928
928
  if (!buf) return { children: EMPTY, rawChildren: EMPTY, triviaLog: EMPTY_TL };
929
929
  const children2 = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY);
930
- const rawChildren = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
930
+ const rawChildren = buf.noRaw === true ? EMPTY : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
931
931
  const triviaLog = buf.tl ?? EMPTY_TL;
932
932
  return { children: children2, rawChildren, triviaLog };
933
933
  }
@@ -959,7 +959,8 @@ function pushCstChild(ctx, built, rawEntry2) {
959
959
  b.single = void 0;
960
960
  } else b.single = built;
961
961
  }
962
- if (b.raw) b.raw.push(rawEntry2);
962
+ if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
963
+ else if (b.raw) b.raw.push(rawEntry2);
963
964
  else if (b.rawSingle !== void 0) {
964
965
  b.raw = [b.rawSingle, rawEntry2];
965
966
  b.rawSingle = void 0;
@@ -973,6 +974,7 @@ function pushCstChild(ctx, built, rawEntry2) {
973
974
  function cstRawLen(ctx) {
974
975
  const b = ctx._cstBuf;
975
976
  if (b) {
977
+ if (b.noRaw === true) return b.rawLen ?? 0;
976
978
  if (b.raw) return b.raw.length;
977
979
  return b.rawSingle !== void 0 ? 1 : 0;
978
980
  }
@@ -1032,19 +1034,37 @@ function rollbackCstCaptureAt(ctx, raw, tlog, leaves, fields, errors) {
1032
1034
  if (ctx._errors && errors !== void 0 && ctx._errors.length !== errors) ctx._errors.length = errors;
1033
1035
  const b = ctx._cstBuf;
1034
1036
  if (b) {
1035
- rollbackBufList(b, "raw", "rawSingle", raw);
1036
- rollbackBufList(b, "ch", "single", leaves);
1037
+ if (b.noRaw === true) {
1038
+ if (b.rawLen !== raw) b.rawLen = raw;
1039
+ } else {
1040
+ const rawList = b.raw;
1041
+ if (rawList) {
1042
+ if (raw === 0) b.raw = void 0;
1043
+ else if (raw === 1) {
1044
+ b.rawSingle = rawList[0];
1045
+ b.raw = void 0;
1046
+ } else if (rawList.length !== raw) rawList.length = raw;
1047
+ } else if (raw === 0) b.rawSingle = void 0;
1048
+ }
1049
+ const childList = b.ch;
1050
+ if (childList) {
1051
+ if (leaves === 0) b.ch = void 0;
1052
+ else if (leaves === 1) {
1053
+ b.single = childList[0];
1054
+ b.ch = void 0;
1055
+ } else if (childList.length !== leaves) childList.length = leaves;
1056
+ } else if (leaves === 0) b.single = void 0;
1037
1057
  if (b.tl) {
1038
1058
  if (tlog === 0) b.tl = void 0;
1039
1059
  else if (b.tl.length !== tlog) b.tl.length = tlog;
1040
1060
  }
1041
- if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
1061
+ if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
1042
1062
  return;
1043
1063
  }
1044
1064
  if (ctx._cstRawChildren && ctx._cstRawChildren.length !== raw) ctx._cstRawChildren.length = raw;
1045
1065
  if (ctx._cstTriviaLog && ctx._cstTriviaLog.length !== tlog) ctx._cstTriviaLog.length = tlog;
1046
1066
  if (ctx._cstLeaves && ctx._cstLeaves.length !== leaves) ctx._cstLeaves.length = leaves;
1047
- if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
1067
+ if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
1048
1068
  }
1049
1069
  function pushCstTriviaEntry(ctx, start, end, kindIndex) {
1050
1070
  const insertIdx = cstRawLen(ctx);
@@ -2476,6 +2496,13 @@ function canConsumeNewline(n) {
2476
2496
  return n.parts.some(canConsumeNewline);
2477
2497
  }
2478
2498
  }
2499
+ function regexCanMatchEmpty(source) {
2500
+ try {
2501
+ return nullable(parseRegex(source));
2502
+ } catch {
2503
+ return true;
2504
+ }
2505
+ }
2479
2506
  function firstSetFromRegex(source) {
2480
2507
  let ast;
2481
2508
  try {
@@ -4923,6 +4950,7 @@ function confirmedArityForDef(def) {
4923
4950
  }
4924
4951
  function buildReadsRaw(def) {
4925
4952
  if (!def.build) return true;
4953
+ if (def.buildRawUnused === true) return false;
4926
4954
  const arity = confirmedArityForDef(def);
4927
4955
  if (arity === null) return true;
4928
4956
  return arity >= 4;
@@ -5479,7 +5507,7 @@ function evalRuleMapIR(ir) {
5479
5507
  l._def.fnSrc = src;
5480
5508
  return l;
5481
5509
  };
5482
- const _nd = (type, child, src, opts, staticError, sigSrc, buildImports) => {
5510
+ const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
5483
5511
  if (staticError !== void 0 && staticError.length > 0) {
5484
5512
  throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
5485
5513
  }
@@ -5489,6 +5517,7 @@ function evalRuleMapIR(ir) {
5489
5517
  n._def.buildSrc = src;
5490
5518
  if (staticError !== void 0) n._def.buildStaticError = staticError;
5491
5519
  if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
5520
+ if (rawUnused === true) n._def.buildRawUnused = true;
5492
5521
  if (buildImports !== void 0) n._def.buildImports = buildImports;
5493
5522
  return n;
5494
5523
  };
@@ -5621,6 +5650,301 @@ function evalRuleMapIR(ir) {
5621
5650
  return Object.entries(map);
5622
5651
  }
5623
5652
 
5653
+ // src/analysis/commitment.ts
5654
+ function mayFail(p, seen = /* @__PURE__ */ new Set()) {
5655
+ if (seen.has(p)) return true;
5656
+ seen.add(p);
5657
+ const d = p._def;
5658
+ switch (d.tag) {
5659
+ case "literal":
5660
+ return d.value.length > 0;
5661
+ case "trivia":
5662
+ return false;
5663
+ // `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
5664
+ // repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
5665
+ // that has selected an arm and then failed inside it breaks out past every
5666
+ // enclosing repeat, straight to the fallible boundary. So these are total
5667
+ // exactly when their body cannot commit. (Measured: treating them as
5668
+ // unconditionally total left an extra zero-width leaf in
5669
+ // `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
5670
+ // build fired and this one had deleted.)
5671
+ case "optional":
5672
+ case "many":
5673
+ return mayCommitFailure(d.parser);
5674
+ case "sepBy":
5675
+ return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
5676
+ case "oneOrMore":
5677
+ return mayFail(d.parser, seen);
5678
+ case "sequence":
5679
+ return d.parsers.some((x) => mayFail(x, seen));
5680
+ // Delegating wrappers: as fallible as what they wrap.
5681
+ case "node":
5682
+ case "transform":
5683
+ case "label":
5684
+ case "field":
5685
+ case "expect":
5686
+ case "withCtx":
5687
+ case "grammar":
5688
+ case "token":
5689
+ case "leaf":
5690
+ return mayFail(d.parser, seen);
5691
+ case "lazy": {
5692
+ try {
5693
+ return mayFail(d.thunk(), seen);
5694
+ } catch {
5695
+ return true;
5696
+ }
5697
+ }
5698
+ // An adjacency assertion is a TEST — failing is its whole job.
5699
+ case "adjacency":
5700
+ return true;
5701
+ default:
5702
+ return true;
5703
+ }
5704
+ }
5705
+ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
5706
+ if (seen.has(p)) return false;
5707
+ seen.add(p);
5708
+ const d = p._def;
5709
+ switch (d.tag) {
5710
+ // Atomic / non-capturing-then-failing: a failure happens before any push.
5711
+ case "literal":
5712
+ case "regex":
5713
+ case "keywords":
5714
+ case "guard":
5715
+ // Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
5716
+ case "adjacency":
5717
+ case "not":
5718
+ // peek(): emitted under a non-capturing probe ctx and zero-width on both
5719
+ // outcomes, so it can never leave a partial capture behind.
5720
+ case "peek":
5721
+ case "trivia":
5722
+ case "token":
5723
+ case "leaf":
5724
+ case "scanTo":
5725
+ case "unknown":
5726
+ return false;
5727
+ // node() captures into its own private buffers and rolls them back on
5728
+ // failure (emitNode restores _ctx.* and never pushes on the !ok path).
5729
+ case "node":
5730
+ return false;
5731
+ // choice/firstMatch already roll back each failed arm; on overall failure
5732
+ // nothing committed remains.
5733
+ case "choice":
5734
+ return false;
5735
+ case "dispatch":
5736
+ return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
5737
+ case "attempt":
5738
+ return false;
5739
+ // optional never fails; many/oneOrMore only "fail" with zero captured items.
5740
+ case "optional":
5741
+ case "many":
5742
+ case "oneOrMore":
5743
+ return false;
5744
+ // sepBy emits its own per-iteration rollback in emitSepBy.
5745
+ case "sepBy":
5746
+ return false;
5747
+ // A sequence is the real case: an earlier capturing term followed by a term
5748
+ // that can fail leaves the earlier captures buffered.
5749
+ //
5750
+ // BOTH halves of that sentence are load-bearing, and the second half is what
5751
+ // this walk exists to exploit. "Some earlier term captures" alone was the old
5752
+ // test, and it is true of very nearly every sequence in a real grammar — a
5753
+ // sequence almost always opens with a literal or a node. The rollback is only
5754
+ // reachable if something AFTER the capture can still fail; once the remainder
5755
+ // is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
5756
+ // failure path left to roll back from, and the save+restore is dead code.
5757
+ //
5758
+ // `captured` tracks whether anything is in the buffers yet as the scan moves
5759
+ // left to right. Two things put it there:
5760
+ // - a term that captures (`capturesLeaf`/`hasNodeDef`), and
5761
+ // - the inter-term TRIVIA scan, which under `capturing` pushes into
5762
+ // `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
5763
+ // i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
5764
+ // path (the "matched empty, so leave the whitespace out of the span"
5765
+ // branch); a term that FAILS breaks straight out with the trivia still
5766
+ // buffered, so from boundary 1 onward the buffers are dirty regardless of
5767
+ // what the earlier terms did.
5768
+ // Each term is also asked about itself: a nested sequence can leave its own
5769
+ // partial capture behind, and its terms are emitted inline into this same
5770
+ // block with no boundary of their own to roll them back.
5771
+ case "sequence": {
5772
+ const parts = d.parsers;
5773
+ let captured = false;
5774
+ for (let i = 0; i < parts.length; i++) {
5775
+ const part = parts[i];
5776
+ if (i > 0 && triviaActive) captured = true;
5777
+ if (captured && mayFail(part)) return true;
5778
+ if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
5779
+ if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
5780
+ }
5781
+ return false;
5782
+ }
5783
+ // Delegating wrappers: defer to the wrapped parser.
5784
+ case "transform":
5785
+ case "label":
5786
+ case "field":
5787
+ case "expect":
5788
+ case "withCtx":
5789
+ case "grammar":
5790
+ return mayLeavePartialCapture(d.parser, seen, triviaActive);
5791
+ case "recover":
5792
+ return mayLeavePartialCapture(d.parser, seen, triviaActive);
5793
+ case "lazy": {
5794
+ try {
5795
+ return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
5796
+ } catch {
5797
+ return true;
5798
+ }
5799
+ }
5800
+ // Unknown shapes: be safe and keep the rollback.
5801
+ default:
5802
+ return true;
5803
+ }
5804
+ }
5805
+ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
5806
+ if (seen.has(p)) return false;
5807
+ seen.add(p);
5808
+ const d = p._def;
5809
+ switch (d.tag) {
5810
+ case "literal":
5811
+ case "regex":
5812
+ case "keywords":
5813
+ case "node":
5814
+ case "token":
5815
+ case "routed":
5816
+ case "leaf":
5817
+ return true;
5818
+ case "not":
5819
+ case "peek":
5820
+ case "guard":
5821
+ case "adjacency":
5822
+ case "trivia":
5823
+ case "unknown":
5824
+ return false;
5825
+ case "sequence":
5826
+ case "choice":
5827
+ return d.parsers.some((x) => capturesLeaf(x, seen));
5828
+ case "dispatch":
5829
+ return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
5830
+ case "sepBy":
5831
+ return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
5832
+ case "many":
5833
+ case "oneOrMore":
5834
+ case "optional":
5835
+ case "attempt":
5836
+ case "transform":
5837
+ case "label":
5838
+ case "field":
5839
+ case "expect":
5840
+ case "withCtx":
5841
+ case "grammar":
5842
+ case "recover":
5843
+ return capturesLeaf(d.parser, seen);
5844
+ case "scanTo":
5845
+ return true;
5846
+ case "lazy": {
5847
+ try {
5848
+ return capturesLeaf(d.thunk(), seen);
5849
+ } catch {
5850
+ return true;
5851
+ }
5852
+ }
5853
+ default:
5854
+ return true;
5855
+ }
5856
+ }
5857
+ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
5858
+ if (seen.has(p)) return false;
5859
+ seen.add(p);
5860
+ const d = p._def;
5861
+ switch (d.tag) {
5862
+ case "node":
5863
+ return true;
5864
+ case "lazy": {
5865
+ try {
5866
+ return hasNodeDef(d.thunk(), seen);
5867
+ } catch {
5868
+ return false;
5869
+ }
5870
+ }
5871
+ case "grammar":
5872
+ case "trivia":
5873
+ case "token":
5874
+ case "leaf":
5875
+ case "label":
5876
+ case "field":
5877
+ case "optional":
5878
+ case "many":
5879
+ case "oneOrMore":
5880
+ case "not":
5881
+ case "peek":
5882
+ case "transform":
5883
+ return hasNodeDef(d.parser, seen);
5884
+ case "sequence":
5885
+ case "choice":
5886
+ return d.parsers.some((x) => hasNodeDef(x, seen));
5887
+ case "dispatch":
5888
+ return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
5889
+ case "sepBy":
5890
+ return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
5891
+ case "scanTo":
5892
+ return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
5893
+ case "recover":
5894
+ return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
5895
+ case "expect":
5896
+ return hasNodeDef(d.parser, seen);
5897
+ case "withCtx":
5898
+ return hasNodeDef(d.parser, seen);
5899
+ default:
5900
+ return false;
5901
+ }
5902
+ }
5903
+ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve2) {
5904
+ if (seen.has(p)) return false;
5905
+ seen.add(p);
5906
+ const d = p._def;
5907
+ switch (d.tag) {
5908
+ case "dispatch":
5909
+ return true;
5910
+ case "choice":
5911
+ case "sequence":
5912
+ return d.parsers.some((x) => mayCommitFailure(x, seen, resolve2));
5913
+ case "many":
5914
+ case "oneOrMore":
5915
+ case "optional":
5916
+ case "attempt":
5917
+ case "transform":
5918
+ case "label":
5919
+ case "field":
5920
+ case "grammar":
5921
+ case "node":
5922
+ return mayCommitFailure(d.parser, seen, resolve2);
5923
+ case "sepBy":
5924
+ return mayCommitFailure(d.parser, seen, resolve2) || mayCommitFailure(d.separator, seen, resolve2);
5925
+ case "token":
5926
+ case "leaf":
5927
+ return mayCommitFailure(d.parser, seen, resolve2);
5928
+ case "withCtx":
5929
+ return mayCommitFailure(d.parser, seen, resolve2);
5930
+ case "scanTo":
5931
+ return mayCommitFailure(d.sentinel, seen, resolve2) || d.skip.some((x) => mayCommitFailure(x, seen, resolve2));
5932
+ case "lazy": {
5933
+ try {
5934
+ return mayCommitFailure(d.thunk(), seen, resolve2);
5935
+ } catch {
5936
+ const name = p._ruleName;
5937
+ const target = name === void 0 ? void 0 : resolve2?.(name);
5938
+ return target === void 0 ? true : mayCommitFailure(target, seen, resolve2);
5939
+ }
5940
+ }
5941
+ case "unknown":
5942
+ return true;
5943
+ default:
5944
+ return false;
5945
+ }
5946
+ }
5947
+
5624
5948
  // src/table/ops.ts
5625
5949
  var OP_LIT = 1;
5626
5950
  var OP_RX = 2;
@@ -6176,8 +6500,26 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
6176
6500
  }
6177
6501
  }
6178
6502
  var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
6179
- function ownTableProgram(prog, resolved) {
6180
- return { ...prog, [TABLE_RUNTIME]: { resolved } };
6503
+ function ownTableProgram(prog, resolved, caches = {}) {
6504
+ const runtime = prog[TABLE_RUNTIME];
6505
+ return {
6506
+ ...prog,
6507
+ [TABLE_RUNTIME]: {
6508
+ resolved,
6509
+ choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
6510
+ nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
6511
+ failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
6512
+ }
6513
+ };
6514
+ }
6515
+ function choiceRollbackMask(prog, ip) {
6516
+ return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
6517
+ }
6518
+ function choiceCannotCommit(prog, ip) {
6519
+ return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
6520
+ }
6521
+ function failureRollbackClean(prog, ip) {
6522
+ return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
6181
6523
  }
6182
6524
  var WIDE_CLASS_PREFIX_LO = 65535;
6183
6525
  var WIDE_CLASS_PREFIX_HI = 0;
@@ -6352,7 +6694,6 @@ function directArrayProjection(fn, fnSrc, arity) {
6352
6694
 
6353
6695
  // src/table/encode.ts
6354
6696
  import {
6355
- assertLexicalCapabilityClosure,
6356
6697
  collectLexicalCapabilities,
6357
6698
  winnerWrapsReference as winnerWrapsReference2
6358
6699
  } from "../compiler/token-capability.js";
@@ -6734,6 +7075,9 @@ var Encoder = class {
6734
7075
  lexIndex = /* @__PURE__ */ new Map();
6735
7076
  lexPrograms = [];
6736
7077
  lexProgramIndex = /* @__PURE__ */ new Map();
7078
+ choiceRollbackMasks = /* @__PURE__ */ new Map();
7079
+ nonCommittingChoiceSites = /* @__PURE__ */ new Set();
7080
+ failureRollbackCleanSites = /* @__PURE__ */ new Set();
6737
7081
  labels = void 0;
6738
7082
  /** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
6739
7083
  activeTrivia = void 0;
@@ -7144,6 +7488,71 @@ var Encoder = class {
7144
7488
  const w = this.winners;
7145
7489
  return w === void 0 ? void 0 : (name) => w[name];
7146
7490
  }
7491
+ /**
7492
+ * Whether a failed ordered-choice arm can leave state that the enclosing
7493
+ * choice must restore before trying its successor.
7494
+ *
7495
+ * `mayLeavePartialCapture` is the existing sound CST/trivia proof. The extra
7496
+ * writer census covers the side sinks that proof deliberately does not model:
7497
+ * fields, recovered errors, and interpreted scanners. Strict assemblies do
7498
+ * not run repeat recovery, but these rows can still publish through a caller's
7499
+ * context. Cycles are safe to stop: revisiting the same combinator cannot
7500
+ * discover a writer the first traversal did not already reach.
7501
+ */
7502
+ failureNeedsRollback(p, autoNot) {
7503
+ const refName = p._ruleName;
7504
+ const winner = refName === void 0 ? void 0 : this.winners?.[refName];
7505
+ const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
7506
+ const sideWriterMemo = /* @__PURE__ */ new Map();
7507
+ const hasSideWriter = (current, seen = /* @__PURE__ */ new Set()) => {
7508
+ const cached = sideWriterMemo.get(current);
7509
+ if (cached !== void 0) return { found: cached, complete: true };
7510
+ if (seen.has(current)) return { found: false, complete: false };
7511
+ const next = new Set(seen);
7512
+ next.add(current);
7513
+ const def = current._def;
7514
+ let result;
7515
+ switch (def.tag) {
7516
+ case "field":
7517
+ case "expect":
7518
+ case "recover":
7519
+ case "scanTo":
7520
+ case "unknown":
7521
+ result = { found: true, complete: true };
7522
+ break;
7523
+ case "lazy": {
7524
+ const name = current._ruleName;
7525
+ const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
7526
+ if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
7527
+ result = hasSideWriter(resolvedWinner, next);
7528
+ break;
7529
+ }
7530
+ try {
7531
+ result = hasSideWriter(def.thunk(), next);
7532
+ } catch {
7533
+ result = { found: true, complete: true };
7534
+ }
7535
+ break;
7536
+ }
7537
+ default: {
7538
+ let complete = true;
7539
+ result = { found: false, complete: true };
7540
+ for (const child of childrenOf(def)) {
7541
+ const childResult = hasSideWriter(child, next);
7542
+ if (childResult.found) {
7543
+ result = { found: true, complete: true };
7544
+ break;
7545
+ }
7546
+ complete &&= childResult.complete;
7547
+ }
7548
+ if (!result.found) result = { found: false, complete };
7549
+ }
7550
+ }
7551
+ if (result.found || result.complete) sideWriterMemo.set(current, result.found);
7552
+ return result;
7553
+ };
7554
+ return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || hasSideWriter(root).found || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
7555
+ }
7147
7556
  /** A first set becomes a char class string, or −1 for `any`. */
7148
7557
  charClass(fs) {
7149
7558
  if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
@@ -7429,9 +7838,39 @@ var Encoder = class {
7429
7838
  });
7430
7839
  const rr = this.refResolver();
7431
7840
  const finalChoice = classifyFinalChoice(arms, rr);
7432
- const classes = arms.map((_, i) => finalChoice.nullable[i] ? -1 : this.charClass(finalChoice.firstSets[i]));
7841
+ const transactionalFirst = arms.map((arm, i) => {
7842
+ if (!finalChoice.nullable[i]) return void 0;
7843
+ const def = arm._def;
7844
+ if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
7845
+ return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
7846
+ });
7847
+ const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
7848
+ const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
7849
+ if (transactionalFirst.some((first) => first !== void 0) && classes.every((cls) => cls >= 0)) {
7850
+ let overlap = false;
7851
+ for (let i = 0; i < gateFirst.length && !overlap; i++) {
7852
+ for (let j = i + 1; j < gateFirst.length; j++) {
7853
+ if (intersects(gateFirst[i], gateFirst[j])) {
7854
+ overlap = true;
7855
+ break;
7856
+ }
7857
+ }
7858
+ }
7859
+ if (!overlap) for (let i = 0; i < classes.length; i++) {
7860
+ if (transactionalFirst[i] !== void 0) classes[i] = -1;
7861
+ }
7862
+ }
7433
7863
  const dispIdx = this.disp.length;
7434
7864
  this.disp.push(classes);
7865
+ let rollbackMask = kids.length > 31 ? -1 : 0;
7866
+ if (rollbackMask === 0) {
7867
+ for (let i = 0; i < arms.length; i++) {
7868
+ const src = order[i];
7869
+ if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
7870
+ rollbackMask |= 1 << i;
7871
+ }
7872
+ }
7873
+ }
7435
7874
  const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
7436
7875
  this.code[head + 1] = dispIdx;
7437
7876
  this.code[head + 2] = kids.length;
@@ -7440,6 +7879,10 @@ var Encoder = class {
7440
7879
  this.code[head + 4 + i] = kids[i];
7441
7880
  this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
7442
7881
  }
7882
+ this.choiceRollbackMasks.set(head, rollbackMask);
7883
+ if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
7884
+ this.nonCommittingChoiceSites.add(head);
7885
+ }
7443
7886
  return head;
7444
7887
  }
7445
7888
  case "many":
@@ -7469,8 +7912,11 @@ var Encoder = class {
7469
7912
  }
7470
7913
  return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
7471
7914
  }
7472
- case "optional":
7473
- return this.emit(OP_OPT, this.node(d.parser).ip);
7915
+ case "optional": {
7916
+ const head = this.emit(OP_OPT, this.node(d.parser).ip);
7917
+ if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
7918
+ return head;
7919
+ }
7474
7920
  case "transform": {
7475
7921
  const inner = d.parser._def;
7476
7922
  if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
@@ -7629,6 +8075,7 @@ var Encoder = class {
7629
8075
  // lowering was correct only for a choice arm.
7630
8076
  case "attempt": {
7631
8077
  const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
8078
+ if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
7632
8079
  const fs = d.parser._meta.firstSet;
7633
8080
  if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
7634
8081
  const cls = this.charClass(fs);
@@ -7797,6 +8244,10 @@ var Encoder = class {
7797
8244
  ...this.rec ? { rec: 1 } : {},
7798
8245
  ...this.cov === void 0 ? {} : { cov: this.cov },
7799
8246
  lines: this.track ? 1 : 0
8247
+ }, void 0, {
8248
+ choiceRollbackMasks: this.choiceRollbackMasks,
8249
+ failureRollbackCleanSites: this.failureRollbackCleanSites,
8250
+ nonCommittingChoiceSites: this.nonCommittingChoiceSites
7800
8251
  });
7801
8252
  }
7802
8253
  };
@@ -7841,7 +8292,6 @@ function encodeTableProgram(ruleMap, settings = {}) {
7841
8292
  const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
7842
8293
  const resolveLexical = (name) => ruleMap[name];
7843
8294
  const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
7844
- assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
7845
8295
  const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
7846
8296
  enc.winners = ruleMap;
7847
8297
  for (const name of names) enc.encodeRule(name, ruleMap[name]);
@@ -8974,13 +9424,17 @@ var TRI_NONE = -1;
8974
9424
  var CAP_UNKNOWN = 0;
8975
9425
  var CAP_OFF = 1;
8976
9426
  var CAP_ON = 2;
8977
- var TOP = { tri: TRI_UNKNOWN, buf: false, cap: CAP_UNKNOWN };
9427
+ var RAW_UNKNOWN = 0;
9428
+ var RAW_CAPTURE = 1;
9429
+ var RAW_OMIT = 2;
9430
+ var TOP = { tri: TRI_UNKNOWN, buf: false, raw: RAW_UNKNOWN, cap: CAP_UNKNOWN };
8978
9431
  function meet(a, b) {
8979
9432
  const tri = a.tri === b.tri ? a.tri : TRI_UNKNOWN;
8980
9433
  const buf = a.buf && b.buf;
9434
+ const raw = a.raw === b.raw ? a.raw : RAW_UNKNOWN;
8981
9435
  const cap = a.cap === b.cap ? a.cap : CAP_UNKNOWN;
8982
- if (tri === a.tri && buf === a.buf && cap === a.cap) return a;
8983
- return { tri, buf, cap };
9436
+ if (tri === a.tri && buf === a.buf && raw === a.raw && cap === a.cap) return a;
9437
+ return { tri, buf, raw, cap };
8984
9438
  }
8985
9439
  function reachableSites(code, roots) {
8986
9440
  const seen = /* @__PURE__ */ new Set();
@@ -9003,25 +9457,26 @@ function transfer(code, ip, at, hostCst) {
9003
9457
  const tri = ki < 0 ? TRI_NONE : ki;
9004
9458
  const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
9005
9459
  if (tri === at.tri && cap === at.cap) return at;
9006
- return { tri, buf: at.buf, cap };
9460
+ return { tri, buf: at.buf, raw: at.raw, cap };
9007
9461
  }
9008
9462
  if (op === OP_NODE || op === OP_NODE_TRACK) {
9009
9463
  const flags = code[ip + 3];
9010
9464
  const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
9011
9465
  if (directChildren) {
9012
- return { tri: at.tri, buf: false, cap: CAP_OFF };
9466
+ return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
9013
9467
  }
9014
9468
  const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
9015
- if (at.buf && cap === at.cap) return at;
9016
- return { tri: at.tri, buf: true, cap };
9469
+ const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
9470
+ if (at.buf && raw === at.raw && cap === at.cap) return at;
9471
+ return { tri: at.tri, buf: true, raw, cap };
9017
9472
  }
9018
9473
  if (op === OP_TOKEN) {
9019
9474
  if (at.tri === TRI_NONE && !at.buf) return at;
9020
- return { tri: TRI_NONE, buf: false, cap: at.cap };
9475
+ return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
9021
9476
  }
9022
9477
  if (op === OP_LEAF) {
9023
9478
  if (!at.buf) return at;
9024
- return { tri: at.tri, buf: false, cap: at.cap };
9479
+ return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
9025
9480
  }
9026
9481
  return at;
9027
9482
  }
@@ -9088,6 +9543,162 @@ function scalarTerminalNotChild(code, ip) {
9088
9543
  const op = code[child];
9089
9544
  return op === OP_RX || op === OP_LIT ? child : -1;
9090
9545
  }
9546
+ function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
9547
+ const seen = /* @__PURE__ */ new Set();
9548
+ let at = ip;
9549
+ let depth = 0;
9550
+ while (!seen.has(at)) {
9551
+ seen.add(at);
9552
+ const op = code[at];
9553
+ if (op === OP_LIT || op === OP_RX) return depth >= minDepth ? at : -1;
9554
+ if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || throughAttempt && op === OP_ATTEMPT) {
9555
+ at = code[at + 1];
9556
+ depth++;
9557
+ continue;
9558
+ }
9559
+ if (throughPeek && op === OP_PEEK) {
9560
+ at = code[at + 1];
9561
+ depth++;
9562
+ continue;
9563
+ }
9564
+ if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9565
+ at = code[at + 2];
9566
+ depth++;
9567
+ continue;
9568
+ }
9569
+ if (op === OP_SEQ || op === OP_SEQV) {
9570
+ if (code[at + 1] < 1) return -1;
9571
+ at = code[at + 2];
9572
+ depth++;
9573
+ continue;
9574
+ }
9575
+ if (op === OP_SEQX) {
9576
+ if (code[at + 2] < 1) return -1;
9577
+ at = code[at + 3];
9578
+ depth++;
9579
+ continue;
9580
+ }
9581
+ return -1;
9582
+ }
9583
+ return -1;
9584
+ }
9585
+ function leadingScalarSequence(code, ip) {
9586
+ const wholeScalar = (start) => {
9587
+ const seen2 = /* @__PURE__ */ new Set();
9588
+ let at2 = start;
9589
+ while (!seen2.has(at2)) {
9590
+ seen2.add(at2);
9591
+ const op = code[at2];
9592
+ if (op === OP_LIT || op === OP_RX) return at2;
9593
+ if (op === OP_RULE || op === OP_TOKEN || op === OP_ATTEMPT) {
9594
+ at2 = code[at2 + 1];
9595
+ continue;
9596
+ }
9597
+ if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9598
+ at2 = code[at2 + 2];
9599
+ continue;
9600
+ }
9601
+ if (op === OP_SEQ || op === OP_SEQV) {
9602
+ if (code[at2 + 1] !== 1) return -1;
9603
+ at2 = code[at2 + 2];
9604
+ continue;
9605
+ }
9606
+ if (op === OP_SEQX) {
9607
+ if (code[at2 + 2] !== 1) return -1;
9608
+ at2 = code[at2 + 3];
9609
+ continue;
9610
+ }
9611
+ return -1;
9612
+ }
9613
+ return -1;
9614
+ };
9615
+ const seen = /* @__PURE__ */ new Set();
9616
+ let at = ip;
9617
+ let ambientTrivia;
9618
+ while (!seen.has(at)) {
9619
+ seen.add(at);
9620
+ const op = code[at];
9621
+ if (op === OP_RULE) {
9622
+ at = code[at + 1];
9623
+ continue;
9624
+ }
9625
+ if (op === OP_SCOPE_PLAIN) {
9626
+ ambientTrivia = code[at + 1];
9627
+ at = code[at + 2];
9628
+ continue;
9629
+ }
9630
+ if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9631
+ at = code[at + 2];
9632
+ continue;
9633
+ }
9634
+ const n = op === OP_SEQ || op === OP_SEQV ? code[at + 1] : op === OP_SEQX ? code[at + 2] : 0;
9635
+ if (n < 3 || ambientTrivia === void 0) return void 0;
9636
+ const base = op === OP_SEQX ? at + 3 : at + 2;
9637
+ const terminals = [
9638
+ wholeScalar(code[base]),
9639
+ wholeScalar(code[base + 1]),
9640
+ wholeScalar(code[base + 2])
9641
+ ];
9642
+ return terminals.every((terminal) => terminal >= 0) ? { terminals, trivia: ambientTrivia } : void 0;
9643
+ }
9644
+ return void 0;
9645
+ }
9646
+ function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
9647
+ const active = /* @__PURE__ */ new Set();
9648
+ const walk = (at, depth) => {
9649
+ if (active.has(at)) return void 0;
9650
+ active.add(at);
9651
+ try {
9652
+ const op = code[at];
9653
+ if (op === OP_LIT) {
9654
+ const value = constants[code[at + 1]];
9655
+ return depth >= minDepth && typeof value === "string" && value.length > 0 ? [at] : void 0;
9656
+ }
9657
+ if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
9658
+ return walk(code[at + 1], depth + 1);
9659
+ }
9660
+ if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
9661
+ return walk(code[at + 2], depth + 1);
9662
+ }
9663
+ if (op === OP_SEQ || op === OP_SEQV) {
9664
+ return code[at + 1] < 1 ? void 0 : walk(code[at + 2], depth + 1);
9665
+ }
9666
+ if (op === OP_SEQX) {
9667
+ return code[at + 2] < 1 ? void 0 : walk(code[at + 3], depth + 1);
9668
+ }
9669
+ if (op !== OP_CHOICE) return void 0;
9670
+ const n = code[at + 2];
9671
+ if (n < 1) return void 0;
9672
+ const out = [];
9673
+ for (let i = 0; i < n; i++) {
9674
+ const branch = walk(code[at + 4 + i], depth + 1);
9675
+ if (branch === void 0) return void 0;
9676
+ for (const terminal of branch) {
9677
+ const value = constants[code[terminal + 1]];
9678
+ let covered = false;
9679
+ for (let j = 0; j < out.length; j++) {
9680
+ const prior = constants[code[out[j] + 1]];
9681
+ if (value.startsWith(prior)) {
9682
+ covered = true;
9683
+ break;
9684
+ }
9685
+ }
9686
+ if (covered) continue;
9687
+ for (let j = out.length - 1; j >= 0; j--) {
9688
+ const prior = constants[code[out[j] + 1]];
9689
+ if (prior.startsWith(value)) out.splice(j, 1);
9690
+ }
9691
+ out.push(terminal);
9692
+ if (out.length > limit) return void 0;
9693
+ }
9694
+ }
9695
+ return out;
9696
+ } finally {
9697
+ active.delete(at);
9698
+ }
9699
+ };
9700
+ return walk(ip, 0);
9701
+ }
9091
9702
 
9092
9703
  // src/table/emit-assembly.ts
9093
9704
  var Unemittable = class extends Error {
@@ -9169,6 +9780,16 @@ let _pfScan=null
9169
9780
  let _pfHost
9170
9781
  let _pfDepth=0
9171
9782
  const _pfFrames=[]
9783
+ let _pfTokInput
9784
+ let _pfTokPos=-1
9785
+ let _pfTokBody=-1
9786
+ let _pfTokPacked=-1
9787
+ let _pfTokValue
9788
+ let _pfTokDispatch=-1
9789
+ let _pfTokArm=-1
9790
+ let _pfTokEnd=-1
9791
+ let _pfSeqEnd=-1
9792
+ function _asciiFoldCode(c){return c>=65&&c<=90?c+32:c}
9172
9793
  function _skipTrivia(input,cur,ctx){
9173
9794
  const s=_pfScan
9174
9795
  if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
@@ -9234,6 +9855,40 @@ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=
9234
9855
  if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
9235
9856
  }
9236
9857
  `;
9858
+ var NO_RAW_RUNTIME_PRELUDE = `
9859
+ function _pushLeafNoRawBuf(ctx,value,s,e){
9860
+ const l={_tag:'leaf',value,span:{start:s,end:e}}
9861
+ const b=ctx._cstBuf
9862
+ if(b.ch!==undefined)b.ch.push(l)
9863
+ else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
9864
+ else b.single=l
9865
+ b.rawLen++
9866
+ }
9867
+ function _pushNodeNoRawBuf(ctx,value){
9868
+ const b=ctx._cstBuf
9869
+ if(b.ch!==undefined)b.ch.push(value)
9870
+ else if(b.single!==undefined){b.ch=[b.single,value];b.single=undefined}
9871
+ else b.single=value
9872
+ b.rawLen++
9873
+ }
9874
+ function _rbNoRawBuf(ctx,raw,tl,lv,lg,rt){
9875
+ const b=ctx._cstBuf
9876
+ if(b.rawLen!==raw)b.rawLen=raw
9877
+ const ch=b.ch
9878
+ if(ch!==undefined){
9879
+ if(lv===0)b.ch=undefined
9880
+ else if(lv===1){b.single=ch[0];b.ch=undefined}
9881
+ else if(ch.length!==lv)ch.length=lv
9882
+ }else if(lv===0)b.single=undefined
9883
+ const bt=b.tl
9884
+ if(bt!==undefined){
9885
+ if(tl===0)b.tl=undefined
9886
+ else if(bt.length!==tl)bt.length=tl
9887
+ }
9888
+ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=lg
9889
+ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
9890
+ }
9891
+ `;
9237
9892
  function q(s) {
9238
9893
  return JSON.stringify(s);
9239
9894
  }
@@ -9246,11 +9901,12 @@ function sinkReads(t2, s) {
9246
9901
  ${t2}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${s.er ? `
9247
9902
  ${t2}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
9248
9903
  }
9249
- function emitMark(t2, buf, s = NO_SINKS, decl = true) {
9904
+ function emitMark(t2, buf, rawMode, s = NO_SINKS, decl = true) {
9250
9905
  if (buf) {
9906
+ const raw = rawMode === RAW_OMIT ? `${t2}raw=b.rawLen` : rawMode === RAW_CAPTURE ? `const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
9251
9907
  return `${decl ? `let ${t2}raw=0,${t2}tl=0,${t2}lv=0,${t2}lg=0,${t2}rt=0${sinkSlots(t2, s)}
9252
9908
  ` : ""}{const b=ctx._cstBuf
9253
- const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
9909
+ ${raw}
9254
9910
  const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
9255
9911
  const l=b.tl;${t2}tl=l!==undefined?l.length:0
9256
9912
  ${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
@@ -9260,7 +9916,7 @@ ${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2
9260
9916
  ` : `${t2}n=false
9261
9917
  `}{const b=ctx._cstBuf
9262
9918
  if(b!==undefined){
9263
- const r=b.raw;${t2}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
9919
+ const r=b.raw;${t2}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
9264
9920
  const h=b.ch;${t2}lv=h!==undefined?h.length:b.single!==undefined?1:0
9265
9921
  const l=b.tl;${t2}tl=l!==undefined?l.length:0
9266
9922
  ${t2}n=true
@@ -9275,14 +9931,16 @@ ${t2}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
9275
9931
  ${t2}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t2, s)}
9276
9932
  }}`;
9277
9933
  }
9278
- function emitRollback(t2, buf, s = NO_SINKS) {
9934
+ function emitRollback(t2, buf, rawMode, s = NO_SINKS) {
9279
9935
  const fd = s.fd ? `
9280
9936
  if(ctx._fields!==undefined&&ctx._fields.length!==${t2}fd)ctx._fields.length=${t2}fd` : "";
9281
9937
  const er = s.er ? `
9282
9938
  if(ctx._errors!==undefined&&ctx._errors.length!==${t2}er)ctx._errors.length=${t2}er` : "";
9283
- if (buf) return `_rbBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9284
- if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,0,undefined,${t2}lg,${t2}rt)`;
9285
- return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "0"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
9939
+ if (buf && rawMode === RAW_OMIT) return `_rbNoRawBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9940
+ if (buf && rawMode === RAW_CAPTURE) return `_rbBuf(ctx,${t2}raw,${t2}tl,${t2}lv,${t2}lg,${t2}rt)${fd}${er}`;
9941
+ if (buf) return `rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)`;
9942
+ if (!s.fd && !s.er) return `if(${t2}n)rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,undefined,undefined,${t2}lg,${t2}rt)`;
9943
+ return `if(${t2}n){rollbackTriviaAt(ctx,${t2}raw,${t2}tl,${t2}lv,${s.fd ? `${t2}fd` : "undefined"},${s.er ? `${t2}er` : "undefined"},${t2}lg,${t2}rt)}`;
9286
9944
  }
9287
9945
  function emitTerm(callee, dst, t2, l, skip) {
9288
9946
  const fast = `const ${t2}v=${callee}(input,cur,ctx)
@@ -9340,37 +9998,111 @@ function rebuildPools(cc, fx, disp, plan) {
9340
9998
  })
9341
9999
  };
9342
10000
  }
9343
- function emitAssemblySource(t2, prog, cfg, extraIps = []) {
9344
- const { code, k, disp, dsp, triviaLabelled } = t2;
10001
+ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
10002
+ const { code, k, fx, disp, dsp, triviaLabelled } = t2;
9345
10003
  const swapLegal = !cfg.trackLines;
9346
10004
  const hostCst = cfg.hostCst;
9347
10005
  const REC = prog.rec === 1 && cfg.tolerant;
9348
10006
  if (cfg.coverage) throw new Unemittable("a coverage assembly");
9349
10007
  const roots = [...Object.values(prog.rules), ...extraIps];
10008
+ const reachable = [...reachableSites(code, roots)];
9350
10009
  const labels = computeSiteLabels(code, roots, hostCst);
9351
10010
  const scalarSpecs = /* @__PURE__ */ new Set();
10011
+ const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
10012
+ const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
10013
+ const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
10014
+ const tokenChoiceCandidates = /* @__PURE__ */ new Map();
10015
+ const tokenChoiceDispatches = /* @__PURE__ */ new Set();
10016
+ const tokenChoiceBodies = /* @__PURE__ */ new Set();
9352
10017
  if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
9353
- for (const ip of reachableSites(code, roots)) {
9354
- if (code[ip] !== OP_NODE) continue;
9355
- const child = scalarTerminalNodeChild(code, ip);
9356
- if (child >= 0) scalarSpecs.add(code[child + 1]);
10018
+ for (const ip of reachable) {
10019
+ if (code[ip] === OP_NODE) {
10020
+ const child = scalarTerminalNodeChild(code, ip);
10021
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
10022
+ continue;
10023
+ }
10024
+ if (code[ip] !== OP_CHOICE || disp[code[ip + 1]].exclusive) continue;
10025
+ const n = code[ip + 2];
10026
+ for (let i = 0; i < n; i++) {
10027
+ const armIp = code[ip + 4 + i];
10028
+ const child = leadingScalarTerminal(code, armIp, 2, true, true);
10029
+ if (n === 2 || n === 3) {
10030
+ if (child >= 0) scalarSpecs.add(code[child + 1]);
10031
+ continue;
10032
+ }
10033
+ if (child >= 0) {
10034
+ const spec = k[code[child + 1]];
10035
+ if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
10036
+ largeChoiceScalarSpecs.add(code[child + 1]);
10037
+ continue;
10038
+ }
10039
+ }
10040
+ const family = leadingLiteralFamily(code, k, armIp);
10041
+ if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
10042
+ const value = k[code[terminal + 1]];
10043
+ return typeof value === "string" && value.length >= 2;
10044
+ })) {
10045
+ largeChoiceLiteralFamilies.set(armIp, family);
10046
+ }
10047
+ const sequence6 = leadingScalarSequence(code, armIp);
10048
+ if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t2.triviaScan[sequence6.trivia] != null)) {
10049
+ largeChoiceScalarSequences.set(armIp, sequence6);
10050
+ }
10051
+ }
10052
+ let candidate;
10053
+ let ambiguous = false;
10054
+ for (let i = 0; i < n; i++) {
10055
+ const armIp = code[ip + 4 + i];
10056
+ if (code[armIp] !== OP_XFORM) continue;
10057
+ const dispatchIp = code[armIp + 2];
10058
+ if (code[dispatchIp] !== OP_DISPATCH) continue;
10059
+ const selectorIp = code[dispatchIp + 1];
10060
+ if (code[selectorIp] !== OP_LEX_BODY) continue;
10061
+ if (candidate !== void 0) {
10062
+ ambiguous = true;
10063
+ break;
10064
+ }
10065
+ candidate = { arm: i, dispatchIp };
10066
+ }
10067
+ if (!ambiguous && candidate !== void 0) {
10068
+ tokenChoiceCandidates.set(ip, candidate);
10069
+ tokenChoiceDispatches.add(candidate.dispatchIp);
10070
+ tokenChoiceBodies.add(code[code[candidate.dispatchIp + 1] + 1]);
10071
+ }
9357
10072
  }
9358
10073
  }
9359
- const sinks = (() => {
9360
- let fd = false;
9361
- let er = REC;
9362
- for (const ip of reachableSites(code, roots)) {
9363
- const op = code[ip];
9364
- if (op === OP_SCAN) {
9365
- fd = true;
9366
- er = true;
9367
- break;
10074
+ const needsNoRawPrelude = !hostCst && reachable.some((ip) => {
10075
+ const op = code[ip];
10076
+ return (op === OP_NODE || op === OP_NODE_TRACK) && code[ip + 1] >= 0 && code[ip + 4] < 0 && (code[ip + 3] & 2) !== 0;
10077
+ });
10078
+ const sinkSites = reachable;
10079
+ const sinkBits = /* @__PURE__ */ new Map();
10080
+ for (const ip of sinkSites) {
10081
+ const op = code[ip];
10082
+ sinkBits.set(
10083
+ ip,
10084
+ op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
10085
+ );
10086
+ }
10087
+ const sinkKids = [];
10088
+ let sinkChanged = true;
10089
+ while (sinkChanged) {
10090
+ sinkChanged = false;
10091
+ for (const ip of sinkSites) {
10092
+ let bits = sinkBits.get(ip) ?? 0;
10093
+ sinkKids.length = 0;
10094
+ childSlots(code, ip, sinkKids);
10095
+ for (let i = 0; i < sinkKids.length; i++) bits |= sinkBits.get(sinkKids[i]) ?? 0;
10096
+ if (bits !== sinkBits.get(ip)) {
10097
+ sinkBits.set(ip, bits);
10098
+ sinkChanged = true;
9368
10099
  }
9369
- if (op === OP_FIELD) fd = true;
9370
- else if (op === OP_EXPECT) er = true;
9371
10100
  }
9372
- return { fd, er };
9373
- })();
10101
+ }
10102
+ const sinksAt = (ip) => {
10103
+ const bits = sinkBits.get(ip) ?? 0;
10104
+ return bits === 0 ? NO_SINKS : { fd: (bits & 1) !== 0, er: (bits & 2) !== 0 };
10105
+ };
9374
10106
  const bodies = [];
9375
10107
  const byIp = /* @__PURE__ */ new Map();
9376
10108
  const reached = /* @__PURE__ */ new Set();
@@ -9397,9 +10129,117 @@ function emitAssemblySource(t2, prog, cfg, extraIps = []) {
9397
10129
  const fxRef = (i) => hoist("fx", `FX[${i}]`);
9398
10130
  const fnRef = (i) => hoist("fn", `FNS[${i}]`);
9399
10131
  const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
10132
+ const scalarSequenceRefs = /* @__PURE__ */ new Map();
10133
+ const scalarSequenceRef = (sequence6) => {
10134
+ const key = `${sequence6.trivia}:${sequence6.terminals.map((terminal) => code[terminal + 1]).join(",")}`;
10135
+ const prior = scalarSequenceRefs.get(key);
10136
+ if (prior !== void 0) return prior;
10137
+ const recognizers = sequence6.terminals.map((terminal) => recognizerRef(code[terminal + 1]));
10138
+ const expected = sequence6.terminals.map((terminal) => fxRef(code[terminal + 2]));
10139
+ const scan = sequence6.trivia < 0 ? void 0 : hoist("ts", `TRIVIASCAN[${sequence6.trivia}]`);
10140
+ const name = `_sd${scalarSequenceRefs.size}_`;
10141
+ const steps = recognizers.map((recognize, i) => `${i === 0 ? "let " : ""}at=${i === 0 ? "pos" : scan === void 0 ? "cur" : `${scan}(input,cur)`}
10142
+ ${i === 0 ? "let " : ""}cur=${recognize}(input,at)
10143
+ if(cur<0){_pfSeqEnd=at;return ${~i}}`).join("\n");
10144
+ choiceDefs.push(`function ${name}(input,pos){
10145
+ ${steps}
10146
+ return cur
10147
+ }`);
10148
+ const made = { name, expected };
10149
+ scalarSequenceRefs.set(key, made);
10150
+ return made;
10151
+ };
9400
10152
  const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
9401
10153
  let uid = 0;
9402
10154
  const tmp = () => `_t${uid++}_`;
10155
+ const dispatchClaim = (m) => {
10156
+ switch (m[0]) {
10157
+ case 0:
10158
+ return `key.startsWith(${q(m[1])})`;
10159
+ case 1:
10160
+ return `key.endsWith(${q(m[1])})`;
10161
+ case 3:
10162
+ return `asciiFoldKey(key).startsWith(${q(m[1])})`;
10163
+ case 4:
10164
+ return `asciiFoldKey(key).endsWith(${q(m[1])})`;
10165
+ default: {
10166
+ if (!m[2].includes("g") && !m[2].includes("y")) {
10167
+ try {
10168
+ new RegExp(m[1], m[2]);
10169
+ return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
10170
+ } catch {
10171
+ }
10172
+ }
10173
+ return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
10174
+ }
10175
+ }
10176
+ };
10177
+ const tokenDecisionRefs = /* @__PURE__ */ new Map();
10178
+ function tokenDecisionFor(dispatchIp) {
10179
+ const prior = tokenDecisionRefs.get(dispatchIp);
10180
+ if (prior !== void 0) return prior;
10181
+ const selectorIp = code[dispatchIp + 1];
10182
+ const body = code[selectorIp + 1];
10183
+ const lineFlags = code[selectorIp + 4];
10184
+ const hasSuffix = (lineFlags & 4) !== 0;
10185
+ const di = code[dispatchIp + 2];
10186
+ const spec = dsp[di];
10187
+ const n = code[dispatchIp + 5];
10188
+ validateDispatchSpec(spec, n, code[dispatchIp + 4]);
10189
+ const recognize = hoist("lex", `LEX[${body}]`);
10190
+ const bk = hoist("bk", `DSP[${di}].byKey`);
10191
+ const expected = hoist("dx", `DSP[${di}].expected`);
10192
+ const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
10193
+ ` : "";
10194
+ const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
10195
+ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
10196
+ }
10197
+ `;
10198
+ const foldedEntries = [...spec.byFold.entries()];
10199
+ const fixedFunctionChoice = spec.byKey.size === 0 && foldedEntries.length === 1 && spec.match.length === 1 && spec.match[0][0] === 2 && spec.match[0][1] === "^(?!(?:url|calc)\\($).+\\($" && spec.match[0][2] === "i" && code[dispatchIp + 3] < 0;
10200
+ const foldedRangeEquals = (value) => {
10201
+ const folded = value.replace(/[A-Z]/g, (c) => c.toLowerCase());
10202
+ return `e-pos===${folded.length}&&${[...folded].map((c, i) => {
10203
+ const cc = c.charCodeAt(0);
10204
+ return `_asciiFoldCode(input.charCodeAt(pos+${i}))===${cc}`;
10205
+ }).join("&&")}`;
10206
+ };
10207
+ const classify = fixedFunctionChoice ? (() => {
10208
+ const [exact, exactArm] = foldedEntries[0];
10209
+ const genericArm = spec.match[0][3];
10210
+ return `let arm
10211
+ if(${foldedRangeEquals(exact)})arm=${exactArm}
10212
+ else if(sm&&e>pos+1){
10213
+ let clean=true
10214
+ for(let i=pos;i<e;i++){const c=input.charCodeAt(i);if(c===10||c===13||c===0x2028||c===0x2029){clean=false;break}}
10215
+ if(clean&&!(${foldedRangeEquals("url(")})&&!(${foldedRangeEquals("calc(")}))arm=${genericArm}
10216
+ }`;
10217
+ })() : `const key=input.slice(pos,e)
10218
+ let arm=${bk}.get(key)
10219
+ ${fold}${chain}`;
10220
+ const name = `_td${tokenDecisionRefs.size}_`;
10221
+ choiceDefs.push(`function ${name}(input,pos){
10222
+ const r=${recognize}(input,pos)
10223
+ if(r<0)return -1
10224
+ const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
10225
+ ${classify}
10226
+ if(arm===undefined){
10227
+ ${code[dispatchIp + 3] < 0 ? "_pfTokEnd=e;return 0" : `arm=${n}`}
10228
+ }
10229
+ ${fixedFunctionChoice ? "const key=input.slice(pos,e)" : ""}
10230
+ _pfTokInput=input
10231
+ _pfTokPos=pos
10232
+ _pfTokBody=${body}
10233
+ _pfTokPacked=r
10234
+ _pfTokValue=key
10235
+ _pfTokDispatch=${dispatchIp}
10236
+ _pfTokArm=arm
10237
+ return 1
10238
+ }`);
10239
+ const made = { name, expected };
10240
+ tokenDecisionRefs.set(dispatchIp, made);
10241
+ return made;
10242
+ }
9403
10243
  function skipFor(l) {
9404
10244
  if (l.tri < 0) return "_skipTrivia";
9405
10245
  const ki = l.tri;
@@ -9487,7 +10327,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
9487
10327
  const op = code[ip];
9488
10328
  const head = `function ${fname}(input,pos,ctx){`;
9489
10329
  const L = labels.at(ip);
9490
- const pushLeaf = L.buf && !cfg.trackLines ? "_pushLeafBuf" : "_pushLeaf";
10330
+ const sinks = sinksAt(ip);
10331
+ const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
9491
10332
  const captureLeaf = (value) => {
9492
10333
  const call = `${pushLeaf}(ctx,${value},pos,e)`;
9493
10334
  return L.buf ? call : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${call}`;
@@ -9738,20 +10579,24 @@ return out
9738
10579
  }`;
9739
10580
  }
9740
10581
  case OP_LEX_BODY: {
9741
- const recognize = hoist("lex", `LEX[${code[ip + 1]}]`);
10582
+ const body = code[ip + 1];
10583
+ const recognize = hoist("lex", `LEX[${body}]`);
9742
10584
  const expected = fxRef(code[ip + 2]);
9743
10585
  const suffixExpected = fxRef(code[ip + 3]);
9744
10586
  const lineFlags = code[ip + 4];
9745
10587
  const hasSuffix = (lineFlags & 4) !== 0;
10588
+ const pending = tokenChoiceBodies.has(body);
9746
10589
  return `${head}
9747
- const r=${recognize}(input,pos)
10590
+ ${pending ? `const tp=_pfTokBody===${body}&&_pfTokInput===input&&_pfTokPos===pos
10591
+ const r=tp?_pfTokPacked:${recognize}(input,pos)` : `const r=${recognize}(input,pos)`}
9748
10592
  if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
9749
10593
  const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
9750
10594
  ${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
9751
10595
  ${hasSuffix ? "ctx._fc=false" : ""}
9752
10596
  ${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
9753
10597
  ${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
9754
- const v=input.slice(pos,e)
10598
+ const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
10599
+ ${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
9755
10600
  if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
9756
10601
  EC.e=e
9757
10602
  return v
@@ -9807,12 +10652,13 @@ return v
9807
10652
  /* ── transaction ─────────────────────────────────────────────────────── */
9808
10653
  case OP_ATTEMPT: {
9809
10654
  const child = link(code[ip + 1]);
10655
+ const clean = !REC && failureRollbackClean(prog, ip);
9810
10656
  const p = tmp();
9811
10657
  return `${head}
9812
- ${emitMark(p, L.buf, sinks)}
10658
+ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
9813
10659
  const v=${child}(input,pos,ctx)
9814
10660
  if(v!==FAIL)return v
9815
- ${emitRollback(p, L.buf, sinks)}
10661
+ ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
9816
10662
  if(ctx._fc===true)return FAIL
9817
10663
  ctx._fe=pos
9818
10664
  return FAIL
@@ -9835,9 +10681,9 @@ return FAIL
9835
10681
  const xf = fxRef(code[ip + 2]);
9836
10682
  const p = tmp();
9837
10683
  return `${head}
9838
- ${emitMark(p, L.buf, sinks)}
10684
+ ${emitMark(p, L.buf, L.raw, sinks)}
9839
10685
  const v=${child}(input,pos,ctx)
9840
- ${emitRollback(p, L.buf, sinks)}
10686
+ ${emitRollback(p, L.buf, L.raw, sinks)}
9841
10687
  if(v===FAIL){EC.e=pos;return null}
9842
10688
  ctx._fe=pos
9843
10689
  ctx._fx=${xf}
@@ -9849,9 +10695,9 @@ return FAIL
9849
10695
  const xf = fxRef(code[ip + 2]);
9850
10696
  const p = tmp();
9851
10697
  return `${head}
9852
- ${emitMark(p, L.buf, sinks)}
10698
+ ${emitMark(p, L.buf, L.raw, sinks)}
9853
10699
  const v=${child}(input,pos,ctx)
9854
- ${emitRollback(p, L.buf, sinks)}
10700
+ ${emitRollback(p, L.buf, L.raw, sinks)}
9855
10701
  if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
9856
10702
  EC.e=pos
9857
10703
  return null
@@ -9859,14 +10705,15 @@ return null
9859
10705
  }
9860
10706
  case OP_OPT: {
9861
10707
  const child = link(code[ip + 1]);
10708
+ const clean = !REC && failureRollbackClean(prog, ip);
9862
10709
  const p = tmp();
9863
10710
  return `${head}
9864
- ${emitMark(p, L.buf, sinks)}
10711
+ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
9865
10712
  ctx._fc=false
9866
10713
  const v=${child}(input,pos,ctx)
9867
10714
  if(v===FAIL){
9868
10715
  if(ctx._fc===true)return FAIL
9869
- ${emitRollback(p, L.buf, sinks)}
10716
+ ${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
9870
10717
  EC.e=pos
9871
10718
  return null
9872
10719
  }
@@ -9965,57 +10812,193 @@ return FAIL
9965
10812
  const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
9966
10813
  const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
9967
10814
  const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
10815
+ const tokenCandidate = tokenChoiceCandidates.get(ip);
10816
+ const pretests = Array.from({ length: n }, (_, i) => {
10817
+ if (tokenCandidate?.arm === i) {
10818
+ return { token: tokenDecisionFor(tokenCandidate.dispatchIp) };
10819
+ }
10820
+ const terminal = leadingScalarTerminal(code, code[base + i], 2, true, true);
10821
+ if (terminal >= 0) {
10822
+ const spec = code[terminal + 1];
10823
+ if ((n === 2 || n === 3 ? scalarSpecs : largeChoiceScalarSpecs).has(spec)) {
10824
+ return { scalar: [recognizerRef(spec)] };
10825
+ }
10826
+ }
10827
+ const family = largeChoiceLiteralFamilies.get(code[base + i]);
10828
+ if (family !== void 0) {
10829
+ return { scalar: family.map((member) => recognizerRef(code[member + 1])) };
10830
+ }
10831
+ const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
10832
+ return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
10833
+ });
9968
10834
  const maskable = n <= 32;
9969
10835
  const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
9970
10836
  if (maskable) maskPlan.push(~di);
9971
10837
  const p = tmp();
9972
- const catchName = maskable ? `_cx${uid++}_` : "";
9973
- if (maskable) {
10838
+ const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
10839
+ const rollbackMask = REC ? -1 : encodedRollbackMask;
10840
+ const hasRollback = rollbackMask !== 0;
10841
+ const startFailureExact = arms.every((_arm, i) => {
10842
+ const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
10843
+ if (terminal < 0) return false;
10844
+ const op2 = code[terminal];
10845
+ const spec = k[code[terminal + 1]];
10846
+ const terminalFx = fx[code[terminal + 2]];
10847
+ const armFx = fx[code[base + n + i]];
10848
+ if (terminalFx.length !== armFx.length || terminalFx.some((expected2, at) => expected2 !== armFx[at])) return false;
10849
+ if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
10850
+ return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
10851
+ });
10852
+ const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
10853
+ if (choiceCannotCommit(prog, ip) && !startFailureExact) {
10854
+ const deepAt = Array.from({ length: n }, () => tmp());
10855
+ const deepFx = Array.from({ length: n }, () => tmp());
10856
+ const remember = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
10857
+ const lazyArms = (ascii) => arms.map((arm, i) => {
10858
+ const pretest = pretests[i];
10859
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10860
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10861
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10862
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10863
+ const gate = ascii ? `(bits&${1 << i})!==0${condition}` : `(${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}`;
10864
+ const routeMiss = pretest?.token === void 0 ? "" : `
10865
+ if(${decision}===0){
10866
+ ctx._fc=false
10867
+ {const at=_pfTokEnd
10868
+ ${remember(i, "at", pretest.token.expected)}}
10869
+ }`;
10870
+ const sequenceMiss = pretest?.sequence === void 0 ? "" : `
10871
+ else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
10872
+ ctx._fc=false
10873
+ {const at=_pfSeqEnd
10874
+ ${remember(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
10875
+ }`;
10876
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10877
+ `}if(${gate}){
10878
+ ctx._fc=false
10879
+ {const v=${arm}(input,pos,ctx)
10880
+ if(v!==FAIL)return v}
10881
+ {const at=ctx._fe??pos
10882
+ ${remember(i, "at", "ctx._fx")}}
10883
+ ${rollbackFor(i)}
10884
+ }${routeMiss}${sequenceMiss}`;
10885
+ }).join("\n");
10886
+ const merge = deepAt.map((at, i) => `{const at=${at}??pos
10887
+ const ex=${at}===undefined?${expected[i]}:${deepFx[i]}
10888
+ if(at>best){best=at;acc=_accSet(ex,undefined)}
10889
+ else if(at===best)acc=_accSet(ex,acc)
10890
+ }`).join("\n");
10891
+ const finish = `let best=pos,acc
10892
+ ${merge}
10893
+ ctx._fe=pos;ctx._fx=acc??${choiceFx}
10894
+ return FAIL`;
10895
+ return `${head}
10896
+ const c=lead(input,pos)
10897
+ ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
10898
+ ${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
10899
+ ${maskable ? `if(c<128){
10900
+ const bits=${maskName}[c<0?128:c]
10901
+ if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
10902
+ ${lazyArms(true)}
10903
+ }else{
10904
+ ${lazyArms(false)}
10905
+ }
10906
+ ` : lazyArms(false)}
10907
+ ${finish}
10908
+ }`;
10909
+ }
10910
+ const needsCatch = maskable || startFailureExact;
10911
+ const catchName = needsCatch ? `_cx${uid++}_` : "";
10912
+ if (needsCatch) {
9974
10913
  const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
9975
10914
  choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
9976
10915
  ${catchCases}
9977
10916
  }return acc}`);
9978
10917
  }
9979
10918
  const maskArms = maskable ? arms.map((arm, i) => {
9980
- return `if((bits&${1 << i})!==0){
10919
+ const pretest = pretests[i];
10920
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10921
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10922
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10923
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10924
+ const routeMiss = pretest?.token === void 0 ? "" : `
10925
+ if(${decision}===0){
10926
+ ctx._fc=false
10927
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10928
+ prev=${i + 1}`}
10929
+ {const at=_pfTokEnd
10930
+ if(at>best){best=at;acc=undefined}
10931
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)}
10932
+ }`;
10933
+ const sequenceMiss = pretest?.sequence === void 0 ? "" : `
10934
+ else if((bits&${1 << i})!==0&&${decision}<0){
10935
+ ctx._fc=false
10936
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10937
+ prev=${i + 1}`}
10938
+ {const at=_pfSeqEnd
10939
+ if(at>best){best=at;acc=undefined}
10940
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)}
10941
+ }`;
10942
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10943
+ `}if((bits&${1 << i})!==0${condition}){
9981
10944
  ctx._fc=false
9982
10945
  {const v=${arm}(input,pos,ctx)
9983
10946
  if(v!==FAIL)return v}
9984
- if(best===pos)acc=${catchName}(${i},prev,acc)
9985
- prev=${i + 1}
10947
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
10948
+ prev=${i + 1}`}
9986
10949
  {const at=ctx._fe??pos
9987
10950
  if(at>best){best=at;acc=undefined}
9988
- if(at===best)acc=_accSet(ctx._fx,acc)}
9989
- if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
9990
- ${emitRollback(p, L.buf, sinks)}
9991
- }`;
10951
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
10952
+ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
10953
+ ${rollbackFor(i)}
10954
+ }${routeMiss}${sequenceMiss}`;
9992
10955
  }).join("\n") : "";
9993
- const generalArms = arms.map((arm, i) => `if(${gateRefs[i]}===null||classHas(${gateRefs[i]},c)){
10956
+ const generalArms = arms.map((arm, i) => {
10957
+ const pretest = pretests[i];
10958
+ const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
10959
+ const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
10960
+ const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
10961
+ const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
10962
+ const miss = pretest?.sequence !== void 0 ? `else if(${decision}<0){
10963
+ ctx._fc=false
10964
+ const at=_pfSeqEnd
10965
+ if(at>best){best=at;acc=undefined}
10966
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)
10967
+ }${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}` : pretest?.token === void 0 ? startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)` : `else if(${decision}===0){
10968
+ ctx._fc=false
10969
+ const at=_pfTokEnd
10970
+ if(at>best){best=at;acc=undefined}
10971
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)
10972
+ }${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
10973
+ return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
10974
+ `}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
9994
10975
  ctx._fc=false
9995
10976
  {const v=${arm}(input,pos,ctx)
9996
10977
  if(v!==FAIL)return v}
9997
10978
  {const at=ctx._fe??pos
9998
10979
  if(at>best){best=at;acc=undefined}
9999
- if(at===best)acc=_accSet(ctx._fx,acc)}
10000
- if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
10001
- ${emitRollback(p, L.buf, sinks)}
10002
- }else if(best===pos)acc=_accSet(${expected[i]},acc)`).join("\n");
10980
+ if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
10981
+ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
10982
+ ${rollbackFor(i)}
10983
+ }${miss}`;
10984
+ }).join("\n");
10003
10985
  return `${head}
10004
10986
  const c=lead(input,pos)
10005
- ${emitMark(p, L.buf, sinks)}
10987
+ ${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
10006
10988
  let acc
10007
10989
  let best=pos
10008
10990
  ${maskable ? `if(c<128){
10009
10991
  const bits=${maskName}[c<0?128:c]
10010
- let prev=0
10992
+ if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
10993
+ ${startFailureExact ? "" : "let prev=0"}
10011
10994
  ${maskArms}
10012
- if(best===pos)acc=${catchName}(${n},prev,acc)
10013
- ctx._fe=pos;ctx._fx=acc??${choiceFx}
10995
+ ${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
10996
+ ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
10014
10997
  return FAIL
10015
10998
  }
10016
10999
  ` : ""}
10017
11000
  ${generalArms}
10018
- ctx._fe=pos;ctx._fx=acc??${choiceFx}
11001
+ ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
10019
11002
  return FAIL
10020
11003
  }`;
10021
11004
  }
@@ -10034,30 +11017,8 @@ return FAIL
10034
11017
  for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
10035
11018
  const bk = hoist("bk", `DSP[${di}].byKey`);
10036
11019
  const dx = hoist("dx", `DSP[${di}].expected`);
10037
- const claims = (m) => {
10038
- switch (m[0]) {
10039
- case 0:
10040
- return `key.startsWith(${q(m[1])})`;
10041
- case 1:
10042
- return `key.endsWith(${q(m[1])})`;
10043
- case 3:
10044
- return `asciiFoldKey(key).startsWith(${q(m[1])})`;
10045
- case 4:
10046
- return `asciiFoldKey(key).endsWith(${q(m[1])})`;
10047
- default: {
10048
- if (!m[2].includes("g") && !m[2].includes("y")) {
10049
- try {
10050
- new RegExp(m[1], m[2]);
10051
- return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
10052
- } catch {
10053
- }
10054
- }
10055
- return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
10056
- }
10057
- }
10058
- };
10059
11020
  const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
10060
- ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
11021
+ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
10061
11022
  }
10062
11023
  `;
10063
11024
  const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
@@ -10065,33 +11026,43 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}
10065
11026
  const m1 = tmp();
10066
11027
  const m2 = tmp();
10067
11028
  const routedCall = (target) => `{const savedRouted=ctx._routed
10068
- ${emitRollback(m1, L.buf, sinks)}
10069
- ${emitMark(m2, L.buf, sinks, false)}
11029
+ ${emitRollback(m1, L.buf, L.raw, sinks)}
11030
+ ${emitMark(m2, L.buf, L.raw, sinks, false)}
10070
11031
  ctx._routed={value:key,span:{start:pos,end:selEnd}}
10071
11032
  try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
10072
11033
  break}`;
10073
11034
  const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
10074
11035
  const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
10075
11036
  const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
11037
+ const armSelection = tokenChoiceDispatches.has(ip) ? `const tp=_pfTokDispatch===${ip}&&_pfTokInput===input&&_pfTokPos===pos
11038
+ let arm
11039
+ if(tp){
11040
+ arm=_pfTokArm
11041
+ _pfTokDispatch=-1
11042
+ _pfTokInput=undefined
11043
+ if(arm===${n})arm=undefined
11044
+ }else{
11045
+ arm=${bk}.get(key)
11046
+ ${fold}${chain}}` : `let arm=${bk}.get(key)
11047
+ ${fold}${chain}`;
10076
11048
  return `${head}
10077
- ${emitMark(m1, L.buf, sinks)}
11049
+ ${emitMark(m1, L.buf, L.raw, sinks)}
10078
11050
  const sv=${selector}(input,pos,ctx)
10079
11051
  if(sv===FAIL)return FAIL
10080
11052
  const selEnd=EC.e
10081
11053
  const key=sv
10082
- let arm=${bk}.get(key)
10083
- ${fold}${chain}
11054
+ ${armSelection}
10084
11055
  if(arm===undefined){
10085
11056
  ${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
10086
11057
  }
10087
- ${emitMark(m2, L.buf, sinks)}
11058
+ ${emitMark(m2, L.buf, L.raw, sinks)}
10088
11059
  let v
10089
11060
  switch(arm){
10090
11061
  ${armCases}
10091
11062
  ${fallbackCase}
10092
11063
  }
10093
11064
  if(v===FAIL){
10094
- ${emitRollback(m2, L.buf, sinks)}
11065
+ ${emitRollback(m2, L.buf, L.raw, sinks)}
10095
11066
  ctx._fc=true
10096
11067
  return FAIL
10097
11068
  }
@@ -10127,23 +11098,25 @@ return [key,v]
10127
11098
  const skip = skipFor(L);
10128
11099
  const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
10129
11100
  const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
10130
- const pfd = sinks.fd ? `${p}fd` : "0";
11101
+ const pfd = sinks.fd ? `${p}fd` : "undefined";
10131
11102
  const per = sinks.er ? `${p}er` : "undefined";
10132
- const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
11103
+ const rbHelper = L.raw === RAW_OMIT ? "_rbNoRawBuf" : "_rbBuf";
11104
+ const rb = L.buf && L.raw !== 0 ? `${rbHelper}(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
10133
11105
  if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
10134
- if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
11106
+ if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : L.buf ? `rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
10135
11107
  const markSinks = `${sinks.fd ? `
10136
11108
  ${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
10137
11109
  ${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
11110
+ const markRaw = L.raw === RAW_OMIT ? `${p}raw=b.rawLen` : L.raw === RAW_CAPTURE ? `const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
10138
11111
  const markBody = L.buf ? `const b=ctx._cstBuf
10139
- const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
11112
+ ${markRaw}
10140
11113
  const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
10141
11114
  const l=b.tl;${p}tl=l!==undefined?l.length:0
10142
11115
  ${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
10143
11116
  ${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
10144
11117
  const b=ctx._cstBuf
10145
11118
  if(b!==undefined){
10146
- const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
11119
+ const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
10147
11120
  const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
10148
11121
  const l=b.tl;${p}tl=l!==undefined?l.length:0
10149
11122
  }else{
@@ -10250,7 +11223,7 @@ const leaf={_tag:'leaf',value,span:{start:pos,end}}
10250
11223
  const kids=[leaf],rawKids=[leaf],span={start:pos,end}
10251
11224
  EC.e=end
10252
11225
  const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
10253
- ${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))"}
11226
+ ${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))"}
10254
11227
  EC.e=end
10255
11228
  return nd
10256
11229
  }`;
@@ -10272,7 +11245,7 @@ return nd
10272
11245
  if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
10273
11246
  const fields = flags === 18;
10274
11247
  const collapseChildren = flags === 34;
10275
- const publish = `if(sBuf!==undefined){
11248
+ const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
10276
11249
  if(sBuf.rawOnly!==true){
10277
11250
  if(sBuf.ch!==undefined)sBuf.ch.push(nd)
10278
11251
  else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
@@ -10285,6 +11258,22 @@ else sBuf.rawSingle=rawNd
10285
11258
  }else if(sCh!==undefined){
10286
11259
  sCh.push(nd)
10287
11260
  if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
11261
+ }` : `if(sBuf!==undefined){
11262
+ if(sBuf.noRaw===true)_pushNodeNoRawBuf(ctx,nd)
11263
+ else{
11264
+ if(sBuf.rawOnly!==true){
11265
+ if(sBuf.ch!==undefined)sBuf.ch.push(nd)
11266
+ else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
11267
+ else sBuf.single=nd
11268
+ }
11269
+ const rawNd=rawEntry(nd,input,pos,end)
11270
+ if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
11271
+ else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
11272
+ else sBuf.rawSingle=rawNd
11273
+ }
11274
+ }else if(sCh!==undefined){
11275
+ sCh.push(nd)
11276
+ if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
10288
11277
  }`;
10289
11278
  return `${head}
10290
11279
  const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
@@ -10320,6 +11309,7 @@ return nd
10320
11309
  const wantFields = hasFields || hostCst;
10321
11310
  const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
10322
11311
  const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
11312
+ const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
10323
11313
  const ty = q(type);
10324
11314
  const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
10325
11315
  const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
@@ -10333,7 +11323,12 @@ return nd
10333
11323
  value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
10334
11324
  }
10335
11325
  const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
10336
- const openCapture = keepChildren ? `const buf={}
11326
+ const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
11327
+ ctx._cstBuf=buf
11328
+ ctx._cstChildren=undefined
11329
+ ctx._cstLeaves=undefined
11330
+ ctx._cstRawChildren=undefined
11331
+ ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
10337
11332
  ctx._cstBuf=buf
10338
11333
  ctx._cstChildren=undefined
10339
11334
  ctx._cstLeaves=undefined
@@ -10344,7 +11339,10 @@ ctx._cstChildren=undefined
10344
11339
  ctx._cstLeaves=undefined
10345
11340
  ctx._cstRawChildren=undefined
10346
11341
  ctx._cstTriviaLog=undefined`;
10347
- const finishCapture = keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
11342
+ const finishCapture = omitsRaw ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
11343
+ const hostKids=kids
11344
+ const rawKids=EMPTY_CH
11345
+ const tlog=buf.tl??EMPTY_TLOG` : keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
10348
11346
  const hostKids=kids
10349
11347
  const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
10350
11348
  const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
@@ -10378,7 +11376,7 @@ const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):unde
10378
11376
  let nd
10379
11377
  ${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]
10380
11378
  else ` : ""}{${value}}
10381
- ${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
11379
+ ${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(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,sBuf!==undefined?(sBuf.noRaw===true?undefined:rawEntry(nd,input,pos,end)):sRaw!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
10382
11380
  EC.e=end
10383
11381
  return nd
10384
11382
  }`;
@@ -10396,7 +11394,7 @@ return nd
10396
11394
  }
10397
11395
  const extra = [];
10398
11396
  for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
10399
- const source = `${RUNTIME_PRELUDE}
11397
+ const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
10400
11398
  ${prelude.join("\n")}
10401
11399
  ${skipDefs.join("\n")}
10402
11400
  ${choiceDefs.join("\n")}
@@ -10411,7 +11409,13 @@ _pfHost=host
10411
11409
  function _finish(){
10412
11410
  if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
10413
11411
  _pfDepth--
10414
- if(_pfDepth===0)return
11412
+ if(_pfDepth===0){
11413
+ _pfTokInput=undefined
11414
+ _pfTokBody=-1
11415
+ _pfTokValue=undefined
11416
+ _pfTokDispatch=-1
11417
+ return
11418
+ }
10415
11419
  const prior=_pfFrames.pop()
10416
11420
  _pfScan=prior[0]
10417
11421
  _pfHost=prior[1]
@@ -10635,6 +11639,17 @@ function assemble(t2, prog, cfg) {
10635
11639
  }
10636
11640
  return recognize;
10637
11641
  }
11642
+ const labelExtraIps = [];
11643
+ for (const s of prog.scans ?? []) {
11644
+ for (const r of s.skip) labelExtraIps.push(r[0]);
11645
+ if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
11646
+ }
11647
+ for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
11648
+ const closureLabels = computeSiteLabels(
11649
+ code,
11650
+ [...Object.values(prog.rules), ...labelExtraIps],
11651
+ hostCst
11652
+ );
10638
11653
  let SCAN = null;
10639
11654
  const memo = /* @__PURE__ */ new Map();
10640
11655
  const reached = /* @__PURE__ */ new Set();
@@ -10880,7 +11895,7 @@ function assemble(t2, prog, cfg) {
10880
11895
  const b = ctx._cstBuf;
10881
11896
  if (b !== void 0) {
10882
11897
  const raw = b.raw;
10883
- MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
11898
+ MRAW = b.noRaw === true ? b.rawLen ?? 0 : raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
10884
11899
  const ch2 = b.ch;
10885
11900
  MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
10886
11901
  const tl = b.tl;
@@ -10964,6 +11979,31 @@ function assemble(t2, prog, cfg) {
10964
11979
  if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
10965
11980
  return cur;
10966
11981
  }
11982
+ function nextTermBuffered(child, input, cur, ctx) {
11983
+ if (ctx.trivia === void 0) {
11984
+ const v2 = child(input, cur, ctx);
11985
+ if (v2 === FAIL) return -1;
11986
+ TERMV = v2;
11987
+ return EC.e;
11988
+ }
11989
+ const before = ctx._cstBuf;
11990
+ const beforeTl = before.tl;
11991
+ const mTl = beforeTl === void 0 ? 0 : beforeTl.length;
11992
+ const mLog = ctx._triviaLog?.length ?? 0;
11993
+ const mRoot = ctx._rootTriviaLog?.length ?? 0;
11994
+ const scanEnd = skipTrivia(input, cur, ctx);
11995
+ const scanned = ctx._cstBuf;
11996
+ const scannedTl = scanned.tl;
11997
+ const scanTl = scannedTl === void 0 ? 0 : scannedTl.length;
11998
+ const scanLog = ctx._triviaLog?.length ?? 0;
11999
+ const scanRoot = ctx._rootTriviaLog?.length ?? 0;
12000
+ const v = child(input, scanEnd, ctx);
12001
+ if (v === FAIL) return -1;
12002
+ TERMV = v;
12003
+ if (EC.e > scanEnd) return EC.e;
12004
+ rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
12005
+ return cur;
12006
+ }
10967
12007
  function committed3(c) {
10968
12008
  return c._fc === true;
10969
12009
  }
@@ -11234,7 +12274,8 @@ function assemble(t2, prog, cfg) {
11234
12274
  target = p;
11235
12275
  } };
11236
12276
  inFlight.set(ip, holder);
11237
- const piece = lower(ip);
12277
+ const op = code[ip];
12278
+ const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : lower(ip);
11238
12279
  inFlight.delete(ip);
11239
12280
  holder.set(piece);
11240
12281
  memo.set(ip, piece);
@@ -11977,6 +13018,7 @@ function assemble(t2, prog, cfg) {
11977
13018
  const reducer = fused ? code[ip + 1] : -1;
11978
13019
  const projection = reducer < 0 ? ~reducer : -1;
11979
13020
  const fn = fused && projection < 0 ? fns[reducer] : void 0;
13021
+ const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
11980
13022
  const runnerBlock = (count, r0, r1, r2, r3, next) => {
11981
13023
  if (count === 1) return (input, cur, ctx, values, inherited) => {
11982
13024
  cur = r0(input, cur, ctx, inherited);
@@ -12031,7 +13073,7 @@ function assemble(t2, prog, cfg) {
12031
13073
  const kid = link(kidIp);
12032
13074
  return (input, cur, ctx, inherited) => {
12033
13075
  ctx._sync = sync ?? inherited;
12034
- return nextTerm(kid, input, cur, ctx);
13076
+ return step(kid, input, cur, ctx);
12035
13077
  };
12036
13078
  }
12037
13079
  const negated = code[kidIp + 1] === 1;
@@ -12116,7 +13158,7 @@ function assemble(t2, prog, cfg) {
12116
13158
  const kidIp = code[base + i];
12117
13159
  if (code[kidIp] !== OP_ADJ) {
12118
13160
  const kid = link(kidIp);
12119
- return (input, cur, ctx) => nextTerm(kid, input, cur, ctx);
13161
+ return (input, cur, ctx) => step(kid, input, cur, ctx);
12120
13162
  }
12121
13163
  const negated = code[kidIp + 1] === 1;
12122
13164
  const ki = code[kidIp + 2];
@@ -12205,7 +13247,7 @@ function assemble(t2, prog, cfg) {
12205
13247
  return (input, pos, ctx) => {
12206
13248
  const v0 = k0(input, pos, ctx);
12207
13249
  if (v0 === FAIL) return FAIL;
12208
- const cur = nextTerm(k1, input, EC.e, ctx);
13250
+ const cur = step(k1, input, EC.e, ctx);
12209
13251
  if (cur < 0) return FAIL;
12210
13252
  EC.e = cur;
12211
13253
  return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
@@ -12215,7 +13257,7 @@ function assemble(t2, prog, cfg) {
12215
13257
  return (input, pos, ctx) => {
12216
13258
  const v0 = k0(input, pos, ctx);
12217
13259
  if (v0 === FAIL) return FAIL;
12218
- const cur = nextTerm(k1, input, EC.e, ctx);
13260
+ const cur = step(k1, input, EC.e, ctx);
12219
13261
  if (cur < 0) return FAIL;
12220
13262
  EC.e = cur;
12221
13263
  return [v0, TERMV];
@@ -12224,7 +13266,7 @@ function assemble(t2, prog, cfg) {
12224
13266
  return (input, pos, ctx) => {
12225
13267
  const v0 = k0(input, pos, ctx);
12226
13268
  if (v0 === FAIL) return FAIL;
12227
- const cur = nextTerm(k1, input, EC.e, ctx);
13269
+ const cur = step(k1, input, EC.e, ctx);
12228
13270
  if (cur < 0) return FAIL;
12229
13271
  EC.e = cur;
12230
13272
  return void 0;
@@ -12236,10 +13278,10 @@ function assemble(t2, prog, cfg) {
12236
13278
  return (input, pos, ctx) => {
12237
13279
  const v0 = k0(input, pos, ctx);
12238
13280
  if (v0 === FAIL) return FAIL;
12239
- let cur = nextTerm(k1, input, EC.e, ctx);
13281
+ let cur = step(k1, input, EC.e, ctx);
12240
13282
  if (cur < 0) return FAIL;
12241
13283
  const v1 = TERMV;
12242
- cur = nextTerm(k2, input, cur, ctx);
13284
+ cur = step(k2, input, cur, ctx);
12243
13285
  if (cur < 0) return FAIL;
12244
13286
  EC.e = cur;
12245
13287
  return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
@@ -12249,10 +13291,10 @@ function assemble(t2, prog, cfg) {
12249
13291
  return (input, pos, ctx) => {
12250
13292
  const v0 = k0(input, pos, ctx);
12251
13293
  if (v0 === FAIL) return FAIL;
12252
- let cur = nextTerm(k1, input, EC.e, ctx);
13294
+ let cur = step(k1, input, EC.e, ctx);
12253
13295
  if (cur < 0) return FAIL;
12254
13296
  const v1 = TERMV;
12255
- cur = nextTerm(k2, input, cur, ctx);
13297
+ cur = step(k2, input, cur, ctx);
12256
13298
  if (cur < 0) return FAIL;
12257
13299
  EC.e = cur;
12258
13300
  return [v0, v1, TERMV];
@@ -12261,9 +13303,9 @@ function assemble(t2, prog, cfg) {
12261
13303
  return (input, pos, ctx) => {
12262
13304
  const v0 = k0(input, pos, ctx);
12263
13305
  if (v0 === FAIL) return FAIL;
12264
- let cur = nextTerm(k1, input, EC.e, ctx);
13306
+ let cur = step(k1, input, EC.e, ctx);
12265
13307
  if (cur < 0) return FAIL;
12266
- cur = nextTerm(k2, input, cur, ctx);
13308
+ cur = step(k2, input, cur, ctx);
12267
13309
  if (cur < 0) return FAIL;
12268
13310
  EC.e = cur;
12269
13311
  return void 0;
@@ -12271,43 +13313,43 @@ function assemble(t2, prog, cfg) {
12271
13313
  }
12272
13314
  const block = (count, k0, k1, k2, k3, next) => {
12273
13315
  if (count === 1) return (input, cur, ctx, values) => {
12274
- cur = nextTerm(k0, input, cur, ctx);
13316
+ cur = step(k0, input, cur, ctx);
12275
13317
  if (cur < 0) return -1;
12276
13318
  if (values !== void 0) values.push(TERMV);
12277
13319
  return next === void 0 ? cur : next(input, cur, ctx, values);
12278
13320
  };
12279
13321
  if (count === 2) return (input, cur, ctx, values) => {
12280
- cur = nextTerm(k0, input, cur, ctx);
13322
+ cur = step(k0, input, cur, ctx);
12281
13323
  if (cur < 0) return -1;
12282
13324
  if (values !== void 0) values.push(TERMV);
12283
- cur = nextTerm(k1, input, cur, ctx);
13325
+ cur = step(k1, input, cur, ctx);
12284
13326
  if (cur < 0) return -1;
12285
13327
  if (values !== void 0) values.push(TERMV);
12286
13328
  return next === void 0 ? cur : next(input, cur, ctx, values);
12287
13329
  };
12288
13330
  if (count === 3) return (input, cur, ctx, values) => {
12289
- cur = nextTerm(k0, input, cur, ctx);
13331
+ cur = step(k0, input, cur, ctx);
12290
13332
  if (cur < 0) return -1;
12291
13333
  if (values !== void 0) values.push(TERMV);
12292
- cur = nextTerm(k1, input, cur, ctx);
13334
+ cur = step(k1, input, cur, ctx);
12293
13335
  if (cur < 0) return -1;
12294
13336
  if (values !== void 0) values.push(TERMV);
12295
- cur = nextTerm(k2, input, cur, ctx);
13337
+ cur = step(k2, input, cur, ctx);
12296
13338
  if (cur < 0) return -1;
12297
13339
  if (values !== void 0) values.push(TERMV);
12298
13340
  return next === void 0 ? cur : next(input, cur, ctx, values);
12299
13341
  };
12300
13342
  return (input, cur, ctx, values) => {
12301
- cur = nextTerm(k0, input, cur, ctx);
13343
+ cur = step(k0, input, cur, ctx);
12302
13344
  if (cur < 0) return -1;
12303
13345
  if (values !== void 0) values.push(TERMV);
12304
- cur = nextTerm(k1, input, cur, ctx);
13346
+ cur = step(k1, input, cur, ctx);
12305
13347
  if (cur < 0) return -1;
12306
13348
  if (values !== void 0) values.push(TERMV);
12307
- cur = nextTerm(k2, input, cur, ctx);
13349
+ cur = step(k2, input, cur, ctx);
12308
13350
  if (cur < 0) return -1;
12309
13351
  if (values !== void 0) values.push(TERMV);
12310
- cur = nextTerm(k3, input, cur, ctx);
13352
+ cur = step(k3, input, cur, ctx);
12311
13353
  if (cur < 0) return -1;
12312
13354
  if (values !== void 0) values.push(TERMV);
12313
13355
  return next === void 0 ? cur : next(input, cur, ctx, values);
@@ -12478,6 +13520,13 @@ function assemble(t2, prog, cfg) {
12478
13520
  if (n === 2 || n === 3) {
12479
13521
  const a0 = link(code[base]), a1 = link(code[base + 1]);
12480
13522
  const a2 = n === 3 ? link(code[base + 2]) : void 0;
13523
+ const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
13524
+ const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
13525
+ const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
13526
+ const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
13527
+ const p0 = p0ip < 0 ? void 0 : scalarFor(p0ip);
13528
+ const p1 = p1ip < 0 ? void 0 : scalarFor(p1ip);
13529
+ const p2 = p2ip < 0 ? void 0 : scalarFor(p2ip);
12481
13530
  const e0 = fx[code[base + n]];
12482
13531
  const e1 = fx[code[base + n + 1]];
12483
13532
  const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
@@ -12507,7 +13556,10 @@ function assemble(t2, prog, cfg) {
12507
13556
  let acc;
12508
13557
  let best = pos;
12509
13558
  if (c < 128) {
12510
- const bits = mask[c < 0 ? 128 : c];
13559
+ let bits = mask[c < 0 ? 128 : c];
13560
+ if ((bits & 1) !== 0 && p0 !== void 0 && p0(input, pos) < 0) bits &= ~1;
13561
+ if ((bits & 2) !== 0 && p1 !== void 0 && p1(input, pos) < 0) bits &= ~2;
13562
+ if ((bits & 4) !== 0 && p2 !== void 0 && p2(input, pos) < 0) bits &= ~4;
12511
13563
  let prev = 0;
12512
13564
  if ((bits & 1) !== 0) {
12513
13565
  ctx._fc = false;
@@ -12570,7 +13622,7 @@ function assemble(t2, prog, cfg) {
12570
13622
  ctx._fx = acc ?? choiceFx;
12571
13623
  return FAIL;
12572
13624
  }
12573
- if (g0 === null || classHas2(g0, c)) {
13625
+ if ((g0 === null || classHas2(g0, c)) && (p0 === void 0 || p0(input, pos) >= 0)) {
12574
13626
  ctx._fc = false;
12575
13627
  const v = a0(input, pos, ctx);
12576
13628
  if (v !== FAIL) return v;
@@ -12586,7 +13638,7 @@ function assemble(t2, prog, cfg) {
12586
13638
  }
12587
13639
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12588
13640
  } else if (best === pos) acc = accSet(e0, acc);
12589
- if (g1 === null || classHas2(g1, c)) {
13641
+ if ((g1 === null || classHas2(g1, c)) && (p1 === void 0 || p1(input, pos) >= 0)) {
12590
13642
  ctx._fc = false;
12591
13643
  const v = a1(input, pos, ctx);
12592
13644
  if (v !== FAIL) return v;
@@ -12603,7 +13655,7 @@ function assemble(t2, prog, cfg) {
12603
13655
  if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
12604
13656
  } else if (best === pos) acc = accSet(e1, acc);
12605
13657
  if (n === 3) {
12606
- if (g2 === null || classHas2(g2, c)) {
13658
+ if ((g2 === null || classHas2(g2, c)) && (p2 === void 0 || p2(input, pos) >= 0)) {
12607
13659
  ctx._fc = false;
12608
13660
  const v = a2(input, pos, ctx);
12609
13661
  if (v !== FAIL) return v;
@@ -13176,20 +14228,14 @@ function assemble(t2, prog, cfg) {
13176
14228
  const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
13177
14229
  const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
13178
14230
  const rawOnly = !keepChildren;
14231
+ const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
13179
14232
  return (input, pos, ctx) => {
13180
14233
  const host = HOST;
13181
14234
  const sCh = ctx._cstChildren;
13182
- const sLv = ctx._cstLeaves;
13183
- const sRaw = ctx._cstRawChildren;
13184
- const sTl = ctx._cstTriviaLog;
13185
14235
  const sCap = ctx.captureTrivia;
13186
14236
  const sBuf = ctx._cstBuf;
13187
- const buf = rawOnly ? { rawOnly: true } : {};
14237
+ const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
13188
14238
  ctx._cstBuf = buf;
13189
- ctx._cstChildren = void 0;
13190
- ctx._cstLeaves = void 0;
13191
- ctx._cstRawChildren = void 0;
13192
- ctx._cstTriviaLog = void 0;
13193
14239
  ctx.captureTrivia = captureWide;
13194
14240
  const savedFields = ctx._fields;
13195
14241
  ctx._fields = wantFields ? [] : void 0;
@@ -13204,13 +14250,9 @@ function assemble(t2, prog, cfg) {
13204
14250
  if (structural) ctx._triviaCaptureMask = savedMask;
13205
14251
  const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
13206
14252
  const hostKids = kids;
13207
- const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
14253
+ const rawKids = omitsRaw ? EMPTY_CH : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
13208
14254
  const tlog = buf.tl ?? EMPTY_TLOG;
13209
14255
  ctx._cstBuf = sBuf;
13210
- ctx._cstChildren = sCh;
13211
- ctx._cstLeaves = sLv;
13212
- ctx._cstRawChildren = sRaw;
13213
- ctx._cstTriviaLog = sTl;
13214
14256
  ctx.captureTrivia = sCap;
13215
14257
  if (v === FAIL) return FAIL;
13216
14258
  const end = EC.e;
@@ -13301,6 +14343,34 @@ function assemble(t2, prog, cfg) {
13301
14343
  rawScalarSpecs.add(code[child + 1]);
13302
14344
  scalarFor(child);
13303
14345
  }
14346
+ } else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]].exclusive) {
14347
+ const n = code[ip + 2];
14348
+ for (let i = 0; i < n; i++) {
14349
+ const armIp = code[ip + 4 + i];
14350
+ const child = leadingScalarTerminal(code, armIp, 2, true, true);
14351
+ if (n === 2 || n === 3) {
14352
+ if (child >= 0) scalarFor(child);
14353
+ continue;
14354
+ }
14355
+ if (child >= 0) {
14356
+ const spec = k[code[child + 1]];
14357
+ if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
14358
+ scalarFor(child);
14359
+ continue;
14360
+ }
14361
+ }
14362
+ const family = leadingLiteralFamily(code, k, armIp);
14363
+ if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
14364
+ const value = k[code[terminal + 1]];
14365
+ return typeof value === "string" && value.length >= 2;
14366
+ })) {
14367
+ for (const terminal of family) scalarFor(terminal);
14368
+ }
14369
+ const sequence6 = leadingScalarSequence(code, armIp);
14370
+ if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
14371
+ for (const terminal of sequence6.terminals) scalarFor(terminal);
14372
+ }
14373
+ }
13304
14374
  }
13305
14375
  }
13306
14376
  const notChild = scalarTerminalNotChild(code, ip);
@@ -13711,7 +14781,7 @@ function emitAssemblies(prog, cfgs) {
13711
14781
  seen.add(key);
13712
14782
  let em;
13713
14783
  try {
13714
- em = emitAssemblySource(t2, prog, cfg, extraIps);
14784
+ em = emitAssemblySource(t2, prog, cfg, extraIps, true);
13715
14785
  } catch (e) {
13716
14786
  if (e instanceof Unemittable) continue;
13717
14787
  throw e;
@@ -16086,7 +17156,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
16086
17156
  };
16087
17157
  const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
16088
17158
  const artifact = closureArtifact(prog);
16089
- const entry = tableRules(artifact)[ENTRY];
17159
+ const entry = tableRules(prog)[ENTRY];
16090
17160
  const offered = opts.fnSources ?? mapFnSources;
16091
17161
  const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
16092
17162
  const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
@@ -16550,6 +17620,7 @@ function rebuildCombinator(root, replacements) {
16550
17620
  return p;
16551
17621
  }
16552
17622
  out = d.type === void 0 ? d.build === void 0 ? node(one(d.parser), opts) : node(one(d.parser), d.build) : node(d.type, one(d.parser), d.build, opts);
17623
+ if (d.buildRawUnused === true && out._def.tag === "node") out._def.buildRawUnused = true;
16553
17624
  break;
16554
17625
  }
16555
17626
  case "grammar": {