parseman 0.40.0 → 0.41.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.
@@ -2617,9 +2617,11 @@ function markUnusedValues(root) {
2617
2617
  visit(def.parser, consumed);
2618
2618
  visit(def.sentinel, false);
2619
2619
  return;
2620
+ case "token":
2621
+ visit(def.parser, false);
2622
+ return;
2620
2623
  case "label":
2621
2624
  case "trivia":
2622
- case "token":
2623
2625
  case "attempt":
2624
2626
  case "withCtx":
2625
2627
  case "expect":
@@ -3357,7 +3359,7 @@ function leaf(root, fn) {
3357
3359
  }
3358
3360
 
3359
3361
  // src/version.ts
3360
- var PARSEMAN_VERSION = "0.40.0";
3362
+ var PARSEMAN_VERSION = "0.41.0";
3361
3363
 
3362
3364
  // src/cst/host-mode.ts
3363
3365
  var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
@@ -6301,7 +6303,7 @@ function scanBranchLabeled(shape, kindIndex, mint) {
6301
6303
  ` if (${m.end} > _e) {`,
6302
6304
  ` if (_cap) {`,
6303
6305
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, ${m.end}, ${kindIndex})`,
6304
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
6306
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << kindIndex}))) _ctx._cstTriviaLog.push(_e, ${m.end}, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${kindIndex})`,
6305
6307
  ` }`,
6306
6308
  ` _e = ${m.end}`,
6307
6309
  ` continue`,
@@ -6357,7 +6359,7 @@ function analyzeTriviaFastPath(trivia2) {
6357
6359
  var CAP_RECORD = [
6358
6360
  ` if (_cap && _e > _pos) {`,
6359
6361
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
6360
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
6362
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
6361
6363
  ` }`
6362
6364
  ].join("\n");
6363
6365
  function composeFastLoop(shapes) {
@@ -6417,7 +6419,7 @@ function buildLabeledRegexTriviaFnDecl(fnName, spec, reNames) {
6417
6419
  ` const _ce = _e + _m${i}[0].length`,
6418
6420
  ` if (_cap) {`,
6419
6421
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
6420
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
6422
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
6421
6423
  ` }`,
6422
6424
  ` _e = _ce`,
6423
6425
  ` _matched = true`,
@@ -6455,7 +6457,7 @@ function buildLabeledRuntimeTriviaFnDecl(fnName, spec, rpStartIndex) {
6455
6457
  ` const _ce = _r${i}.span.end`,
6456
6458
  ` if (_cap) {`,
6457
6459
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_e, _ce, ${k})`,
6458
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
6460
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia && (_ctx._triviaCaptureMask === undefined || (_ctx._triviaCaptureMask & ${1 << k}))) _ctx._cstTriviaLog.push(_e, _ce, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0, ${k})`,
6459
6461
  ` }`,
6460
6462
  ` _e = _ce`,
6461
6463
  ` _matched = true`,
@@ -6541,6 +6543,9 @@ function transformFnSource(fn, fnSrc) {
6541
6543
  function replaceParam(body, param, valueVar) {
6542
6544
  return body.replace(new RegExp(`\\b${escapeRegExp2(param)}\\b`, "g"), valueVar);
6543
6545
  }
6546
+ function hasExplicitObjectKey(body, param) {
6547
+ return new RegExp(`\\b${escapeRegExp2(param)}\\b\\s*:`).test(body);
6548
+ }
6544
6549
  function stripForIdCheck(body) {
6545
6550
  return body.replace(/'[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"/g, '""').replace(/\bas\s+const\b/g, "").replace(/\b[A-Za-z_$][\w$]*\s*:/g, ":");
6546
6551
  }
@@ -6583,10 +6588,19 @@ function tryInlineDestructureTransform(src, valueVars) {
6583
6588
  const allowed = new Set(valueVars);
6584
6589
  for (let i = 0; i < slots.length; i++) {
6585
6590
  const name = slots[i];
6586
- if (name) body = replaceParam(body, name, valueVars[i]);
6591
+ if (!name) continue;
6592
+ if (hasExplicitObjectKey(body, name)) return null;
6593
+ body = replaceParam(body, name, valueVars[i]);
6587
6594
  }
6588
6595
  return hasFreeIdentifiers(body, allowed) ? null : body;
6589
6596
  }
6597
+ function isDispatchTailOnlyTransform(src) {
6598
+ const m = src.match(/^\(\s*\[([^\]]*)\]\s*\)\s*=>\s*(.+)$/s);
6599
+ if (!m) return false;
6600
+ const slots = parseArrayDestructure(m[1], 2);
6601
+ const tail = slots[1];
6602
+ return tail !== null && m[2].trim() === tail;
6603
+ }
6590
6604
 
6591
6605
  // src/compiler/codegen.ts
6592
6606
  function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
@@ -6845,6 +6859,17 @@ function ensureRegexDecl(ctx, source, flags) {
6845
6859
  }
6846
6860
  return rName;
6847
6861
  }
6862
+ function ensurePlainRegexDecl(ctx, source, flags) {
6863
+ const f = flags.replace(/[gy]/g, "");
6864
+ const key = `${source}/${f}`;
6865
+ let rName = ctx.regexMap.get(key);
6866
+ if (rName === void 0) {
6867
+ rName = `${nsp(ctx)}_re${ctx.regexDecls.length}`;
6868
+ ctx.regexDecls.push(`const ${rName} = ${new RegExp(source, f).toString()}`);
6869
+ ctx.regexMap.set(key, rName);
6870
+ }
6871
+ return rName;
6872
+ }
6848
6873
  function ensureTriviaFn(ctx) {
6849
6874
  const trivia2 = ctx.activeTrivia;
6850
6875
  const existing = ctx.triviaFnNames.get(trivia2);
@@ -6910,7 +6935,7 @@ function ensureTriviaFn(ctx) {
6910
6935
  ` }`,
6911
6936
  ` if (_cap && _e > _pos) {`,
6912
6937
  ` if (_ctx._triviaLog !== undefined) _ctx._triviaLog.push(_pos, _e)`,
6913
- ` if (_ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
6938
+ ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
6914
6939
  ` }`,
6915
6940
  ` return _e`,
6916
6941
  `}`
@@ -7371,14 +7396,19 @@ function emitSeqValues(def, ctx, pos) {
7371
7396
  continue;
7372
7397
  } else {
7373
7398
  const trivFn = ensureTriviaFn(ctx);
7399
+ const markLog = v(ctx, "_mklg");
7374
7400
  const scanEndV = v(ctx, "_sne");
7375
- stmts.push(`${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx)`);
7401
+ const capArg = ctx.noHoist ? "0" : "_ctx._triviaLog !== undefined ? 2 : 0";
7402
+ stmts.push(
7403
+ `${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
7404
+ `${ind(ctx)}const ${scanEndV} = ${trivFn}(input, ${curV}, _ctx, ${capArg})`
7405
+ );
7376
7406
  const r2 = emit(def.parsers[i], ctx, scanEndV);
7377
7407
  stmts.push(...r2.stmts);
7378
7408
  const endAfterV = v(ctx, "_sea");
7379
7409
  stmts.push(
7380
7410
  `${ind(ctx)}const ${endAfterV} = ${r2.endVar}`,
7381
- `${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}`
7411
+ `${ind(ctx)}if (${endAfterV} > ${scanEndV}) ${curV} = ${endAfterV}; else if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}`
7382
7412
  );
7383
7413
  valueVars.push(r2.valueVar);
7384
7414
  continue;
@@ -7608,19 +7638,20 @@ function mayRecordRecoveryError(p, recovery, seen = /* @__PURE__ */ new Set()) {
7608
7638
  return false;
7609
7639
  }
7610
7640
  }
7611
- function emitDispatchCombinator(parser2, def, ctx, pos) {
7641
+ function emitDispatchCombinator(parser2, def, ctx, pos, valueMode = "pair") {
7612
7642
  if (parserUsesRouted2(def.selector)) {
7613
7643
  throw new Error("parseman: routed() can only appear inside a dispatch() branch");
7614
7644
  }
7615
7645
  const coverageIds = ctx.coverage?.plan.dispatches.get(parser2) ?? [];
7616
7646
  const branchUsesRouted2 = (entry) => entry.usesRouted === true || parserUsesRouted2(entry.parser);
7617
7647
  const hasRoutedBranch = def.cases.some(branchUsesRouted2) || (def.matchers ? def.matchers.some(branchUsesRouted2) : false) || (def.otherwise ? def.otherwiseUsesRouted === true || parserUsesRouted2(def.otherwise) : false);
7618
- const selectorLeafMark = hasRoutedBranch ? v(ctx, "_dsl") : null;
7619
- const selectorRawMark = hasRoutedBranch ? v(ctx, "_dsr") : null;
7620
- const selectorTriviaMark = hasRoutedBranch ? v(ctx, "_dst") : null;
7621
- const selectorLogMark = hasRoutedBranch ? v(ctx, "_dsg") : null;
7622
- const selectorFieldMark = hasRoutedBranch ? v(ctx, "_dsf") : null;
7623
- const selectorErrorMark = hasRoutedBranch ? v(ctx, "_dse") : null;
7648
+ const selectorNeedsRollback = hasRoutedBranch && (ctx.capturing === true && capturesLeaf(def.selector) || ctx.activeTrivia !== void 0 && parserHasTriviaSite(def.selector) || parserEnablesTriviaCapture(def.selector) || parserHasOwnFields(def.selector) || mayRecordRecoveryError(def.selector, !!ctx.recovery));
7649
+ const selectorLeafMark = selectorNeedsRollback ? v(ctx, "_dsl") : null;
7650
+ const selectorRawMark = selectorNeedsRollback ? v(ctx, "_dsr") : null;
7651
+ const selectorTriviaMark = selectorNeedsRollback ? v(ctx, "_dst") : null;
7652
+ const selectorLogMark = selectorNeedsRollback ? v(ctx, "_dsg") : null;
7653
+ const selectorFieldMark = selectorNeedsRollback ? v(ctx, "_dsf") : null;
7654
+ const selectorErrorMark = selectorNeedsRollback ? v(ctx, "_dse") : null;
7624
7655
  const selector = emit(def.selector, ctx, pos);
7625
7656
  const outV = v(ctx, "_dval");
7626
7657
  const outE = v(ctx, "_dend");
@@ -7645,13 +7676,14 @@ function emitDispatchCombinator(parser2, def, ctx, pos) {
7645
7676
  stmts.push(head);
7646
7677
  ctx.indent++;
7647
7678
  const usesRouted = branchUsesRouted2(entry);
7648
- const routedV = usesRouted ? v(ctx, "_drt") : null;
7679
+ const needsRoutedContext = usesRouted && routedNeedsContextBridge(parser3, ctx);
7680
+ const routedV = needsRoutedContext ? v(ctx, "_drt") : null;
7649
7681
  const mayError = mayRecordRecoveryError(parser3, !!ctx.recovery);
7650
7682
  const errMark = mayError ? v(ctx, "_derr") : null;
7651
7683
  const logMark = ctx.activeTrivia ? v(ctx, "_dlog") : null;
7652
- if (routedV) {
7684
+ if (usesRouted) {
7653
7685
  stmts.push(
7654
- `${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`,
7686
+ ...routedV ? [`${ind(ctx)}const ${routedV} = _ctx._routed; _ctx._routed = { value: ${selector.valueVar}, span: { start: ${pos}, end: ${selector.endVar} } }`] : [],
7655
7687
  ...selectorLeafMark ? [
7656
7688
  `${ind(ctx)}if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${selectorLeafMark}) _ctx._cstLeaves.length = ${selectorLeafMark}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${selectorRawMark}) _ctx._cstRawChildren.length = ${selectorRawMark}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${selectorTriviaMark}) _ctx._cstTriviaLog.length = ${selectorTriviaMark}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${selectorLogMark}) _ctx._triviaLog.length = ${selectorLogMark}; if (_ctx._fields && _ctx._fields.length !== ${selectorFieldMark}) _ctx._fields.length = ${selectorFieldMark}; if (_ctx._errors && _ctx._errors.length !== ${selectorErrorMark}) _ctx._errors.length = ${selectorErrorMark}`
7657
7689
  ] : []
@@ -7659,7 +7691,17 @@ function emitDispatchCombinator(parser2, def, ctx, pos) {
7659
7691
  }
7660
7692
  if (errMark) stmts.push(`${ind(ctx)}const ${errMark} = _ctx._errors?.length ?? 0`);
7661
7693
  if (logMark) stmts.push(`${ind(ctx)}const ${logMark} = _ctx._triviaLog?.length ?? 0`);
7694
+ const savedRoutedLocal = ctx.routedLocal;
7695
+ const savedNoHoist = ctx.noHoist;
7696
+ if (usesRouted && !needsRoutedContext) {
7697
+ ctx.routedLocal = { valueVar: selector.valueVar, startVar: pos, endVar: selector.endVar };
7698
+ ctx.noHoist = true;
7699
+ } else if (usesRouted) {
7700
+ ctx.routedLocal = void 0;
7701
+ }
7662
7702
  const tail = emitTailFallible(parser3, ctx, usesRouted ? pos : selector.endVar);
7703
+ ctx.routedLocal = savedRoutedLocal;
7704
+ ctx.noHoist = savedNoHoist;
7663
7705
  stmts.push(...coverageAttempt(ctx, coverageId, pos));
7664
7706
  const errorRollback = errMark ? `if (_ctx._errors && _ctx._errors.length !== ${errMark}) _ctx._errors.length = ${errMark}; ` : "";
7665
7707
  const logRollback = logMark ? `if (_ctx._triviaLog && _ctx._triviaLog.length !== ${logMark}) _ctx._triviaLog.length = ${logMark}; ` : "";
@@ -7669,7 +7711,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos) {
7669
7711
  ...tail.stmts,
7670
7712
  `${ind(ctx)}if (!${tail.okVar}) { ${routedRollback}${errorRollback}${logRollback}${coverageFailure}${committedFailBody(ctx)} }`,
7671
7713
  ...routedV ? [`${ind(ctx)}_ctx._routed = ${routedV}`] : [],
7672
- `${ind(ctx)}${outV} = [${selector.valueVar}, ${tail.valVar}]`,
7714
+ `${ind(ctx)}${outV} = ${valueMode === "tail" ? tail.valVar : `[${selector.valueVar}, ${tail.valVar}]`}`,
7673
7715
  `${ind(ctx)}${outE} = ${tail.endVar}`,
7674
7716
  ...coverageHit(ctx, coverageId, pos, tail.endVar)
7675
7717
  );
@@ -7684,7 +7726,7 @@ function emitDispatchCombinator(parser2, def, ctx, pos) {
7684
7726
  }
7685
7727
  const emitMatcherTails = () => {
7686
7728
  for (const matcher of def.matchers ?? []) {
7687
- emitSelectedTail(matcher, wroteBranch ? "else if" : "if", emitDispatchMatcherCondition(keyV, matcher), coverageIds[coverageIndex++]);
7729
+ emitSelectedTail(matcher, wroteBranch ? "else if" : "if", emitDispatchMatcherCondition(ctx, keyV, matcher), coverageIds[coverageIndex++]);
7688
7730
  wroteBranch = true;
7689
7731
  }
7690
7732
  };
@@ -7709,10 +7751,10 @@ function emitDispatchKeyCondition(valueVar, key, caseInsensitive) {
7709
7751
  }
7710
7752
  return parts.join(" && ");
7711
7753
  }
7712
- function emitDispatchMatcherCondition(valueVar, matcher) {
7754
+ function emitDispatchMatcherCondition(ctx, valueVar, matcher) {
7713
7755
  if (matcher.kind === "matches") {
7714
7756
  const flags = matcher.caseInsensitive && !matcher.flags?.includes("i") ? `${matcher.flags ?? ""}i` : matcher.flags ?? "";
7715
- return `${new RegExp(matcher.value, flags).toString()}.test(${valueVar})`;
7757
+ return `${ensurePlainRegexDecl(ctx, matcher.value, flags)}.test(${valueVar})`;
7716
7758
  }
7717
7759
  const text = matcher.value;
7718
7760
  const parts = [`${valueVar}.length >= ${text.length}`];
@@ -7915,6 +7957,28 @@ function emitsAsNamedFn(p, ctx) {
7915
7957
  const usage = ctx.lazyUsage;
7916
7958
  return !!usage && !ctx.noHoist && !ctx.capAsTrivia && isHoistableTag(p._def.tag) && (usage.counts.get(p) ?? 0) > 1 && (usage.sizes.get(p) ?? 0) >= HOIST_MIN_SUBTREE;
7917
7959
  }
7960
+ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
7961
+ if (seen.has(p)) return false;
7962
+ seen.add(p);
7963
+ if (p._def.tag === "lazy") {
7964
+ if (ctx.ruleNames?.has(p) || ctx.namedParsers.has(p)) return parserUsesRouted2(p);
7965
+ const usage = ctx.lazyUsage;
7966
+ if (usage && (usage.counts.get(p) ?? 0) <= 1 && !usage.recursive.has(p)) {
7967
+ try {
7968
+ return routedNeedsContextBridge(p._def.thunk(), ctx, seen);
7969
+ } catch {
7970
+ return parserUsesRouted2(p);
7971
+ }
7972
+ }
7973
+ return parserUsesRouted2(p);
7974
+ }
7975
+ if (ctx.ruleNames?.has(p)) return parserUsesRouted2(p);
7976
+ if (ctx.namedParsers.has(p)) return parserUsesRouted2(p);
7977
+ const d = p._def;
7978
+ if (d.tag === "dispatch") return false;
7979
+ if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
7980
+ return childrenOf2(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
7981
+ }
7918
7982
  function armReplayInScope(arm, ctx) {
7919
7983
  let p = arm;
7920
7984
  for (; ; ) {
@@ -8165,15 +8229,16 @@ function emitSepBy(_p, def, ctx, pos) {
8165
8229
  const itemFailBreak = (sepEndVar, sepRb, postSepRb) => def.trailing === void 0 ? `${sepRb}break` : `${postSepRb}${curV} = ${sepEndVar}; break`;
8166
8230
  const postSepMarks = () => {
8167
8231
  if (def.trailing === void 0 || !ctx.capturing) return { decl: [], rb: "" };
8168
- const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg");
8232
+ const lv = v(ctx, "_tlv"), rw = v(ctx, "_trw"), tl = v(ctx, "_ttl"), lg = v(ctx, "_tlg"), fl = v(ctx, "_tlf");
8169
8233
  return {
8170
8234
  decl: [
8171
8235
  `${ind(ctx)}const ${lv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
8172
8236
  `${ind(ctx)}const ${rw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
8173
8237
  `${ind(ctx)}const ${tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
8174
- `${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`
8238
+ `${ind(ctx)}const ${lg} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
8239
+ `${ind(ctx)}const ${fl} = _ctx._fields ? _ctx._fields.length : 0`
8175
8240
  ],
8176
- rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg}; `
8241
+ rb: `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${lv}) _ctx._cstLeaves.length = ${lv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${rw}) _ctx._cstRawChildren.length = ${rw}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${tl}) _ctx._cstTriviaLog.length = ${tl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${lg}) _ctx._triviaLog.length = ${lg}; if (_ctx._fields && _ctx._fields.length !== ${fl}) _ctx._fields.length = ${fl}; `
8177
8242
  };
8178
8243
  };
8179
8244
  if (rec) {
@@ -8212,16 +8277,18 @@ function emitSepBy(_p, def, ctx, pos) {
8212
8277
  const markTl = v(ctx, "_mktl");
8213
8278
  const markLog = v(ctx, "_mklg");
8214
8279
  const markLv = v(ctx, "_mklv");
8280
+ const markFld = v(ctx, "_mkf");
8215
8281
  const spV = v(ctx, "_sp");
8216
8282
  stmts.push(
8217
8283
  `${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
8218
8284
  `${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
8219
8285
  `${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
8220
8286
  `${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
8287
+ `${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`,
8221
8288
  `${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`
8222
8289
  );
8223
8290
  sepAtPos = spV;
8224
- const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}; `;
8291
+ const rollbackToSep = `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markV}) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog && _ctx._cstTriviaLog.length !== ${markTl}) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog && _ctx._triviaLog.length !== ${markLog}) _ctx._triviaLog.length = ${markLog}; if (_ctx._fields && _ctx._fields.length !== ${markFld}) _ctx._fields.length = ${markFld}; `;
8225
8292
  const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
8226
8293
  const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
8227
8294
  stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
@@ -8259,16 +8326,18 @@ function emitSepBy(_p, def, ctx, pos) {
8259
8326
  } else {
8260
8327
  const markLv = ctx.capturing ? v(ctx, "_mklv") : null;
8261
8328
  const markRw = ctx.capturing ? v(ctx, "_mkrw") : null;
8329
+ const markFld = ctx.capturing ? v(ctx, "_mkf") : null;
8262
8330
  if (markLv) {
8263
8331
  stmts.push(
8264
8332
  `${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
8265
- `${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
8333
+ `${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
8334
+ `${ind(ctx)}const ${markFld} = _ctx._fields ? _ctx._fields.length : 0`
8266
8335
  );
8267
8336
  }
8268
8337
  const sep2 = emitFallible(def.separator, ctx, sepAtPos, true);
8269
8338
  const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = sep2;
8270
8339
  stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sep2.mayCommit ? `if (_ctx._fc) ${committedFailBody(ctx)}; ` : ""}break }`);
8271
- const nextRb = markLv ? `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markRw}) _ctx._cstRawChildren.length = ${markRw}; ` : "";
8340
+ const nextRb = markLv ? `if (_ctx._cstLeaves && _ctx._cstLeaves.length !== ${markLv}) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren && _ctx._cstRawChildren.length !== ${markRw}) _ctx._cstRawChildren.length = ${markRw}; if (_ctx._fields && _ctx._fields.length !== ${markFld}) _ctx._fields.length = ${markFld}; ` : "";
8272
8341
  const post = postSepMarks();
8273
8342
  stmts.push(...post.decl);
8274
8343
  const next = emitFallible(def.parser, ctx, sepEnd, true);
@@ -8338,7 +8407,7 @@ function emitScanTo(def, ctx, pos) {
8338
8407
  return { stmts, valueVar: valV, endVar: curV };
8339
8408
  }
8340
8409
  function emitNot(def, ctx, pos) {
8341
- const sinksLive = !!ctx.capturing || !!ctx.recovery;
8410
+ const sinksLive = !!ctx.capturing || !!ctx.recovery || !!ctx.activeTrivia;
8342
8411
  const leaves = sinksLive ? v(ctx, "_ntl") : null;
8343
8412
  const raw = sinksLive ? v(ctx, "_ntr") : null;
8344
8413
  const tl = sinksLive ? v(ctx, "_ntt") : null;
@@ -8377,6 +8446,17 @@ function emitPeek(def, ctx, pos) {
8377
8446
  };
8378
8447
  }
8379
8448
  function emitRouted(ctx, pos) {
8449
+ const local = ctx.routedLocal;
8450
+ if (local !== void 0) {
8451
+ return {
8452
+ stmts: [
8453
+ ...emitIfFail(ctx, `${local.startVar} !== ${pos}`, failBody(ctx, '"routed()"', pos)),
8454
+ ...emitLeafCapture(ctx, local.valueVar, local.startVar, local.endVar)
8455
+ ],
8456
+ valueVar: local.valueVar,
8457
+ endVar: local.endVar
8458
+ };
8459
+ }
8380
8460
  const item = v(ctx, "_rt");
8381
8461
  return {
8382
8462
  stmts: [
@@ -8872,6 +8952,9 @@ function emitDispatch(p, ctx, pos) {
8872
8952
  return emitSepBy(p, def, ctx, pos);
8873
8953
  case "transform": {
8874
8954
  const fnSrc = transformFnSource(def.fn, def.fnSrc);
8955
+ if (fnSrc && def.parser._def.tag === "dispatch" && isDispatchTailOnlyTransform(fnSrc)) {
8956
+ return emitDispatchCombinator(def.parser, def.parser._def, ctx, pos, "tail");
8957
+ }
8875
8958
  if (fnSrc && def.parser._def.tag === "sequence") {
8876
8959
  const seqR = emitSeqValues(def.parser._def, ctx, pos);
8877
8960
  const inlined = tryInlineDestructureTransform(fnSrc, seqR.valueVars);
@@ -9561,8 +9644,8 @@ function assertRuleName(name) {
9561
9644
  );
9562
9645
  }
9563
9646
  }
9564
- function publicRuleWrapperSource(rule, fnSource) {
9565
- const labels = rule._meta.triviaKindLabels;
9647
+ function publicRuleWrapperSource(rule, fnSource, ambientTriviaKindLabels) {
9648
+ const labels = rule._meta.triviaKindLabels ?? ambientTriviaKindLabels;
9566
9649
  if (labels === void 0) return fnSource;
9567
9650
  return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
9568
9651
  }
@@ -9670,7 +9753,7 @@ function compileRuleMap(ruleMap, opts) {
9670
9753
  return [`function(input, _pos, _ctx) {`, ...body, `}`].join("\n");
9671
9754
  };
9672
9755
  const objBody = perEntry.map(({ key, rule, r }) => {
9673
- const src = publicRuleWrapperSource(rule, entryFnText(r, rule));
9756
+ const src = publicRuleWrapperSource(rule, entryFnText(r, rule), ctx.triviaKindLabels);
9674
9757
  return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
9675
9758
  }).join(",\n");
9676
9759
  const replacement = [
@@ -9857,7 +9940,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
9857
9940
  ...r.stmts,
9858
9941
  ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
9859
9942
  `}`
9860
- ].join("\n")));
9943
+ ].join("\n"), ctx.triviaKindLabels));
9861
9944
  }
9862
9945
  const firstSets = /* @__PURE__ */ new Map();
9863
9946
  const firstSetRecipes = /* @__PURE__ */ new Map();
@@ -10710,6 +10793,10 @@ function gate(predicate) {
10710
10793
  };
10711
10794
  }
10712
10795
 
10796
+ // src/cst/trivia-entries.ts
10797
+ var EMPTY_INDICES = Object.freeze([]);
10798
+ var EMPTY_GAPS = Object.freeze([]);
10799
+
10713
10800
  // src/cst/offset-model.ts
10714
10801
  var { isFinite } = Number;
10715
10802