parseman 0.60.0 → 0.60.1
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.
- package/dist/analysis/diagnostics.js +3 -3
- package/dist/analysis/diagnostics.js.map +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +3 -3
- package/dist/plugin/index.js.map +1 -1
- package/dist/table/assemble.d.ts +1 -1
- package/dist/table/compile-rule-map.d.ts +1 -1
- package/dist/table/compile.d.ts +1 -1
- package/dist/table/exec.d.ts +0 -35
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +3 -3
- package/dist/table/index.js.map +1 -1
- package/dist/table/ops.d.ts +1 -10
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -4
- package/src/table/assemble.ts +5 -5
- package/src/table/compile-rule-map.ts +1 -1
- package/src/table/compile.ts +1 -1
- package/src/table/emit-assembly.ts +2 -2
- package/src/table/encode.ts +1 -1
- package/src/table/exec.ts +0 -69
- package/src/table/ops.ts +1 -10
- package/src/version.ts +1 -1
- package/dist/table/encode-baseline.d.ts +0 -16
- package/dist/table/encode-baseline.d.ts.map +0 -1
- package/dist/table/exec-baseline.d.ts +0 -9
- package/dist/table/exec-baseline.d.ts.map +0 -1
- package/src/table/encode-baseline.ts +0 -346
- package/src/table/exec-baseline.ts +0 -557
package/dist/table/ops.d.ts
CHANGED
|
@@ -73,13 +73,7 @@ export declare const OP_XFORM = 9;
|
|
|
73
73
|
* from the reducer's declared arity by the same analysis codegen runs, and
|
|
74
74
|
* forced on under `hostMode: 'cst'`. The driver reads the bits and re-derives
|
|
75
75
|
* nothing.
|
|
76
|
-
|
|
77
|
-
* TWO ENCODERS SHARE THIS OPCODE and they do NOT agree on its length. The layout
|
|
78
|
-
* above is `encode.ts` / `exec.ts`. `encode-baseline.ts` / `exec-baseline.ts` emit
|
|
79
|
-
* the FOUR-word form `NODE b c flags` with bits 2 and 3 only, and refuse
|
|
80
|
-
* `collapse` / `unwrap` / `project` outright. Neither driver walks the stream by
|
|
81
|
-
* instruction length, so the divergence is contained — but read the pair you are
|
|
82
|
-
* in, not this comment alone. */
|
|
76
|
+
*/
|
|
83
77
|
export declare const OP_NODE = 10;
|
|
84
78
|
/** `RULE r` — `r` indexes `prog.rules`. */
|
|
85
79
|
export declare const OP_RULE = 11;
|
|
@@ -92,9 +86,6 @@ export declare const OP_NOT = 13;
|
|
|
92
86
|
* `['peek(<child tag>)']`, because `peek.ts:60` DISCARDS the body's expectation:
|
|
93
87
|
* a lookahead's failure is "the guard did not hold", not a request for whatever
|
|
94
88
|
* token the body happened to stop on.
|
|
95
|
-
*
|
|
96
|
-
* `encode-baseline.ts` / `exec-baseline.ts` emit and read the two-word form and
|
|
97
|
-
* are internally consistent; read the pair you are in.
|
|
98
89
|
*/
|
|
99
90
|
export declare const OP_PEEK = 14;
|
|
100
91
|
/** `LEAF f c` — `leaf()`: reduce, then record as a spanned leaf. */
|
package/dist/table/ops.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/table/ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,kFAAkF;AAClF,eAAO,MAAM,KAAK,IAAI,CAAA;AACtB,6EAA6E;AAC7E,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,iFAAiF;AACjF,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,IAAI,CAAA;AAC1B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,2CAA2C;AAC3C,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB;;;;kDAIkD;AAClD,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,qEAAqE;AACrE,eAAO,MAAM,QAAQ,IAAI,CAAA;AACzB
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/table/ops.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
|
|
14
14
|
* the build if this constant drifts from the published version.
|
|
15
15
|
*/
|
|
16
|
-
export declare const PARSEMAN_VERSION = "0.60.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.60.1";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "parseman",
|
|
3
|
-
"version": "0.60.
|
|
3
|
+
"version": "0.60.1",
|
|
4
4
|
"packageManager": "pnpm@10.15.1",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": "^20.19.0 || >=22.13.0"
|
|
@@ -84,13 +84,10 @@
|
|
|
84
84
|
"bench": "node --import tsx/esm bench/run.ts",
|
|
85
85
|
"bench:parseman": "node --import tsx/esm bench/parseman.ts",
|
|
86
86
|
"bench:closure-json": "node --import tsx/esm bench/closure-json-path.ts",
|
|
87
|
-
"bench:composeleaf": "node --import tsx/esm bench/composeleaf-firstset.ts",
|
|
88
87
|
"bench:incremental": "node --import tsx/esm bench/incremental-run.ts",
|
|
89
88
|
"bench:literal": "node --import tsx/esm bench/literal-match.ts",
|
|
90
89
|
"bench:dispatch": "node --import tsx/esm bench/dispatch-vs-choice.ts",
|
|
91
|
-
"bench:codegen": "node --import tsx/esm bench/codegen-ab.ts",
|
|
92
90
|
"bench:treeidentity": "node --import tsx/esm bench/tree-identity.ts",
|
|
93
|
-
"bench:sharedprefix": "node --import tsx/esm bench/shared-prefix-ab.ts",
|
|
94
91
|
"bench:baseline": "node --import tsx/esm bench/update-parseman-baseline.ts",
|
|
95
92
|
"perf:guard": "node --import tsx/esm bench/perf-guard.ts",
|
|
96
93
|
"perf:guard:grammars": "node --import tsx/esm bench/grammar-perf-guard.ts",
|
|
@@ -109,6 +106,7 @@
|
|
|
109
106
|
"bench:release-compare-svg": "node --import tsx/esm bench/gen-release-compare-svg.ts",
|
|
110
107
|
"bench:size": "node --import tsx/esm bench/measure-expansion.ts",
|
|
111
108
|
"docs:favicons": "node scripts/gen-favicons.mjs",
|
|
109
|
+
"docs:railroad": "node --import tsx/esm scripts/gen-railroad-svg.ts",
|
|
112
110
|
"build:chevrotain-bench": "node --import tsx/esm scripts/build-chevrotain-bench.mjs",
|
|
113
111
|
"bench:compile-grammars": "peggy --format es -o bench/json-parser.js bench/json.pegjs && peggy --format es -o bench/csv-parser.js bench/csv.pegjs && peggy --format es -o bench/graphql-parser.js bench/graphql.pegjs && nearleyc bench/vendor/nearley/json.ne -o bench/json-nearley.cjs && nearleyc bench/vendor/nearley/csv.ne -o bench/csv-nearley.cjs && nearleyc bench/vendor/nearley/graphql.ne -o bench/graphql-nearley.cjs && node bench/compile-jison.mjs",
|
|
114
112
|
"perf:workloads": "node --import tsx/esm bench/workload-perf-guard.ts",
|
package/src/table/assemble.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* making the swaps on rules / sub-rules (leaves) at that point, then run with NO
|
|
6
6
|
* logic branching for that option input"*. `exec.ts` builds the same table and
|
|
7
7
|
* then interprets it: one `switch (code[ip])` over every opcode (29 then), executed ONCE PER
|
|
8
|
-
* ROW — 497,360 rows for `benchmark.less` (`
|
|
8
|
+
* ROW — 497,360 rows for `benchmark.less` (measured with a one-off `g5-rows` bench, last at `4a5d0341`) — each
|
|
9
9
|
* re-reading its opcode and re-decoding its operands from the `Int32Array`, and
|
|
10
10
|
* re-testing the same per-parse options. That is the per-node branching the
|
|
11
11
|
* design exists to remove.
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
*
|
|
21
21
|
* The numbers that make this obviously the right trade, measured not assumed:
|
|
22
22
|
*
|
|
23
|
-
* 2,241 distinct reachable sites in the less table (`
|
|
23
|
+
* 2,241 distinct reachable sites in the less table (`g5-sites`)
|
|
24
24
|
* 497,360 rows executed for one parse of `benchmark.less`
|
|
25
25
|
*
|
|
26
26
|
* Pieces are GRAMMAR-sized; rows are INPUT-sized. Assembly allocates ~2.2k
|
|
27
27
|
* closures once per process and removes a dispatch plus an operand decode from
|
|
28
28
|
* ~497k executions — a 222x ratio. Assembly cost is paid once and is not the
|
|
29
|
-
* metric; it is measured anyway (`
|
|
29
|
+
* metric; it is measured anyway (`g5-ms`, `g5-profile`).
|
|
30
30
|
*
|
|
31
31
|
* ## Why this is not "just tuning the switch"
|
|
32
32
|
*
|
|
@@ -4298,7 +4298,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
4298
4298
|
// Two engines that can only be compared across two checkouts cannot be
|
|
4299
4299
|
// compared at all: the bench harness's own guidance is that a
|
|
4300
4300
|
// cross-worktree measurement carries a bias no repetition removes. Same
|
|
4301
|
-
// spelling as `PM_TABLE_COUNT`
|
|
4301
|
+
// spelling as the removed `PM_TABLE_COUNT` counters.
|
|
4302
4302
|
if (!EMIT_ENABLED) throw new Unemittable('PM_TABLE_EMIT=0 (measurement toggle)')
|
|
4303
4303
|
const em = emitAssemblySource(t, prog, cfg, extraIps)
|
|
4304
4304
|
/**
|
|
@@ -4569,7 +4569,7 @@ export class AssemblyCache {
|
|
|
4569
4569
|
* That is not a hole in G5, it is G5's own first clause: "quickly building the
|
|
4570
4570
|
* grammar reference ON RUN START, making some swaps on rules or sub-rules, and
|
|
4571
4571
|
* then the run actually runs with no logic branching for that option input"
|
|
4572
|
-
* (`notes/TABLE-DRIVER.md`). This IS the run-start step. What the criterion
|
|
4572
|
+
* (`notes/history/TABLE-DRIVER.md`). This IS the run-start step. What the criterion
|
|
4573
4573
|
* forbids is the second sentence, and past this call there is no option read
|
|
4574
4574
|
* anywhere — `scripts/check-invariants.mjs` INV-6 decides that mechanically.
|
|
4575
4575
|
*
|
|
@@ -68,7 +68,7 @@ export type TableRuleMapOptions = {
|
|
|
68
68
|
* `coverage: grammarCoverage` here for every `rules()` grammar — so this is what
|
|
69
69
|
* makes `{ grammarCoverage: true }` a working build under the table lowering.
|
|
70
70
|
*
|
|
71
|
-
* COUNTERS ONLY, per the owner ruling recorded in `notes/RELEASE-0.48-TARGET.md`
|
|
71
|
+
* COUNTERS ONLY, per the owner ruling recorded in `notes/history/RELEASE-0.48-TARGET.md`
|
|
72
72
|
* §1; `_grammarTrace` parity is 0.48 work. The plugin's coverage path needs the
|
|
73
73
|
* DEFINITIONS STAMP and the HITS, and both are here.
|
|
74
74
|
*/
|
package/src/table/compile.ts
CHANGED
|
@@ -90,7 +90,7 @@ export type TableCompileOptions = {
|
|
|
90
90
|
*
|
|
91
91
|
* COUNTERS ONLY — owner ruling. `_grammarTrace`'s six phases are emitted at
|
|
92
92
|
* ~40 fine-grained sites by codegen and are deferred to 0.48
|
|
93
|
-
* (`notes/RELEASE-0.48-TARGET.md` §1). A table entry rejects a context carrying
|
|
93
|
+
* (`notes/history/RELEASE-0.48-TARGET.md` §1). A table entry rejects a context carrying
|
|
94
94
|
* a trace sink before parsing: silently returning an empty trace would look
|
|
95
95
|
* exactly like a real trace whose grammar sites were never visited. The
|
|
96
96
|
* plugin's coverage path reads `_grammarCoverage` and the definitions stamp,
|
|
@@ -1400,8 +1400,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)\n` : ''}return FAIL
|
|
|
1400
1400
|
}
|
|
1401
1401
|
|
|
1402
1402
|
case OP_EMPTY:
|
|
1403
|
-
// `''`, not `null` — the zero-width match's value. The other
|
|
1404
|
-
// (exec.ts,
|
|
1403
|
+
// `''`, not `null` — the zero-width match's value. The other engines
|
|
1404
|
+
// (exec.ts, assemble.ts) both return `''`; this one returned
|
|
1405
1405
|
// `null`, so the SAME program yielded a different `value` depending only on
|
|
1406
1406
|
// which engine ran. Unreached from the combinator API today — `OP_EMPTY` is
|
|
1407
1407
|
// emitted only as `finish()` padding for an EMPTY rule map, which then has no
|
package/src/table/encode.ts
CHANGED
|
@@ -783,7 +783,7 @@ class Encoder {
|
|
|
783
783
|
* simply parses it with the gate switched off at every choice arm that reaches
|
|
784
784
|
* a hole.
|
|
785
785
|
*
|
|
786
|
-
* Measured on jess's less grammar (`
|
|
786
|
+
* Measured on jess's less grammar (with the one-off `macro-program-diff` bench, last at `4a5d0341`): 195 of
|
|
787
787
|
* 562 reachable choice arms carried NO first set in the shipped artifact
|
|
788
788
|
* against 103 of 540 in the runtime encode, and 10 dispatch sites lost the O(1)
|
|
789
789
|
* `exclusive` piece (`assemble.ts:1758`) for the candidate-mask loop. With this
|
package/src/table/exec.ts
CHANGED
|
@@ -75,60 +75,6 @@ import { FAIL, newEndCell, type EndCell } from './cell.ts'
|
|
|
75
75
|
import { fieldSpec, leadingTriviaFieldAt } from './field-spec.ts'
|
|
76
76
|
import { FIELD_LEADING_TRIVIA, FIELD_TRAILING_TRIVIA, LEAD, triviaFieldCapture } from '../combinators/field-trivia.ts'
|
|
77
77
|
|
|
78
|
-
/**
|
|
79
|
-
* DIAGNOSTIC ROW COUNTER — off unless `PM_TABLE_COUNT=1` at process start.
|
|
80
|
-
*
|
|
81
|
-
* Read ONCE, at module load, into a module const, so this is not the per-parse
|
|
82
|
-
* option branch G5 forbids: with the variable false the whole thing folds away
|
|
83
|
-
* after tier-up. It exists because "too many rows" and "each row too slow" are
|
|
84
|
-
* different defects with the same symptom, and only a count separates them.
|
|
85
|
-
* No timing run in this repo may set it — see `bench/jess/table-rows.ts`.
|
|
86
|
-
*/
|
|
87
|
-
export const tableCounters: {
|
|
88
|
-
rows: number
|
|
89
|
-
byOp: Int32Array
|
|
90
|
-
/** Distinct reducer/host functions actually reaching each shared call site. */
|
|
91
|
-
sites: Map<string, Set<unknown>>
|
|
92
|
-
/**
|
|
93
|
-
* SPECULATION AT UNGATED CHOICES. `encode.ts:368-376` gives a choice its
|
|
94
|
-
* first-char dispatch only when NO arm is nullable, ALL arms are pairwise
|
|
95
|
-
* disjoint and ALL map to a char class; any one failure ungates every arm of
|
|
96
|
-
* the site, which then runs the linear loop below. Codegen has no such
|
|
97
|
-
* all-or-nothing rule — `emitFirstMatch` guards each arm on its OWN first set
|
|
98
|
-
* — so these counts are work the table does and the compiled engine does not.
|
|
99
|
-
*
|
|
100
|
-
* `ungatedEntries` is arms entered there; `ungatedFails` is those that then
|
|
101
|
-
* failed, which is pure waste by construction: a failing arm consumed nothing
|
|
102
|
-
* the winning arm will not scan again.
|
|
103
|
-
*/
|
|
104
|
-
ungatedEntries: number
|
|
105
|
-
ungatedFails: number
|
|
106
|
-
/** Rows executed INSIDE failed ungated arms — the subtree each wasted entry drags. */
|
|
107
|
-
ungatedFailRows: number
|
|
108
|
-
gatedEntries: number
|
|
109
|
-
/** Arm entries DECLINED by the per-arm class gate — the work this change removes. */
|
|
110
|
-
armGateSkips: number
|
|
111
|
-
} = { rows: 0, byOp: new Int32Array(64), sites: new Map(), ungatedEntries: 0, ungatedFails: 0, ungatedFailRows: 0, gatedEntries: 0, armGateSkips: 0 }
|
|
112
|
-
|
|
113
|
-
const COUNT = process.env.PM_TABLE_COUNT === '1'
|
|
114
|
-
|
|
115
|
-
function siteFn(site: string, fn: unknown): void {
|
|
116
|
-
let s = tableCounters.sites.get(site)
|
|
117
|
-
if (s === undefined) { s = new Set(); tableCounters.sites.set(site, s) }
|
|
118
|
-
s.add(fn)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function resetTableCounters(): void {
|
|
122
|
-
tableCounters.rows = 0
|
|
123
|
-
tableCounters.byOp = new Int32Array(64)
|
|
124
|
-
tableCounters.sites = new Map()
|
|
125
|
-
tableCounters.ungatedEntries = 0
|
|
126
|
-
tableCounters.ungatedFails = 0
|
|
127
|
-
tableCounters.ungatedFailRows = 0
|
|
128
|
-
tableCounters.gatedEntries = 0
|
|
129
|
-
tableCounters.armGateSkips = 0
|
|
130
|
-
}
|
|
131
|
-
|
|
132
78
|
const EMPTY_TL: readonly number[] = Object.freeze([])
|
|
133
79
|
const EMPTY_FX: string[] = []
|
|
134
80
|
const ROUTED_FX: string[] = ['routed()']
|
|
@@ -380,7 +326,6 @@ function makeDriver(
|
|
|
380
326
|
// recursing, so the reference driver's stack grows with the grammar's
|
|
381
327
|
// nesting, not with its gate rows.
|
|
382
328
|
rows: for (;;) {
|
|
383
|
-
if (COUNT) { tableCounters.rows++; tableCounters.byOp[code[ip]!]!++ }
|
|
384
329
|
switch (code[ip]) {
|
|
385
330
|
case OP_LIT: {
|
|
386
331
|
const s = k[code[ip + 1]!] as string
|
|
@@ -891,7 +836,6 @@ function makeDriver(
|
|
|
891
836
|
// Running it through `exec` at the POST-scan position would find the gap
|
|
892
837
|
// already consumed and answer "adjacent" unconditionally.
|
|
893
838
|
if (code[child] === OP_ADJ) {
|
|
894
|
-
if (COUNT) { tableCounters.rows++; tableCounters.byOp[OP_ADJ]!++ }
|
|
895
839
|
const ki = code[child + 2]!
|
|
896
840
|
if (!adjacencyHolds(input, cur, ctx, code[child + 1] === 1, ki < 0 ? undefined : k[ki] as readonly string[])) {
|
|
897
841
|
ctx._fe = cur; ctx._fx = fx[code[child + 3]!] as string[]
|
|
@@ -927,10 +871,6 @@ function makeDriver(
|
|
|
927
871
|
// LIT/RX in place removes both. The duplication is in the DRIVER,
|
|
928
872
|
// which ships once for every grammar — the cost this design trades on.
|
|
929
873
|
const cop = code[child]
|
|
930
|
-
// The two inline terminals below execute a ROW without going through
|
|
931
|
-
// `exec`, so the counter has to see them or the row count understates
|
|
932
|
-
// exactly where the driver already won.
|
|
933
|
-
if (COUNT && (cop === OP_LIT || cop === OP_RX)) { tableCounters.rows++; tableCounters.byOp[cop]!++ }
|
|
934
874
|
if (cop === OP_LIT) {
|
|
935
875
|
const lit = k[code[child + 1]!] as string
|
|
936
876
|
if (!input.startsWith(lit, cur)) {
|
|
@@ -971,7 +911,6 @@ function makeDriver(
|
|
|
971
911
|
const reducer = code[ip + 1]!
|
|
972
912
|
if (reducer < 0) return values![~reducer]
|
|
973
913
|
const fn = fns[reducer] as (value: unknown, span: { start: number; end: number }) => unknown
|
|
974
|
-
if (COUNT) siteFn('SEQX fn()', fn)
|
|
975
914
|
return fn(values, { start: pos, end: cur })
|
|
976
915
|
}
|
|
977
916
|
return values
|
|
@@ -1003,7 +942,6 @@ function makeDriver(
|
|
|
1003
942
|
}
|
|
1004
943
|
if (arm >= 0) {
|
|
1005
944
|
ctx._fc = false
|
|
1006
|
-
if (COUNT) tableCounters.gatedEntries++
|
|
1007
945
|
const v = exec(code[base + arm]!, input, pos, ctx)
|
|
1008
946
|
if (v !== FAIL) return v
|
|
1009
947
|
// THE CUT. `dispatch()` is the library's one true cut: once its
|
|
@@ -1085,7 +1023,6 @@ function makeDriver(
|
|
|
1085
1023
|
// Under a completion probe every arm is entered, as the interpreter's
|
|
1086
1024
|
// `firstMatch` enters it: its opener then reaches the probe (`failAt`).
|
|
1087
1025
|
if (ctx._probe === undefined && cls !== undefined && cls !== null && !classHas(cls, c)) {
|
|
1088
|
-
if (COUNT) tableCounters.armGateSkips++
|
|
1089
1026
|
// THE GATED ARM STILL REPORTS. The interpreter has no char gate: it
|
|
1090
1027
|
// enters the arm, the arm's opener fails, and its static set is what
|
|
1091
1028
|
// lands in the accumulation. Declining to enter must not also decline
|
|
@@ -1094,11 +1031,8 @@ function makeDriver(
|
|
|
1094
1031
|
continue
|
|
1095
1032
|
}
|
|
1096
1033
|
ctx._fc = false
|
|
1097
|
-
if (COUNT) tableCounters.ungatedEntries++
|
|
1098
|
-
const rows0 = COUNT ? tableCounters.rows : 0
|
|
1099
1034
|
const v = exec(code[base + i]!, input, pos, ctx)
|
|
1100
1035
|
if (v !== FAIL) return v
|
|
1101
|
-
if (COUNT) { tableCounters.ungatedFails++; tableCounters.ungatedFailRows += tableCounters.rows - rows0 }
|
|
1102
1036
|
const at = ctx._fe ?? pos
|
|
1103
1037
|
if (at > best) { best = at; acc = undefined }
|
|
1104
1038
|
if (at === best) push(ctx._fx)
|
|
@@ -1421,7 +1355,6 @@ function makeDriver(
|
|
|
1421
1355
|
const v = exec(code[ip + 2]!, input, pos, ctx)
|
|
1422
1356
|
if (v === FAIL) return FAIL
|
|
1423
1357
|
const fn = fns[code[ip + 1]!] as (value: unknown, span: { start: number; end: number }) => unknown
|
|
1424
|
-
if (COUNT) siteFn('XFORM fn()', fn)
|
|
1425
1358
|
return fn(v, { start: pos, end: EC.e })
|
|
1426
1359
|
}
|
|
1427
1360
|
|
|
@@ -1463,7 +1396,6 @@ function makeDriver(
|
|
|
1463
1396
|
if (v === FAIL) return FAIL
|
|
1464
1397
|
const end = EC.e
|
|
1465
1398
|
const fn = fns[code[ip + 1]!] as (value: unknown, span: { start: number; end: number }) => unknown
|
|
1466
|
-
if (COUNT) siteFn('LEAF fn()', fn)
|
|
1467
1399
|
const out = fn(v, { start: pos, end })
|
|
1468
1400
|
if (wasCapturing) pushCstLeaf(ctx, {
|
|
1469
1401
|
_tag: 'leaf',
|
|
@@ -1566,7 +1498,6 @@ function makeDriver(
|
|
|
1566
1498
|
children: readonly unknown[], fields: FieldMap | undefined, span: { start: number; end: number },
|
|
1567
1499
|
rawChildren: readonly unknown[], triviaLog: readonly number[], state: unknown,
|
|
1568
1500
|
) => unknown
|
|
1569
|
-
if (COUNT) siteFn('NODE build()', build)
|
|
1570
1501
|
nd = build(kids, fieldMap, span, cap.rawChildren, (flags & 4) !== 0 || hostCst ? cap.triviaLog : EMPTY_TL, st)
|
|
1571
1502
|
}
|
|
1572
1503
|
} else if (host !== undefined) {
|
package/src/table/ops.ts
CHANGED
|
@@ -74,13 +74,7 @@ export const OP_XFORM = 9
|
|
|
74
74
|
* from the reducer's declared arity by the same analysis codegen runs, and
|
|
75
75
|
* forced on under `hostMode: 'cst'`. The driver reads the bits and re-derives
|
|
76
76
|
* nothing.
|
|
77
|
-
|
|
78
|
-
* TWO ENCODERS SHARE THIS OPCODE and they do NOT agree on its length. The layout
|
|
79
|
-
* above is `encode.ts` / `exec.ts`. `encode-baseline.ts` / `exec-baseline.ts` emit
|
|
80
|
-
* the FOUR-word form `NODE b c flags` with bits 2 and 3 only, and refuse
|
|
81
|
-
* `collapse` / `unwrap` / `project` outright. Neither driver walks the stream by
|
|
82
|
-
* instruction length, so the divergence is contained — but read the pair you are
|
|
83
|
-
* in, not this comment alone. */
|
|
77
|
+
*/
|
|
84
78
|
export const OP_NODE = 10
|
|
85
79
|
/** `RULE r` — `r` indexes `prog.rules`. */
|
|
86
80
|
export const OP_RULE = 11
|
|
@@ -93,9 +87,6 @@ export const OP_NOT = 13
|
|
|
93
87
|
* `['peek(<child tag>)']`, because `peek.ts:60` DISCARDS the body's expectation:
|
|
94
88
|
* a lookahead's failure is "the guard did not hold", not a request for whatever
|
|
95
89
|
* token the body happened to stop on.
|
|
96
|
-
*
|
|
97
|
-
* `encode-baseline.ts` / `exec-baseline.ts` emit and read the two-word form and
|
|
98
|
-
* are internally consistent; read the pair you are in.
|
|
99
90
|
*/
|
|
100
91
|
export const OP_PEEK = 14
|
|
101
92
|
/** `LEAF f c` — `leaf()`: reduce, then record as a spanned leaf. */
|
package/src/version.ts
CHANGED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Combinator } from '../types.ts';
|
|
2
|
-
import type { TableProgram } from './program.ts';
|
|
3
|
-
/** Settings that select the TABLE'S CONTENTS. They never reach the driver. */
|
|
4
|
-
export type TableSettings = {
|
|
5
|
-
readonly hostMode?: 'ast' | 'cst';
|
|
6
|
-
readonly trackLines?: boolean;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Encode a rule map into ONE table for ONE settings pair.
|
|
10
|
-
*
|
|
11
|
-
* Two settings pairs give two programs and therefore two cached reference
|
|
12
|
-
* tables; the driver that reads them is the same function in both cases and
|
|
13
|
-
* never sees `settings`.
|
|
14
|
-
*/
|
|
15
|
-
export declare function encodeTableBaseline(ruleMap: Record<string, Combinator<unknown>>, settings?: TableSettings): TableProgram;
|
|
16
|
-
//# sourceMappingURL=encode-baseline.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encode-baseline.d.ts","sourceRoot":"","sources":["../../src/table/encode-baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAuB,MAAM,aAAa,CAAA;AAUlE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAQhD,8EAA8E;AAC9E,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,CAAA;IACjC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAC9B,CAAA;AAqTD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,EAC5C,QAAQ,GAAE,aAAkB,GAC3B,YAAY,CAId"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type CompactProgram, type TableProgram, type TableRule } from './program.ts';
|
|
2
|
-
/**
|
|
3
|
-
* Turn a program into the rule map a compiled artifact exports.
|
|
4
|
-
*
|
|
5
|
-
* The entries have the SAME signature as codegen rule functions, so `run()`,
|
|
6
|
-
* the linker's public wrappers and every consumer are unchanged.
|
|
7
|
-
*/
|
|
8
|
-
export declare function execRulesBaseline(source: TableProgram | CompactProgram): Record<string, TableRule>;
|
|
9
|
-
//# sourceMappingURL=exec-baseline.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exec-baseline.d.ts","sourceRoot":"","sources":["../../src/table/exec-baseline.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,cAAc,EAA6C,KAAK,YAAY,EAAE,KAAK,SAAS,EAClG,MAAM,cAAc,CAAA;AAggBrB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAwBlG"}
|