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.
- package/dist/analysis/diagnostics.js +2232 -1088
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +2247 -1103
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts +1 -1
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +69 -16
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/capture-buffer.d.ts +6 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +9 -1
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.js +1446 -236
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +1 -0
- package/dist/language-service/index.js.map +1 -1
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +1 -1
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -1
- package/dist/plugin/index.d.ts +51 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +2126 -380
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +2 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -1
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/table/assemble.d.ts +9 -0
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts +4 -6
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +14 -2
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +17 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +5 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +42 -0
- package/dist/table/factor-choice.d.ts.map +1 -0
- package/dist/table/fail-clean.d.ts +3 -0
- package/dist/table/fail-clean.d.ts.map +1 -0
- package/dist/table/hold-gap.d.ts +8 -0
- package/dist/table/hold-gap.d.ts.map +1 -0
- package/dist/table/index.js +1798 -316
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts +7 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +17 -6
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +13 -0
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/run-support.d.ts +19 -0
- package/dist/table/run-support.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +2 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/select-hot.d.ts +6 -0
- package/dist/table/select-hot.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/table/trivia-gap.d.ts +31 -0
- package/dist/table/trivia-gap.d.ts.map +1 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/combinators/node.ts +6 -13
- package/src/combinators/trivia-skip.ts +44 -1
- package/src/compiler/build-arity.ts +3 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/cst/trivia-kinds.ts +12 -1
- package/src/parse-context.ts +1 -0
- package/src/plugin/entry-supercompiler.ts +8 -9
- package/src/plugin/index.ts +362 -42
- package/src/plugin/ir-eval.ts +7 -1
- package/src/regex/classes.ts +3 -0
- package/src/table/assemble.ts +371 -83
- package/src/table/child-slots.ts +6 -8
- package/src/table/compile-rule-map.ts +64 -15
- package/src/table/emit-assembly.ts +244 -42
- package/src/table/emit.ts +11 -8
- package/src/table/encode.ts +149 -35
- package/src/table/exec-baseline.ts +1 -3
- package/src/table/exec.ts +34 -14
- package/src/table/factor-choice.ts +173 -0
- package/src/table/fail-clean.ts +130 -0
- package/src/table/hold-gap.ts +68 -0
- package/src/table/lex-program.ts +197 -43
- package/src/table/ops.ts +18 -7
- package/src/table/program.ts +24 -0
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/select-hot.ts +70 -0
- package/src/table/site-labels.ts +135 -4
- package/src/table/trivia-gap.ts +109 -0
- package/src/types.ts +18 -0
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -465,6 +465,31 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
465
465
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
466
466
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
467
467
|
}
|
|
468
|
+
function popCstChild(ctx) {
|
|
469
|
+
const b = ctx._cstBuf;
|
|
470
|
+
if (b) {
|
|
471
|
+
const ch2 = b.ch;
|
|
472
|
+
if (b.rawOnly !== true && ch2) {
|
|
473
|
+
ch2.pop();
|
|
474
|
+
if (ch2.length === 1) {
|
|
475
|
+
b.single = ch2[0];
|
|
476
|
+
b.ch = void 0;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1;
|
|
480
|
+
else if (b.raw) {
|
|
481
|
+
b.raw.pop();
|
|
482
|
+
if (b.raw.length === 1) {
|
|
483
|
+
b.rawSingle = b.raw[0];
|
|
484
|
+
b.raw = void 0;
|
|
485
|
+
}
|
|
486
|
+
} else b.rawSingle = void 0;
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
490
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
491
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop();
|
|
492
|
+
}
|
|
468
493
|
function cstRawLen(ctx) {
|
|
469
494
|
const b = ctx._cstBuf;
|
|
470
495
|
if (b) {
|
|
@@ -726,6 +751,7 @@ function literalCodePoints(frag) {
|
|
|
726
751
|
if (ch2 === "\\") {
|
|
727
752
|
const e = frag[i + 1];
|
|
728
753
|
if (e === void 0) return null;
|
|
754
|
+
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
729
755
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
730
756
|
i += 2;
|
|
731
757
|
continue;
|
|
@@ -1323,6 +1349,7 @@ function createParseContext() {
|
|
|
1323
1349
|
_rootTriviaKindIndex: void 0,
|
|
1324
1350
|
_rootTriviaStrictScopes: void 0,
|
|
1325
1351
|
_rootTriviaCapture: void 0,
|
|
1352
|
+
_gap: void 0,
|
|
1326
1353
|
_cstTriviaLog: void 0,
|
|
1327
1354
|
_fields: void 0,
|
|
1328
1355
|
_cstBuf: void 0,
|
|
@@ -1805,7 +1832,10 @@ function labeledTriviaSpec(arms, minRepeats) {
|
|
|
1805
1832
|
arms,
|
|
1806
1833
|
minRepeats,
|
|
1807
1834
|
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1808
|
-
charArms: charArmsFor({ arms, minRepeats })
|
|
1835
|
+
charArms: charArmsFor({ arms, minRepeats }),
|
|
1836
|
+
rootKinds: void 0,
|
|
1837
|
+
rootLeaders: [],
|
|
1838
|
+
rootScan: null
|
|
1809
1839
|
};
|
|
1810
1840
|
}
|
|
1811
1841
|
function matchArmAt(input, pos, arm, state) {
|
|
@@ -2265,8 +2295,50 @@ function loopScanner(arms) {
|
|
|
2265
2295
|
function regexTriviaScanner(parser2) {
|
|
2266
2296
|
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
2267
2297
|
if (d.tag !== "regex" || d.flags) return null;
|
|
2268
|
-
|
|
2269
|
-
|
|
2298
|
+
return sourceScanner(d.source);
|
|
2299
|
+
}
|
|
2300
|
+
function sourceScanner(source) {
|
|
2301
|
+
return classRunSource(source) ?? altStarSource(source) ?? prefixRunSource(source) ?? delimitedSource(source) ?? sharedPrefixAltSource(source);
|
|
2302
|
+
}
|
|
2303
|
+
function sharedPrefixAltSource(source) {
|
|
2304
|
+
const m = /^((?:\\.|[^\\[\]()*+?|^$.{}])+)\(\?:(.*)\)$/.exec(source);
|
|
2305
|
+
if (!m) return null;
|
|
2306
|
+
const alts = [];
|
|
2307
|
+
const body = m[2];
|
|
2308
|
+
let depth = 0;
|
|
2309
|
+
let start = 0;
|
|
2310
|
+
for (let i = 0; i < body.length; i++) {
|
|
2311
|
+
const c = body[i];
|
|
2312
|
+
if (c === "\\") {
|
|
2313
|
+
i++;
|
|
2314
|
+
continue;
|
|
2315
|
+
}
|
|
2316
|
+
if (c === "[") {
|
|
2317
|
+
while (i < body.length && body[i] !== "]") i += body[i] === "\\" ? 2 : 1;
|
|
2318
|
+
continue;
|
|
2319
|
+
}
|
|
2320
|
+
if (c === "(") depth++;
|
|
2321
|
+
else if (c === ")" && --depth < 0) return null;
|
|
2322
|
+
else if (c === "|" && depth === 0) {
|
|
2323
|
+
alts.push(body.slice(start, i));
|
|
2324
|
+
start = i + 1;
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
if (depth !== 0 || alts.length === 0) return null;
|
|
2328
|
+
alts.push(body.slice(start));
|
|
2329
|
+
const scanners = [];
|
|
2330
|
+
for (const alt of alts) {
|
|
2331
|
+
const scanner = sourceScanner(m[1] + alt);
|
|
2332
|
+
if (scanner === null) return null;
|
|
2333
|
+
scanners.push(scanner);
|
|
2334
|
+
}
|
|
2335
|
+
return (input, cur) => {
|
|
2336
|
+
for (const scanner of scanners) {
|
|
2337
|
+
const end = scanner(input, cur);
|
|
2338
|
+
if (end > cur) return end;
|
|
2339
|
+
}
|
|
2340
|
+
return cur;
|
|
2341
|
+
};
|
|
2270
2342
|
}
|
|
2271
2343
|
function bmpString(cps) {
|
|
2272
2344
|
if (!cps) return null;
|
|
@@ -3351,10 +3423,16 @@ function branchUsesRouted(branch) {
|
|
|
3351
3423
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
3352
3424
|
}
|
|
3353
3425
|
function asciiFoldKey(key) {
|
|
3354
|
-
let
|
|
3355
|
-
for (
|
|
3426
|
+
let i = 0;
|
|
3427
|
+
for (; i < key.length; i++) {
|
|
3356
3428
|
const c = key.charCodeAt(i);
|
|
3357
|
-
|
|
3429
|
+
if (c >= 65 && c <= 90) break;
|
|
3430
|
+
}
|
|
3431
|
+
if (i === key.length) return key;
|
|
3432
|
+
let out = key.slice(0, i);
|
|
3433
|
+
for (; i < key.length; i++) {
|
|
3434
|
+
const c = key.charCodeAt(i);
|
|
3435
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
3358
3436
|
}
|
|
3359
3437
|
return out;
|
|
3360
3438
|
}
|
|
@@ -4846,7 +4924,7 @@ function confirmedArityForDef(def) {
|
|
|
4846
4924
|
severity: "warn",
|
|
4847
4925
|
where: `node("${def.type ?? "<inferred>"}")`,
|
|
4848
4926
|
subject,
|
|
4849
|
-
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and
|
|
4927
|
+
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and hands it \`_ctx.state\` on every match`,
|
|
4850
4928
|
otherwise: "only the tiers the reducer actually declares would be captured (arity >= 1 children, >= 2 fields, >= 4 raw, >= 5 trivia, >= 6 state). Declare it with `node(..., { buildArity: n })` if it cannot be derived"
|
|
4851
4929
|
});
|
|
4852
4930
|
return null;
|
|
@@ -5003,7 +5081,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
5003
5081
|
}
|
|
5004
5082
|
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
5005
5083
|
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
5006
|
-
const
|
|
5084
|
+
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
5007
5085
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
5008
5086
|
const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
5009
5087
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
@@ -5044,12 +5122,11 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
5044
5122
|
ctx._triviaCaptureMask = savedMask;
|
|
5045
5123
|
const { children: children2, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
5046
5124
|
if (!r.ok) return r;
|
|
5047
|
-
const st =
|
|
5125
|
+
const st = readsState ? ctx.state : void 0;
|
|
5048
5126
|
const nodeType = def.type ?? missingInferredType();
|
|
5049
5127
|
const cstOutput2 = cstOutputHost(ctx.build);
|
|
5050
5128
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
5051
|
-
const
|
|
5052
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput2 || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
5129
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : (cstOutput2 || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children2, project, nodeType) : build ? cstOutput2 && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
5053
5130
|
const rawEntry2 = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
5054
5131
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
5055
5132
|
pushCstChild(ctx, built, rawEntry2);
|
|
@@ -5342,17 +5419,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
5342
5419
|
};
|
|
5343
5420
|
}
|
|
5344
5421
|
|
|
5422
|
+
// src/table/run-support.ts
|
|
5423
|
+
function lineCol(ctx, offset) {
|
|
5424
|
+
const starts = ctx._lineStarts ?? [0];
|
|
5425
|
+
let lo = 0, hi = starts.length - 1;
|
|
5426
|
+
while (lo < hi) {
|
|
5427
|
+
const mid = lo + hi + 1 >> 1;
|
|
5428
|
+
if (starts[mid] <= offset) lo = mid;
|
|
5429
|
+
else hi = mid - 1;
|
|
5430
|
+
}
|
|
5431
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
5432
|
+
}
|
|
5433
|
+
function spanLines(ctx, start, end) {
|
|
5434
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
5435
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
5436
|
+
}
|
|
5437
|
+
function rawEntry(v, input, s, e) {
|
|
5438
|
+
if (typeof v === "object" && v !== null) {
|
|
5439
|
+
const tg = v._tag;
|
|
5440
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
5441
|
+
}
|
|
5442
|
+
return {
|
|
5443
|
+
_tag: "leaf",
|
|
5444
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
5445
|
+
span: { start: s, end: e }
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
function lead(input, pos) {
|
|
5449
|
+
if (pos >= input.length) return -1;
|
|
5450
|
+
const c = input.charCodeAt(pos);
|
|
5451
|
+
if (c < 55296 || c > 56319) return c;
|
|
5452
|
+
return input.codePointAt(pos) ?? c;
|
|
5453
|
+
}
|
|
5454
|
+
var EMPTY_KIDS = Object.freeze([]);
|
|
5455
|
+
var EMPTY_TRIVIA = Object.freeze([]);
|
|
5456
|
+
function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
|
|
5457
|
+
const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
|
|
5458
|
+
if (collected) popCstChild(ctx);
|
|
5459
|
+
const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
|
|
5460
|
+
const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
|
|
5461
|
+
if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
|
|
5462
|
+
return nd;
|
|
5463
|
+
}
|
|
5464
|
+
|
|
5345
5465
|
// src/table/lex-program.ts
|
|
5346
5466
|
var LEX_NODE_TERMINAL = 0;
|
|
5347
5467
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
5348
5468
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
5349
5469
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
5350
5470
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
5351
|
-
var
|
|
5352
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
5353
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5471
|
+
var LEX_NODE_CHOICE = 5;
|
|
5354
5472
|
var LEX_NODE_NOT = 8;
|
|
5355
5473
|
var LEX_NODE_OPTIONAL = 9;
|
|
5474
|
+
var LEX_NODE_REPEAT = 10;
|
|
5356
5475
|
function lexProgramDigest(words) {
|
|
5357
5476
|
let hash = 2166136261;
|
|
5358
5477
|
for (const word2 of words) {
|
|
@@ -5381,85 +5500,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
5381
5500
|
ctx._lineScannedTo = end;
|
|
5382
5501
|
}
|
|
5383
5502
|
function terminalNode(matcher, failure, tracksLines) {
|
|
5384
|
-
const match = (input, pos) => {
|
|
5385
|
-
const result = matcher(input, pos);
|
|
5386
|
-
return result < 0 ? -1 : result / 2;
|
|
5387
|
-
};
|
|
5388
5503
|
return {
|
|
5389
|
-
match,
|
|
5504
|
+
match: (input, pos) => {
|
|
5505
|
+
const result = matcher(input, pos);
|
|
5506
|
+
return result < 0 ? -1 : result / 2;
|
|
5507
|
+
},
|
|
5390
5508
|
run: (input, pos, ctx) => {
|
|
5391
|
-
const
|
|
5392
|
-
if (
|
|
5509
|
+
const result = matcher(input, pos);
|
|
5510
|
+
if (result < 0) {
|
|
5393
5511
|
ctx._fe = pos;
|
|
5394
5512
|
ctx._fx = failure;
|
|
5395
5513
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
5396
5514
|
return -1;
|
|
5397
5515
|
}
|
|
5516
|
+
const end = result / 2;
|
|
5398
5517
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
5399
5518
|
return end;
|
|
5400
5519
|
}
|
|
5401
5520
|
};
|
|
5402
5521
|
}
|
|
5403
5522
|
function sequence2(a, b) {
|
|
5523
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
5404
5524
|
return {
|
|
5405
5525
|
match: (input, pos) => {
|
|
5406
|
-
const e0 =
|
|
5407
|
-
return e0 < 0 ? -1 :
|
|
5526
|
+
const e0 = am(input, pos);
|
|
5527
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
5408
5528
|
},
|
|
5409
5529
|
run: (input, pos, ctx) => {
|
|
5410
|
-
const e0 =
|
|
5530
|
+
const e0 = ar(input, pos, ctx);
|
|
5411
5531
|
if (e0 < 0) return -1;
|
|
5412
5532
|
ctx._fc = false;
|
|
5413
|
-
return
|
|
5533
|
+
return br(input, e0, ctx);
|
|
5414
5534
|
}
|
|
5415
5535
|
};
|
|
5416
5536
|
}
|
|
5417
5537
|
function sequence3(a, b, c) {
|
|
5538
|
+
const am = a.match, bm = b.match, cm = c.match, ar = a.run, br = b.run, cr = c.run;
|
|
5418
5539
|
return {
|
|
5419
5540
|
match: (input, pos) => {
|
|
5420
|
-
const e0 =
|
|
5541
|
+
const e0 = am(input, pos);
|
|
5421
5542
|
if (e0 < 0) return -1;
|
|
5422
|
-
const e1 =
|
|
5423
|
-
return e1 < 0 ? -1 :
|
|
5543
|
+
const e1 = bm(input, e0);
|
|
5544
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
5424
5545
|
},
|
|
5425
5546
|
run: (input, pos, ctx) => {
|
|
5426
|
-
const e0 =
|
|
5547
|
+
const e0 = ar(input, pos, ctx);
|
|
5427
5548
|
if (e0 < 0) return -1;
|
|
5428
5549
|
ctx._fc = false;
|
|
5429
|
-
const e1 =
|
|
5550
|
+
const e1 = br(input, e0, ctx);
|
|
5430
5551
|
if (e1 < 0) return -1;
|
|
5431
5552
|
ctx._fc = false;
|
|
5432
|
-
return
|
|
5553
|
+
return cr(input, e1, ctx);
|
|
5433
5554
|
}
|
|
5434
5555
|
};
|
|
5435
5556
|
}
|
|
5436
5557
|
function sequence4(a, b, c, d) {
|
|
5437
|
-
const
|
|
5558
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match;
|
|
5559
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run;
|
|
5438
5560
|
return {
|
|
5439
5561
|
match: (input, pos) => {
|
|
5440
|
-
const
|
|
5441
|
-
|
|
5562
|
+
const e0 = am(input, pos);
|
|
5563
|
+
if (e0 < 0) return -1;
|
|
5564
|
+
const e1 = bm(input, e0);
|
|
5565
|
+
if (e1 < 0) return -1;
|
|
5566
|
+
const e2 = cm(input, e1);
|
|
5567
|
+
return e2 < 0 ? -1 : dm(input, e2);
|
|
5442
5568
|
},
|
|
5443
5569
|
run: (input, pos, ctx) => {
|
|
5444
|
-
const
|
|
5445
|
-
if (
|
|
5570
|
+
const e0 = ar(input, pos, ctx);
|
|
5571
|
+
if (e0 < 0) return -1;
|
|
5572
|
+
ctx._fc = false;
|
|
5573
|
+
const e1 = br(input, e0, ctx);
|
|
5574
|
+
if (e1 < 0) return -1;
|
|
5575
|
+
ctx._fc = false;
|
|
5576
|
+
const e2 = cr(input, e1, ctx);
|
|
5577
|
+
if (e2 < 0) return -1;
|
|
5446
5578
|
ctx._fc = false;
|
|
5447
|
-
return
|
|
5579
|
+
return dr(input, e2, ctx);
|
|
5448
5580
|
}
|
|
5449
5581
|
};
|
|
5450
5582
|
}
|
|
5451
5583
|
function sequence5(a, b, c, d, e) {
|
|
5452
|
-
const
|
|
5584
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match, em = e.match;
|
|
5585
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run, er = e.run;
|
|
5453
5586
|
return {
|
|
5454
5587
|
match: (input, pos) => {
|
|
5455
|
-
const
|
|
5456
|
-
|
|
5588
|
+
const e0 = am(input, pos);
|
|
5589
|
+
if (e0 < 0) return -1;
|
|
5590
|
+
const e1 = bm(input, e0);
|
|
5591
|
+
if (e1 < 0) return -1;
|
|
5592
|
+
const e2 = cm(input, e1);
|
|
5593
|
+
if (e2 < 0) return -1;
|
|
5594
|
+
const e3 = dm(input, e2);
|
|
5595
|
+
return e3 < 0 ? -1 : em(input, e3);
|
|
5457
5596
|
},
|
|
5458
5597
|
run: (input, pos, ctx) => {
|
|
5459
|
-
const
|
|
5460
|
-
if (
|
|
5598
|
+
const e0 = ar(input, pos, ctx);
|
|
5599
|
+
if (e0 < 0) return -1;
|
|
5600
|
+
ctx._fc = false;
|
|
5601
|
+
const e1 = br(input, e0, ctx);
|
|
5602
|
+
if (e1 < 0) return -1;
|
|
5603
|
+
ctx._fc = false;
|
|
5604
|
+
const e2 = cr(input, e1, ctx);
|
|
5605
|
+
if (e2 < 0) return -1;
|
|
5461
5606
|
ctx._fc = false;
|
|
5462
|
-
|
|
5607
|
+
const e3 = dr(input, e2, ctx);
|
|
5608
|
+
if (e3 < 0) return -1;
|
|
5609
|
+
ctx._fc = false;
|
|
5610
|
+
return er(input, e3, ctx);
|
|
5463
5611
|
}
|
|
5464
5612
|
};
|
|
5465
5613
|
}
|
|
@@ -5472,9 +5620,9 @@ function appendExpected(acc, values) {
|
|
|
5472
5620
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5473
5621
|
let matchTail = () => -1;
|
|
5474
5622
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5475
|
-
const
|
|
5623
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
5476
5624
|
matchTail = (input, pos) => {
|
|
5477
|
-
const end =
|
|
5625
|
+
const end = armMatch(input, pos);
|
|
5478
5626
|
return end < 0 ? next(input, pos) : end;
|
|
5479
5627
|
};
|
|
5480
5628
|
}
|
|
@@ -5484,7 +5632,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5484
5632
|
return -1;
|
|
5485
5633
|
};
|
|
5486
5634
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5487
|
-
const
|
|
5635
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5488
5636
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5489
5637
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5490
5638
|
return next(
|
|
@@ -5497,7 +5645,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5497
5645
|
);
|
|
5498
5646
|
}
|
|
5499
5647
|
ctx._fc = false;
|
|
5500
|
-
const end =
|
|
5648
|
+
const end = armRun(input, pos, ctx);
|
|
5501
5649
|
if (end >= 0) return end;
|
|
5502
5650
|
const at = ctx._fe ?? pos;
|
|
5503
5651
|
if (at > best) {
|
|
@@ -5524,11 +5672,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5524
5672
|
)
|
|
5525
5673
|
};
|
|
5526
5674
|
}
|
|
5675
|
+
function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
5676
|
+
const ascii = (classes.length <= 128 ? new Int8Array(128) : new Int32Array(128)).fill(-1);
|
|
5677
|
+
const hi = [];
|
|
5678
|
+
for (let i = 0; i < classes.length; i++) {
|
|
5679
|
+
const cls = classes[i];
|
|
5680
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) ascii[c] = i;
|
|
5681
|
+
for (let r = 0; r < cls.hi.length; r += 2) hi.push(cls.hi[r], cls.hi[r + 1], i);
|
|
5682
|
+
}
|
|
5683
|
+
const select = (code) => {
|
|
5684
|
+
if (code < 0) return -1;
|
|
5685
|
+
if (code < 128) return ascii[code];
|
|
5686
|
+
for (let r = 0; r < hi.length; r += 3) if (code >= hi[r] && code <= hi[r + 1]) return hi[r + 2];
|
|
5687
|
+
return -1;
|
|
5688
|
+
};
|
|
5689
|
+
let matchArm = () => -1;
|
|
5690
|
+
let selectRun = () => -1;
|
|
5691
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5692
|
+
const armMatch = arms[i].match, armRun = arms[i].run, nextMatch = matchArm, nextRun = selectRun;
|
|
5693
|
+
matchArm = (selected, input, pos) => selected === i ? armMatch(input, pos) : nextMatch(selected, input, pos);
|
|
5694
|
+
selectRun = (selected, input, pos, ctx) => selected === i ? armRun(input, pos, ctx) : nextRun(selected, input, pos, ctx);
|
|
5695
|
+
}
|
|
5696
|
+
const runArm = (input, pos, ctx) => {
|
|
5697
|
+
const arm = select(lead(input, pos));
|
|
5698
|
+
if (arm >= 0) {
|
|
5699
|
+
ctx._fc = false;
|
|
5700
|
+
const end = selectRun(arm, input, pos, ctx);
|
|
5701
|
+
if (end >= 0) return end;
|
|
5702
|
+
if (committed(ctx)) return -1;
|
|
5703
|
+
const failed = ctx._fx;
|
|
5704
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
5705
|
+
ctx._fe = pos;
|
|
5706
|
+
return -1;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
ctx._fe = pos;
|
|
5710
|
+
ctx._fx = choiceFx;
|
|
5711
|
+
return -1;
|
|
5712
|
+
};
|
|
5713
|
+
return {
|
|
5714
|
+
match: (input, pos) => {
|
|
5715
|
+
const arm = select(lead(input, pos));
|
|
5716
|
+
return arm < 0 ? -1 : matchArm(arm, input, pos);
|
|
5717
|
+
},
|
|
5718
|
+
run: runArm
|
|
5719
|
+
};
|
|
5720
|
+
}
|
|
5527
5721
|
function notNode(body, failure) {
|
|
5722
|
+
const bodyMatch = body.match;
|
|
5528
5723
|
return {
|
|
5529
|
-
match: (input, pos) =>
|
|
5724
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
5530
5725
|
run: (input, pos, ctx) => {
|
|
5531
|
-
if (
|
|
5726
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
5532
5727
|
ctx._fe = pos;
|
|
5533
5728
|
ctx._fx = failure;
|
|
5534
5729
|
return -1;
|
|
@@ -5536,18 +5731,57 @@ function notNode(body, failure) {
|
|
|
5536
5731
|
};
|
|
5537
5732
|
}
|
|
5538
5733
|
function optionalNode(body) {
|
|
5734
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
5539
5735
|
return {
|
|
5540
5736
|
match: (input, pos) => {
|
|
5541
|
-
const end =
|
|
5737
|
+
const end = bodyMatch(input, pos);
|
|
5542
5738
|
return end < 0 ? pos : end;
|
|
5543
5739
|
},
|
|
5544
5740
|
run: (input, pos, ctx) => {
|
|
5545
5741
|
ctx._fc = false;
|
|
5546
|
-
const end =
|
|
5742
|
+
const end = bodyRun(input, pos, ctx);
|
|
5547
5743
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
5548
5744
|
}
|
|
5549
5745
|
};
|
|
5550
5746
|
}
|
|
5747
|
+
function repeatNode(item, min, max) {
|
|
5748
|
+
const itemMatch = item.match, itemRun = item.run;
|
|
5749
|
+
return {
|
|
5750
|
+
match: (input, pos) => {
|
|
5751
|
+
let cur = pos;
|
|
5752
|
+
let count = 0;
|
|
5753
|
+
for (; ; ) {
|
|
5754
|
+
if (max >= 0 && count >= max) break;
|
|
5755
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5756
|
+
if (optional2 && cur >= input.length) break;
|
|
5757
|
+
const end = itemMatch(input, cur);
|
|
5758
|
+
if (end < 0 || optional2 && end === cur) break;
|
|
5759
|
+
cur = end;
|
|
5760
|
+
count++;
|
|
5761
|
+
}
|
|
5762
|
+
return count < min ? -1 : cur;
|
|
5763
|
+
},
|
|
5764
|
+
run: (input, pos, ctx) => {
|
|
5765
|
+
let cur = pos;
|
|
5766
|
+
let count = 0;
|
|
5767
|
+
for (; ; ) {
|
|
5768
|
+
if (max >= 0 && count >= max) break;
|
|
5769
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5770
|
+
if (optional2 && cur >= input.length) break;
|
|
5771
|
+
ctx._fc = false;
|
|
5772
|
+
const end = itemRun(input, cur, ctx);
|
|
5773
|
+
if (end < 0) {
|
|
5774
|
+
if (committed(ctx)) return -1;
|
|
5775
|
+
break;
|
|
5776
|
+
}
|
|
5777
|
+
if (optional2 && end === cur) break;
|
|
5778
|
+
cur = end;
|
|
5779
|
+
count++;
|
|
5780
|
+
}
|
|
5781
|
+
return count < min ? -1 : cur;
|
|
5782
|
+
}
|
|
5783
|
+
};
|
|
5784
|
+
}
|
|
5551
5785
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
5552
5786
|
const stack = [];
|
|
5553
5787
|
const pop = () => {
|
|
@@ -5575,9 +5809,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5575
5809
|
else stack.push(sequence5(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4]));
|
|
5576
5810
|
continue;
|
|
5577
5811
|
}
|
|
5578
|
-
if (op
|
|
5579
|
-
const count =
|
|
5812
|
+
if (op === LEX_NODE_CHOICE) {
|
|
5813
|
+
const count = words[at++];
|
|
5814
|
+
const exclusive = words[at++];
|
|
5815
|
+
if (exclusive !== 0 && exclusive !== 1) throw new TypeError("table lexical tree choice has an invalid dispatch mode");
|
|
5580
5816
|
const choiceFx = expected[words[at++]];
|
|
5817
|
+
if (!Number.isInteger(count) || count < 2 || count > stack.length) {
|
|
5818
|
+
throw new TypeError("table lexical tree choice has an invalid arm count");
|
|
5819
|
+
}
|
|
5581
5820
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
5582
5821
|
const armClasses = [];
|
|
5583
5822
|
const armFx = [];
|
|
@@ -5590,7 +5829,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5590
5829
|
armFx.push(fx);
|
|
5591
5830
|
}
|
|
5592
5831
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
5593
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5832
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5594
5833
|
continue;
|
|
5595
5834
|
}
|
|
5596
5835
|
if (op === LEX_NODE_NOT) {
|
|
@@ -5603,6 +5842,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5603
5842
|
stack.push(optionalNode(pop()));
|
|
5604
5843
|
continue;
|
|
5605
5844
|
}
|
|
5845
|
+
if (op === LEX_NODE_REPEAT) {
|
|
5846
|
+
const min = words[at++], max = words[at++];
|
|
5847
|
+
if (!Number.isInteger(min) || min < 0 || !Number.isInteger(max) || max >= 0 && max < min) {
|
|
5848
|
+
throw new TypeError("table lexical tree repeat has invalid bounds");
|
|
5849
|
+
}
|
|
5850
|
+
stack.push(repeatNode(pop(), min, max));
|
|
5851
|
+
continue;
|
|
5852
|
+
}
|
|
5606
5853
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
5607
5854
|
}
|
|
5608
5855
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -5757,6 +6004,12 @@ function scanRefs(s) {
|
|
|
5757
6004
|
refs.push(...s.skip);
|
|
5758
6005
|
return refs;
|
|
5759
6006
|
}
|
|
6007
|
+
function assemblyExtraIps(prog) {
|
|
6008
|
+
const ips = [];
|
|
6009
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) ips.push(r[0]);
|
|
6010
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) ips.push(r[0]);
|
|
6011
|
+
return ips;
|
|
6012
|
+
}
|
|
5760
6013
|
function expandCompact(p) {
|
|
5761
6014
|
if ("code" in p) return p;
|
|
5762
6015
|
return ownTableProgram({
|
|
@@ -5887,6 +6140,11 @@ function classHas2(cls, code) {
|
|
|
5887
6140
|
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
5888
6141
|
return false;
|
|
5889
6142
|
}
|
|
6143
|
+
function dispatchIsExclusive(arms, cc) {
|
|
6144
|
+
const resolved = [];
|
|
6145
|
+
for (const ci of arms) if (ci >= 0) resolved[ci] = resolveClass(cc[ci]);
|
|
6146
|
+
return resolveDispatch(arms, resolved).exclusive;
|
|
6147
|
+
}
|
|
5890
6148
|
function resolveDispatch(arms, cc) {
|
|
5891
6149
|
const ascii = new Uint8Array(128);
|
|
5892
6150
|
const hi = [];
|
|
@@ -6857,6 +7115,111 @@ function classifyRuleMap(ruleMap) {
|
|
|
6857
7115
|
};
|
|
6858
7116
|
}
|
|
6859
7117
|
|
|
7118
|
+
// src/table/factor-choice.ts
|
|
7119
|
+
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
7120
|
+
function isCombinator(v) {
|
|
7121
|
+
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
7122
|
+
}
|
|
7123
|
+
function sameComb(a, b, depth) {
|
|
7124
|
+
if (a === b) return true;
|
|
7125
|
+
if (depth > 32 || a._tag !== b._tag) return false;
|
|
7126
|
+
for (const k of Object.keys(a)) if (!DERIVED.has(k)) return false;
|
|
7127
|
+
for (const k of Object.keys(b)) if (!DERIVED.has(k)) return false;
|
|
7128
|
+
return sameFields(a._def, b._def, depth, void 0);
|
|
7129
|
+
}
|
|
7130
|
+
function sameValue(u, v, depth) {
|
|
7131
|
+
if (u === v) return true;
|
|
7132
|
+
if (isCombinator(u) && isCombinator(v)) return sameComb(u, v, depth + 1);
|
|
7133
|
+
if (Array.isArray(u) && Array.isArray(v)) return u.length === v.length && u.every((x, i) => sameValue(x, v[i], depth));
|
|
7134
|
+
if (typeof u === "object" && u !== null && typeof v === "object" && v !== null && Object.getPrototypeOf(u) === Object.prototype && Object.getPrototypeOf(v) === Object.prototype) {
|
|
7135
|
+
return sameFields(u, v, depth, void 0);
|
|
7136
|
+
}
|
|
7137
|
+
return false;
|
|
7138
|
+
}
|
|
7139
|
+
function sameFields(x, y, depth, skip) {
|
|
7140
|
+
const kx = Object.keys(x).filter((k) => k !== skip && x[k] !== void 0);
|
|
7141
|
+
const ky = Object.keys(y).filter((k) => k !== skip && y[k] !== void 0);
|
|
7142
|
+
if (kx.length !== ky.length) return false;
|
|
7143
|
+
for (const k of kx) {
|
|
7144
|
+
if (!(k in y)) return false;
|
|
7145
|
+
const u = x[k];
|
|
7146
|
+
const v = y[k];
|
|
7147
|
+
if (k === "fn" && typeof u === "function" && typeof v === "function" && u !== v) {
|
|
7148
|
+
if (typeof x.fnSrc !== "string" || x.fnSrc === "" || x.fnSrc !== y.fnSrc) return false;
|
|
7149
|
+
continue;
|
|
7150
|
+
}
|
|
7151
|
+
if (!sameValue(u, v, depth)) return false;
|
|
7152
|
+
}
|
|
7153
|
+
return true;
|
|
7154
|
+
}
|
|
7155
|
+
function rewrap(w, body) {
|
|
7156
|
+
const d = w._def;
|
|
7157
|
+
let out;
|
|
7158
|
+
if (d.tag === "leaf") {
|
|
7159
|
+
out = d.cstValue === "source" ? sourceLeaf(body, d.fn) : leaf(body, d.fn);
|
|
7160
|
+
if (d.fnSrc !== void 0) out._def.fnSrc = d.fnSrc;
|
|
7161
|
+
} else if (d.tag === "grammar") {
|
|
7162
|
+
out = d.clearTrivia === true ? noTrivia(body) : parser({ trivia: d.triviaParser ?? null }, body);
|
|
7163
|
+
} else return void 0;
|
|
7164
|
+
return sameFields(d, out._def, 0, "parser") ? out : void 0;
|
|
7165
|
+
}
|
|
7166
|
+
function unusedOf(seq) {
|
|
7167
|
+
return seq._def.tag === "sequence" && seq._def.valueUnused === true;
|
|
7168
|
+
}
|
|
7169
|
+
function never(c) {
|
|
7170
|
+
const t = c._def.tag;
|
|
7171
|
+
return t === "optional" || t === "many";
|
|
7172
|
+
}
|
|
7173
|
+
function factorSharedEnds(d) {
|
|
7174
|
+
const arms = d.parsers;
|
|
7175
|
+
if (arms.length < 2) return void 0;
|
|
7176
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
7177
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
7178
|
+
const shapes = [];
|
|
7179
|
+
for (const arm of arms) {
|
|
7180
|
+
const wrappers = [];
|
|
7181
|
+
let c = arm;
|
|
7182
|
+
while ((c._def.tag === "leaf" || c._def.tag === "grammar") && wrappers.length < 4) {
|
|
7183
|
+
wrappers.push(c);
|
|
7184
|
+
c = c._def.parser;
|
|
7185
|
+
}
|
|
7186
|
+
if (c._def.tag !== "sequence" || c._def.parsers.length < 2) return void 0;
|
|
7187
|
+
shapes.push({ wrappers, terms: c._def.parsers, seq: c });
|
|
7188
|
+
}
|
|
7189
|
+
const first = shapes[0];
|
|
7190
|
+
const n = first.terms.length;
|
|
7191
|
+
for (const s of shapes) {
|
|
7192
|
+
if (s.wrappers.length !== first.wrappers.length || s.terms.length !== n) return void 0;
|
|
7193
|
+
if (unusedOf(s.seq) !== unusedOf(first.seq)) return void 0;
|
|
7194
|
+
for (let j = 0; j < s.wrappers.length; j++) {
|
|
7195
|
+
const a = first.wrappers[j]._def;
|
|
7196
|
+
const b = s.wrappers[j]._def;
|
|
7197
|
+
if (a.tag !== b.tag || !sameFields(a, b, 0, "parser")) return void 0;
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
7200
|
+
let at = -1;
|
|
7201
|
+
for (let i = 0; i < n; i++) {
|
|
7202
|
+
if (shapes.every((s) => sameComb(s.terms[i], first.terms[i], 0))) continue;
|
|
7203
|
+
if (at >= 0) return void 0;
|
|
7204
|
+
at = i;
|
|
7205
|
+
}
|
|
7206
|
+
if (at < 0) return void 0;
|
|
7207
|
+
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
7208
|
+
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
7209
|
+
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
7210
|
+
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
7211
|
+
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
7212
|
+
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
7213
|
+
let out = sequence(
|
|
7214
|
+
...[...first.terms.slice(0, at), middle, ...first.terms.slice(at + 1)]
|
|
7215
|
+
);
|
|
7216
|
+
if (unusedOf(first.seq)) {
|
|
7217
|
+
out._def.valueUnused = true;
|
|
7218
|
+
}
|
|
7219
|
+
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
7220
|
+
return out === void 0 ? void 0 : attempt(out);
|
|
7221
|
+
}
|
|
7222
|
+
|
|
6860
7223
|
// src/table/ops.ts
|
|
6861
7224
|
var OP_LIT = 1;
|
|
6862
7225
|
var OP_RX = 2;
|
|
@@ -6900,6 +7263,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
6900
7263
|
var OP_LEX_BODY = 42;
|
|
6901
7264
|
var OP_LEX_PROGRAM = 43;
|
|
6902
7265
|
var OP_SOURCE_LEAF = 44;
|
|
7266
|
+
var OP_RGATE = 45;
|
|
6903
7267
|
var OP_DISPATCH = 25;
|
|
6904
7268
|
var OP_ROUTED = 26;
|
|
6905
7269
|
var OP_NAMES = {
|
|
@@ -6919,6 +7283,7 @@ var OP_NAMES = {
|
|
|
6919
7283
|
[OP_PEEK]: "PEEK",
|
|
6920
7284
|
[OP_LEAF]: "LEAF",
|
|
6921
7285
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
7286
|
+
[OP_RGATE]: "RGATE",
|
|
6922
7287
|
[OP_EMPTY]: "EMPTY",
|
|
6923
7288
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
6924
7289
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -6999,7 +7364,10 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
6999
7364
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
7000
7365
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
7001
7366
|
}
|
|
7002
|
-
function
|
|
7367
|
+
function reinstallsRuleTrivia(reference, target) {
|
|
7368
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
7369
|
+
}
|
|
7370
|
+
function directTokenBodyParser(parser2, resolve, scope) {
|
|
7003
7371
|
const outer = parser2._def;
|
|
7004
7372
|
if (outer.tag !== "token") return void 0;
|
|
7005
7373
|
let body = outer.parser;
|
|
@@ -7009,12 +7377,13 @@ function directTokenBodyParser(parser2, resolve) {
|
|
|
7009
7377
|
const wrapper = body._def;
|
|
7010
7378
|
if (wrapper.tag === "grammar") {
|
|
7011
7379
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
7380
|
+
if (scope !== void 0) scope.cleared = true;
|
|
7012
7381
|
body = wrapper.parser;
|
|
7013
7382
|
continue;
|
|
7014
7383
|
}
|
|
7015
7384
|
if (wrapper.tag === "lazy") {
|
|
7016
7385
|
const target = resolvedLazyTarget(body, resolve);
|
|
7017
|
-
if (target === void 0) return void 0;
|
|
7386
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
7018
7387
|
body = target;
|
|
7019
7388
|
continue;
|
|
7020
7389
|
}
|
|
@@ -7186,7 +7555,7 @@ function directNot2TokenBody(parser2, resolve) {
|
|
|
7186
7555
|
terminal
|
|
7187
7556
|
};
|
|
7188
7557
|
}
|
|
7189
|
-
function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
7558
|
+
function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared = false) {
|
|
7190
7559
|
let current = parser2;
|
|
7191
7560
|
const wrappers = /* @__PURE__ */ new Set();
|
|
7192
7561
|
while (!wrappers.has(current)) {
|
|
@@ -7194,7 +7563,7 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7194
7563
|
const def = current._def;
|
|
7195
7564
|
if (def.tag === "lazy") {
|
|
7196
7565
|
const target = resolvedLazyTarget(current, resolve);
|
|
7197
|
-
if (target === void 0) return void 0;
|
|
7566
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
7198
7567
|
current = target;
|
|
7199
7568
|
continue;
|
|
7200
7569
|
}
|
|
@@ -7212,30 +7581,33 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7212
7581
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
7213
7582
|
const def = current._def;
|
|
7214
7583
|
if (def.tag === "grammar") {
|
|
7584
|
+
if (def.triviaParser === void 0 && def.captureTrivia !== true && def.rootCapture !== "opaque" && def.constructionCaptureTriviaKinds === void 0) {
|
|
7585
|
+
return directFixedLexNode(def.parser, resolve, active, pureOnly, cleared || def.clearTrivia === true);
|
|
7586
|
+
}
|
|
7215
7587
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
7216
|
-
return directFixedLexNode(def.parser, resolve, active, true);
|
|
7588
|
+
return directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
7217
7589
|
}
|
|
7218
7590
|
if (def.tag === "sequence") {
|
|
7219
7591
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
7220
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly));
|
|
7592
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve, active, pureOnly, cleared));
|
|
7221
7593
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
7222
7594
|
return { kind: "sequence", parts };
|
|
7223
7595
|
}
|
|
7224
7596
|
if (def.tag === "choice") {
|
|
7225
|
-
if (def.parsers.length
|
|
7226
|
-
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly));
|
|
7597
|
+
if (def.parsers.length < 2 || def.strategy.tag !== "firstMatch" || def.gates.some((gate2) => gate2 !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
7598
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve, active, pureOnly, cleared));
|
|
7227
7599
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
7228
|
-
const final = classifyFinalChoice(def.parsers, resolve);
|
|
7229
7600
|
return {
|
|
7230
7601
|
kind: "choice",
|
|
7231
7602
|
arms,
|
|
7232
|
-
|
|
7603
|
+
parsers: def.parsers,
|
|
7604
|
+
cleared,
|
|
7233
7605
|
armExpected: def.parsers.map(deriveExpected),
|
|
7234
7606
|
expected: def.parsers.flatMap(deriveExpected)
|
|
7235
7607
|
};
|
|
7236
7608
|
}
|
|
7237
7609
|
if (def.tag === "not") {
|
|
7238
|
-
const body = directFixedLexNode(def.parser, resolve, active, true);
|
|
7610
|
+
const body = directFixedLexNode(def.parser, resolve, active, true, cleared);
|
|
7239
7611
|
return body === void 0 ? void 0 : {
|
|
7240
7612
|
kind: "not",
|
|
7241
7613
|
body,
|
|
@@ -7243,18 +7615,28 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false) {
|
|
|
7243
7615
|
};
|
|
7244
7616
|
}
|
|
7245
7617
|
if (def.tag === "optional") {
|
|
7246
|
-
const body = directFixedLexNode(def.parser, resolve, active, pureOnly);
|
|
7618
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
7247
7619
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
7248
7620
|
}
|
|
7621
|
+
if (def.tag === "many" || def.tag === "oneOrMore") {
|
|
7622
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared);
|
|
7623
|
+
return body === void 0 ? void 0 : {
|
|
7624
|
+
kind: "repeat",
|
|
7625
|
+
body,
|
|
7626
|
+
min: def.tag === "many" ? 0 : def.min,
|
|
7627
|
+
max: def.max ?? -1
|
|
7628
|
+
};
|
|
7629
|
+
}
|
|
7249
7630
|
return void 0;
|
|
7250
7631
|
} finally {
|
|
7251
7632
|
active.delete(current);
|
|
7252
7633
|
}
|
|
7253
7634
|
}
|
|
7254
7635
|
function directFixedTokenBody(parser2, resolve) {
|
|
7255
|
-
const
|
|
7636
|
+
const scope = { cleared: false };
|
|
7637
|
+
const body = directTokenBodyParser(parser2, resolve, scope);
|
|
7256
7638
|
if (body === void 0) return void 0;
|
|
7257
|
-
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set());
|
|
7639
|
+
const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
7258
7640
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
7259
7641
|
}
|
|
7260
7642
|
function directBalancedTokenBody(parser2, resolve) {
|
|
@@ -7501,13 +7883,16 @@ var Encoder = class {
|
|
|
7501
7883
|
}
|
|
7502
7884
|
case "choice": {
|
|
7503
7885
|
for (const arm of node2.arms) if (!emitNode(arm)) return false;
|
|
7504
|
-
const
|
|
7505
|
-
|
|
7506
|
-
|
|
7886
|
+
const final = classifyFinalChoice(
|
|
7887
|
+
node2.parsers,
|
|
7888
|
+
this.refResolver(),
|
|
7889
|
+
node2.cleared ? void 0 : this.activeTrivia
|
|
7890
|
+
);
|
|
7891
|
+
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
7892
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
7893
|
+
words.push(LEX_NODE_CHOICE, node2.arms.length, exclusive ? 1 : 0, this.expected(node2.expected));
|
|
7507
7894
|
for (let i = 0; i < node2.arms.length; i++) {
|
|
7508
|
-
|
|
7509
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
7510
|
-
words.push(this.expected(node2.armExpected[i]));
|
|
7895
|
+
words.push(classes[i], this.expected(node2.armExpected[i]));
|
|
7511
7896
|
}
|
|
7512
7897
|
return true;
|
|
7513
7898
|
}
|
|
@@ -7519,6 +7904,10 @@ var Encoder = class {
|
|
|
7519
7904
|
if (!emitNode(node2.body)) return false;
|
|
7520
7905
|
words.push(LEX_NODE_OPTIONAL);
|
|
7521
7906
|
return true;
|
|
7907
|
+
case "repeat":
|
|
7908
|
+
if (!emitNode(node2.body)) return false;
|
|
7909
|
+
words.push(LEX_NODE_REPEAT, node2.min, node2.max);
|
|
7910
|
+
return true;
|
|
7522
7911
|
}
|
|
7523
7912
|
};
|
|
7524
7913
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -7846,6 +8235,33 @@ var Encoder = class {
|
|
|
7846
8235
|
return childrenOf2(def);
|
|
7847
8236
|
}
|
|
7848
8237
|
}
|
|
8238
|
+
/**
|
|
8239
|
+
* THE FIRST-CHARACTER GATE OF AN `optional`, `not` OR `peek` CHILD.
|
|
8240
|
+
*
|
|
8241
|
+
* A non-nullable child cannot match at a character outside its first set, so
|
|
8242
|
+
* the wrapper's outcome there is already decided: `optional` yields `null`,
|
|
8243
|
+
* `not` succeeds, `peek` fails with its own set. The interpreter's `optional`
|
|
8244
|
+
* makes that test itself (`repeat.ts` `startsFirstSet`); the table entered the
|
|
8245
|
+
* child — a rollback mark, the call, the child's own failure — to learn it.
|
|
8246
|
+
*
|
|
8247
|
+
* The gate is an `OP_GATE` row around the child, so every engine runs it
|
|
8248
|
+
* unchanged, a probe or tolerant parse forwards through it as for a node's
|
|
8249
|
+
* gate, and the wrapper's row keeps its layout. The engines test the class
|
|
8250
|
+
* before taking the wrapper's mark. The first set is resolved through
|
|
8251
|
+
* `winners`, the analysis a choice arm's gate uses, so a composed rule's set
|
|
8252
|
+
* is the merged one. A scalar `not` child stays bare: `scalarTerminalNotChild`
|
|
8253
|
+
* already reduces it to one recognizer call.
|
|
8254
|
+
*/
|
|
8255
|
+
lookaheadGate(p, child) {
|
|
8256
|
+
const op = this.code[child];
|
|
8257
|
+
if (op === OP_GATE || op === OP_LIT || op === OP_LIT_CI || op === OP_LIT_TRACK || op === OP_LIT_CI_TRACK || op === OP_RX || op === OP_RX_TRACK) return child;
|
|
8258
|
+
const rr = this.refResolver();
|
|
8259
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
8260
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
8261
|
+
if (cls < 0) return child;
|
|
8262
|
+
const e = deriveExpected(p);
|
|
8263
|
+
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
8264
|
+
}
|
|
7849
8265
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
7850
8266
|
charClass(fs) {
|
|
7851
8267
|
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
@@ -7857,12 +8273,19 @@ var Encoder = class {
|
|
|
7857
8273
|
this.ccIndex.set(spec, i);
|
|
7858
8274
|
return i;
|
|
7859
8275
|
}
|
|
7860
|
-
/**
|
|
7861
|
-
*
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
8276
|
+
/**
|
|
8277
|
+
* The first set a node's or an attempt's fail-fast gate tests. A bare
|
|
8278
|
+
* cross-rule ref resolves through `winners` (a compose OVERRIDE may widen
|
|
8279
|
+
* it). Any other body keeps its construction-time `_meta.firstSet`, except
|
|
8280
|
+
* where that is `any`: under `compose()` a body that reaches a rule of
|
|
8281
|
+
* another piece is built before that rule exists, so its cached set is
|
|
8282
|
+
* `any` and the node got NO gate (jess's `CompoundSelector` was entered at
|
|
8283
|
+
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
8284
|
+
* over the final merged map.
|
|
8285
|
+
*/
|
|
8286
|
+
gateFirstSet(p) {
|
|
8287
|
+
const cached = p._meta.firstSet;
|
|
8288
|
+
return p._def.tag === "lazy" || cached.kind === "any" ? firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : cached;
|
|
7866
8289
|
}
|
|
7867
8290
|
/**
|
|
7868
8291
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -7990,6 +8413,50 @@ var Encoder = class {
|
|
|
7990
8413
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
7991
8414
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
7992
8415
|
}
|
|
8416
|
+
/**
|
|
8417
|
+
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
8418
|
+
* `undefined`. Through `node()`/scope wrappers and first sequence terms, the
|
|
8419
|
+
* arm's next term after the routed token is found; the gate is that term's
|
|
8420
|
+
* first characters, with the trivia in force at the boundary before it, so
|
|
8421
|
+
* the arm is entered only where it can get past the token. The term must be
|
|
8422
|
+
* unable to match empty or to commit, so a miss is exactly that term failing
|
|
8423
|
+
* at the token's end with its own set.
|
|
8424
|
+
*/
|
|
8425
|
+
routedArmGate(arm) {
|
|
8426
|
+
const walk = (p, trivia2, depth) => {
|
|
8427
|
+
if (depth > 16) return void 0;
|
|
8428
|
+
const d = p._def;
|
|
8429
|
+
switch (d.tag) {
|
|
8430
|
+
case "routed":
|
|
8431
|
+
return "end";
|
|
8432
|
+
case "node":
|
|
8433
|
+
return walk(d.parser, trivia2, depth + 1);
|
|
8434
|
+
case "grammar":
|
|
8435
|
+
return walk(d.parser, d.clearTrivia === true ? void 0 : d.triviaParser ?? trivia2, depth + 1);
|
|
8436
|
+
case "sequence": {
|
|
8437
|
+
const head = d.parsers[0];
|
|
8438
|
+
if (head === void 0) return void 0;
|
|
8439
|
+
const r = walk(head, trivia2, depth + 1);
|
|
8440
|
+
if (r !== "end") return r;
|
|
8441
|
+
const next2 = d.parsers[1];
|
|
8442
|
+
return next2 === void 0 ? "end" : { next: next2, boundary: trivia2 };
|
|
8443
|
+
}
|
|
8444
|
+
default:
|
|
8445
|
+
return void 0;
|
|
8446
|
+
}
|
|
8447
|
+
};
|
|
8448
|
+
const follow = walk(arm, this.activeTrivia, 0);
|
|
8449
|
+
if (follow === void 0 || follow === "end") return void 0;
|
|
8450
|
+
const rr = this.refResolver();
|
|
8451
|
+
const { next, boundary } = follow;
|
|
8452
|
+
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
8453
|
+
const nextTag = next._def.tag;
|
|
8454
|
+
if (nextTag !== "literal" && nextTag !== "regex" && nextTag !== "keywords" && nextTag !== "label") return void 0;
|
|
8455
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary);
|
|
8456
|
+
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
8457
|
+
if (cls < 0) return void 0;
|
|
8458
|
+
return { cls, fx: this.expected(deriveExpected(next)) };
|
|
8459
|
+
}
|
|
7993
8460
|
node(p) {
|
|
7994
8461
|
const lazyRef = p._def.tag === "lazy";
|
|
7995
8462
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -8114,6 +8581,10 @@ var Encoder = class {
|
|
|
8114
8581
|
return head;
|
|
8115
8582
|
}
|
|
8116
8583
|
case "choice": {
|
|
8584
|
+
if (this.plan === void 0) {
|
|
8585
|
+
const factored = factorSharedEnds(d);
|
|
8586
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
8587
|
+
}
|
|
8117
8588
|
if (d.strategy.tag === "greedyClassify") {
|
|
8118
8589
|
const superIndex = d.strategy.superIndex;
|
|
8119
8590
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -8137,9 +8608,12 @@ var Encoder = class {
|
|
|
8137
8608
|
const kids = arms.map((c, k) => {
|
|
8138
8609
|
const src = order[k];
|
|
8139
8610
|
const checks = d.autoNot[src];
|
|
8140
|
-
const inner = this.node(c).ip;
|
|
8141
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
8142
8611
|
const gate2 = d.gates[src];
|
|
8612
|
+
const plain = (checks === null || checks === void 0 || checks.length === 0) && (gate2 === null || gate2 === void 0);
|
|
8613
|
+
const routedGate = plain ? this.routedArmGate(c) : void 0;
|
|
8614
|
+
const body = this.node(c).ip;
|
|
8615
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
8616
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
8143
8617
|
const gated = gate2 === null || gate2 === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate2, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
8144
8618
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
8145
8619
|
});
|
|
@@ -8167,6 +8641,12 @@ var Encoder = class {
|
|
|
8167
8641
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
8168
8642
|
}
|
|
8169
8643
|
}
|
|
8644
|
+
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
8645
|
+
for (let k = 0; k < classes.length; k++) {
|
|
8646
|
+
const gate2 = d.gates[order[k]];
|
|
8647
|
+
if (gate2 !== null && gate2 !== void 0) classes[k] = -1;
|
|
8648
|
+
}
|
|
8649
|
+
}
|
|
8170
8650
|
const dispIdx = this.disp.length;
|
|
8171
8651
|
this.disp.push(classes);
|
|
8172
8652
|
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
@@ -8196,7 +8676,7 @@ var Encoder = class {
|
|
|
8196
8676
|
case "oneOrMore": {
|
|
8197
8677
|
const child = this.node(d.parser).ip;
|
|
8198
8678
|
const rr = this.refResolver();
|
|
8199
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.
|
|
8679
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
8200
8680
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
8201
8681
|
const min = d.tag === "many" ? 0 : d.min;
|
|
8202
8682
|
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
|
|
@@ -8220,7 +8700,7 @@ var Encoder = class {
|
|
|
8220
8700
|
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);
|
|
8221
8701
|
}
|
|
8222
8702
|
case "optional": {
|
|
8223
|
-
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
8703
|
+
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
8224
8704
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
8225
8705
|
return head;
|
|
8226
8706
|
}
|
|
@@ -8268,8 +8748,8 @@ var Encoder = class {
|
|
|
8268
8748
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
8269
8749
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
8270
8750
|
);
|
|
8271
|
-
if (matchesEmpty(d.parser)) return body;
|
|
8272
|
-
const fs =
|
|
8751
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
8752
|
+
const fs = this.gateFirstSet(d.parser);
|
|
8273
8753
|
if (fs.kind === "any") return body;
|
|
8274
8754
|
const cls = this.charClass(fs);
|
|
8275
8755
|
if (cls < 0) return body;
|
|
@@ -8361,7 +8841,7 @@ var Encoder = class {
|
|
|
8361
8841
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
8362
8842
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
8363
8843
|
case "not":
|
|
8364
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
8844
|
+
return this.emit(OP_NOT, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
8365
8845
|
case "guard":
|
|
8366
8846
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
8367
8847
|
case "adjacency":
|
|
@@ -8382,14 +8862,14 @@ var Encoder = class {
|
|
|
8382
8862
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
8383
8863
|
}
|
|
8384
8864
|
case "peek":
|
|
8385
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
8865
|
+
return this.emit(OP_PEEK, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
8386
8866
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
8387
8867
|
// lowering was correct only for a choice arm.
|
|
8388
8868
|
case "attempt": {
|
|
8389
8869
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
8390
8870
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
8391
|
-
const fs =
|
|
8392
|
-
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8871
|
+
const fs = this.gateFirstSet(d.parser);
|
|
8872
|
+
if (fs.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
8393
8873
|
const cls = this.charClass(fs);
|
|
8394
8874
|
if (cls < 0) return inner;
|
|
8395
8875
|
const e = deriveExpected(d.parser);
|
|
@@ -8457,6 +8937,7 @@ var Encoder = class {
|
|
|
8457
8937
|
const slots = (ip) => {
|
|
8458
8938
|
switch (this.code[ip]) {
|
|
8459
8939
|
case OP_GATE:
|
|
8940
|
+
case OP_RGATE:
|
|
8460
8941
|
return [ip + 2];
|
|
8461
8942
|
case OP_RULE:
|
|
8462
8943
|
case OP_OPT:
|
|
@@ -9687,6 +10168,7 @@ function childSlots(code, ip, out) {
|
|
|
9687
10168
|
case OP_LEAF:
|
|
9688
10169
|
case OP_SOURCE_LEAF:
|
|
9689
10170
|
case OP_ARMGATE:
|
|
10171
|
+
case OP_RGATE:
|
|
9690
10172
|
out.push(code[ip + 2]);
|
|
9691
10173
|
return true;
|
|
9692
10174
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -9770,6 +10252,42 @@ function reachableSites(code, roots) {
|
|
|
9770
10252
|
}
|
|
9771
10253
|
return seen;
|
|
9772
10254
|
}
|
|
10255
|
+
function passCollapse(code, ip, hostCst) {
|
|
10256
|
+
const flags = code[ip + 3];
|
|
10257
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
10258
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
10259
|
+
let at = code[ip + 2];
|
|
10260
|
+
for (let n = 0; n < 8; n++) {
|
|
10261
|
+
const op = code[at];
|
|
10262
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
10263
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
10264
|
+
else break;
|
|
10265
|
+
}
|
|
10266
|
+
return code[at] === OP_NODE;
|
|
10267
|
+
}
|
|
10268
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
10269
|
+
const flags = code[ip + 3];
|
|
10270
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
10271
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
10272
|
+
const seq = code[ip + 2];
|
|
10273
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
10274
|
+
const n = code[seq + 1];
|
|
10275
|
+
if (n < 2) return void 0;
|
|
10276
|
+
const leads = [];
|
|
10277
|
+
const lits = [];
|
|
10278
|
+
for (let i = 0; i < n - 1; i++) {
|
|
10279
|
+
const t = code[seq + 2 + i];
|
|
10280
|
+
if (code[t] !== OP_OPT && code[t] !== OP_NOT) return void 0;
|
|
10281
|
+
const g = code[t + 1];
|
|
10282
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
10283
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
10284
|
+
else return void 0;
|
|
10285
|
+
}
|
|
10286
|
+
const last = code[seq + 2 + n - 1];
|
|
10287
|
+
let at = last;
|
|
10288
|
+
for (let k = 0; k < 8 && (code[at] === OP_GATE || code[at] === OP_RULE); k++) at = code[at] === OP_RULE ? code[at + 1] : code[at + 2];
|
|
10289
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
10290
|
+
}
|
|
9773
10291
|
function transfer(code, ip, at, hostCst) {
|
|
9774
10292
|
const op = code[ip];
|
|
9775
10293
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -9781,14 +10299,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
9781
10299
|
}
|
|
9782
10300
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
9783
10301
|
const flags = code[ip + 3];
|
|
10302
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
10303
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
9784
10304
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
9785
10305
|
if (directChildren) {
|
|
9786
|
-
|
|
10306
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
10307
|
+
return gated ? meet(at, framed2) : framed2;
|
|
9787
10308
|
}
|
|
9788
10309
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
9789
10310
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
9790
10311
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
9791
|
-
|
|
10312
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
10313
|
+
return gated ? meet(at, framed) : framed;
|
|
9792
10314
|
}
|
|
9793
10315
|
if (op === OP_TOKEN) {
|
|
9794
10316
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -9826,6 +10348,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
9826
10348
|
}
|
|
9827
10349
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
9828
10350
|
}
|
|
10351
|
+
function scopeIsIdentity(code, ip, at) {
|
|
10352
|
+
const op = code[ip];
|
|
10353
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
10354
|
+
const ki = code[ip + 1];
|
|
10355
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
10356
|
+
}
|
|
10357
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
10358
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10359
|
+
const stack = [ip];
|
|
10360
|
+
const kids = [];
|
|
10361
|
+
while (stack.length > 0) {
|
|
10362
|
+
const at = stack.pop();
|
|
10363
|
+
if (seen.has(at)) continue;
|
|
10364
|
+
seen.add(at);
|
|
10365
|
+
const l = labels.at(at);
|
|
10366
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
10367
|
+
const op = code[at];
|
|
10368
|
+
if (op === OP_SCAN) return true;
|
|
10369
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
10370
|
+
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE) && !(code[at + 1] >= 0 && l.tri === code[at + 1] && (op === OP_SCOPE_PLAIN || code[at + 3] === 0))) continue;
|
|
10371
|
+
kids.length = 0;
|
|
10372
|
+
if (!childSlots(code, at, kids)) return true;
|
|
10373
|
+
for (const c of kids) stack.push(c);
|
|
10374
|
+
}
|
|
10375
|
+
return false;
|
|
10376
|
+
}
|
|
10377
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
10378
|
+
if (tri === TRI_NONE) return [];
|
|
10379
|
+
if (tri < 0) return void 0;
|
|
10380
|
+
const fs = trivia2[tri]?._meta.firstSet;
|
|
10381
|
+
if (fs === void 0) return void 0;
|
|
10382
|
+
if (fs.kind === "empty") return [];
|
|
10383
|
+
return fs.kind === "ranges" && fs.ranges !== void 0 ? fs.ranges : void 0;
|
|
10384
|
+
}
|
|
9829
10385
|
|
|
9830
10386
|
// src/table/scalar-terminal.ts
|
|
9831
10387
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -9863,6 +10419,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
9863
10419
|
const op = code[child];
|
|
9864
10420
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
9865
10421
|
}
|
|
10422
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
10423
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
10424
|
+
const child = code[ip + 1];
|
|
10425
|
+
const op = code[child];
|
|
10426
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
10427
|
+
}
|
|
9866
10428
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
9867
10429
|
const seen = /* @__PURE__ */ new Set();
|
|
9868
10430
|
let at = ip;
|
|
@@ -10040,6 +10602,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
10040
10602
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
10041
10603
|
}
|
|
10042
10604
|
|
|
10605
|
+
// src/table/hold-gap.ts
|
|
10606
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
10607
|
+
OP_NODE,
|
|
10608
|
+
OP_XFORM,
|
|
10609
|
+
OP_LEAF,
|
|
10610
|
+
OP_SOURCE_LEAF,
|
|
10611
|
+
OP_TOKEN,
|
|
10612
|
+
OP_SCOPE,
|
|
10613
|
+
OP_SCOPE_CAP,
|
|
10614
|
+
OP_SCOPE_PLAIN,
|
|
10615
|
+
OP_FIELD,
|
|
10616
|
+
OP_LABEL,
|
|
10617
|
+
OP_EXPECT,
|
|
10618
|
+
OP_WITHCTX,
|
|
10619
|
+
OP_RULE,
|
|
10620
|
+
OP_ATTEMPT,
|
|
10621
|
+
OP_COV
|
|
10622
|
+
]);
|
|
10623
|
+
function rowNullable(code, k, ip, memo) {
|
|
10624
|
+
const hit = memo.get(ip);
|
|
10625
|
+
if (hit !== void 0) return hit;
|
|
10626
|
+
memo.set(ip, true);
|
|
10627
|
+
const op = code[ip];
|
|
10628
|
+
const kids = [];
|
|
10629
|
+
let out = true;
|
|
10630
|
+
if (op === OP_GATE) out = false;
|
|
10631
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
10632
|
+
else if (op === OP_RX) {
|
|
10633
|
+
const re = k[code[ip + 1]];
|
|
10634
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
10635
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
10636
|
+
childSlots(code, ip, kids);
|
|
10637
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
10638
|
+
} else if (op === OP_CHOICE) {
|
|
10639
|
+
childSlots(code, ip, kids);
|
|
10640
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
10641
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
10642
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
10643
|
+
} else if (WRAPPERS.has(op)) {
|
|
10644
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
10645
|
+
}
|
|
10646
|
+
memo.set(ip, out);
|
|
10647
|
+
return out;
|
|
10648
|
+
}
|
|
10649
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
10650
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
10651
|
+
const term = code[base + i];
|
|
10652
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
10653
|
+
const next = code[base + i + 1];
|
|
10654
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
10655
|
+
return !rowNullable(code, k, next, memo);
|
|
10656
|
+
}
|
|
10657
|
+
|
|
10043
10658
|
// src/table/emit-assembly.ts
|
|
10044
10659
|
var Unemittable = class extends Error {
|
|
10045
10660
|
construct;
|
|
@@ -10117,7 +10732,13 @@ var EMITTED_PARAMS = [
|
|
|
10117
10732
|
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
10118
10733
|
// old factories ignore them.
|
|
10119
10734
|
"LEAD",
|
|
10120
|
-
"triviaFieldCapture"
|
|
10735
|
+
"triviaFieldCapture",
|
|
10736
|
+
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
10737
|
+
// factories ignore it.
|
|
10738
|
+
"skipDeferredTrivia",
|
|
10739
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
10740
|
+
// ignore it.
|
|
10741
|
+
"collapseEmpty"
|
|
10121
10742
|
];
|
|
10122
10743
|
var RUNTIME_PRELUDE = `
|
|
10123
10744
|
let _pfScan=null
|
|
@@ -10138,7 +10759,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
10138
10759
|
const s=_pfScan
|
|
10139
10760
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
10140
10761
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
10141
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
10762
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
10142
10763
|
return advanceTrivia(input,cur,ctx)
|
|
10143
10764
|
}
|
|
10144
10765
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -10314,6 +10935,24 @@ ${fast}
|
|
|
10314
10935
|
${scanned}
|
|
10315
10936
|
}`;
|
|
10316
10937
|
}
|
|
10938
|
+
function emitHoldTerm(callee, dst, t, l, skip) {
|
|
10939
|
+
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
10940
|
+
if(${t}v===FAIL)return FAIL
|
|
10941
|
+
${dst}=${t}v
|
|
10942
|
+
cur=EC.e`;
|
|
10943
|
+
if (l.tri === TRI_NONE) return fast;
|
|
10944
|
+
const held = `const ${t}s=${skip}(input,cur,ctx)
|
|
10945
|
+
const ${t}v=${callee}(input,${t}s,ctx)
|
|
10946
|
+
if(${t}v===FAIL)return FAIL
|
|
10947
|
+
${dst}=${t}v
|
|
10948
|
+
cur=${t}s`;
|
|
10949
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
10950
|
+
return `if(ctx.trivia===undefined){
|
|
10951
|
+
${fast}
|
|
10952
|
+
}else{
|
|
10953
|
+
${held}
|
|
10954
|
+
}`;
|
|
10955
|
+
}
|
|
10317
10956
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
10318
10957
|
if (hasTrivia === "false") return "{}";
|
|
10319
10958
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -10345,7 +10984,7 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
10345
10984
|
})
|
|
10346
10985
|
};
|
|
10347
10986
|
}
|
|
10348
|
-
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
10987
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
10349
10988
|
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
10350
10989
|
const swapLegal = !cfg.trackLines;
|
|
10351
10990
|
const hostCst = cfg.hostCst;
|
|
@@ -10355,6 +10994,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
10355
10994
|
const reachable = [...reachableSites(code, roots)];
|
|
10356
10995
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
10357
10996
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
10997
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
10358
10998
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
10359
10999
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
10360
11000
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -10444,6 +11084,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
10444
11084
|
};
|
|
10445
11085
|
const bodies = [];
|
|
10446
11086
|
const byIp = /* @__PURE__ */ new Map();
|
|
11087
|
+
const externals = [];
|
|
11088
|
+
const siteBytes = /* @__PURE__ */ new Map();
|
|
10447
11089
|
const reached = /* @__PURE__ */ new Set();
|
|
10448
11090
|
const prelude = [];
|
|
10449
11091
|
const skipDefs = [];
|
|
@@ -10579,6 +11221,18 @@ return 1
|
|
|
10579
11221
|
tokenDecisionRefs.set(dispatchIp, made);
|
|
10580
11222
|
return made;
|
|
10581
11223
|
}
|
|
11224
|
+
function gateMissTest(gip) {
|
|
11225
|
+
const resolved = t.cc[code[gip + 1]];
|
|
11226
|
+
const ci = classes.push([resolved]) - 1;
|
|
11227
|
+
classPlan.push([code[gip + 1]]);
|
|
11228
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
11229
|
+
return isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`;
|
|
11230
|
+
}
|
|
11231
|
+
function lookaheadMiss(child, miss) {
|
|
11232
|
+
if (code[child] !== OP_GATE || cfg.tolerant || cfg.probe) return "";
|
|
11233
|
+
return `if(${gateMissTest(child)}){${miss}}
|
|
11234
|
+
`;
|
|
11235
|
+
}
|
|
10582
11236
|
function skipFor(l) {
|
|
10583
11237
|
if (l.tri < 0) return "_skipTrivia";
|
|
10584
11238
|
const ki = l.tri;
|
|
@@ -10589,8 +11243,8 @@ return 1
|
|
|
10589
11243
|
const nm = `_sk${skipPool.size}`;
|
|
10590
11244
|
skipPool.set(key, nm);
|
|
10591
11245
|
if (!hasScan) {
|
|
10592
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return
|
|
10593
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
11246
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
11247
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
10594
11248
|
return advanceTrivia(input,cur,ctx)}`);
|
|
10595
11249
|
return nm;
|
|
10596
11250
|
}
|
|
@@ -10635,9 +11289,17 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10635
11289
|
const target = resolveAlias(ip);
|
|
10636
11290
|
const done = byIp.get(target);
|
|
10637
11291
|
if (done !== void 0) return done;
|
|
11292
|
+
if (select !== void 0 && !select.has(target)) {
|
|
11293
|
+
const ext = `_px${target}`;
|
|
11294
|
+
byIp.set(target, ext);
|
|
11295
|
+
externals.push(target);
|
|
11296
|
+
return ext;
|
|
11297
|
+
}
|
|
10638
11298
|
const fname = `_pf${target}`;
|
|
10639
11299
|
byIp.set(target, fname);
|
|
10640
|
-
|
|
11300
|
+
const body = lower(target, fname);
|
|
11301
|
+
siteBytes.set(target, body.length);
|
|
11302
|
+
bodies.push(body);
|
|
10641
11303
|
return fname;
|
|
10642
11304
|
}
|
|
10643
11305
|
function resolveAlias(ip) {
|
|
@@ -10657,9 +11319,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10657
11319
|
const op = code[ip];
|
|
10658
11320
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
10659
11321
|
if (op === OP_RULE) return code[ip + 1];
|
|
10660
|
-
if ((
|
|
10661
|
-
return code[ip + 2];
|
|
10662
|
-
}
|
|
11322
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
10663
11323
|
return void 0;
|
|
10664
11324
|
}
|
|
10665
11325
|
function lower(ip, fname) {
|
|
@@ -10777,14 +11437,44 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10777
11437
|
return `${head}EC.e=pos;return ''}`;
|
|
10778
11438
|
case OP_GATE: {
|
|
10779
11439
|
const child = link(code[ip + 2]);
|
|
11440
|
+
const xf = fxRef(code[ip + 3]);
|
|
11441
|
+
return `${head}
|
|
11442
|
+
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11443
|
+
return ${child}(input,pos,ctx)
|
|
11444
|
+
}`;
|
|
11445
|
+
}
|
|
11446
|
+
case OP_RGATE: {
|
|
11447
|
+
const child = link(code[ip + 2]);
|
|
11448
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
11449
|
+
return ${child}(input,pos,ctx)
|
|
11450
|
+
}`;
|
|
10780
11451
|
const resolved = t.cc[code[ip + 1]];
|
|
10781
11452
|
const ci = classes.push([resolved]) - 1;
|
|
10782
11453
|
classPlan.push([code[ip + 1]]);
|
|
10783
11454
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10784
11455
|
const xf = fxRef(code[ip + 3]);
|
|
10785
11456
|
return `${head}
|
|
10786
|
-
|
|
11457
|
+
const it=ctx._routed
|
|
11458
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
11459
|
+
return ${child}(input,pos,ctx)
|
|
11460
|
+
}`;
|
|
11461
|
+
}
|
|
11462
|
+
case OP_ARMGATE: {
|
|
11463
|
+
const pred = fnRef(code[ip + 1]);
|
|
11464
|
+
const child = link(code[ip + 2]);
|
|
11465
|
+
const xf = fxRef(code[ip + 3]);
|
|
11466
|
+
return `${head}
|
|
11467
|
+
if(!${pred}(ctx.state)){ctx._fc=false;ctx._fe=-1;ctx._fx=${xf};return FAIL}
|
|
10787
11468
|
return ${child}(input,pos,ctx)
|
|
11469
|
+
}`;
|
|
11470
|
+
}
|
|
11471
|
+
case OP_WITHCTX: {
|
|
11472
|
+
const ki = code[ip + 1];
|
|
11473
|
+
const child = link(code[ip + 2]);
|
|
11474
|
+
return `${head}
|
|
11475
|
+
const saved=ctx.state
|
|
11476
|
+
ctx.state=${ki < 0 ? `${fnRef(~ki)}(saved)` : kRef(ki)}
|
|
11477
|
+
try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
|
|
10788
11478
|
}`;
|
|
10789
11479
|
}
|
|
10790
11480
|
case OP_XFORM: {
|
|
@@ -11040,24 +11730,34 @@ return FAIL
|
|
|
11040
11730
|
const xf = fxRef(code[ip + 2]);
|
|
11041
11731
|
const p = tmp();
|
|
11042
11732
|
return `${head}
|
|
11043
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
11044
|
-
const v=${child}(input,pos,ctx)
|
|
11733
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11734
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
11045
11735
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
11046
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
11736
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
11047
11737
|
ctx._fe=pos
|
|
11048
11738
|
ctx._fx=${xf}
|
|
11049
11739
|
return FAIL
|
|
11050
11740
|
}`;
|
|
11051
11741
|
}
|
|
11052
11742
|
case OP_PEEK: {
|
|
11743
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
11744
|
+
if (scalarChild >= 0) {
|
|
11745
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
11746
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
11747
|
+
return `${head}
|
|
11748
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
11749
|
+
EC.e=pos
|
|
11750
|
+
return null
|
|
11751
|
+
}`;
|
|
11752
|
+
}
|
|
11053
11753
|
const child = link(code[ip + 1]);
|
|
11054
11754
|
const xf = fxRef(code[ip + 2]);
|
|
11055
11755
|
const p = tmp();
|
|
11056
11756
|
return `${head}
|
|
11057
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
11058
|
-
const v=${child}(input,pos,ctx)
|
|
11757
|
+
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11758
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
11059
11759
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
11060
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11760
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11061
11761
|
EC.e=pos
|
|
11062
11762
|
return null
|
|
11063
11763
|
}`;
|
|
@@ -11067,7 +11767,7 @@ return null
|
|
|
11067
11767
|
const clean = !REC2 && failureRollbackClean(prog, ip);
|
|
11068
11768
|
const p = tmp();
|
|
11069
11769
|
return `${head}
|
|
11070
|
-
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
11770
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
11071
11771
|
ctx._fc=false
|
|
11072
11772
|
const v=${child}(input,pos,ctx)
|
|
11073
11773
|
if(v===FAIL){
|
|
@@ -11128,7 +11828,7 @@ return v
|
|
|
11128
11828
|
);
|
|
11129
11829
|
} else {
|
|
11130
11830
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
11131
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11831
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11132
11832
|
}
|
|
11133
11833
|
names.push(vn);
|
|
11134
11834
|
}
|
|
@@ -11148,7 +11848,7 @@ return v
|
|
|
11148
11848
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
11149
11849
|
const hiArr = table.hi;
|
|
11150
11850
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
11151
|
-
const directAscii =
|
|
11851
|
+
const directAscii = table.hi.length === 0;
|
|
11152
11852
|
return `${head}
|
|
11153
11853
|
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
11154
11854
|
let arm=-1
|
|
@@ -11175,7 +11875,7 @@ return FAIL
|
|
|
11175
11875
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
11176
11876
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
11177
11877
|
const maskable = n <= 32;
|
|
11178
|
-
const directAsciiMask =
|
|
11878
|
+
const directAsciiMask = maskable && gates.every(isAsciiOnlyClass);
|
|
11179
11879
|
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
11180
11880
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
11181
11881
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
@@ -11217,7 +11917,7 @@ return FAIL
|
|
|
11217
11917
|
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
11218
11918
|
const deepAt = Array.from({ length: n }, () => tmp());
|
|
11219
11919
|
const deepFx = Array.from({ length: n }, () => tmp());
|
|
11220
|
-
const
|
|
11920
|
+
const remember2 = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
11221
11921
|
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
11222
11922
|
const pretest = pretests[i];
|
|
11223
11923
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
@@ -11229,13 +11929,13 @@ return FAIL
|
|
|
11229
11929
|
if(${decision}===0){
|
|
11230
11930
|
ctx._fc=false
|
|
11231
11931
|
{const at=_pfTokEnd
|
|
11232
|
-
${
|
|
11932
|
+
${remember2(i, "at", pretest.token.expected)}}
|
|
11233
11933
|
}`;
|
|
11234
11934
|
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
11235
11935
|
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
11236
11936
|
ctx._fc=false
|
|
11237
11937
|
{const at=_pfSeqEnd
|
|
11238
|
-
${
|
|
11938
|
+
${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
11239
11939
|
}`;
|
|
11240
11940
|
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
11241
11941
|
`}if(${gate2}){
|
|
@@ -11243,7 +11943,7 @@ ctx._fc=false
|
|
|
11243
11943
|
{const v=${arm}(input,pos,ctx)
|
|
11244
11944
|
if(v!==FAIL)return v}
|
|
11245
11945
|
{const at=ctx._fe??pos
|
|
11246
|
-
${
|
|
11946
|
+
${remember2(i, "at", "ctx._fx")}}
|
|
11247
11947
|
${rollbackFor(i)}
|
|
11248
11948
|
}${routeMiss}${sequenceMiss}`;
|
|
11249
11949
|
}).join("\n");
|
|
@@ -11356,7 +12056,7 @@ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
|
11356
12056
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
11357
12057
|
${startFailureExact ? "" : "let prev=0"}
|
|
11358
12058
|
${maskArms}
|
|
11359
|
-
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
12059
|
+
${startFailureExact ? "" : `if(best===pos&&prev!==0)acc=${catchName}(${n},prev,acc)`}
|
|
11360
12060
|
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
11361
12061
|
return FAIL
|
|
11362
12062
|
}
|
|
@@ -11455,7 +12155,7 @@ return [key,v]
|
|
|
11455
12155
|
const ci = classes.push([resolved]) - 1;
|
|
11456
12156
|
classPlan.push([itemClassIndex]);
|
|
11457
12157
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
11458
|
-
itemAscii =
|
|
12158
|
+
itemAscii = isAsciiOnlyClass(resolved);
|
|
11459
12159
|
}
|
|
11460
12160
|
}
|
|
11461
12161
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
@@ -11611,6 +12311,26 @@ return nd
|
|
|
11611
12311
|
const trailingTrivia = (flags & 128) !== 0;
|
|
11612
12312
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
11613
12313
|
const leanFlags = flags & ~128;
|
|
12314
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
12315
|
+
return `${head}
|
|
12316
|
+
const v=${child}(input,pos,ctx)
|
|
12317
|
+
if(v!==undefined)return v
|
|
12318
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
12319
|
+
}`;
|
|
12320
|
+
}
|
|
12321
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
12322
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t.trivia);
|
|
12323
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
12324
|
+
if(!(${[
|
|
12325
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
12326
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
12327
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
12328
|
+
].join("||") || "false"})){
|
|
12329
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
12330
|
+
if(gv!==undefined)return gv
|
|
12331
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
12332
|
+
}
|
|
12333
|
+
` : "";
|
|
11614
12334
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
11615
12335
|
const fields = flags === 18;
|
|
11616
12336
|
const collapseChildren = flags === 34;
|
|
@@ -11645,7 +12365,7 @@ sCh.push(nd)
|
|
|
11645
12365
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
11646
12366
|
}`;
|
|
11647
12367
|
return `${head}
|
|
11648
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
12368
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11649
12369
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
11650
12370
|
const flat=[]
|
|
11651
12371
|
ctx._cstBuf=undefined
|
|
@@ -11681,7 +12401,7 @@ return nd
|
|
|
11681
12401
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
11682
12402
|
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
11683
12403
|
const ty = q(type);
|
|
11684
|
-
const stArg =
|
|
12404
|
+
const stArg = "ctx.state";
|
|
11685
12405
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
11686
12406
|
let value;
|
|
11687
12407
|
if (proj >= 0) {
|
|
@@ -11720,7 +12440,7 @@ const hostKids=kids
|
|
|
11720
12440
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
11721
12441
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
11722
12442
|
return `${head}
|
|
11723
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
12443
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11724
12444
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
11725
12445
|
${openCapture}
|
|
11726
12446
|
ctx.captureTrivia=${captureWide}
|
|
@@ -11742,7 +12462,7 @@ ctx.captureTrivia=sCap
|
|
|
11742
12462
|
if(v===FAIL)return FAIL
|
|
11743
12463
|
const end=EC.e
|
|
11744
12464
|
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
11745
|
-
const st=${readsState ? "
|
|
12465
|
+
const st=${readsState ? "ctx.state" : "undefined"}
|
|
11746
12466
|
let nd
|
|
11747
12467
|
${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]
|
|
11748
12468
|
else ` : ""}{${value}}
|
|
@@ -11755,21 +12475,57 @@ return nd
|
|
|
11755
12475
|
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
11756
12476
|
}
|
|
11757
12477
|
}
|
|
12478
|
+
const served = (ip) => select === void 0 || select.has(resolveAlias(ip));
|
|
11758
12479
|
const ruleEntries = [];
|
|
11759
12480
|
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
12481
|
+
if (!served(entryIp)) continue;
|
|
11760
12482
|
const target = link(entryIp);
|
|
11761
12483
|
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
11762
12484
|
bodies.push(`const ${rn}=${target}`);
|
|
11763
12485
|
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
11764
12486
|
}
|
|
11765
12487
|
const extra = [];
|
|
11766
|
-
|
|
12488
|
+
const exported = /* @__PURE__ */ new Set();
|
|
12489
|
+
for (const ip of extraIps) {
|
|
12490
|
+
if (!served(ip)) continue;
|
|
12491
|
+
exported.add(ip);
|
|
12492
|
+
extra.push(`${ip}:${link(ip)}`);
|
|
12493
|
+
}
|
|
12494
|
+
if (select !== void 0) {
|
|
12495
|
+
const kids = [];
|
|
12496
|
+
for (const ip of reachable) {
|
|
12497
|
+
if (select.has(resolveAlias(ip))) continue;
|
|
12498
|
+
kids.length = 0;
|
|
12499
|
+
childSlots(code, ip, kids);
|
|
12500
|
+
for (const kid of kids) {
|
|
12501
|
+
const target = resolveAlias(kid);
|
|
12502
|
+
if (!select.has(target) || exported.has(target)) continue;
|
|
12503
|
+
exported.add(target);
|
|
12504
|
+
extra.push(`${target}:${link(target)}`);
|
|
12505
|
+
}
|
|
12506
|
+
}
|
|
12507
|
+
}
|
|
12508
|
+
const hybrid = select === void 0 ? "" : `,
|
|
12509
|
+
ext:[${externals.join(",")}],
|
|
12510
|
+
bind:function(xs,ps){_xScan=xs
|
|
12511
|
+
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
12512
|
+
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
12513
|
+
const scannerFor = (ip) => {
|
|
12514
|
+
const ki = labels.at(ip).tri;
|
|
12515
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
12516
|
+
if (ki === TRI_NONE) return "null";
|
|
12517
|
+
return swapLegal && !triviaLabelled[ki] && t.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
12518
|
+
};
|
|
12519
|
+
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
12520
|
+
${externals.map((ip) => `let _xp${ip}
|
|
12521
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
12522
|
+
`;
|
|
11767
12523
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
11768
12524
|
${prelude.join("\n")}
|
|
11769
12525
|
${skipDefs.join("\n")}
|
|
11770
12526
|
${choiceDefs.join("\n")}
|
|
11771
12527
|
${bodies.join("\n")}
|
|
11772
|
-
function _begin(ctx){
|
|
12528
|
+
${externalDefs}function _begin(ctx){
|
|
11773
12529
|
const host=ctx.build
|
|
11774
12530
|
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
11775
12531
|
_pfDepth++
|
|
@@ -11796,7 +12552,7 @@ pieces:{${ruleEntries.join(",")}},
|
|
|
11796
12552
|
byIp:{${extra.join(",")}},
|
|
11797
12553
|
end:function(){return EC.e},
|
|
11798
12554
|
begin:_begin,
|
|
11799
|
-
finish:_finish
|
|
12555
|
+
finish:_finish${hybrid}
|
|
11800
12556
|
}`;
|
|
11801
12557
|
return {
|
|
11802
12558
|
source,
|
|
@@ -11804,6 +12560,7 @@ finish:_finish
|
|
|
11804
12560
|
masks,
|
|
11805
12561
|
classes,
|
|
11806
12562
|
armExpected,
|
|
12563
|
+
siteBytes,
|
|
11807
12564
|
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
11808
12565
|
};
|
|
11809
12566
|
}
|
|
@@ -12234,37 +12991,184 @@ function escapeClassChar(ch2) {
|
|
|
12234
12991
|
return ch2.replace(/[\\\]^-]/g, "\\$&");
|
|
12235
12992
|
}
|
|
12236
12993
|
|
|
12237
|
-
// src/table/
|
|
12238
|
-
function
|
|
12239
|
-
const
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12994
|
+
// src/table/trivia-gap.ts
|
|
12995
|
+
function skipDeferredTrivia(input, cur, ctx) {
|
|
12996
|
+
const triviaP = ctx.trivia;
|
|
12997
|
+
const plain = ctx.trackLines !== true && ctx.captureTrivia !== true;
|
|
12998
|
+
const gap = ctx._gap;
|
|
12999
|
+
if (plain && gap !== void 0 && cur === gap.at && input === gap.input && triviaP === gap.of && ctx._rootTriviaCapture === gap.root && ctx.state === gap.state && ctx._rootTriviaKindIndex === gap.rootKinds && ctx._triviaLog === gap.log) return gap.end;
|
|
13000
|
+
const end = clearRunEnd(input, cur, ctx, triviaP, plain);
|
|
13001
|
+
if (end >= 0) {
|
|
13002
|
+
remember(cur, end, ctx, input, triviaP);
|
|
13003
|
+
return end;
|
|
12245
13004
|
}
|
|
12246
|
-
|
|
13005
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
13006
|
+
if (typeof scan !== "number") return commitTriviaScan(scan);
|
|
13007
|
+
if (plain) remember(cur, scan, ctx, input, triviaP);
|
|
13008
|
+
return scan;
|
|
12247
13009
|
}
|
|
12248
|
-
function
|
|
12249
|
-
const
|
|
12250
|
-
|
|
13010
|
+
function clearRunEnd(input, cur, ctx, triviaP, plain) {
|
|
13011
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
13012
|
+
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
13013
|
+
if (!plain || triviaP === void 0 || spec == null || rootKinds === void 0 || ctx._triviaLog !== void 0) return -1;
|
|
13014
|
+
if (spec.rootKinds !== rootKinds) prime(spec, triviaP, rootKinds);
|
|
13015
|
+
const fast = spec.rootScan;
|
|
13016
|
+
if (fast === null) return -1;
|
|
13017
|
+
const end = fast(input, cur);
|
|
13018
|
+
return ctx._rootTriviaCapture === false || clearOf(spec.rootLeaders, input, cur, end) ? end : -1;
|
|
13019
|
+
}
|
|
13020
|
+
function remember(cur, end, ctx, input, triviaP) {
|
|
13021
|
+
const gap = ctx._gap;
|
|
13022
|
+
if (gap === void 0) {
|
|
13023
|
+
ctx._gap = { at: cur, end, input, of: triviaP, root: ctx._rootTriviaCapture, rootKinds: ctx._rootTriviaKindIndex, log: ctx._triviaLog, state: ctx.state };
|
|
13024
|
+
return;
|
|
13025
|
+
}
|
|
13026
|
+
gap.at = cur;
|
|
13027
|
+
gap.end = end;
|
|
13028
|
+
gap.input = input;
|
|
13029
|
+
gap.of = triviaP;
|
|
13030
|
+
gap.root = ctx._rootTriviaCapture;
|
|
13031
|
+
gap.rootKinds = ctx._rootTriviaKindIndex;
|
|
13032
|
+
gap.log = ctx._triviaLog;
|
|
13033
|
+
gap.state = ctx.state;
|
|
12251
13034
|
}
|
|
12252
|
-
function
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
13035
|
+
function prime(spec, triviaP, rootKinds) {
|
|
13036
|
+
const ranges = [];
|
|
13037
|
+
let bounded = true;
|
|
13038
|
+
for (const arm of spec.arms) {
|
|
13039
|
+
if (rootKinds[arm.label] === void 0) continue;
|
|
13040
|
+
const fs = arm.parser._meta.firstSet;
|
|
13041
|
+
if (fs.kind === "any") bounded = false;
|
|
13042
|
+
else if (fs.kind === "ranges") ranges.push(...fs.ranges);
|
|
13043
|
+
}
|
|
13044
|
+
const classified = triviaP._meta.triviaScanner;
|
|
13045
|
+
spec.rootKinds = rootKinds;
|
|
13046
|
+
spec.rootLeaders = ranges;
|
|
13047
|
+
spec.rootScan = !bounded ? null : classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
13048
|
+
}
|
|
13049
|
+
function clearOf(ranges, input, from, to) {
|
|
13050
|
+
for (let i = from; i < to; i++) {
|
|
13051
|
+
const c = input.charCodeAt(i);
|
|
13052
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
13053
|
+
for (const r of ranges) if (c >= r.lo && c <= r.hi) return false;
|
|
12256
13054
|
}
|
|
12257
|
-
return
|
|
12258
|
-
_tag: "leaf",
|
|
12259
|
-
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
12260
|
-
span: { start: s, end: e }
|
|
12261
|
-
};
|
|
13055
|
+
return true;
|
|
12262
13056
|
}
|
|
12263
|
-
|
|
12264
|
-
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
13057
|
+
|
|
13058
|
+
// src/table/fail-clean.ts
|
|
13059
|
+
function passChild(code, ip) {
|
|
13060
|
+
switch (code[ip]) {
|
|
13061
|
+
case OP_RULE:
|
|
13062
|
+
case OP_LABEL:
|
|
13063
|
+
case OP_COV:
|
|
13064
|
+
case OP_TOKEN:
|
|
13065
|
+
return code[ip + 1];
|
|
13066
|
+
case OP_GATE:
|
|
13067
|
+
case OP_NODE:
|
|
13068
|
+
case OP_NODE_TRACK:
|
|
13069
|
+
case OP_XFORM:
|
|
13070
|
+
case OP_FIELD:
|
|
13071
|
+
case OP_SCOPE:
|
|
13072
|
+
case OP_SCOPE_CAP:
|
|
13073
|
+
case OP_SCOPE_PLAIN:
|
|
13074
|
+
case OP_WITHCTX:
|
|
13075
|
+
case OP_LEAF:
|
|
13076
|
+
case OP_SOURCE_LEAF:
|
|
13077
|
+
return code[ip + 2];
|
|
13078
|
+
default:
|
|
13079
|
+
return -1;
|
|
13080
|
+
}
|
|
13081
|
+
}
|
|
13082
|
+
function seqCount(code, ip) {
|
|
13083
|
+
const op = code[ip];
|
|
13084
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
13085
|
+
}
|
|
13086
|
+
function failCleanAnalysis(code) {
|
|
13087
|
+
const cleanAt = new Uint8Array(code.length);
|
|
13088
|
+
const neverAt = new Uint8Array(code.length);
|
|
13089
|
+
const neverFails = (ip) => {
|
|
13090
|
+
const hit = neverAt[ip];
|
|
13091
|
+
if (hit !== 0) return hit === 1;
|
|
13092
|
+
neverAt[ip] = 3;
|
|
13093
|
+
let out = false;
|
|
13094
|
+
const op = code[ip];
|
|
13095
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
13096
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
13097
|
+
else {
|
|
13098
|
+
const at = seqCount(code, ip);
|
|
13099
|
+
if (at >= 0) {
|
|
13100
|
+
out = true;
|
|
13101
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
13102
|
+
} else if (op !== OP_GATE) {
|
|
13103
|
+
const c = passChild(code, ip);
|
|
13104
|
+
out = c >= 0 && neverFails(c);
|
|
13105
|
+
}
|
|
13106
|
+
}
|
|
13107
|
+
neverAt[ip] = out ? 1 : 2;
|
|
13108
|
+
return out;
|
|
13109
|
+
};
|
|
13110
|
+
const clean = (ip) => {
|
|
13111
|
+
const hit = cleanAt[ip];
|
|
13112
|
+
if (hit !== 0) return hit === 1;
|
|
13113
|
+
cleanAt[ip] = 3;
|
|
13114
|
+
let out = false;
|
|
13115
|
+
switch (code[ip]) {
|
|
13116
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
13117
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
13118
|
+
case OP_LIT:
|
|
13119
|
+
case OP_RX:
|
|
13120
|
+
case OP_LIT_TRACK:
|
|
13121
|
+
case OP_RX_TRACK:
|
|
13122
|
+
case OP_LIT_CI:
|
|
13123
|
+
case OP_LIT_CI_TRACK:
|
|
13124
|
+
case OP_GUARD:
|
|
13125
|
+
case OP_NOT:
|
|
13126
|
+
case OP_PEEK:
|
|
13127
|
+
case OP_ATTEMPT:
|
|
13128
|
+
case OP_EMPTY:
|
|
13129
|
+
case OP_OPT:
|
|
13130
|
+
case OP_EXPECT:
|
|
13131
|
+
out = true;
|
|
13132
|
+
break;
|
|
13133
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
13134
|
+
// restores the failed item itself.
|
|
13135
|
+
case OP_REP:
|
|
13136
|
+
case OP_REPV:
|
|
13137
|
+
out = code[ip + 2] <= 1;
|
|
13138
|
+
break;
|
|
13139
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
13140
|
+
// wrote, and after the trivia scanned in front of it.
|
|
13141
|
+
case OP_SEQ:
|
|
13142
|
+
case OP_SEQV:
|
|
13143
|
+
case OP_SEQX: {
|
|
13144
|
+
const at = seqCount(code, ip);
|
|
13145
|
+
const n = code[at];
|
|
13146
|
+
out = n > 0 && clean(code[at + 1]);
|
|
13147
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
13148
|
+
break;
|
|
13149
|
+
}
|
|
13150
|
+
case OP_CHOICE: {
|
|
13151
|
+
out = true;
|
|
13152
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
13153
|
+
break;
|
|
13154
|
+
}
|
|
13155
|
+
case OP_ROUTED:
|
|
13156
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
13157
|
+
break;
|
|
13158
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
13159
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
13160
|
+
case OP_DISPATCH:
|
|
13161
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
13162
|
+
break;
|
|
13163
|
+
default: {
|
|
13164
|
+
const c = passChild(code, ip);
|
|
13165
|
+
out = c >= 0 && clean(c);
|
|
13166
|
+
}
|
|
13167
|
+
}
|
|
13168
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
13169
|
+
return out;
|
|
13170
|
+
};
|
|
13171
|
+
return clean;
|
|
12268
13172
|
}
|
|
12269
13173
|
|
|
12270
13174
|
// src/cst/host-mode.ts
|
|
@@ -12429,6 +13333,7 @@ function assemble(t, prog, cfg) {
|
|
|
12429
13333
|
const swapLegal = !cfg.trackLines;
|
|
12430
13334
|
const hostCst = cfg.hostCst;
|
|
12431
13335
|
const REC2 = prog.rec === 1 && cfg.tolerant;
|
|
13336
|
+
const PROBE = cfg.probe;
|
|
12432
13337
|
const sentinels = /* @__PURE__ */ new Map();
|
|
12433
13338
|
function sentinelFor(cls) {
|
|
12434
13339
|
if (cls < 0) return void 0;
|
|
@@ -12443,6 +13348,9 @@ function assemble(t, prog, cfg) {
|
|
|
12443
13348
|
const EC = newEndCell();
|
|
12444
13349
|
const scalarRecognizers = [];
|
|
12445
13350
|
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
13351
|
+
function lookaheadClass(child) {
|
|
13352
|
+
return code[child] === OP_GATE && !cfg.tolerant && !cfg.probe ? cc[code[child + 1]] : null;
|
|
13353
|
+
}
|
|
12446
13354
|
function scalarFor(child) {
|
|
12447
13355
|
const spec = code[child + 1];
|
|
12448
13356
|
let recognize = scalarRecognizers[spec];
|
|
@@ -12452,17 +13360,27 @@ function assemble(t, prog, cfg) {
|
|
|
12452
13360
|
}
|
|
12453
13361
|
return recognize;
|
|
12454
13362
|
}
|
|
12455
|
-
const labelExtraIps =
|
|
12456
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) labelExtraIps.push(r[0]);
|
|
12457
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
13363
|
+
const labelExtraIps = assemblyExtraIps(prog);
|
|
12458
13364
|
const closureLabels = computeSiteLabels(
|
|
12459
13365
|
code,
|
|
12460
13366
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
12461
13367
|
hostCst
|
|
12462
13368
|
);
|
|
12463
13369
|
let SCAN = null;
|
|
13370
|
+
let HYBRID;
|
|
13371
|
+
function hybridPiece(piece) {
|
|
13372
|
+
const setScan = HYBRID.scan;
|
|
13373
|
+
return (input, pos, ctx) => {
|
|
13374
|
+
const saved = setScan(SCAN);
|
|
13375
|
+
const value = piece(input, pos, ctx);
|
|
13376
|
+
setScan(saved);
|
|
13377
|
+
return value;
|
|
13378
|
+
};
|
|
13379
|
+
}
|
|
12464
13380
|
const memo = /* @__PURE__ */ new Map();
|
|
12465
13381
|
const reached = /* @__PURE__ */ new Set();
|
|
13382
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
13383
|
+
const CLEAN = REC2 ? () => false : failCleanAnalysis(code);
|
|
12466
13384
|
function pushLeaf(ctx, value, s, e) {
|
|
12467
13385
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
12468
13386
|
pushCstLeaf(ctx, lf);
|
|
@@ -12661,6 +13579,22 @@ function assemble(t, prog, cfg) {
|
|
|
12661
13579
|
return node2;
|
|
12662
13580
|
};
|
|
12663
13581
|
}
|
|
13582
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
13583
|
+
return (input, pos, ctx) => {
|
|
13584
|
+
const v = child(input, pos, ctx);
|
|
13585
|
+
if (v !== void 0) return v;
|
|
13586
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13587
|
+
};
|
|
13588
|
+
}
|
|
13589
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
13590
|
+
return (input, pos, ctx) => {
|
|
13591
|
+
const c = lead(input, pos);
|
|
13592
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
13593
|
+
const v = last(input, pos, ctx);
|
|
13594
|
+
if (v !== void 0) return v;
|
|
13595
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13596
|
+
};
|
|
13597
|
+
}
|
|
12664
13598
|
function plainProjectNode(child, projection, type) {
|
|
12665
13599
|
return (input, pos, ctx) => {
|
|
12666
13600
|
const sCh = ctx._cstChildren;
|
|
@@ -12752,9 +13686,7 @@ function assemble(t, prog, cfg) {
|
|
|
12752
13686
|
return s(input, cur);
|
|
12753
13687
|
}
|
|
12754
13688
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
12755
|
-
if (needsDeferredTriviaCommit(ctx))
|
|
12756
|
-
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
12757
|
-
}
|
|
13689
|
+
if (needsDeferredTriviaCommit(ctx)) return skipDeferredTrivia(input, cur, ctx);
|
|
12758
13690
|
return advanceTrivia(input, cur, ctx);
|
|
12759
13691
|
}
|
|
12760
13692
|
let TERMV;
|
|
@@ -12924,7 +13856,7 @@ function assemble(t, prog, cfg) {
|
|
|
12924
13856
|
if (next !== void 0) {
|
|
12925
13857
|
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
12926
13858
|
}
|
|
12927
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13859
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12928
13860
|
ctx._fe = pos;
|
|
12929
13861
|
ctx._fx = acc ?? choiceFx;
|
|
12930
13862
|
return FAIL;
|
|
@@ -13007,7 +13939,7 @@ function assemble(t, prog, cfg) {
|
|
|
13007
13939
|
if (next !== void 0) {
|
|
13008
13940
|
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
13009
13941
|
}
|
|
13010
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13942
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
13011
13943
|
ctx._fe = pos;
|
|
13012
13944
|
ctx._fx = acc ?? choiceFx;
|
|
13013
13945
|
return FAIL;
|
|
@@ -13033,21 +13965,27 @@ function assemble(t, prog, cfg) {
|
|
|
13033
13965
|
}
|
|
13034
13966
|
function dispatchBranch(child, usesRouted) {
|
|
13035
13967
|
if (!usesRouted) {
|
|
13036
|
-
return (input, _pos, selEnd, key,
|
|
13037
|
-
const
|
|
13968
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
13969
|
+
const need = markCst(ctx);
|
|
13970
|
+
const mRaw = MRAW;
|
|
13971
|
+
const mTl = MTL;
|
|
13972
|
+
const mLv = MLV;
|
|
13973
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13974
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13975
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13976
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
13038
13977
|
const v = child(input, selEnd, ctx);
|
|
13039
13978
|
if (v === FAIL) {
|
|
13040
|
-
|
|
13979
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13041
13980
|
ctx._fc = true;
|
|
13042
13981
|
return FAIL;
|
|
13043
13982
|
}
|
|
13044
13983
|
return [key, v];
|
|
13045
13984
|
};
|
|
13046
13985
|
}
|
|
13047
|
-
return (input, pos, selEnd, key,
|
|
13986
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
13048
13987
|
const savedRouted = ctx._routed;
|
|
13049
|
-
|
|
13050
|
-
const mark = saveTriviaMark(ctx);
|
|
13988
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13051
13989
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
13052
13990
|
let v;
|
|
13053
13991
|
try {
|
|
@@ -13056,7 +13994,7 @@ function assemble(t, prog, cfg) {
|
|
|
13056
13994
|
ctx._routed = savedRouted;
|
|
13057
13995
|
}
|
|
13058
13996
|
if (v === FAIL) {
|
|
13059
|
-
|
|
13997
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13060
13998
|
ctx._fc = true;
|
|
13061
13999
|
return FAIL;
|
|
13062
14000
|
}
|
|
@@ -13064,12 +14002,12 @@ function assemble(t, prog, cfg) {
|
|
|
13064
14002
|
};
|
|
13065
14003
|
}
|
|
13066
14004
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
13067
|
-
return (arm, input, pos, selEnd, key,
|
|
13068
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
13069
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
13070
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
13071
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
13072
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
14005
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
14006
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14007
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14008
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14009
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14010
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13073
14011
|
};
|
|
13074
14012
|
}
|
|
13075
14013
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -13086,20 +14024,68 @@ function assemble(t, prog, cfg) {
|
|
|
13086
14024
|
if (done !== void 0) return done;
|
|
13087
14025
|
const flight = inFlight.get(ip);
|
|
13088
14026
|
if (flight !== void 0) return flight.fwd;
|
|
14027
|
+
const selected = HYBRID?.byIp[ip];
|
|
14028
|
+
if (selected !== void 0) {
|
|
14029
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
14030
|
+
memo.set(ip, piece2);
|
|
14031
|
+
reached.add(ip);
|
|
14032
|
+
return piece2;
|
|
14033
|
+
}
|
|
13089
14034
|
let target;
|
|
13090
14035
|
const fwd = (input, pos, ctx) => target(input, pos, ctx);
|
|
13091
14036
|
const holder = { fwd, set: (p) => {
|
|
13092
14037
|
target = p;
|
|
13093
14038
|
} };
|
|
13094
14039
|
inFlight.set(ip, holder);
|
|
13095
|
-
const
|
|
13096
|
-
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);
|
|
14040
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
13097
14041
|
inFlight.delete(ip);
|
|
13098
14042
|
holder.set(piece);
|
|
13099
14043
|
memo.set(ip, piece);
|
|
13100
14044
|
reached.add(ip);
|
|
13101
14045
|
return piece;
|
|
13102
14046
|
}
|
|
14047
|
+
let FIRST_DECIDED;
|
|
14048
|
+
let NODE_BODY;
|
|
14049
|
+
const DECIDED = (_input, pos) => {
|
|
14050
|
+
EC.e = pos;
|
|
14051
|
+
return null;
|
|
14052
|
+
};
|
|
14053
|
+
function lookaheadLedNode(ip) {
|
|
14054
|
+
const op = code[ip];
|
|
14055
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC2 || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
14056
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
14057
|
+
const body = code[ip + 2];
|
|
14058
|
+
const bop = code[body];
|
|
14059
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
14060
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
14061
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
14062
|
+
const first = code[base];
|
|
14063
|
+
const negative = code[first] === OP_NOT;
|
|
14064
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
14065
|
+
if (terminal < 0) return void 0;
|
|
14066
|
+
const recognize = scalarFor(terminal);
|
|
14067
|
+
const xf = fx[code[first + 2]];
|
|
14068
|
+
FIRST_DECIDED = DECIDED;
|
|
14069
|
+
NODE_BODY = lower(body);
|
|
14070
|
+
const node2 = lower(ip);
|
|
14071
|
+
NODE_BODY = void 0;
|
|
14072
|
+
return negative ? (input, pos, ctx) => {
|
|
14073
|
+
if (recognize(input, pos) >= 0) {
|
|
14074
|
+
ctx._fe = pos;
|
|
14075
|
+
ctx._fx = xf;
|
|
14076
|
+
EC.e = pos;
|
|
14077
|
+
return FAIL;
|
|
14078
|
+
}
|
|
14079
|
+
return node2(input, pos, ctx);
|
|
14080
|
+
} : (input, pos, ctx) => {
|
|
14081
|
+
if (recognize(input, pos) < 0) {
|
|
14082
|
+
ctx._fe = pos;
|
|
14083
|
+
ctx._fx = xf;
|
|
14084
|
+
return FAIL;
|
|
14085
|
+
}
|
|
14086
|
+
return node2(input, pos, ctx);
|
|
14087
|
+
};
|
|
14088
|
+
}
|
|
13103
14089
|
function lower(ip) {
|
|
13104
14090
|
const op = code[ip];
|
|
13105
14091
|
switch (op) {
|
|
@@ -13630,7 +14616,12 @@ function assemble(t, prog, cfg) {
|
|
|
13630
14616
|
}
|
|
13631
14617
|
const child = link(code[ip + 1]);
|
|
13632
14618
|
const xf = fx[code[ip + 2]];
|
|
14619
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
13633
14620
|
return (input, pos, ctx) => {
|
|
14621
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14622
|
+
EC.e = pos;
|
|
14623
|
+
return null;
|
|
14624
|
+
}
|
|
13634
14625
|
const need = markCst(ctx);
|
|
13635
14626
|
const mRaw = MRAW;
|
|
13636
14627
|
const mTl = MTL;
|
|
@@ -13639,8 +14630,10 @@ function assemble(t, prog, cfg) {
|
|
|
13639
14630
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13640
14631
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13641
14632
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14633
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13642
14634
|
const v = child(input, pos, ctx);
|
|
13643
14635
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14636
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13644
14637
|
if (v === FAIL) {
|
|
13645
14638
|
EC.e = pos;
|
|
13646
14639
|
return null;
|
|
@@ -13651,9 +14644,29 @@ function assemble(t, prog, cfg) {
|
|
|
13651
14644
|
};
|
|
13652
14645
|
}
|
|
13653
14646
|
case OP_PEEK: {
|
|
14647
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
14648
|
+
if (scalarChild >= 0) {
|
|
14649
|
+
const recognize = scalarFor(scalarChild);
|
|
14650
|
+
const xf2 = fx[code[ip + 2]];
|
|
14651
|
+
return (input, pos, ctx) => {
|
|
14652
|
+
if (recognize(input, pos) < 0) {
|
|
14653
|
+
ctx._fe = pos;
|
|
14654
|
+
ctx._fx = xf2;
|
|
14655
|
+
return FAIL;
|
|
14656
|
+
}
|
|
14657
|
+
EC.e = pos;
|
|
14658
|
+
return null;
|
|
14659
|
+
};
|
|
14660
|
+
}
|
|
13654
14661
|
const child = link(code[ip + 1]);
|
|
13655
14662
|
const xf = fx[code[ip + 2]];
|
|
14663
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
13656
14664
|
return (input, pos, ctx) => {
|
|
14665
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14666
|
+
ctx._fe = pos;
|
|
14667
|
+
ctx._fx = xf;
|
|
14668
|
+
return FAIL;
|
|
14669
|
+
}
|
|
13657
14670
|
const need = markCst(ctx);
|
|
13658
14671
|
const mRaw = MRAW;
|
|
13659
14672
|
const mTl = MTL;
|
|
@@ -13662,8 +14675,10 @@ function assemble(t, prog, cfg) {
|
|
|
13662
14675
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13663
14676
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13664
14677
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14678
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13665
14679
|
const v = child(input, pos, ctx);
|
|
13666
14680
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14681
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13667
14682
|
if (v === FAIL) {
|
|
13668
14683
|
ctx._fe = pos;
|
|
13669
14684
|
ctx._fx = xf;
|
|
@@ -13675,8 +14690,14 @@ function assemble(t, prog, cfg) {
|
|
|
13675
14690
|
}
|
|
13676
14691
|
case OP_OPT: {
|
|
13677
14692
|
const child = link(code[ip + 1]);
|
|
14693
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
14694
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
13678
14695
|
return (input, pos, ctx) => {
|
|
13679
|
-
|
|
14696
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14697
|
+
EC.e = pos;
|
|
14698
|
+
return null;
|
|
14699
|
+
}
|
|
14700
|
+
const need = !childClean && markCst(ctx);
|
|
13680
14701
|
const mRaw = MRAW;
|
|
13681
14702
|
const mTl = MTL;
|
|
13682
14703
|
const mLv = MLV;
|
|
@@ -13874,6 +14895,9 @@ function assemble(t, prog, cfg) {
|
|
|
13874
14895
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
13875
14896
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
13876
14897
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
14898
|
+
const decided = FIRST_DECIDED;
|
|
14899
|
+
FIRST_DECIDED = void 0;
|
|
14900
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
13877
14901
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
13878
14902
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
13879
14903
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -13919,7 +14943,7 @@ function assemble(t, prog, cfg) {
|
|
|
13919
14943
|
};
|
|
13920
14944
|
};
|
|
13921
14945
|
if (REC2) {
|
|
13922
|
-
const first2 =
|
|
14946
|
+
const first2 = linkFirst();
|
|
13923
14947
|
const firstSync = sentinelFor(code[base + n]);
|
|
13924
14948
|
const runnerAt = (i) => {
|
|
13925
14949
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -13955,13 +14979,13 @@ function assemble(t, prog, cfg) {
|
|
|
13955
14979
|
const bindRunners = (start) => {
|
|
13956
14980
|
const count = Math.min(4, n - start);
|
|
13957
14981
|
const at = (offset) => runnerAt(start + offset);
|
|
13958
|
-
const
|
|
14982
|
+
const never2 = () => -1;
|
|
13959
14983
|
return runnerBlock(
|
|
13960
14984
|
count,
|
|
13961
14985
|
at(0),
|
|
13962
|
-
count > 1 ? at(1) :
|
|
13963
|
-
count > 2 ? at(2) :
|
|
13964
|
-
count > 3 ? at(3) :
|
|
14986
|
+
count > 1 ? at(1) : never2,
|
|
14987
|
+
count > 2 ? at(2) : never2,
|
|
14988
|
+
count > 3 ? at(3) : never2,
|
|
13965
14989
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13966
14990
|
);
|
|
13967
14991
|
};
|
|
@@ -14011,15 +15035,31 @@ function assemble(t, prog, cfg) {
|
|
|
14011
15035
|
let hasAdj = false;
|
|
14012
15036
|
for (let i = 1; i < n; i++) {
|
|
14013
15037
|
const kidIp = code[base + i];
|
|
14014
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
15038
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
14015
15039
|
hasAdj = true;
|
|
14016
15040
|
break;
|
|
14017
15041
|
}
|
|
14018
15042
|
}
|
|
14019
15043
|
if (hasAdj) {
|
|
14020
|
-
const first2 =
|
|
15044
|
+
const first2 = linkFirst();
|
|
14021
15045
|
const runnerAt = (i) => {
|
|
14022
15046
|
const kidIp = code[base + i];
|
|
15047
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
15048
|
+
const kid = link(kidIp);
|
|
15049
|
+
return (input, cur, ctx) => {
|
|
15050
|
+
if (ctx.trivia === void 0) {
|
|
15051
|
+
const v2 = kid(input, cur, ctx);
|
|
15052
|
+
if (v2 === FAIL) return -1;
|
|
15053
|
+
TERMV = v2;
|
|
15054
|
+
return EC.e;
|
|
15055
|
+
}
|
|
15056
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
15057
|
+
const v = kid(input, scanEnd, ctx);
|
|
15058
|
+
if (v === FAIL) return -1;
|
|
15059
|
+
TERMV = v;
|
|
15060
|
+
return scanEnd;
|
|
15061
|
+
};
|
|
15062
|
+
}
|
|
14023
15063
|
if (code[kidIp] !== OP_ADJ) {
|
|
14024
15064
|
const kid = link(kidIp);
|
|
14025
15065
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -14044,13 +15084,13 @@ function assemble(t, prog, cfg) {
|
|
|
14044
15084
|
const bindRunners = (start) => {
|
|
14045
15085
|
const count = Math.min(4, n - start);
|
|
14046
15086
|
const at = (offset) => runnerAt(start + offset);
|
|
14047
|
-
const
|
|
15087
|
+
const never2 = () => -1;
|
|
14048
15088
|
return runnerBlock(
|
|
14049
15089
|
count,
|
|
14050
15090
|
at(0),
|
|
14051
|
-
count > 1 ? at(1) :
|
|
14052
|
-
count > 2 ? at(2) :
|
|
14053
|
-
count > 3 ? at(3) :
|
|
15091
|
+
count > 1 ? at(1) : never2,
|
|
15092
|
+
count > 2 ? at(2) : never2,
|
|
15093
|
+
count > 3 ? at(3) : never2,
|
|
14054
15094
|
start + count < n ? bindRunners(start + count) : void 0
|
|
14055
15095
|
);
|
|
14056
15096
|
};
|
|
@@ -14087,7 +15127,7 @@ function assemble(t, prog, cfg) {
|
|
|
14087
15127
|
};
|
|
14088
15128
|
}
|
|
14089
15129
|
if (n === 1) {
|
|
14090
|
-
const k0 =
|
|
15130
|
+
const k0 = linkFirst();
|
|
14091
15131
|
if (fused) {
|
|
14092
15132
|
return (input, pos, ctx) => {
|
|
14093
15133
|
const v = k0(input, pos, ctx);
|
|
@@ -14109,7 +15149,7 @@ function assemble(t, prog, cfg) {
|
|
|
14109
15149
|
};
|
|
14110
15150
|
}
|
|
14111
15151
|
if (n === 2) {
|
|
14112
|
-
const k0 =
|
|
15152
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
14113
15153
|
if (fused) {
|
|
14114
15154
|
return (input, pos, ctx) => {
|
|
14115
15155
|
const v0 = k0(input, pos, ctx);
|
|
@@ -14140,7 +15180,7 @@ function assemble(t, prog, cfg) {
|
|
|
14140
15180
|
};
|
|
14141
15181
|
}
|
|
14142
15182
|
if (n === 3) {
|
|
14143
|
-
const k0 =
|
|
15183
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
14144
15184
|
if (fused) {
|
|
14145
15185
|
return (input, pos, ctx) => {
|
|
14146
15186
|
const v0 = k0(input, pos, ctx);
|
|
@@ -14234,7 +15274,7 @@ function assemble(t, prog, cfg) {
|
|
|
14234
15274
|
start + count < n ? bind(start + count) : void 0
|
|
14235
15275
|
);
|
|
14236
15276
|
};
|
|
14237
|
-
const first =
|
|
15277
|
+
const first = linkFirst();
|
|
14238
15278
|
const tail = bind(1);
|
|
14239
15279
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
14240
15280
|
const v0 = first(input, pos, ctx);
|
|
@@ -14273,6 +15313,8 @@ function assemble(t, prog, cfg) {
|
|
|
14273
15313
|
const n = code[ip + 2];
|
|
14274
15314
|
const choiceFx = fx[code[ip + 3]];
|
|
14275
15315
|
const base = ip + 4;
|
|
15316
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
15317
|
+
const armsClean = CLEAN(ip);
|
|
14276
15318
|
if (table.exclusive) {
|
|
14277
15319
|
const ascii = table.ascii;
|
|
14278
15320
|
const hi = table.hi;
|
|
@@ -14412,7 +15454,7 @@ function assemble(t, prog, cfg) {
|
|
|
14412
15454
|
if (n === 3) addGate(g2, 4);
|
|
14413
15455
|
return (input, pos, ctx) => {
|
|
14414
15456
|
const c = lead(input, pos);
|
|
14415
|
-
const need = markCst(ctx);
|
|
15457
|
+
const need = !armsClean && markCst(ctx);
|
|
14416
15458
|
const mRaw = MRAW;
|
|
14417
15459
|
const mTl = MTL;
|
|
14418
15460
|
const mLv = MLV;
|
|
@@ -14482,6 +15524,11 @@ function assemble(t, prog, cfg) {
|
|
|
14482
15524
|
}
|
|
14483
15525
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14484
15526
|
}
|
|
15527
|
+
if (prev === 0) {
|
|
15528
|
+
ctx._fe = pos;
|
|
15529
|
+
ctx._fx = choiceFx;
|
|
15530
|
+
return FAIL;
|
|
15531
|
+
}
|
|
14485
15532
|
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
14486
15533
|
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
14487
15534
|
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
@@ -14624,7 +15671,7 @@ function assemble(t, prog, cfg) {
|
|
|
14624
15671
|
if (pn !== 0) {
|
|
14625
15672
|
return (input, pos, ctx) => {
|
|
14626
15673
|
const c = lead(input, pos);
|
|
14627
|
-
const need = markCst(ctx);
|
|
15674
|
+
const need = !armsClean && markCst(ctx);
|
|
14628
15675
|
const mRaw = MRAW;
|
|
14629
15676
|
const mTl = MTL;
|
|
14630
15677
|
const mLv = MLV;
|
|
@@ -14681,7 +15728,7 @@ function assemble(t, prog, cfg) {
|
|
|
14681
15728
|
}
|
|
14682
15729
|
return (input, pos, ctx) => {
|
|
14683
15730
|
const c = lead(input, pos);
|
|
14684
|
-
const need = markCst(ctx);
|
|
15731
|
+
const need = !armsClean && markCst(ctx);
|
|
14685
15732
|
const mRaw = MRAW;
|
|
14686
15733
|
const mTl = MTL;
|
|
14687
15734
|
const mLv = MLV;
|
|
@@ -14729,7 +15776,7 @@ function assemble(t, prog, cfg) {
|
|
|
14729
15776
|
}
|
|
14730
15777
|
return (input, pos, ctx) => {
|
|
14731
15778
|
const c = lead(input, pos);
|
|
14732
|
-
const need = markCst(ctx);
|
|
15779
|
+
const need = !armsClean && markCst(ctx);
|
|
14733
15780
|
const mRaw = MRAW;
|
|
14734
15781
|
const mTl = MTL;
|
|
14735
15782
|
const mLv = MLV;
|
|
@@ -14783,6 +15830,21 @@ function assemble(t, prog, cfg) {
|
|
|
14783
15830
|
return lit(input, pos, ctx);
|
|
14784
15831
|
};
|
|
14785
15832
|
}
|
|
15833
|
+
case OP_RGATE: {
|
|
15834
|
+
const cls = cc[code[ip + 1]];
|
|
15835
|
+
const xf = fx[code[ip + 3]];
|
|
15836
|
+
const child = link(code[ip + 2]);
|
|
15837
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
15838
|
+
return (input, pos, ctx) => {
|
|
15839
|
+
const item = ctx._routed;
|
|
15840
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
15841
|
+
ctx._fe = item.span.end;
|
|
15842
|
+
ctx._fx = xf;
|
|
15843
|
+
return FAIL;
|
|
15844
|
+
}
|
|
15845
|
+
return child(input, pos, ctx);
|
|
15846
|
+
};
|
|
15847
|
+
}
|
|
14786
15848
|
case OP_ARMGATE: {
|
|
14787
15849
|
const pred = fns[code[ip + 1]];
|
|
14788
15850
|
const child = link(code[ip + 2]);
|
|
@@ -14790,7 +15852,7 @@ function assemble(t, prog, cfg) {
|
|
|
14790
15852
|
return (input, pos, ctx) => {
|
|
14791
15853
|
if (!pred(ctx.state)) {
|
|
14792
15854
|
ctx._fc = false;
|
|
14793
|
-
ctx._fe =
|
|
15855
|
+
ctx._fe = -1;
|
|
14794
15856
|
ctx._fx = xf;
|
|
14795
15857
|
return FAIL;
|
|
14796
15858
|
}
|
|
@@ -14851,6 +15913,7 @@ function assemble(t, prog, cfg) {
|
|
|
14851
15913
|
const itemClass = !REC2 && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
14852
15914
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
14853
15915
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
15916
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
14854
15917
|
if (REC2) {
|
|
14855
15918
|
const itemFx2 = fx[code[ip + 6]];
|
|
14856
15919
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
@@ -14947,6 +16010,8 @@ function assemble(t, prog, cfg) {
|
|
|
14947
16010
|
const out = collect ? [] : void 0;
|
|
14948
16011
|
const hasTrivia = ctx.trivia !== void 0;
|
|
14949
16012
|
const needMark = rollbackNeeded(ctx);
|
|
16013
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
16014
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
14950
16015
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
14951
16016
|
let cur = pos;
|
|
14952
16017
|
let count = 0;
|
|
@@ -14954,14 +16019,15 @@ function assemble(t, prog, cfg) {
|
|
|
14954
16019
|
if (max >= 0 && count >= max) break;
|
|
14955
16020
|
if (sep !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
14956
16021
|
if (count >= min && sep === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
14957
|
-
|
|
14958
|
-
|
|
14959
|
-
const
|
|
14960
|
-
const
|
|
14961
|
-
const
|
|
14962
|
-
const
|
|
14963
|
-
const
|
|
14964
|
-
const
|
|
16022
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
16023
|
+
if (markIt) markCst(ctx);
|
|
16024
|
+
const mRaw = markIt ? MRAW : 0;
|
|
16025
|
+
const mTl = markIt ? MTL : 0;
|
|
16026
|
+
const mLv = markIt ? MLV : 0;
|
|
16027
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
16028
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
16029
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
16030
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14965
16031
|
let itemStart = cur;
|
|
14966
16032
|
let sepEnd = -1;
|
|
14967
16033
|
const viaRepItem = sep === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -14973,7 +16039,7 @@ function assemble(t, prog, cfg) {
|
|
|
14973
16039
|
if (sepLeads) LEAD.at = cur;
|
|
14974
16040
|
const sv = sep(input, sp, ctx);
|
|
14975
16041
|
if (sv === FAIL) {
|
|
14976
|
-
if (
|
|
16042
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14977
16043
|
if (committed3(ctx)) return FAIL;
|
|
14978
16044
|
break;
|
|
14979
16045
|
}
|
|
@@ -14984,25 +16050,25 @@ function assemble(t, prog, cfg) {
|
|
|
14984
16050
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
14985
16051
|
}
|
|
14986
16052
|
if (itemStart >= input.length && viaRepItem) {
|
|
14987
|
-
if (
|
|
16053
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14988
16054
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14989
16055
|
break;
|
|
14990
16056
|
}
|
|
14991
16057
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
14992
|
-
if (
|
|
16058
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14993
16059
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14994
16060
|
break;
|
|
14995
16061
|
}
|
|
14996
16062
|
ctx._fc = false;
|
|
14997
16063
|
const v = child(input, itemStart, ctx);
|
|
14998
16064
|
if (v === FAIL) {
|
|
14999
|
-
if (
|
|
16065
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15000
16066
|
if (committed3(ctx)) return FAIL;
|
|
15001
16067
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
15002
16068
|
break;
|
|
15003
16069
|
}
|
|
15004
16070
|
if (EC.e === itemStart && viaRepItem) {
|
|
15005
|
-
if (
|
|
16071
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15006
16072
|
break;
|
|
15007
16073
|
}
|
|
15008
16074
|
if (out !== void 0) out.push(v);
|
|
@@ -15076,7 +16142,14 @@ function assemble(t, prog, cfg) {
|
|
|
15076
16142
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
15077
16143
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
15078
16144
|
return (input, pos, ctx) => {
|
|
15079
|
-
const
|
|
16145
|
+
const need = markCst(ctx);
|
|
16146
|
+
const mRaw = MRAW;
|
|
16147
|
+
const mTl = MTL;
|
|
16148
|
+
const mLv = MLV;
|
|
16149
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
16150
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
16151
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
16152
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
15080
16153
|
const selVal = selector(input, pos, ctx);
|
|
15081
16154
|
if (selVal === FAIL) return FAIL;
|
|
15082
16155
|
const selEnd = EC.e;
|
|
@@ -15088,9 +16161,9 @@ function assemble(t, prog, cfg) {
|
|
|
15088
16161
|
ctx._fx = expected;
|
|
15089
16162
|
return FAIL;
|
|
15090
16163
|
}
|
|
15091
|
-
return runOther(input, pos, selEnd, key,
|
|
16164
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15092
16165
|
}
|
|
15093
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
16166
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
15094
16167
|
};
|
|
15095
16168
|
}
|
|
15096
16169
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -15126,7 +16199,8 @@ function assemble(t, prog, cfg) {
|
|
|
15126
16199
|
return nd;
|
|
15127
16200
|
};
|
|
15128
16201
|
}
|
|
15129
|
-
const child = link(code[ip + 2]);
|
|
16202
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
16203
|
+
NODE_BODY = void 0;
|
|
15130
16204
|
const proj = code[ip + 4];
|
|
15131
16205
|
const buildIdx = code[ip + 1];
|
|
15132
16206
|
const type = k[code[ip + 5]];
|
|
@@ -15150,6 +16224,30 @@ function assemble(t, prog, cfg) {
|
|
|
15150
16224
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
15151
16225
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
15152
16226
|
}
|
|
16227
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
16228
|
+
return passCollapseNode(child, build, flags === 32);
|
|
16229
|
+
}
|
|
16230
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
16231
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
16232
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
16233
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
16234
|
+
return gatedPassCollapseNode(
|
|
16235
|
+
[
|
|
16236
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
16237
|
+
resolveClass(encodeClassSpec([
|
|
16238
|
+
...triviaLead,
|
|
16239
|
+
...gated.lits.map((i) => {
|
|
16240
|
+
const c = k[i].codePointAt(0);
|
|
16241
|
+
return { lo: c, hi: c };
|
|
16242
|
+
})
|
|
16243
|
+
]))
|
|
16244
|
+
],
|
|
16245
|
+
link(gated.last),
|
|
16246
|
+
classic,
|
|
16247
|
+
build,
|
|
16248
|
+
flags === 32
|
|
16249
|
+
);
|
|
16250
|
+
}
|
|
15153
16251
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
15154
16252
|
return collapseBuildNode(child, build);
|
|
15155
16253
|
}
|
|
@@ -15196,7 +16294,7 @@ function assemble(t, prog, cfg) {
|
|
|
15196
16294
|
if (v === FAIL) return FAIL;
|
|
15197
16295
|
const end = EC.e;
|
|
15198
16296
|
const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
|
|
15199
|
-
const st = readsState
|
|
16297
|
+
const st = readsState ? ctx.state : void 0;
|
|
15200
16298
|
let nd;
|
|
15201
16299
|
if (unwrap && kids.length === 1) {
|
|
15202
16300
|
nd = unwrapChild(kids[0]);
|
|
@@ -15209,10 +16307,10 @@ function assemble(t, prog, cfg) {
|
|
|
15209
16307
|
) {
|
|
15210
16308
|
nd = kids[0];
|
|
15211
16309
|
} else if (proj >= 0) {
|
|
15212
|
-
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog,
|
|
16310
|
+
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags) : projectChild(kids, proj, type);
|
|
15213
16311
|
} else if (build !== void 0) {
|
|
15214
16312
|
if (hostCst && host !== void 0) {
|
|
15215
|
-
nd = host(type, kids, fieldMap, span, rawKids, tlog,
|
|
16313
|
+
nd = host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags);
|
|
15216
16314
|
} else {
|
|
15217
16315
|
nd = build(kids, fieldMap, span, rawKids, captureWide ? tlog : EMPTY_TL2, st);
|
|
15218
16316
|
}
|
|
@@ -15263,9 +16361,7 @@ function assemble(t, prog, cfg) {
|
|
|
15263
16361
|
let emitRefusal;
|
|
15264
16362
|
let emitReached;
|
|
15265
16363
|
{
|
|
15266
|
-
const extraIps =
|
|
15267
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
15268
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
16364
|
+
const extraIps = assemblyExtraIps(prog);
|
|
15269
16365
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
15270
16366
|
for (const ip of reachableSites(code, roots)) {
|
|
15271
16367
|
if (code[ip] === OP_DISPATCH) {
|
|
@@ -15300,6 +16396,8 @@ function assemble(t, prog, cfg) {
|
|
|
15300
16396
|
}
|
|
15301
16397
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
15302
16398
|
if (notChild >= 0) scalarFor(notChild);
|
|
16399
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
16400
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
15303
16401
|
}
|
|
15304
16402
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
15305
16403
|
if (pre !== void 0) {
|
|
@@ -15358,9 +16456,12 @@ function assemble(t, prog, cfg) {
|
|
|
15358
16456
|
adjacencyHolds,
|
|
15359
16457
|
t.lexPrograms,
|
|
15360
16458
|
LEAD,
|
|
15361
|
-
triviaFieldCapture
|
|
16459
|
+
triviaFieldCapture,
|
|
16460
|
+
skipDeferredTrivia,
|
|
16461
|
+
collapseEmpty
|
|
15362
16462
|
);
|
|
15363
16463
|
emitReached = new Set(pre.reached);
|
|
16464
|
+
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
15364
16465
|
}
|
|
15365
16466
|
try {
|
|
15366
16467
|
if (emitted !== void 0) throw new ServedByBuild();
|
|
@@ -15442,7 +16543,9 @@ function assemble(t, prog, cfg) {
|
|
|
15442
16543
|
adjacencyHolds,
|
|
15443
16544
|
t.lexPrograms,
|
|
15444
16545
|
LEAD,
|
|
15445
|
-
triviaFieldCapture
|
|
16546
|
+
triviaFieldCapture,
|
|
16547
|
+
skipDeferredTrivia,
|
|
16548
|
+
collapseEmpty
|
|
15446
16549
|
);
|
|
15447
16550
|
emitReached = em.reached;
|
|
15448
16551
|
} catch (e) {
|
|
@@ -15453,7 +16556,7 @@ function assemble(t, prog, cfg) {
|
|
|
15453
16556
|
}
|
|
15454
16557
|
function pieceAt(ip) {
|
|
15455
16558
|
const em = emitted;
|
|
15456
|
-
if (em !== void 0) {
|
|
16559
|
+
if (em !== void 0 && HYBRID === void 0) {
|
|
15457
16560
|
const p = em.byIp[ip];
|
|
15458
16561
|
if (p === void 0) throw new Error(`table emitter: no emitted body for site ${ip}`);
|
|
15459
16562
|
return p;
|
|
@@ -15483,6 +16586,37 @@ function assemble(t, prog, cfg) {
|
|
|
15483
16586
|
}
|
|
15484
16587
|
const scans = scansArr;
|
|
15485
16588
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
16589
|
+
if (HYBRID !== void 0) {
|
|
16590
|
+
const em = HYBRID;
|
|
16591
|
+
em.bind(
|
|
16592
|
+
(s) => {
|
|
16593
|
+
const saved = SCAN;
|
|
16594
|
+
SCAN = s;
|
|
16595
|
+
return saved;
|
|
16596
|
+
},
|
|
16597
|
+
em.ext.map((ip) => link(ip))
|
|
16598
|
+
);
|
|
16599
|
+
const pieces2 = {};
|
|
16600
|
+
for (const [name, entryIp] of Object.entries(prog.rules)) {
|
|
16601
|
+
pieces2[name] = em.pieces[name] ?? link(entryIp);
|
|
16602
|
+
}
|
|
16603
|
+
for (const ip of emitReached) reached.add(ip);
|
|
16604
|
+
return {
|
|
16605
|
+
pieces: pieces2,
|
|
16606
|
+
end: () => EC.e,
|
|
16607
|
+
begin: (ctx) => {
|
|
16608
|
+
begin(ctx);
|
|
16609
|
+
em.begin(ctx);
|
|
16610
|
+
},
|
|
16611
|
+
finish: () => {
|
|
16612
|
+
em.finish();
|
|
16613
|
+
finish();
|
|
16614
|
+
},
|
|
16615
|
+
scanSkip,
|
|
16616
|
+
reached,
|
|
16617
|
+
emitRefusal: void 0
|
|
16618
|
+
};
|
|
16619
|
+
}
|
|
15486
16620
|
if (emitted !== void 0) {
|
|
15487
16621
|
const em = emitted;
|
|
15488
16622
|
return {
|
|
@@ -15518,6 +16652,15 @@ function assemble(t, prog, cfg) {
|
|
|
15518
16652
|
}
|
|
15519
16653
|
return { pieces, end: () => EC.e, begin, finish, scanSkip, reached, emitRefusal };
|
|
15520
16654
|
}
|
|
16655
|
+
var SITE_COUNTS;
|
|
16656
|
+
function countedPiece(piece, ip) {
|
|
16657
|
+
const counts = SITE_COUNTS;
|
|
16658
|
+
if (counts === void 0) return piece;
|
|
16659
|
+
return (input, pos, ctx) => {
|
|
16660
|
+
counts[ip]++;
|
|
16661
|
+
return piece(input, pos, ctx);
|
|
16662
|
+
};
|
|
16663
|
+
}
|
|
15521
16664
|
var AssemblyCache = class {
|
|
15522
16665
|
t;
|
|
15523
16666
|
prog;
|
|
@@ -15669,7 +16812,7 @@ function emitClassPool(classes) {
|
|
|
15669
16812
|
if (classes.length < 2) return array;
|
|
15670
16813
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
15671
16814
|
if (delimiter === void 0) return array;
|
|
15672
|
-
const split =
|
|
16815
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
15673
16816
|
return split.length < array.length ? split : array;
|
|
15674
16817
|
}
|
|
15675
16818
|
function emitConst(v) {
|
|
@@ -15731,9 +16874,7 @@ function defaultAssemblyCfgs(prog) {
|
|
|
15731
16874
|
function emitAssemblies(prog, cfgs) {
|
|
15732
16875
|
if (cfgs.length === 0) return ["a:[],"];
|
|
15733
16876
|
const t = resolveTable(prog);
|
|
15734
|
-
const extraIps =
|
|
15735
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
15736
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
16877
|
+
const extraIps = assemblyExtraIps(prog);
|
|
15737
16878
|
const out = [];
|
|
15738
16879
|
const seen = /* @__PURE__ */ new Set();
|
|
15739
16880
|
for (const cfg of cfgs) {
|
|
@@ -15742,7 +16883,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
15742
16883
|
seen.add(key);
|
|
15743
16884
|
let em;
|
|
15744
16885
|
try {
|
|
15745
|
-
em = emitAssemblySource(t, prog, cfg, extraIps, true);
|
|
16886
|
+
em = emitAssemblySource(t, prog, cfg, extraIps, true, cfg.select);
|
|
15746
16887
|
} catch (e) {
|
|
15747
16888
|
if (e instanceof Unemittable) continue;
|
|
15748
16889
|
throw e;
|
|
@@ -17299,8 +18440,46 @@ function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
|
17299
18440
|
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
17300
18441
|
}
|
|
17301
18442
|
|
|
18443
|
+
// src/table/select-hot.ts
|
|
18444
|
+
var LOOP = 8;
|
|
18445
|
+
var ROUNDS = 60;
|
|
18446
|
+
var CAP = 1e12;
|
|
18447
|
+
function selectHotSites(code, entries, siteBytes, budget, profile) {
|
|
18448
|
+
const selected = /* @__PURE__ */ new Set();
|
|
18449
|
+
if (budget <= 0) return selected;
|
|
18450
|
+
const weight = profile === void 0 ? staticWeights(code, entries) : void 0;
|
|
18451
|
+
const w = (ip) => (weight !== void 0 ? weight.get(ip) : profile[ip]) ?? 0;
|
|
18452
|
+
const ranked = [...siteBytes.keys()].sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
|
|
18453
|
+
let spent = 0;
|
|
18454
|
+
for (const ip of ranked) {
|
|
18455
|
+
if (w(ip) === 0) break;
|
|
18456
|
+
const bytes2 = siteBytes.get(ip);
|
|
18457
|
+
if (spent + bytes2 > budget) continue;
|
|
18458
|
+
spent += bytes2;
|
|
18459
|
+
selected.add(ip);
|
|
18460
|
+
}
|
|
18461
|
+
return selected;
|
|
18462
|
+
}
|
|
18463
|
+
function staticWeights(code, entries) {
|
|
18464
|
+
let weight = /* @__PURE__ */ new Map();
|
|
18465
|
+
const kids = [];
|
|
18466
|
+
for (let round = 0; round < ROUNDS; round++) {
|
|
18467
|
+
const next = /* @__PURE__ */ new Map();
|
|
18468
|
+
for (const ip of entries) next.set(ip, 1);
|
|
18469
|
+
for (const [ip, w] of weight) {
|
|
18470
|
+
kids.length = 0;
|
|
18471
|
+
childSlots(code, ip, kids);
|
|
18472
|
+
const op = code[ip];
|
|
18473
|
+
const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
|
|
18474
|
+
for (const kid of kids) next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
18475
|
+
}
|
|
18476
|
+
weight = next;
|
|
18477
|
+
}
|
|
18478
|
+
return weight;
|
|
18479
|
+
}
|
|
18480
|
+
|
|
17302
18481
|
// src/table/compile-rule-map.ts
|
|
17303
|
-
var
|
|
18482
|
+
var SUPERCOMPILE_GROWTH = 1.05;
|
|
17304
18483
|
function resolveHostMode(ruleMap, explicit) {
|
|
17305
18484
|
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
17306
18485
|
}
|
|
@@ -17397,14 +18576,45 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17397
18576
|
entry: null,
|
|
17398
18577
|
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
17399
18578
|
fnSources: sources,
|
|
17400
|
-
...options.
|
|
18579
|
+
...options.select !== void 0 && options.select.size > 0 ? { assemblies: [{ ...defaultAssemblyCfgs(artifact)[0], select: options.select }] } : {},
|
|
17401
18580
|
...metadataSource === void 0 ? {} : { metadataSource }
|
|
17402
18581
|
});
|
|
17403
18582
|
const replacement = replacementWithMetadata();
|
|
18583
|
+
const selectAssembly = (budget, profile) => {
|
|
18584
|
+
const none = { sites: /* @__PURE__ */ new Set(), bytes: 0 };
|
|
18585
|
+
if (hostMode !== "ast" || prog.lines === 1) return none;
|
|
18586
|
+
const table = resolveTable(artifact);
|
|
18587
|
+
const cfg = defaultAssemblyCfgs(artifact)[0];
|
|
18588
|
+
const roots = assemblyExtraIps(artifact);
|
|
18589
|
+
let siteBytes, fixed;
|
|
18590
|
+
try {
|
|
18591
|
+
siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes;
|
|
18592
|
+
fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set()).source.length;
|
|
18593
|
+
} catch (e) {
|
|
18594
|
+
if (e instanceof Unemittable) return { ...none, refusal: e.construct };
|
|
18595
|
+
throw e;
|
|
18596
|
+
}
|
|
18597
|
+
const ceiling = budget / SUPERCOMPILE_GROWTH;
|
|
18598
|
+
if (ceiling <= fixed) return none;
|
|
18599
|
+
let target = ceiling;
|
|
18600
|
+
for (; ; ) {
|
|
18601
|
+
const sites = selectHotSites(artifact.code, Object.values(artifact.rules), siteBytes, target - fixed, profile);
|
|
18602
|
+
if (sites.size === 0) {
|
|
18603
|
+
return {
|
|
18604
|
+
...none,
|
|
18605
|
+
refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
|
|
18606
|
+
};
|
|
18607
|
+
}
|
|
18608
|
+
const bytes2 = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
|
|
18609
|
+
if (bytes2 <= ceiling) return { sites, bytes: Math.ceil(bytes2 * SUPERCOMPILE_GROWTH) };
|
|
18610
|
+
target *= Math.min(ceiling / bytes2, 0.99);
|
|
18611
|
+
}
|
|
18612
|
+
};
|
|
17404
18613
|
return {
|
|
17405
18614
|
keys: ruleMap.map(([key]) => key),
|
|
17406
18615
|
replacement,
|
|
17407
18616
|
replacementWithMetadata,
|
|
18617
|
+
selectAssembly,
|
|
17408
18618
|
hostMode,
|
|
17409
18619
|
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
17410
18620
|
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
@@ -17486,16 +18696,16 @@ function ownSource(fn) {
|
|
|
17486
18696
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
17487
18697
|
}
|
|
17488
18698
|
function compile(target, second, third) {
|
|
17489
|
-
if (!
|
|
18699
|
+
if (!isCombinator2(target)) return compileMap(target, second);
|
|
17490
18700
|
return compileRoot(target, second, third);
|
|
17491
18701
|
}
|
|
17492
|
-
function
|
|
18702
|
+
function isCombinator2(x) {
|
|
17493
18703
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
17494
18704
|
}
|
|
17495
18705
|
function compileMap(grammar, opts = {}) {
|
|
17496
18706
|
const entries = [];
|
|
17497
18707
|
for (const [key, value] of Object.entries(grammar)) {
|
|
17498
|
-
if (!
|
|
18708
|
+
if (!isCombinator2(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
17499
18709
|
if (value._def.tag === "lazy") {
|
|
17500
18710
|
try {
|
|
17501
18711
|
value._def.thunk();
|
|
@@ -18037,7 +19247,7 @@ function fieldOptionsSrc(def) {
|
|
|
18037
19247
|
}
|
|
18038
19248
|
|
|
18039
19249
|
// src/version.ts
|
|
18040
|
-
var PARSEMAN_VERSION = "0.
|
|
19250
|
+
var PARSEMAN_VERSION = "0.58.0";
|
|
18041
19251
|
|
|
18042
19252
|
// src/compiler/compile-linkable-table.ts
|
|
18043
19253
|
function isLocal(rule) {
|
|
@@ -18306,7 +19516,7 @@ function analyzeGrammarGating(grammar, opts) {
|
|
|
18306
19516
|
}
|
|
18307
19517
|
|
|
18308
19518
|
// src/analysis/diagnose.ts
|
|
18309
|
-
var
|
|
19519
|
+
var isCombinator3 = (g) => typeof g === "object" && g !== null && "_def" in g;
|
|
18310
19520
|
var isRuleEntries = (g) => Array.isArray(g);
|
|
18311
19521
|
function diagnoseGrammar(grammar, opts) {
|
|
18312
19522
|
const depth = degradationCaptureDepth();
|
|
@@ -18350,7 +19560,7 @@ function formatGrammarDiagnosis(d) {
|
|
|
18350
19560
|
return lines2;
|
|
18351
19561
|
}
|
|
18352
19562
|
function runAnalysis(grammar, opts) {
|
|
18353
|
-
if (
|
|
19563
|
+
if (isCombinator3(grammar)) return analyzeGating(grammar, opts);
|
|
18354
19564
|
if (isRuleEntries(grammar)) return analyzeGatingRules(grammar, opts);
|
|
18355
19565
|
return analyzeGrammarGating(grammar, opts);
|
|
18356
19566
|
}
|
|
@@ -20657,13 +21867,13 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
20657
21867
|
}
|
|
20658
21868
|
|
|
20659
21869
|
// src/cst/walk.ts
|
|
20660
|
-
function
|
|
21870
|
+
function isCombinator4(value) {
|
|
20661
21871
|
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
20662
21872
|
}
|
|
20663
21873
|
function reflectionFor(grammar) {
|
|
20664
21874
|
const stamped = grammarReflectionOf(grammar);
|
|
20665
21875
|
if (stamped) return stamped;
|
|
20666
|
-
const entries = Object.entries(grammar).filter((entry) =>
|
|
21876
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator4(entry[1]));
|
|
20667
21877
|
return collectGrammarReflection(entries);
|
|
20668
21878
|
}
|
|
20669
21879
|
function createVisitor(grammar, spec) {
|