parseman 0.56.0 → 0.58.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 (106) hide show
  1. package/dist/analysis/diagnostics.js +2232 -1088
  2. package/dist/analysis/diagnostics.js.map +3 -3
  3. package/dist/cli/index.js +2247 -1103
  4. package/dist/cli/index.js.map +3 -3
  5. package/dist/combinators/dispatch.d.ts.map +1 -1
  6. package/dist/combinators/node.d.ts +1 -1
  7. package/dist/compiler/build-arity.d.ts +1 -1
  8. package/dist/compiler/build-arity.d.ts.map +1 -1
  9. package/dist/compiler/token-alphabet.d.ts +11 -1
  10. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  11. package/dist/compiler/token-capability.js +69 -16
  12. package/dist/compiler/token-capability.js.map +2 -2
  13. package/dist/cst/capture-buffer.d.ts +6 -0
  14. package/dist/cst/capture-buffer.d.ts.map +1 -1
  15. package/dist/cst/trivia-kinds.d.ts +9 -1
  16. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  17. package/dist/index.js +1446 -236
  18. package/dist/index.js.map +3 -3
  19. package/dist/language-service/index.js +1 -0
  20. package/dist/language-service/index.js.map +1 -1
  21. package/dist/parse-context.d.ts.map +1 -1
  22. package/dist/plugin/entry-supercompiler.d.ts +1 -1
  23. package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
  24. package/dist/plugin/index.d.ts +51 -1
  25. package/dist/plugin/index.d.ts.map +1 -1
  26. package/dist/plugin/index.js +2126 -380
  27. package/dist/plugin/index.js.map +3 -3
  28. package/dist/plugin/ir-eval.d.ts +2 -0
  29. package/dist/plugin/ir-eval.d.ts.map +1 -1
  30. package/dist/regex/classes.d.ts.map +1 -1
  31. package/dist/run/index.js +1 -0
  32. package/dist/run/index.js.map +1 -1
  33. package/dist/table/assemble.d.ts +9 -0
  34. package/dist/table/assemble.d.ts.map +1 -1
  35. package/dist/table/child-slots.d.ts +4 -6
  36. package/dist/table/child-slots.d.ts.map +1 -1
  37. package/dist/table/compile-rule-map.d.ts +14 -2
  38. package/dist/table/compile-rule-map.d.ts.map +1 -1
  39. package/dist/table/emit-assembly.d.ts +17 -2
  40. package/dist/table/emit-assembly.d.ts.map +1 -1
  41. package/dist/table/emit.d.ts +5 -1
  42. package/dist/table/emit.d.ts.map +1 -1
  43. package/dist/table/encode.d.ts.map +1 -1
  44. package/dist/table/exec-baseline.d.ts.map +1 -1
  45. package/dist/table/exec.d.ts.map +1 -1
  46. package/dist/table/factor-choice.d.ts +42 -0
  47. package/dist/table/factor-choice.d.ts.map +1 -0
  48. package/dist/table/fail-clean.d.ts +3 -0
  49. package/dist/table/fail-clean.d.ts.map +1 -0
  50. package/dist/table/hold-gap.d.ts +8 -0
  51. package/dist/table/hold-gap.d.ts.map +1 -0
  52. package/dist/table/index.js +1798 -316
  53. package/dist/table/index.js.map +3 -3
  54. package/dist/table/lex-program.d.ts +7 -3
  55. package/dist/table/lex-program.d.ts.map +1 -1
  56. package/dist/table/ops.d.ts +17 -6
  57. package/dist/table/ops.d.ts.map +1 -1
  58. package/dist/table/program.d.ts +13 -0
  59. package/dist/table/program.d.ts.map +1 -1
  60. package/dist/table/run-support.d.ts +19 -0
  61. package/dist/table/run-support.d.ts.map +1 -1
  62. package/dist/table/scalar-terminal.d.ts +2 -0
  63. package/dist/table/scalar-terminal.d.ts.map +1 -1
  64. package/dist/table/select-hot.d.ts +6 -0
  65. package/dist/table/select-hot.d.ts.map +1 -0
  66. package/dist/table/site-labels.d.ts +66 -0
  67. package/dist/table/site-labels.d.ts.map +1 -1
  68. package/dist/table/trivia-gap.d.ts +31 -0
  69. package/dist/table/trivia-gap.d.ts.map +1 -0
  70. package/dist/types.d.ts +17 -0
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/version.d.ts +1 -1
  73. package/package.json +4 -1
  74. package/src/combinators/dispatch.ts +12 -3
  75. package/src/combinators/node.ts +6 -13
  76. package/src/combinators/trivia-skip.ts +44 -1
  77. package/src/compiler/build-arity.ts +3 -3
  78. package/src/compiler/token-alphabet.ts +57 -17
  79. package/src/cst/capture-buffer.ts +25 -0
  80. package/src/cst/trivia-kinds.ts +12 -1
  81. package/src/parse-context.ts +1 -0
  82. package/src/plugin/entry-supercompiler.ts +8 -9
  83. package/src/plugin/index.ts +362 -42
  84. package/src/plugin/ir-eval.ts +7 -1
  85. package/src/regex/classes.ts +3 -0
  86. package/src/table/assemble.ts +371 -83
  87. package/src/table/child-slots.ts +6 -8
  88. package/src/table/compile-rule-map.ts +64 -15
  89. package/src/table/emit-assembly.ts +244 -42
  90. package/src/table/emit.ts +11 -8
  91. package/src/table/encode.ts +149 -35
  92. package/src/table/exec-baseline.ts +1 -3
  93. package/src/table/exec.ts +34 -14
  94. package/src/table/factor-choice.ts +173 -0
  95. package/src/table/fail-clean.ts +130 -0
  96. package/src/table/hold-gap.ts +68 -0
  97. package/src/table/lex-program.ts +197 -43
  98. package/src/table/ops.ts +18 -7
  99. package/src/table/program.ts +24 -0
  100. package/src/table/run-support.ts +35 -0
  101. package/src/table/scalar-terminal.ts +8 -0
  102. package/src/table/select-hot.ts +70 -0
  103. package/src/table/site-labels.ts +135 -4
  104. package/src/table/trivia-gap.ts +109 -0
  105. package/src/types.ts +18 -0
  106. package/src/version.ts +1 -1
@@ -1,5 +1,5 @@
1
1
  import {
2
- OP_ADJ, OP_ARMGATE, OP_ATTEMPT, OP_CHOICE, OP_COV, OP_DISPATCH, OP_EMPTY, OP_EXPECT,
2
+ OP_ADJ, OP_ARMGATE, OP_RGATE, OP_ATTEMPT, OP_CHOICE, OP_COV, OP_DISPATCH, OP_EMPTY, OP_EXPECT,
3
3
  OP_FIELD, OP_GATE, OP_GREEDY, OP_GUARD, OP_LABEL, OP_LEAF, OP_SOURCE_LEAF, OP_LIT, OP_LIT_CI,
4
4
  OP_LIT_CI_TRACK, OP_LIT_TRACK, OP_LIVE, OP_NODE, OP_NODE_TRACK, OP_NOT, OP_OPT,
5
5
  OP_PEEK, OP_REJECT, OP_REP, OP_REPV, OP_ROUTED, OP_RULE, OP_RX, OP_RX_TRACK, OP_SCAN,
@@ -19,12 +19,10 @@ import {
19
19
  * only against it happening WITHIN that file.
20
20
  *
21
21
  * The subset was never load-bearing. The five opcodes it omitted — COV, GREEDY,
22
- * REJECT, ARMGATE, WITHCTX — are exactly the five `emit-assembly.ts` has no case
23
- * for, so any program containing one throws `Unemittable` from the default arm and
24
- * the whole assembly falls back to closures. Walking into their subtrees can
25
- * therefore only affect a result that is about to be discarded. (Verified: none of
26
- * the five is so much as imported by `emit-assembly.ts`. Its one consumer of these
27
- * edges, the `fd`/`er` sink census, is computed before the lowering that throws.)
22
+ * REJECT, ARMGATE, WITHCTX — were exactly the five `emit-assembly.ts` had no case
23
+ * for. ARMGATE and WITHCTX are lowered there now, so their subtrees are walked like
24
+ * any other; COV, GREEDY and REJECT still throw `Unemittable` from the default arm,
25
+ * and the whole assembly falls back to closures.
28
26
  *
29
27
  * `code` is `ArrayLike<number>` because the two callers hold different
30
28
  * representations of the same stream — `TableProgram.code` is a `readonly number[]`,
@@ -55,7 +53,7 @@ export function childSlots(code: ArrayLike<number>, ip: number, out: number[]):
55
53
 
56
54
  // Single child at `ip + 2`.
57
55
  case OP_GATE: case OP_SCOPE: case OP_SCOPE_CAP: case OP_SCOPE_PLAIN: case OP_WITHCTX: case OP_XFORM:
58
- case OP_NODE: case OP_NODE_TRACK: case OP_FIELD: case OP_LEAF: case OP_SOURCE_LEAF: case OP_ARMGATE:
56
+ case OP_NODE: case OP_NODE_TRACK: case OP_FIELD: case OP_LEAF: case OP_SOURCE_LEAF: case OP_ARMGATE: case OP_RGATE:
59
57
  out.push(code[ip + 2]!)
60
58
  return true
61
59
 
@@ -4,20 +4,17 @@ import type { HostMode } from '../cst/host-mode.ts'
4
4
  import { collectGrammarReflection, GRAMMAR_REFLECTION, type GrammarReflection } from '../cst/reflection.ts'
5
5
  import { encodeTableProgram, type TableSettings } from './encode.ts'
6
6
  import { defaultAssemblyCfgs, emitTableExpression } from './emit.ts'
7
+ import { emitAssemblySource, Unemittable } from './emit-assembly.ts'
8
+ import { selectHotSites } from './select-hot.ts'
9
+
10
+ /** The most the entry supercompiler may grow an assembly (`entry-supercompiler.ts`, its 5% source cap). */
11
+ const SUPERCOMPILE_GROWTH = 1.05
7
12
  import { tableRules } from './assemble.ts'
8
- import { closureArtifact } from './program.ts'
13
+ import { assemblyExtraIps, closureArtifact, resolveTable } from './program.ts'
9
14
  import type { TableProgram, TableRule } from './program.ts'
10
15
  import { buildGrammarPlan, type GrammarCoverageDefinition } from '../compiler/grammar-coverage-ids.ts'
11
16
  import { runDuplicationDiagnosticRules, type DuplicationOption } from './duplication-hook.ts'
12
17
 
13
- /**
14
- * Static assembly has a fixed source cost that tiny grammars cannot amortize.
15
- * The canonical size probe's composeLeaf is 62 words and grows by ~12 kB with
16
- * a factory; the shipping Jess leaves are 6,365/10,892 words. Keep the policy
17
- * between those measured populations so small artifacts retain table density.
18
- */
19
- const DEFAULT_PRECOMPILE_MIN_WORDS = 1_024
20
-
21
18
  /**
22
19
  * `compileRuleMap()` FOR THE TABLE LOWERING — the counterpart that did not exist.
23
20
  *
@@ -116,8 +113,16 @@ export type CompiledRuleMapTable = {
116
113
  /** Re-emit the same table call with construction-time artifact metadata. */
117
114
  replacementWithMetadata(
118
115
  metadataSource: string,
119
- options?: { readonly precompileDefault?: boolean },
116
+ options?: { readonly select?: ReadonlySet<number> },
120
117
  ): string
118
+ /**
119
+ * The sites a SELECTIVE default assembly emits within `budget` bytes — its
120
+ * fixed prelude plus the site bodies `select-hot.ts` ranks highest — and the
121
+ * bytes that spends. Empty for a CST or line-tracking table (only the default
122
+ * AST/no-lines option set is pre-compiled), for a budget smaller than the
123
+ * prelude, and for a table the emitter refuses, which names the construct.
124
+ */
125
+ selectAssembly(budget: number, profile?: ArrayLike<number>): { readonly sites: ReadonlySet<number>; readonly bytes: number; readonly refusal?: string }
121
126
  hostMode: HostMode
122
127
  hostBranchElided: boolean
123
128
  reflection: GrammarReflection
@@ -234,7 +239,7 @@ function withAmbient(
234
239
  export function compileRuleMapRunnable(
235
240
  ruleMap: ReadonlyArray<readonly [string, Combinator<unknown>]>,
236
241
  opts: TableRuleMapOptions = {},
237
- ): Omit<CompiledRuleMapTable, 'replacement' | 'replacementWithMetadata'> | null {
242
+ ): Omit<CompiledRuleMapTable, 'replacement' | 'replacementWithMetadata' | 'selectAssembly'> | null {
238
243
  const encoded = encodeForRun(ruleMap, opts)
239
244
  if (encoded === null) return null
240
245
  const { prog, hostMode, plan } = encoded
@@ -331,23 +336,67 @@ export function compileRuleMap(
331
336
 
332
337
  const replacementWithMetadata = (
333
338
  metadataSource?: string,
334
- options: { readonly precompileDefault?: boolean } = {},
339
+ options: { readonly select?: ReadonlySet<number> } = {},
335
340
  ): string => emitTableExpression(artifact, {
336
341
  entry: null,
337
342
  runtimeRef: opts.runtimeRef ?? 'tableRules',
338
343
  fnSources: sources as string[],
339
- ...(options.precompileDefault === true && hostMode === 'ast' && prog.lines !== 1
340
- && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS
341
- ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) }
344
+ ...(options.select !== undefined && options.select.size > 0
345
+ ? { assemblies: [{ ...defaultAssemblyCfgs(artifact)[0]!, select: options.select }] }
342
346
  : {}),
343
347
  ...(metadataSource === undefined ? {} : { metadataSource }),
344
348
  })
345
349
  const replacement = replacementWithMetadata()
350
+ const selectAssembly = (budget: number, profile?: ArrayLike<number>): { sites: ReadonlySet<number>; bytes: number; refusal?: string } => {
351
+ const none = { sites: new Set<number>(), bytes: 0 }
352
+ if (hostMode !== 'ast' || prog.lines === 1) return none
353
+ const table = resolveTable(artifact)
354
+ const cfg = defaultAssemblyCfgs(artifact)[0]!
355
+ const roots = assemblyExtraIps(artifact)
356
+ let siteBytes, fixed
357
+ try {
358
+ siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes
359
+ // What any selective assembly costs before its first site body: the shared
360
+ // prelude and the factory's tail. A budget that cannot cover it buys nothing.
361
+ fixed = emitAssemblySource(table, artifact, cfg, roots, true, new Set()).source.length
362
+ } catch (e) {
363
+ if (e instanceof Unemittable) return { ...none, refusal: e.construct }
364
+ throw e
365
+ }
366
+ // The estimate (prelude plus site bodies) leaves out what selected sites add
367
+ // around their bodies — shared helpers and the `_px` wrappers of the closure
368
+ // sites they call — and the supercompiler may grow the source by up to 5%. So
369
+ // the selection is judged by the source it actually emits, scaled for that 5%,
370
+ // and narrowed until that fits.
371
+ const ceiling = budget / SUPERCOMPILE_GROWTH
372
+ // A budget that cannot cover the prelude buys nothing, by design: no refusal.
373
+ if (ceiling <= fixed) return none
374
+ // Narrowed until it fits, with no attempt limit: the target shrinks by at
375
+ // least 1% a round, so the selection either fits or empties. An empty one
376
+ // says why — a build that asked for an assembly and silently shipped none is
377
+ // a regression no test sees (the artifact still parses, on the closures).
378
+ let target = ceiling
379
+ for (;;) {
380
+ const sites = selectHotSites(artifact.code, Object.values(artifact.rules), siteBytes, target - fixed, profile)
381
+ if (sites.size === 0) {
382
+ return {
383
+ ...none,
384
+ refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`,
385
+ }
386
+ }
387
+ const bytes = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length
388
+ if (bytes <= ceiling) return { sites, bytes: Math.ceil(bytes * SUPERCOMPILE_GROWTH) }
389
+ // Scale by the overshoot, and by at least 1%: near the ceiling a site is
390
+ // the unit, and the ratio alone can stall a few bytes over it.
391
+ target *= Math.min(ceiling / bytes, 0.99)
392
+ }
393
+ }
346
394
 
347
395
  return {
348
396
  keys: ruleMap.map(([key]) => key),
349
397
  replacement,
350
398
  replacementWithMetadata,
399
+ selectAssembly,
351
400
  hostMode,
352
401
  // WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
353
402
  // dropped", which is what the driver's `'ast' artifact + CST host` check keys