parseman 0.43.0 → 0.45.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 (97) hide show
  1. package/dist/analysis/diagnose.d.ts +118 -0
  2. package/dist/analysis/diagnose.d.ts.map +1 -0
  3. package/dist/analysis/gating.d.ts +9 -9
  4. package/dist/analysis/gating.d.ts.map +1 -1
  5. package/dist/analysis/grammar.d.ts.map +1 -1
  6. package/dist/combinators/attempt.d.ts.map +1 -1
  7. package/dist/combinators/choice.d.ts.map +1 -1
  8. package/dist/combinators/dispatch.d.ts +19 -1
  9. package/dist/combinators/dispatch.d.ts.map +1 -1
  10. package/dist/combinators/expect.d.ts.map +1 -1
  11. package/dist/combinators/first-set.d.ts.map +1 -1
  12. package/dist/combinators/grammar.d.ts +7 -0
  13. package/dist/combinators/grammar.d.ts.map +1 -1
  14. package/dist/combinators/map.d.ts +11 -0
  15. package/dist/combinators/map.d.ts.map +1 -1
  16. package/dist/combinators/node.d.ts +19 -0
  17. package/dist/combinators/node.d.ts.map +1 -1
  18. package/dist/combinators/token.d.ts +3 -2
  19. package/dist/combinators/token.d.ts.map +1 -1
  20. package/dist/combinators/trivia-skip.d.ts +1 -0
  21. package/dist/combinators/trivia-skip.d.ts.map +1 -1
  22. package/dist/compiler/build-arity.d.ts +28 -0
  23. package/dist/compiler/build-arity.d.ts.map +1 -1
  24. package/dist/compiler/codegen.d.ts +80 -60
  25. package/dist/compiler/codegen.d.ts.map +1 -1
  26. package/dist/compiler/degradation.d.ts +123 -0
  27. package/dist/compiler/degradation.d.ts.map +1 -0
  28. package/dist/compiler/fields.d.ts.map +1 -1
  29. package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
  30. package/dist/compiler/inline-build.d.ts.map +1 -1
  31. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  32. package/dist/compiler/linker.d.ts +1 -1
  33. package/dist/compiler/linker.d.ts.map +1 -1
  34. package/dist/compiler/scannable-run.d.ts +1 -1
  35. package/dist/compiler/scannable-run.d.ts.map +1 -1
  36. package/dist/compiler/trivia-fast-path.d.ts +4 -3
  37. package/dist/compiler/trivia-fast-path.d.ts.map +1 -1
  38. package/dist/coverage.d.ts +13 -0
  39. package/dist/coverage.d.ts.map +1 -1
  40. package/dist/cst/reflection.d.ts.map +1 -1
  41. package/dist/cst/trivia-entries.d.ts +15 -9
  42. package/dist/cst/trivia-entries.d.ts.map +1 -1
  43. package/dist/cst/trivia-kinds.d.ts +15 -11
  44. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  45. package/dist/functional/run.d.ts +22 -16
  46. package/dist/functional/run.d.ts.map +1 -1
  47. package/dist/index.cjs +2131 -1594
  48. package/dist/index.cjs.map +4 -4
  49. package/dist/index.d.ts +6 -8
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +2131 -1594
  52. package/dist/index.js.map +4 -4
  53. package/dist/language-service/index.cjs +201 -132
  54. package/dist/language-service/index.cjs.map +4 -4
  55. package/dist/language-service/index.js +201 -132
  56. package/dist/language-service/index.js.map +4 -4
  57. package/dist/oracle/digest.d.ts +132 -6
  58. package/dist/oracle/digest.d.ts.map +1 -1
  59. package/dist/oracle/index.cjs +136 -305
  60. package/dist/oracle/index.cjs.map +4 -4
  61. package/dist/oracle/index.d.ts +43 -31
  62. package/dist/oracle/index.d.ts.map +1 -1
  63. package/dist/oracle/index.js +136 -305
  64. package/dist/oracle/index.js.map +4 -4
  65. package/dist/plugin/evaluator.d.ts +3 -0
  66. package/dist/plugin/evaluator.d.ts.map +1 -1
  67. package/dist/plugin/index.cjs +2333 -1721
  68. package/dist/plugin/index.cjs.map +4 -4
  69. package/dist/plugin/index.d.ts +18 -0
  70. package/dist/plugin/index.d.ts.map +1 -1
  71. package/dist/plugin/index.js +2333 -1721
  72. package/dist/plugin/index.js.map +4 -4
  73. package/dist/plugin/reducer-resolver.d.ts +41 -0
  74. package/dist/plugin/reducer-resolver.d.ts.map +1 -0
  75. package/dist/run/index.cjs +185 -132
  76. package/dist/run/index.cjs.map +3 -3
  77. package/dist/run/index.d.ts +1 -1
  78. package/dist/run/index.d.ts.map +1 -1
  79. package/dist/run/index.js +185 -132
  80. package/dist/run/index.js.map +3 -3
  81. package/dist/spec/index.cjs +1637 -1322
  82. package/dist/spec/index.cjs.map +4 -4
  83. package/dist/spec/index.js +1637 -1322
  84. package/dist/spec/index.js.map +4 -4
  85. package/dist/spec/model.d.ts.map +1 -1
  86. package/dist/types.d.ts +31 -1
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/version.d.ts +1 -1
  89. package/package.json +7 -3
  90. package/dist/combinators/guard.d.ts +0 -8
  91. package/dist/combinators/guard.d.ts.map +0 -1
  92. package/dist/cst/offset-model.d.ts +0 -119
  93. package/dist/cst/offset-model.d.ts.map +0 -1
  94. package/dist/oracle/corpus.d.ts +0 -32
  95. package/dist/oracle/corpus.d.ts.map +0 -1
  96. package/dist/oracle/identity.d.ts +0 -117
  97. package/dist/oracle/identity.d.ts.map +0 -1
@@ -102,6 +102,7 @@ function probeAt(sentinel, input, pos, ctx) {
102
102
  _cstRawChildren: ctx._cstRawChildren,
103
103
  _cstTriviaLog: ctx._cstTriviaLog,
104
104
  _triviaLog: ctx._triviaLog,
105
+ _rootTriviaLog: ctx._rootTriviaLog,
105
106
  _fields: ctx._fields,
106
107
  _cstBuf: ctx._cstBuf,
107
108
  _tolerant: ctx._tolerant,
@@ -114,6 +115,7 @@ function probeAt(sentinel, input, pos, ctx) {
114
115
  ctx._cstRawChildren = void 0;
115
116
  ctx._cstTriviaLog = void 0;
116
117
  ctx._triviaLog = void 0;
118
+ ctx._rootTriviaLog = void 0;
117
119
  ctx._fields = void 0;
118
120
  ctx._cstBuf = void 0;
119
121
  ctx._tolerant = void 0;
@@ -128,6 +130,7 @@ function probeAt(sentinel, input, pos, ctx) {
128
130
  ctx._cstRawChildren = s._cstRawChildren;
129
131
  ctx._cstTriviaLog = s._cstTriviaLog;
130
132
  ctx._triviaLog = s._triviaLog;
133
+ ctx._rootTriviaLog = s._rootTriviaLog;
131
134
  ctx._fields = s._fields;
132
135
  ctx._cstBuf = s._cstBuf;
133
136
  ctx._tolerant = s._tolerant;
@@ -185,105 +188,97 @@ var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSet
185
188
  // src/cst/trivia-entries.ts
186
189
  var EMPTY_INDICES = Object.freeze([]);
187
190
  var EMPTY_GAPS = Object.freeze([]);
188
- function entryOffset(i, stride) {
189
- return i * stride;
190
- }
191
- function triviaEntries(log, labels, opts) {
192
- const baseStride = opts?.nodeLog ? 3 : 2;
193
- const stride = labels ? baseStride + 1 : baseStride;
194
- const length = Math.floor(log.length / stride);
195
- return {
191
+ var SELECTED_ROOT_STRIDE = 5;
192
+ function buildRootTriviaIndex(log, labels) {
193
+ const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
194
+ const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
195
+ const ownedRangeStart = (i) => log[markerOffset(i)];
196
+ const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
197
+ const markerStart = (i) => log[markerOffset(i) + 2];
198
+ const markerEnd = (i) => log[markerOffset(i) + 3];
199
+ const markerKind = (i) => log[markerOffset(i) + 4];
200
+ const entries = {
196
201
  length,
197
202
  labels,
198
- stride,
199
- start(i) {
200
- return log[entryOffset(i, stride)];
201
- },
202
- end(i) {
203
- return log[entryOffset(i, stride) + 1];
204
- },
205
- insertIndex(i) {
206
- return opts?.nodeLog ? log[entryOffset(i, stride) + 2] : void 0;
207
- },
208
- kindIndex(i) {
209
- if (!labels) return void 0;
210
- return log[entryOffset(i, stride) + baseStride];
211
- },
203
+ stride: SELECTED_ROOT_STRIDE,
204
+ start: markerStart,
205
+ end: markerEnd,
206
+ insertIndex: () => void 0,
207
+ kindIndex: markerKind,
212
208
  kind(i) {
213
- const ki = labels ? log[entryOffset(i, stride) + baseStride] : void 0;
214
- return ki !== void 0 ? labels[ki] : void 0;
209
+ return labels[markerKind(i)];
215
210
  },
216
211
  text(i, input) {
217
- const s = log[entryOffset(i, stride)];
218
- const e = log[entryOffset(i, stride) + 1];
219
- return input.slice(s, e);
212
+ return input.slice(markerStart(i), markerEnd(i));
220
213
  }
221
214
  };
222
- }
223
- function appendEntryRange(map, key, first, last) {
224
- let indices = map.get(key);
225
- if (!indices) {
226
- indices = [];
227
- map.set(key, indices);
228
- }
229
- for (let i = first; i <= last; i++) indices.push(i);
230
- }
231
- function buildGap(entries, start, end, first, last) {
232
- const entryIndices = [];
233
- for (let i = first; i <= last; i++) entryIndices.push(i);
234
- return {
235
- start,
236
- end,
237
- entryIndices,
238
- hasKind(kind) {
239
- for (const i of entryIndices) {
240
- if (entries.kind(i) === kind) return true;
241
- }
242
- return false;
243
- },
244
- text(input) {
245
- return input.slice(start, end);
215
+ const lowerBound = (offset, by) => {
216
+ let lo = 0;
217
+ let hi = length;
218
+ while (lo < hi) {
219
+ const mid = lo + hi >>> 1;
220
+ if (by(mid) < offset) lo = mid + 1;
221
+ else hi = mid;
246
222
  }
223
+ return lo;
247
224
  };
248
- }
249
- function buildRootMaps(entries) {
250
- const before = /* @__PURE__ */ new Map();
251
- const after = /* @__PURE__ */ new Map();
252
- const beforeGaps = /* @__PURE__ */ new Map();
253
- const afterGaps = /* @__PURE__ */ new Map();
254
- const gaps = [];
255
- if (entries.length === 0) return { before, after, beforeGaps, afterGaps, gaps };
256
- const appendGap = (first2, last, start2, end2) => {
257
- const gap = buildGap(entries, start2, end2, first2, last);
258
- gaps.push(gap);
259
- afterGaps.set(start2, gap);
260
- beforeGaps.set(end2, gap);
261
- appendEntryRange(after, start2, first2, last);
262
- appendEntryRange(before, end2, first2, last);
225
+ const gapRowsAt = (offset, direction) => {
226
+ const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
227
+ let first = lowerBound(offset, edge);
228
+ if (first === length || edge(first) !== offset) return void 0;
229
+ const start = ownedRangeStart(first);
230
+ const end = ownedRangeEnd(first);
231
+ while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
232
+ let last = first + 1;
233
+ while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
234
+ return [first, last];
235
+ };
236
+ const indices = (first, last) => {
237
+ const out = [];
238
+ for (let i = first; i < last; i++) out.push(i);
239
+ return out;
240
+ };
241
+ const makeGap = (first, last) => {
242
+ const start = ownedRangeStart(first);
243
+ const end = ownedRangeEnd(first);
244
+ let entryIndices;
245
+ return {
246
+ start,
247
+ end,
248
+ get entryIndices() {
249
+ return entryIndices ??= indices(first, last);
250
+ },
251
+ hasKind(kind) {
252
+ for (let i = first; i < last; i++) {
253
+ if (labels[markerKind(i)] === kind) return true;
254
+ }
255
+ return false;
256
+ },
257
+ text(input) {
258
+ return input.slice(start, end);
259
+ }
260
+ };
263
261
  };
264
- let first = 0;
265
- let start = entries.start(0);
266
- let end = entries.end(0);
267
- for (let i = 1; i < entries.length; i++) {
268
- const nextStart = entries.start(i);
269
- const nextEnd = entries.end(i);
270
- if (nextStart === end) {
271
- end = nextEnd;
272
- continue;
273
- }
274
- appendGap(first, i - 1, start, end);
275
- first = i;
276
- start = nextStart;
277
- end = nextEnd;
278
- }
279
- appendGap(first, entries.length - 1, start, end);
280
- return { before, after, beforeGaps, afterGaps, gaps };
281
- }
282
- function buildRootTriviaIndex(log, labels) {
283
- const entries = triviaEntries(log, labels);
284
262
  let maps;
285
263
  const getMaps = () => {
286
- maps ??= buildRootMaps(entries);
264
+ if (maps !== void 0) return maps;
265
+ const before = /* @__PURE__ */ new Map();
266
+ const after = /* @__PURE__ */ new Map();
267
+ const beforeGaps = /* @__PURE__ */ new Map();
268
+ const afterGaps = /* @__PURE__ */ new Map();
269
+ const gaps = [];
270
+ for (let first = 0; first < length; ) {
271
+ let last = first + 1;
272
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
273
+ const gap = makeGap(first, last);
274
+ gaps.push(gap);
275
+ afterGaps.set(gap.start, gap);
276
+ beforeGaps.set(gap.end, gap);
277
+ after.set(gap.start, [...gap.entryIndices]);
278
+ before.set(gap.end, [...gap.entryIndices]);
279
+ first = last;
280
+ }
281
+ maps = { before, after, beforeGaps, afterGaps, gaps };
287
282
  return maps;
288
283
  };
289
284
  return {
@@ -296,16 +291,20 @@ function buildRootTriviaIndex(log, labels) {
296
291
  return getMaps().after;
297
292
  },
298
293
  entryIndicesBefore(offset) {
299
- return getMaps().before.get(offset) ?? EMPTY_INDICES;
294
+ const rows = gapRowsAt(offset, "before");
295
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
300
296
  },
301
297
  entryIndicesAfter(offset) {
302
- return getMaps().after.get(offset) ?? EMPTY_INDICES;
298
+ const rows = gapRowsAt(offset, "after");
299
+ return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
303
300
  },
304
301
  gapBefore(offset) {
305
- return getMaps().beforeGaps.get(offset);
302
+ const rows = gapRowsAt(offset, "before");
303
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
306
304
  },
307
305
  gapAfter(offset) {
308
- return getMaps().afterGaps.get(offset);
306
+ const rows = gapRowsAt(offset, "after");
307
+ return rows ? makeGap(rows[0], rows[1]) : void 0;
309
308
  },
310
309
  gaps() {
311
310
  return getMaps().gaps;
@@ -313,13 +312,21 @@ function buildRootTriviaIndex(log, labels) {
313
312
  gapsWithKind(kind) {
314
313
  const kinds = typeof kind === "string" ? [kind] : kind;
315
314
  const matches2 = [];
316
- for (const gap of getMaps().gaps) {
317
- for (const k of kinds) {
318
- if (gap.hasKind(k)) {
319
- matches2.push(gap);
320
- break;
315
+ for (let first = 0; first < length; ) {
316
+ let last = first + 1;
317
+ while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
318
+ let matched = false;
319
+ for (let i = first; i < last && !matched; i++) {
320
+ const label2 = labels[markerKind(i)];
321
+ for (const kind2 of kinds) {
322
+ if (label2 === kind2) {
323
+ matched = true;
324
+ break;
325
+ }
321
326
  }
322
327
  }
328
+ if (matched) matches2.push(makeGap(first, last));
329
+ first = last;
323
330
  }
324
331
  return matches2.length === 0 ? EMPTY_GAPS : matches2;
325
332
  }
@@ -344,12 +351,54 @@ function assertHostModeCompatible(mode, build, hostBranchElided = true) {
344
351
  }
345
352
 
346
353
  // src/functional/run.ts
354
+ var SELECT_EXAMPLE = "run(entry, input, { rootTrivia: { select: ['blockComment', 'lineComment'] } })";
355
+ var REMOVED_RUN_RESULT_FIELDS = [
356
+ [
357
+ "triviaMap",
358
+ `It was a dense root-trivia index built on every parse; root trivia is now an OPT-IN sparse capture, because most grammars paid for an index they never read. Migration: name the trivia labels your grammar defines \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia\`, whose \`.index\` carries the labels and gap lookups \`triviaMap\` exposed.`
359
+ ],
360
+ [
361
+ "triviaLog",
362
+ `It was the flat \`start, end[, kindIndex]\` log every other trivia view was derived from, and it is no longer allocated at all \u2014 not empty, absent. Migration: request the labels you need \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia.rows\`. Do NOT reuse a stride-2/3 reader: rows are a different width and a different unit (one row per SELECTED marker, not one per trivia chunk), so an old loop reads confidently wrong offsets rather than failing.`
363
+ ],
364
+ [
365
+ "triviaKindLabels",
366
+ `It was already optional, so nothing ever flagged its disappearance \u2014 and \`triviaKindMask(undefined, \u2026)\` means "capture everything", so reading it now silently WIDENS capture instead of erroring. Migration: request labels \u2014 ${SELECT_EXAMPLE} \u2014 then the set you asked for is \`RunResult.rootTrivia.select\` and the resolved table is \`RunResult.rootTrivia.index.labels\`.`
367
+ ]
368
+ ];
369
+ function guardRemovedFields(result) {
370
+ for (const [name, detail] of REMOVED_RUN_RESULT_FIELDS) {
371
+ Object.defineProperty(result, name, {
372
+ configurable: true,
373
+ enumerable: false,
374
+ get() {
375
+ throw new TypeError(
376
+ `RunResult.${name} was REMOVED in parseman 0.44.0 and has no default replacement. ${detail}`
377
+ );
378
+ }
379
+ });
380
+ }
381
+ return result;
382
+ }
347
383
  var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
348
384
  function triviaKindLabelsFromRunnable(r) {
349
385
  if (!r) return void 0;
350
386
  if (typeof r === "function") return r._meta?.triviaKindLabels;
351
387
  const grammarTrivia = r._meta.grammarTrivia;
352
- return r._meta.triviaKindLabels ?? grammarTrivia?._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
388
+ return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
389
+ }
390
+ function rootTriviaClassifiedFromRunnable(r) {
391
+ if (!r) return false;
392
+ if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
393
+ const grammarTrivia = r._meta.grammarTrivia;
394
+ return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
395
+ }
396
+ function makeSelectedRootLabelIndex(labels) {
397
+ const index = /* @__PURE__ */ Object.create(null);
398
+ for (let i = 0; i < labels.length; i++) {
399
+ if (index[labels[i]] === void 0) index[labels[i]] = i;
400
+ }
401
+ return index;
353
402
  }
354
403
  function runOnce(entry, input, options, phase, profileState) {
355
404
  if (typeof entry !== "function" && typeof entry?.parse !== "function") {
@@ -357,13 +406,31 @@ function runOnce(entry, input, options, phase, profileState) {
357
406
  `run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
358
407
  );
359
408
  }
360
- const triviaLog = [];
409
+ const rootTriviaSelection = options.rootTrivia?.select;
410
+ const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
411
+ const selectedRootLog = captureRootTrivia ? [] : void 0;
412
+ const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
361
413
  const errors = [];
362
414
  const profile = profileState ?? (phase === void 0 ? void 0 : { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 });
363
415
  const skipGlobalSinks = phase === "recognizer" || phase === "capture";
364
416
  const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
365
417
  const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
366
418
  const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
419
+ if (captureRootTrivia && triviaKindLabels === void 0) {
420
+ throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
421
+ }
422
+ if (captureRootTrivia) {
423
+ for (const label2 of rootTriviaSelection) {
424
+ if (!triviaKindLabels.includes(label2)) {
425
+ throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label2)}.`);
426
+ }
427
+ }
428
+ }
429
+ if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
430
+ throw new TypeError(
431
+ "run(): rootTrivia.select requires classifiedTrivia() at the root."
432
+ );
433
+ }
367
434
  const stamped = entry;
368
435
  assertHostModeCompatible(
369
436
  typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
@@ -372,7 +439,15 @@ function runOnce(entry, input, options, phase, profileState) {
372
439
  );
373
440
  const ctx = {
374
441
  trackLines: false,
375
- ...skipGlobalSinks ? { _pmProfile: profile } : { _triviaLog: triviaLog, _errors: errors, ...profile === void 0 ? {} : { _pmProfile: profile } },
442
+ ...skipGlobalSinks ? { _pmProfile: profile } : {
443
+ ...captureRootTrivia ? {
444
+ _rootTriviaLog: selectedRootLog,
445
+ _rootTriviaKindIndex: selectedRootLabelIndex,
446
+ _rootTriviaStrictScopes: true
447
+ } : {},
448
+ _errors: errors,
449
+ ...profile === void 0 ? {} : { _pmProfile: profile }
450
+ },
376
451
  build: options.build,
377
452
  state: options.state,
378
453
  ...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...triviaKindLabels ? { triviaKindLabels } : {} } : triviaKindLabels ? { triviaKindLabels } : {},
@@ -397,43 +472,21 @@ function runOnce(entry, input, options, phase, profileState) {
397
472
  span: r.span ?? { start: 0, end: 0 },
398
473
  expected: r.ok ? [] : r.expected ?? [],
399
474
  errors,
400
- triviaLog,
401
- ...triviaKindLabels === void 0 ? {} : { triviaKindLabels },
402
- triviaMap: buildRootTriviaIndex(triviaLog, triviaKindLabels),
475
+ ...selectedRootLog !== void 0 && selectedRootLog.length > 0 ? {
476
+ rootTrivia: {
477
+ rows: selectedRootLog,
478
+ select: rootTriviaSelection,
479
+ index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
480
+ }
481
+ } : {},
403
482
  unconsumedFrom
404
483
  };
405
484
  }
406
- function clonePassState(state) {
407
- if (state === null || typeof state !== "object") return state;
408
- return Array.isArray(state) ? [...state] : { ...state };
409
- }
410
- function profilePass(entry, input, options, phase) {
411
- const state = { phase, nodes: 0, childSlots: 0, rawSlots: 0, triviaSlots: 0, fieldSlots: 0, hostCalls: 0 };
412
- const passOptions = options.state === void 0 ? options : { ...options, state: clonePassState(options.state) };
413
- const start = performance.now();
414
- const result = runOnce(entry, input, passOptions, phase, state);
415
- const { phase: _phase, ...counts } = state;
416
- return { result, profile: { ms: performance.now() - start, ...counts } };
417
- }
418
485
  function run(entry, input, options = {}) {
419
- if (!options.profile) return runOnce(entry, input, options);
420
- if (typeof entry !== "function") {
421
- throw new TypeError("run({ profile: true }) requires a compiled parser entry");
422
- }
423
- const recognizer = profilePass(entry, input, options, "recognizer");
424
- const capture = profilePass(entry, input, options, "capture");
425
- const host = profilePass(entry, input, options, "host");
426
- if (recognizer.result.ok !== host.result.ok || capture.result.ok !== host.result.ok || recognizer.result.unconsumedFrom !== host.result.unconsumedFrom || capture.result.unconsumedFrom !== host.result.unconsumedFrom) {
427
- throw new Error("run({ profile: true }) changed recognition; the grammar is not profile-safe");
428
- }
429
- return {
430
- ...host.result,
431
- profile: {
432
- recognizer: recognizer.profile,
433
- structuralCapture: capture.profile,
434
- hostConstruction: host.profile
435
- }
436
- };
486
+ if (!options.profile) return guardRemovedFields(runOnce(entry, input, options));
487
+ throw new TypeError(
488
+ "run({ profile: true }) is unavailable: profiling counters are no longer compiled into parser artifacts, and the interpreter does not implement them yet. Profiling is moving to interpreted mode."
489
+ );
437
490
  }
438
491
 
439
492
  // src/combinators/completions.ts
@@ -458,6 +511,10 @@ var WORDS_RE = new RegExp(`^${WORD_RE_SRC}(?:\\|${WORD_RE_SRC})*$`);
458
511
 
459
512
  // src/compiler/scannable-run.ts
460
513
  var META = new Set("()[]{}*+?|^$.".split(""));
514
+ var SELECTED_ROOT_OWNED_RANGE_PLACEHOLDER = Array.from(
515
+ { length: SELECTED_ROOT_STRIDE - 3 },
516
+ () => "0"
517
+ ).join(", ");
461
518
 
462
519
  // src/compiler/trivia-fast-path.ts
463
520
  var CAP_RECORD = [
@@ -466,6 +523,18 @@ var CAP_RECORD = [
466
523
  ` if (_cap === 1 && _ctx._cstTriviaLog !== undefined && _ctx.captureTrivia) _ctx._cstTriviaLog.push(_pos, _e, _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0)`,
467
524
  ` }`
468
525
  ].join("\n");
526
+ var SELECTED_ROOT_FINISH = [
527
+ ` if (_cap && _ctx._rootTriviaCapture !== false && _ctx._rootTriviaLog !== undefined && _ctx._rootTriviaLog.length !== _rootMark) {`,
528
+ ` for (let _ri = _rootMark; _ri < _ctx._rootTriviaLog.length; _ri += ${SELECTED_ROOT_STRIDE}) { _ctx._rootTriviaLog[_ri] = _pos; _ctx._rootTriviaLog[_ri + 1] = _e }`,
529
+ ` }`
530
+ ].join("\n");
531
+
532
+ // src/compiler/inline-build.ts
533
+ var ANN = String.raw`\s*\??\s*(?::[^,)=]+)?`;
534
+ var ANY_P = String.raw`\w+${ANN}`;
535
+ var MK_BUILD_RE = new RegExp(
536
+ String.raw`^\(\s*(\w+)${ANN}\s*,\s*${ANY_P}\s*,\s*(\w+)${ANN}\s*,\s*(\w+)${ANN}\s*,\s*(\w+)${ANN}\s*\)\s*=>\s*mk\s*\(\s*(['"])([^'"]+)\5\s*,\s*\1\s*,\s*\3\s*,\s*\2\s*,\s*\4\s*\)\s*$`
537
+ );
469
538
 
470
539
  // src/compiler/linker.ts
471
540
  function normalizeCstCollapse(collapse) {