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/plugin/index.js
CHANGED
|
@@ -366,12 +366,12 @@ function scalarRootOf(combinator) {
|
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
// src/combinators/ref.ts
|
|
369
|
-
function withRuleTrivia(trivia2, ctx,
|
|
369
|
+
function withRuleTrivia(trivia2, ctx, run2) {
|
|
370
370
|
const savedLabels = ctx.triviaKindLabels;
|
|
371
371
|
ctx.trivia = trivia2;
|
|
372
372
|
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
373
373
|
try {
|
|
374
|
-
return
|
|
374
|
+
return run2();
|
|
375
375
|
} finally {
|
|
376
376
|
ctx.trivia = void 0;
|
|
377
377
|
ctx.triviaKindLabels = savedLabels;
|
|
@@ -663,6 +663,31 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
663
663
|
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
664
664
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
665
665
|
}
|
|
666
|
+
function popCstChild(ctx) {
|
|
667
|
+
const b = ctx._cstBuf;
|
|
668
|
+
if (b) {
|
|
669
|
+
const ch2 = b.ch;
|
|
670
|
+
if (b.rawOnly !== true && ch2) {
|
|
671
|
+
ch2.pop();
|
|
672
|
+
if (ch2.length === 1) {
|
|
673
|
+
b.single = ch2[0];
|
|
674
|
+
b.ch = void 0;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1;
|
|
678
|
+
else if (b.raw) {
|
|
679
|
+
b.raw.pop();
|
|
680
|
+
if (b.raw.length === 1) {
|
|
681
|
+
b.rawSingle = b.raw[0];
|
|
682
|
+
b.raw = void 0;
|
|
683
|
+
}
|
|
684
|
+
} else b.rawSingle = void 0;
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
if (ctx._cstChildren) ctx._cstChildren.pop();
|
|
688
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop();
|
|
689
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop();
|
|
690
|
+
}
|
|
666
691
|
function cstRawLen(ctx) {
|
|
667
692
|
const b = ctx._cstBuf;
|
|
668
693
|
if (b) {
|
|
@@ -816,6 +841,7 @@ function createParseContext() {
|
|
|
816
841
|
_rootTriviaKindIndex: void 0,
|
|
817
842
|
_rootTriviaStrictScopes: void 0,
|
|
818
843
|
_rootTriviaCapture: void 0,
|
|
844
|
+
_gap: void 0,
|
|
819
845
|
_cstTriviaLog: void 0,
|
|
820
846
|
_fields: void 0,
|
|
821
847
|
_cstBuf: void 0,
|
|
@@ -869,6 +895,7 @@ function literalCodePoints(frag) {
|
|
|
869
895
|
if (ch2 === "\\") {
|
|
870
896
|
const e = frag[i + 1];
|
|
871
897
|
if (e === void 0) return null;
|
|
898
|
+
if (!(e in CLASS_ESCAPES) && /\w/.test(e)) return null;
|
|
872
899
|
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
873
900
|
i += 2;
|
|
874
901
|
continue;
|
|
@@ -1415,7 +1442,10 @@ function labeledTriviaSpec(arms, minRepeats) {
|
|
|
1415
1442
|
arms,
|
|
1416
1443
|
minRepeats,
|
|
1417
1444
|
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1418
|
-
charArms: charArmsFor({ arms, minRepeats })
|
|
1445
|
+
charArms: charArmsFor({ arms, minRepeats }),
|
|
1446
|
+
rootKinds: void 0,
|
|
1447
|
+
rootLeaders: [],
|
|
1448
|
+
rootScan: null
|
|
1419
1449
|
};
|
|
1420
1450
|
}
|
|
1421
1451
|
function matchArmAt(input, pos, arm, state) {
|
|
@@ -2831,8 +2861,50 @@ function loopScanner(arms) {
|
|
|
2831
2861
|
function regexTriviaScanner(parser2) {
|
|
2832
2862
|
const d = parser2._def.tag === "label" ? parser2._def.parser._def : parser2._def;
|
|
2833
2863
|
if (d.tag !== "regex" || d.flags) return null;
|
|
2834
|
-
|
|
2835
|
-
|
|
2864
|
+
return sourceScanner(d.source);
|
|
2865
|
+
}
|
|
2866
|
+
function sourceScanner(source) {
|
|
2867
|
+
return classRunSource(source) ?? altStarSource(source) ?? prefixRunSource(source) ?? delimitedSource(source) ?? sharedPrefixAltSource(source);
|
|
2868
|
+
}
|
|
2869
|
+
function sharedPrefixAltSource(source) {
|
|
2870
|
+
const m = /^((?:\\.|[^\\[\]()*+?|^$.{}])+)\(\?:(.*)\)$/.exec(source);
|
|
2871
|
+
if (!m) return null;
|
|
2872
|
+
const alts = [];
|
|
2873
|
+
const body = m[2];
|
|
2874
|
+
let depth = 0;
|
|
2875
|
+
let start = 0;
|
|
2876
|
+
for (let i = 0; i < body.length; i++) {
|
|
2877
|
+
const c = body[i];
|
|
2878
|
+
if (c === "\\") {
|
|
2879
|
+
i++;
|
|
2880
|
+
continue;
|
|
2881
|
+
}
|
|
2882
|
+
if (c === "[") {
|
|
2883
|
+
while (i < body.length && body[i] !== "]") i += body[i] === "\\" ? 2 : 1;
|
|
2884
|
+
continue;
|
|
2885
|
+
}
|
|
2886
|
+
if (c === "(") depth++;
|
|
2887
|
+
else if (c === ")" && --depth < 0) return null;
|
|
2888
|
+
else if (c === "|" && depth === 0) {
|
|
2889
|
+
alts.push(body.slice(start, i));
|
|
2890
|
+
start = i + 1;
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
if (depth !== 0 || alts.length === 0) return null;
|
|
2894
|
+
alts.push(body.slice(start));
|
|
2895
|
+
const scanners = [];
|
|
2896
|
+
for (const alt of alts) {
|
|
2897
|
+
const scanner = sourceScanner(m[1] + alt);
|
|
2898
|
+
if (scanner === null) return null;
|
|
2899
|
+
scanners.push(scanner);
|
|
2900
|
+
}
|
|
2901
|
+
return (input, cur) => {
|
|
2902
|
+
for (const scanner of scanners) {
|
|
2903
|
+
const end = scanner(input, cur);
|
|
2904
|
+
if (end > cur) return end;
|
|
2905
|
+
}
|
|
2906
|
+
return cur;
|
|
2907
|
+
};
|
|
2836
2908
|
}
|
|
2837
2909
|
function bmpString(cps) {
|
|
2838
2910
|
if (!cps) return null;
|
|
@@ -3185,6 +3257,7 @@ function matchesAt(sentinel, input, pos, ctx) {
|
|
|
3185
3257
|
function captureError(ctx, error) {
|
|
3186
3258
|
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
3187
3259
|
}
|
|
3260
|
+
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
3188
3261
|
|
|
3189
3262
|
// src/combinators/adjacency.ts
|
|
3190
3263
|
function adjacencyOf(p) {
|
|
@@ -3891,10 +3964,16 @@ function branchUsesRouted(branch) {
|
|
|
3891
3964
|
return branch.usesRouted === true || parserUsesRouted(branch.parser);
|
|
3892
3965
|
}
|
|
3893
3966
|
function asciiFoldKey(key) {
|
|
3894
|
-
let
|
|
3895
|
-
for (
|
|
3967
|
+
let i = 0;
|
|
3968
|
+
for (; i < key.length; i++) {
|
|
3969
|
+
const c = key.charCodeAt(i);
|
|
3970
|
+
if (c >= 65 && c <= 90) break;
|
|
3971
|
+
}
|
|
3972
|
+
if (i === key.length) return key;
|
|
3973
|
+
let out = key.slice(0, i);
|
|
3974
|
+
for (; i < key.length; i++) {
|
|
3896
3975
|
const c = key.charCodeAt(i);
|
|
3897
|
-
out +=
|
|
3976
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i];
|
|
3898
3977
|
}
|
|
3899
3978
|
return out;
|
|
3900
3979
|
}
|
|
@@ -4821,7 +4900,7 @@ function confirmedArityForDef(def) {
|
|
|
4821
4900
|
severity: "warn",
|
|
4822
4901
|
where: `node("${def.type ?? "<inferred>"}")`,
|
|
4823
4902
|
subject,
|
|
4824
|
-
fellBackTo: `could not confirm its declared arity \u2014 ${unconfirmableReason(def, src)} \u2014 so this node captures children, fields and raw children, logs trivia, and
|
|
4903
|
+
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`,
|
|
4825
4904
|
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"
|
|
4826
4905
|
});
|
|
4827
4906
|
return null;
|
|
@@ -4978,7 +5057,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4978
5057
|
}
|
|
4979
5058
|
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;
|
|
4980
5059
|
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
4981
|
-
const
|
|
5060
|
+
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
4982
5061
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
4983
5062
|
const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
4984
5063
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
@@ -5019,12 +5098,11 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
5019
5098
|
ctx._triviaCaptureMask = savedMask;
|
|
5020
5099
|
const { children: children3, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
5021
5100
|
if (!r.ok) return r;
|
|
5022
|
-
const st =
|
|
5101
|
+
const st = readsState ? ctx.state : void 0;
|
|
5023
5102
|
const nodeType = def.type ?? missingInferredType();
|
|
5024
5103
|
const cstOutput = cstOutputHost(ctx.build);
|
|
5025
5104
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
5026
|
-
const
|
|
5027
|
-
const built = unwrap && children3.length === 1 ? unwrapChild(children3[0]) : collapse && children3.length === 1 ? children3[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children3.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children3[0], children3, rawChildren) ? children3[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children3, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children3, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children3, fields, span, rawChildren, triviaLog, hostState, tags) : build(children3, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children3, 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: children3 };
|
|
5105
|
+
const built = unwrap && children3.length === 1 ? unwrapChild(children3[0]) : collapse && children3.length === 1 ? children3[0] : (cstOutput || !build && project === void 0) && ctx.build?._parsemanCstCollapse && children3.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children3[0], children3, rawChildren) ? children3[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children3, fields, span, rawChildren, triviaLog, ctx.state, tags) : projectChild(children3, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children3, fields, span, rawChildren, triviaLog, ctx.state, tags) : build(children3, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children3, 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: children3 };
|
|
5028
5106
|
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 };
|
|
5029
5107
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
5030
5108
|
pushCstChild(ctx, built, rawEntry2);
|
|
@@ -5317,17 +5395,59 @@ function buildLexBodyRecognizer(spec, constants) {
|
|
|
5317
5395
|
};
|
|
5318
5396
|
}
|
|
5319
5397
|
|
|
5398
|
+
// src/table/run-support.ts
|
|
5399
|
+
function lineCol(ctx, offset) {
|
|
5400
|
+
const starts = ctx._lineStarts ?? [0];
|
|
5401
|
+
let lo = 0, hi = starts.length - 1;
|
|
5402
|
+
while (lo < hi) {
|
|
5403
|
+
const mid = lo + hi + 1 >> 1;
|
|
5404
|
+
if (starts[mid] <= offset) lo = mid;
|
|
5405
|
+
else hi = mid - 1;
|
|
5406
|
+
}
|
|
5407
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
5408
|
+
}
|
|
5409
|
+
function spanLines(ctx, start, end) {
|
|
5410
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
5411
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
5412
|
+
}
|
|
5413
|
+
function rawEntry(v, input, s, e) {
|
|
5414
|
+
if (typeof v === "object" && v !== null) {
|
|
5415
|
+
const tg = v._tag;
|
|
5416
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
5417
|
+
}
|
|
5418
|
+
return {
|
|
5419
|
+
_tag: "leaf",
|
|
5420
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
5421
|
+
span: { start: s, end: e }
|
|
5422
|
+
};
|
|
5423
|
+
}
|
|
5424
|
+
function lead(input, pos) {
|
|
5425
|
+
if (pos >= input.length) return -1;
|
|
5426
|
+
const c = input.charCodeAt(pos);
|
|
5427
|
+
if (c < 55296 || c > 56319) return c;
|
|
5428
|
+
return input.codePointAt(pos) ?? c;
|
|
5429
|
+
}
|
|
5430
|
+
var EMPTY_KIDS = Object.freeze([]);
|
|
5431
|
+
var EMPTY_TRIVIA = Object.freeze([]);
|
|
5432
|
+
function collapseEmpty(ctx, build, input, pos, end, readsRaw) {
|
|
5433
|
+
const collected = ctx._cstBuf !== void 0 || ctx._cstChildren !== void 0;
|
|
5434
|
+
if (collected) popCstChild(ctx);
|
|
5435
|
+
const raw = readsRaw ? [rawEntry(void 0, input, pos, end)] : EMPTY_KIDS;
|
|
5436
|
+
const nd = build(EMPTY_KIDS, void 0, { start: pos, end }, raw, EMPTY_TRIVIA, void 0);
|
|
5437
|
+
if (collected) pushCstChild(ctx, nd, ctx._cstBuf?.noRaw === true ? void 0 : rawEntry(nd, input, pos, end));
|
|
5438
|
+
return nd;
|
|
5439
|
+
}
|
|
5440
|
+
|
|
5320
5441
|
// src/table/lex-program.ts
|
|
5321
5442
|
var LEX_NODE_TERMINAL = 0;
|
|
5322
5443
|
var LEX_NODE_SEQUENCE2 = 1;
|
|
5323
5444
|
var LEX_NODE_SEQUENCE3 = 2;
|
|
5324
5445
|
var LEX_NODE_SEQUENCE4 = 3;
|
|
5325
5446
|
var LEX_NODE_SEQUENCE5 = 4;
|
|
5326
|
-
var
|
|
5327
|
-
var LEX_NODE_CHOICE4 = 6;
|
|
5328
|
-
var LEX_NODE_CHOICE8 = 7;
|
|
5447
|
+
var LEX_NODE_CHOICE = 5;
|
|
5329
5448
|
var LEX_NODE_NOT = 8;
|
|
5330
5449
|
var LEX_NODE_OPTIONAL = 9;
|
|
5450
|
+
var LEX_NODE_REPEAT = 10;
|
|
5331
5451
|
function lexProgramDigest(words) {
|
|
5332
5452
|
let hash = 2166136261;
|
|
5333
5453
|
for (const word2 of words) {
|
|
@@ -5356,85 +5476,114 @@ function trackLexLines(ctx, input, end) {
|
|
|
5356
5476
|
ctx._lineScannedTo = end;
|
|
5357
5477
|
}
|
|
5358
5478
|
function terminalNode(matcher, failure, tracksLines) {
|
|
5359
|
-
const match = (input, pos) => {
|
|
5360
|
-
const result = matcher(input, pos);
|
|
5361
|
-
return result < 0 ? -1 : result / 2;
|
|
5362
|
-
};
|
|
5363
5479
|
return {
|
|
5364
|
-
match,
|
|
5480
|
+
match: (input, pos) => {
|
|
5481
|
+
const result = matcher(input, pos);
|
|
5482
|
+
return result < 0 ? -1 : result / 2;
|
|
5483
|
+
},
|
|
5365
5484
|
run: (input, pos, ctx) => {
|
|
5366
|
-
const
|
|
5367
|
-
if (
|
|
5485
|
+
const result = matcher(input, pos);
|
|
5486
|
+
if (result < 0) {
|
|
5368
5487
|
ctx._fe = pos;
|
|
5369
5488
|
ctx._fx = failure;
|
|
5370
5489
|
if (ctx._probe !== void 0) failAt(ctx, ctx._fx, pos);
|
|
5371
5490
|
return -1;
|
|
5372
5491
|
}
|
|
5492
|
+
const end = result / 2;
|
|
5373
5493
|
if (tracksLines) trackLexLines(ctx, input, end);
|
|
5374
5494
|
return end;
|
|
5375
5495
|
}
|
|
5376
5496
|
};
|
|
5377
5497
|
}
|
|
5378
5498
|
function sequence2(a, b) {
|
|
5499
|
+
const am = a.match, bm = b.match, ar = a.run, br = b.run;
|
|
5379
5500
|
return {
|
|
5380
5501
|
match: (input, pos) => {
|
|
5381
|
-
const e0 =
|
|
5382
|
-
return e0 < 0 ? -1 :
|
|
5502
|
+
const e0 = am(input, pos);
|
|
5503
|
+
return e0 < 0 ? -1 : bm(input, e0);
|
|
5383
5504
|
},
|
|
5384
5505
|
run: (input, pos, ctx) => {
|
|
5385
|
-
const e0 =
|
|
5506
|
+
const e0 = ar(input, pos, ctx);
|
|
5386
5507
|
if (e0 < 0) return -1;
|
|
5387
5508
|
ctx._fc = false;
|
|
5388
|
-
return
|
|
5509
|
+
return br(input, e0, ctx);
|
|
5389
5510
|
}
|
|
5390
5511
|
};
|
|
5391
5512
|
}
|
|
5392
5513
|
function sequence3(a, b, c) {
|
|
5514
|
+
const am = a.match, bm = b.match, cm = c.match, ar = a.run, br = b.run, cr = c.run;
|
|
5393
5515
|
return {
|
|
5394
5516
|
match: (input, pos) => {
|
|
5395
|
-
const e0 =
|
|
5517
|
+
const e0 = am(input, pos);
|
|
5396
5518
|
if (e0 < 0) return -1;
|
|
5397
|
-
const e1 =
|
|
5398
|
-
return e1 < 0 ? -1 :
|
|
5519
|
+
const e1 = bm(input, e0);
|
|
5520
|
+
return e1 < 0 ? -1 : cm(input, e1);
|
|
5399
5521
|
},
|
|
5400
5522
|
run: (input, pos, ctx) => {
|
|
5401
|
-
const e0 =
|
|
5523
|
+
const e0 = ar(input, pos, ctx);
|
|
5402
5524
|
if (e0 < 0) return -1;
|
|
5403
5525
|
ctx._fc = false;
|
|
5404
|
-
const e1 =
|
|
5526
|
+
const e1 = br(input, e0, ctx);
|
|
5405
5527
|
if (e1 < 0) return -1;
|
|
5406
5528
|
ctx._fc = false;
|
|
5407
|
-
return
|
|
5529
|
+
return cr(input, e1, ctx);
|
|
5408
5530
|
}
|
|
5409
5531
|
};
|
|
5410
5532
|
}
|
|
5411
5533
|
function sequence4(a, b, c, d) {
|
|
5412
|
-
const
|
|
5534
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match;
|
|
5535
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run;
|
|
5413
5536
|
return {
|
|
5414
5537
|
match: (input, pos) => {
|
|
5415
|
-
const
|
|
5416
|
-
|
|
5538
|
+
const e0 = am(input, pos);
|
|
5539
|
+
if (e0 < 0) return -1;
|
|
5540
|
+
const e1 = bm(input, e0);
|
|
5541
|
+
if (e1 < 0) return -1;
|
|
5542
|
+
const e2 = cm(input, e1);
|
|
5543
|
+
return e2 < 0 ? -1 : dm(input, e2);
|
|
5417
5544
|
},
|
|
5418
5545
|
run: (input, pos, ctx) => {
|
|
5419
|
-
const
|
|
5420
|
-
if (
|
|
5546
|
+
const e0 = ar(input, pos, ctx);
|
|
5547
|
+
if (e0 < 0) return -1;
|
|
5421
5548
|
ctx._fc = false;
|
|
5422
|
-
|
|
5549
|
+
const e1 = br(input, e0, ctx);
|
|
5550
|
+
if (e1 < 0) return -1;
|
|
5551
|
+
ctx._fc = false;
|
|
5552
|
+
const e2 = cr(input, e1, ctx);
|
|
5553
|
+
if (e2 < 0) return -1;
|
|
5554
|
+
ctx._fc = false;
|
|
5555
|
+
return dr(input, e2, ctx);
|
|
5423
5556
|
}
|
|
5424
5557
|
};
|
|
5425
5558
|
}
|
|
5426
5559
|
function sequence5(a, b, c, d, e) {
|
|
5427
|
-
const
|
|
5560
|
+
const am = a.match, bm = b.match, cm = c.match, dm = d.match, em = e.match;
|
|
5561
|
+
const ar = a.run, br = b.run, cr = c.run, dr = d.run, er = e.run;
|
|
5428
5562
|
return {
|
|
5429
5563
|
match: (input, pos) => {
|
|
5430
|
-
const
|
|
5431
|
-
|
|
5564
|
+
const e0 = am(input, pos);
|
|
5565
|
+
if (e0 < 0) return -1;
|
|
5566
|
+
const e1 = bm(input, e0);
|
|
5567
|
+
if (e1 < 0) return -1;
|
|
5568
|
+
const e2 = cm(input, e1);
|
|
5569
|
+
if (e2 < 0) return -1;
|
|
5570
|
+
const e3 = dm(input, e2);
|
|
5571
|
+
return e3 < 0 ? -1 : em(input, e3);
|
|
5432
5572
|
},
|
|
5433
5573
|
run: (input, pos, ctx) => {
|
|
5434
|
-
const
|
|
5435
|
-
if (
|
|
5574
|
+
const e0 = ar(input, pos, ctx);
|
|
5575
|
+
if (e0 < 0) return -1;
|
|
5576
|
+
ctx._fc = false;
|
|
5577
|
+
const e1 = br(input, e0, ctx);
|
|
5578
|
+
if (e1 < 0) return -1;
|
|
5436
5579
|
ctx._fc = false;
|
|
5437
|
-
|
|
5580
|
+
const e2 = cr(input, e1, ctx);
|
|
5581
|
+
if (e2 < 0) return -1;
|
|
5582
|
+
ctx._fc = false;
|
|
5583
|
+
const e3 = dr(input, e2, ctx);
|
|
5584
|
+
if (e3 < 0) return -1;
|
|
5585
|
+
ctx._fc = false;
|
|
5586
|
+
return er(input, e3, ctx);
|
|
5438
5587
|
}
|
|
5439
5588
|
};
|
|
5440
5589
|
}
|
|
@@ -5447,9 +5596,9 @@ function appendExpected(acc, values) {
|
|
|
5447
5596
|
function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
5448
5597
|
let matchTail = () => -1;
|
|
5449
5598
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5450
|
-
const
|
|
5599
|
+
const armMatch = arms[i].match, next = matchTail;
|
|
5451
5600
|
matchTail = (input, pos) => {
|
|
5452
|
-
const end =
|
|
5601
|
+
const end = armMatch(input, pos);
|
|
5453
5602
|
return end < 0 ? next(input, pos) : end;
|
|
5454
5603
|
};
|
|
5455
5604
|
}
|
|
@@ -5459,7 +5608,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5459
5608
|
return -1;
|
|
5460
5609
|
};
|
|
5461
5610
|
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5462
|
-
const
|
|
5611
|
+
const armRun = arms[i].run, cls = classes[i], staticExpected = armExpected[i], next = tail;
|
|
5463
5612
|
tail = (input, pos, ctx, lead2, acc, best) => {
|
|
5464
5613
|
if (cls !== void 0 && !classHas(cls, lead2)) {
|
|
5465
5614
|
return next(
|
|
@@ -5472,7 +5621,7 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5472
5621
|
);
|
|
5473
5622
|
}
|
|
5474
5623
|
ctx._fc = false;
|
|
5475
|
-
const end =
|
|
5624
|
+
const end = armRun(input, pos, ctx);
|
|
5476
5625
|
if (end >= 0) return end;
|
|
5477
5626
|
const at = ctx._fe ?? pos;
|
|
5478
5627
|
if (at > best) {
|
|
@@ -5499,11 +5648,58 @@ function choiceNode(arms, classes, armExpected, choiceExpected) {
|
|
|
5499
5648
|
)
|
|
5500
5649
|
};
|
|
5501
5650
|
}
|
|
5651
|
+
function exclusiveChoiceNode(arms, classes, choiceFx) {
|
|
5652
|
+
const ascii = (classes.length <= 128 ? new Int8Array(128) : new Int32Array(128)).fill(-1);
|
|
5653
|
+
const hi = [];
|
|
5654
|
+
for (let i = 0; i < classes.length; i++) {
|
|
5655
|
+
const cls = classes[i];
|
|
5656
|
+
for (let c = 0; c < 128; c++) if (cls.ascii[c] === 1) ascii[c] = i;
|
|
5657
|
+
for (let r = 0; r < cls.hi.length; r += 2) hi.push(cls.hi[r], cls.hi[r + 1], i);
|
|
5658
|
+
}
|
|
5659
|
+
const select = (code) => {
|
|
5660
|
+
if (code < 0) return -1;
|
|
5661
|
+
if (code < 128) return ascii[code];
|
|
5662
|
+
for (let r = 0; r < hi.length; r += 3) if (code >= hi[r] && code <= hi[r + 1]) return hi[r + 2];
|
|
5663
|
+
return -1;
|
|
5664
|
+
};
|
|
5665
|
+
let matchArm = () => -1;
|
|
5666
|
+
let selectRun = () => -1;
|
|
5667
|
+
for (let i = arms.length - 1; i >= 0; i--) {
|
|
5668
|
+
const armMatch = arms[i].match, armRun = arms[i].run, nextMatch = matchArm, nextRun = selectRun;
|
|
5669
|
+
matchArm = (selected, input, pos) => selected === i ? armMatch(input, pos) : nextMatch(selected, input, pos);
|
|
5670
|
+
selectRun = (selected, input, pos, ctx) => selected === i ? armRun(input, pos, ctx) : nextRun(selected, input, pos, ctx);
|
|
5671
|
+
}
|
|
5672
|
+
const runArm = (input, pos, ctx) => {
|
|
5673
|
+
const arm = select(lead(input, pos));
|
|
5674
|
+
if (arm >= 0) {
|
|
5675
|
+
ctx._fc = false;
|
|
5676
|
+
const end = selectRun(arm, input, pos, ctx);
|
|
5677
|
+
if (end >= 0) return end;
|
|
5678
|
+
if (committed(ctx)) return -1;
|
|
5679
|
+
const failed = ctx._fx;
|
|
5680
|
+
if (failed !== void 0 && failed.length > 0) {
|
|
5681
|
+
ctx._fe = pos;
|
|
5682
|
+
return -1;
|
|
5683
|
+
}
|
|
5684
|
+
}
|
|
5685
|
+
ctx._fe = pos;
|
|
5686
|
+
ctx._fx = choiceFx;
|
|
5687
|
+
return -1;
|
|
5688
|
+
};
|
|
5689
|
+
return {
|
|
5690
|
+
match: (input, pos) => {
|
|
5691
|
+
const arm = select(lead(input, pos));
|
|
5692
|
+
return arm < 0 ? -1 : matchArm(arm, input, pos);
|
|
5693
|
+
},
|
|
5694
|
+
run: runArm
|
|
5695
|
+
};
|
|
5696
|
+
}
|
|
5502
5697
|
function notNode(body, failure) {
|
|
5698
|
+
const bodyMatch = body.match;
|
|
5503
5699
|
return {
|
|
5504
|
-
match: (input, pos) =>
|
|
5700
|
+
match: (input, pos) => bodyMatch(input, pos) < 0 ? pos : -1,
|
|
5505
5701
|
run: (input, pos, ctx) => {
|
|
5506
|
-
if (
|
|
5702
|
+
if (bodyMatch(input, pos) < 0) return pos;
|
|
5507
5703
|
ctx._fe = pos;
|
|
5508
5704
|
ctx._fx = failure;
|
|
5509
5705
|
return -1;
|
|
@@ -5511,18 +5707,57 @@ function notNode(body, failure) {
|
|
|
5511
5707
|
};
|
|
5512
5708
|
}
|
|
5513
5709
|
function optionalNode(body) {
|
|
5710
|
+
const bodyMatch = body.match, bodyRun = body.run;
|
|
5514
5711
|
return {
|
|
5515
5712
|
match: (input, pos) => {
|
|
5516
|
-
const end =
|
|
5713
|
+
const end = bodyMatch(input, pos);
|
|
5517
5714
|
return end < 0 ? pos : end;
|
|
5518
5715
|
},
|
|
5519
5716
|
run: (input, pos, ctx) => {
|
|
5520
5717
|
ctx._fc = false;
|
|
5521
|
-
const end =
|
|
5718
|
+
const end = bodyRun(input, pos, ctx);
|
|
5522
5719
|
return end < 0 && !committed(ctx) ? pos : end;
|
|
5523
5720
|
}
|
|
5524
5721
|
};
|
|
5525
5722
|
}
|
|
5723
|
+
function repeatNode(item, min, max) {
|
|
5724
|
+
const itemMatch = item.match, itemRun = item.run;
|
|
5725
|
+
return {
|
|
5726
|
+
match: (input, pos) => {
|
|
5727
|
+
let cur = pos;
|
|
5728
|
+
let count = 0;
|
|
5729
|
+
for (; ; ) {
|
|
5730
|
+
if (max >= 0 && count >= max) break;
|
|
5731
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5732
|
+
if (optional2 && cur >= input.length) break;
|
|
5733
|
+
const end = itemMatch(input, cur);
|
|
5734
|
+
if (end < 0 || optional2 && end === cur) break;
|
|
5735
|
+
cur = end;
|
|
5736
|
+
count++;
|
|
5737
|
+
}
|
|
5738
|
+
return count < min ? -1 : cur;
|
|
5739
|
+
},
|
|
5740
|
+
run: (input, pos, ctx) => {
|
|
5741
|
+
let cur = pos;
|
|
5742
|
+
let count = 0;
|
|
5743
|
+
for (; ; ) {
|
|
5744
|
+
if (max >= 0 && count >= max) break;
|
|
5745
|
+
const optional2 = count >= min && (count > 0 || min === 0);
|
|
5746
|
+
if (optional2 && cur >= input.length) break;
|
|
5747
|
+
ctx._fc = false;
|
|
5748
|
+
const end = itemRun(input, cur, ctx);
|
|
5749
|
+
if (end < 0) {
|
|
5750
|
+
if (committed(ctx)) return -1;
|
|
5751
|
+
break;
|
|
5752
|
+
}
|
|
5753
|
+
if (optional2 && end === cur) break;
|
|
5754
|
+
cur = end;
|
|
5755
|
+
count++;
|
|
5756
|
+
}
|
|
5757
|
+
return count < min ? -1 : cur;
|
|
5758
|
+
}
|
|
5759
|
+
};
|
|
5760
|
+
}
|
|
5526
5761
|
function fixedTreeRunner(words, matchers, classes, expected) {
|
|
5527
5762
|
const stack = [];
|
|
5528
5763
|
const pop = () => {
|
|
@@ -5550,9 +5785,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5550
5785
|
else stack.push(sequence5(nodes2[0], nodes2[1], nodes2[2], nodes2[3], nodes2[4]));
|
|
5551
5786
|
continue;
|
|
5552
5787
|
}
|
|
5553
|
-
if (op
|
|
5554
|
-
const count =
|
|
5788
|
+
if (op === LEX_NODE_CHOICE) {
|
|
5789
|
+
const count = words[at++];
|
|
5790
|
+
const exclusive = words[at++];
|
|
5791
|
+
if (exclusive !== 0 && exclusive !== 1) throw new TypeError("table lexical tree choice has an invalid dispatch mode");
|
|
5555
5792
|
const choiceFx = expected[words[at++]];
|
|
5793
|
+
if (!Number.isInteger(count) || count < 2 || count > stack.length) {
|
|
5794
|
+
throw new TypeError("table lexical tree choice has an invalid arm count");
|
|
5795
|
+
}
|
|
5556
5796
|
if (choiceFx === void 0) throw new TypeError("table lexical tree choice has an invalid expected set");
|
|
5557
5797
|
const armClasses = [];
|
|
5558
5798
|
const armFx = [];
|
|
@@ -5565,7 +5805,7 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5565
5805
|
armFx.push(fx);
|
|
5566
5806
|
}
|
|
5567
5807
|
const arms = Array.from({ length: count }, pop).reverse();
|
|
5568
|
-
stack.push(choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5808
|
+
stack.push(exclusive === 1 ? exclusiveChoiceNode(arms, armClasses, choiceFx) : choiceNode(arms, armClasses, armFx, choiceFx));
|
|
5569
5809
|
continue;
|
|
5570
5810
|
}
|
|
5571
5811
|
if (op === LEX_NODE_NOT) {
|
|
@@ -5578,6 +5818,14 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5578
5818
|
stack.push(optionalNode(pop()));
|
|
5579
5819
|
continue;
|
|
5580
5820
|
}
|
|
5821
|
+
if (op === LEX_NODE_REPEAT) {
|
|
5822
|
+
const min = words[at++], max = words[at++];
|
|
5823
|
+
if (!Number.isInteger(min) || min < 0 || !Number.isInteger(max) || max >= 0 && max < min) {
|
|
5824
|
+
throw new TypeError("table lexical tree repeat has invalid bounds");
|
|
5825
|
+
}
|
|
5826
|
+
stack.push(repeatNode(pop(), min, max));
|
|
5827
|
+
continue;
|
|
5828
|
+
}
|
|
5581
5829
|
throw new TypeError("table lexical tree has an unknown fixed body");
|
|
5582
5830
|
}
|
|
5583
5831
|
if (stack.length !== 1) throw new TypeError("table lexical tree does not resolve to one root body");
|
|
@@ -5594,7 +5842,7 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
5594
5842
|
if (!Number.isInteger(spec[2]) || spec[2] < 0) {
|
|
5595
5843
|
throw new TypeError("table balanced lexical program has an invalid scan reference");
|
|
5596
5844
|
}
|
|
5597
|
-
const
|
|
5845
|
+
const run2 = (_input, _pos, ctx, scan) => {
|
|
5598
5846
|
if (scan === void 0) throw new TypeError("table balanced lexical program lost its scan body");
|
|
5599
5847
|
const result = scan.parse(_input, _pos, ctx);
|
|
5600
5848
|
if (!result.ok) {
|
|
@@ -5604,7 +5852,7 @@ function buildLexProgramRunner(spec, matchers, classes, expected) {
|
|
|
5604
5852
|
}
|
|
5605
5853
|
return result.span.end;
|
|
5606
5854
|
};
|
|
5607
|
-
return Object.assign(
|
|
5855
|
+
return Object.assign(run2, { scan: spec[2] });
|
|
5608
5856
|
}
|
|
5609
5857
|
if (spec[0] === 2) return fixedTreeRunner(spec.slice(2), matchers, classes, expected);
|
|
5610
5858
|
if (spec[0] === 1) {
|
|
@@ -5732,6 +5980,12 @@ function scanRefs(s) {
|
|
|
5732
5980
|
refs.push(...s.skip);
|
|
5733
5981
|
return refs;
|
|
5734
5982
|
}
|
|
5983
|
+
function assemblyExtraIps(prog) {
|
|
5984
|
+
const ips = [];
|
|
5985
|
+
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) ips.push(r[0]);
|
|
5986
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) ips.push(r[0]);
|
|
5987
|
+
return ips;
|
|
5988
|
+
}
|
|
5735
5989
|
function expandCompact(p) {
|
|
5736
5990
|
if ("code" in p) return p;
|
|
5737
5991
|
return ownTableProgram({
|
|
@@ -5862,6 +6116,11 @@ function classHas2(cls, code) {
|
|
|
5862
6116
|
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
5863
6117
|
return false;
|
|
5864
6118
|
}
|
|
6119
|
+
function dispatchIsExclusive(arms, cc) {
|
|
6120
|
+
const resolved = [];
|
|
6121
|
+
for (const ci of arms) if (ci >= 0) resolved[ci] = resolveClass(cc[ci]);
|
|
6122
|
+
return resolveDispatch(arms, resolved).exclusive;
|
|
6123
|
+
}
|
|
5865
6124
|
function resolveDispatch(arms, cc) {
|
|
5866
6125
|
const ascii = new Uint8Array(128);
|
|
5867
6126
|
const hi = [];
|
|
@@ -6453,6 +6712,111 @@ function classifyRuleMap(ruleMap) {
|
|
|
6453
6712
|
};
|
|
6454
6713
|
}
|
|
6455
6714
|
|
|
6715
|
+
// src/table/factor-choice.ts
|
|
6716
|
+
var DERIVED = /* @__PURE__ */ new Set(["_tag", "_meta", "_def", "_parseScalar", "_stickyRegex", "parse"]);
|
|
6717
|
+
function isCombinator(v) {
|
|
6718
|
+
return typeof v === "object" && v !== null && "_def" in v && "_meta" in v;
|
|
6719
|
+
}
|
|
6720
|
+
function sameComb(a, b, depth) {
|
|
6721
|
+
if (a === b) return true;
|
|
6722
|
+
if (depth > 32 || a._tag !== b._tag) return false;
|
|
6723
|
+
for (const k of Object.keys(a)) if (!DERIVED.has(k)) return false;
|
|
6724
|
+
for (const k of Object.keys(b)) if (!DERIVED.has(k)) return false;
|
|
6725
|
+
return sameFields(a._def, b._def, depth, void 0);
|
|
6726
|
+
}
|
|
6727
|
+
function sameValue(u, v, depth) {
|
|
6728
|
+
if (u === v) return true;
|
|
6729
|
+
if (isCombinator(u) && isCombinator(v)) return sameComb(u, v, depth + 1);
|
|
6730
|
+
if (Array.isArray(u) && Array.isArray(v)) return u.length === v.length && u.every((x, i) => sameValue(x, v[i], depth));
|
|
6731
|
+
if (typeof u === "object" && u !== null && typeof v === "object" && v !== null && Object.getPrototypeOf(u) === Object.prototype && Object.getPrototypeOf(v) === Object.prototype) {
|
|
6732
|
+
return sameFields(u, v, depth, void 0);
|
|
6733
|
+
}
|
|
6734
|
+
return false;
|
|
6735
|
+
}
|
|
6736
|
+
function sameFields(x, y, depth, skip) {
|
|
6737
|
+
const kx = Object.keys(x).filter((k) => k !== skip && x[k] !== void 0);
|
|
6738
|
+
const ky = Object.keys(y).filter((k) => k !== skip && y[k] !== void 0);
|
|
6739
|
+
if (kx.length !== ky.length) return false;
|
|
6740
|
+
for (const k of kx) {
|
|
6741
|
+
if (!(k in y)) return false;
|
|
6742
|
+
const u = x[k];
|
|
6743
|
+
const v = y[k];
|
|
6744
|
+
if (k === "fn" && typeof u === "function" && typeof v === "function" && u !== v) {
|
|
6745
|
+
if (typeof x.fnSrc !== "string" || x.fnSrc === "" || x.fnSrc !== y.fnSrc) return false;
|
|
6746
|
+
continue;
|
|
6747
|
+
}
|
|
6748
|
+
if (!sameValue(u, v, depth)) return false;
|
|
6749
|
+
}
|
|
6750
|
+
return true;
|
|
6751
|
+
}
|
|
6752
|
+
function rewrap(w, body) {
|
|
6753
|
+
const d = w._def;
|
|
6754
|
+
let out;
|
|
6755
|
+
if (d.tag === "leaf") {
|
|
6756
|
+
out = d.cstValue === "source" ? sourceLeaf(body, d.fn) : leaf(body, d.fn);
|
|
6757
|
+
if (d.fnSrc !== void 0) out._def.fnSrc = d.fnSrc;
|
|
6758
|
+
} else if (d.tag === "grammar") {
|
|
6759
|
+
out = d.clearTrivia === true ? noTrivia(body) : parser({ trivia: d.triviaParser ?? null }, body);
|
|
6760
|
+
} else return void 0;
|
|
6761
|
+
return sameFields(d, out._def, 0, "parser") ? out : void 0;
|
|
6762
|
+
}
|
|
6763
|
+
function unusedOf(seq) {
|
|
6764
|
+
return seq._def.tag === "sequence" && seq._def.valueUnused === true;
|
|
6765
|
+
}
|
|
6766
|
+
function never(c) {
|
|
6767
|
+
const t = c._def.tag;
|
|
6768
|
+
return t === "optional" || t === "many";
|
|
6769
|
+
}
|
|
6770
|
+
function factorSharedEnds(d) {
|
|
6771
|
+
const arms = d.parsers;
|
|
6772
|
+
if (arms.length < 2) return void 0;
|
|
6773
|
+
if (d.strategy.tag !== "firstMatch" && d.strategy.tag !== "sharedPrefix") return void 0;
|
|
6774
|
+
if (d.gates.some((g) => g !== null) || d.autoNot.some((a) => a !== null)) return void 0;
|
|
6775
|
+
const shapes = [];
|
|
6776
|
+
for (const arm of arms) {
|
|
6777
|
+
const wrappers = [];
|
|
6778
|
+
let c = arm;
|
|
6779
|
+
while ((c._def.tag === "leaf" || c._def.tag === "grammar") && wrappers.length < 4) {
|
|
6780
|
+
wrappers.push(c);
|
|
6781
|
+
c = c._def.parser;
|
|
6782
|
+
}
|
|
6783
|
+
if (c._def.tag !== "sequence" || c._def.parsers.length < 2) return void 0;
|
|
6784
|
+
shapes.push({ wrappers, terms: c._def.parsers, seq: c });
|
|
6785
|
+
}
|
|
6786
|
+
const first = shapes[0];
|
|
6787
|
+
const n = first.terms.length;
|
|
6788
|
+
for (const s of shapes) {
|
|
6789
|
+
if (s.wrappers.length !== first.wrappers.length || s.terms.length !== n) return void 0;
|
|
6790
|
+
if (unusedOf(s.seq) !== unusedOf(first.seq)) return void 0;
|
|
6791
|
+
for (let j = 0; j < s.wrappers.length; j++) {
|
|
6792
|
+
const a = first.wrappers[j]._def;
|
|
6793
|
+
const b = s.wrappers[j]._def;
|
|
6794
|
+
if (a.tag !== b.tag || !sameFields(a, b, 0, "parser")) return void 0;
|
|
6795
|
+
}
|
|
6796
|
+
}
|
|
6797
|
+
let at = -1;
|
|
6798
|
+
for (let i = 0; i < n; i++) {
|
|
6799
|
+
if (shapes.every((s) => sameComb(s.terms[i], first.terms[i], 0))) continue;
|
|
6800
|
+
if (at >= 0) return void 0;
|
|
6801
|
+
at = i;
|
|
6802
|
+
}
|
|
6803
|
+
if (at < 0) return void 0;
|
|
6804
|
+
for (let i = at + 1; i < n; i++) if (!never(first.terms[i])) return void 0;
|
|
6805
|
+
if (arms.some((a) => mayCommitFailure(a))) return void 0;
|
|
6806
|
+
const middle = choice(...shapes.map((s) => s.terms[at]));
|
|
6807
|
+
if (middle._def.tag === "choice" && middle._def.autoNot.some((a) => a !== null)) return void 0;
|
|
6808
|
+
const st = middle._def.tag === "choice" ? middle._def.strategy : void 0;
|
|
6809
|
+
if (st === void 0 || st.tag !== "firstMatch" && st.tag !== "sharedPrefix" && !(st.tag === "literalsLongestFirst" && st.sortedIndices.every((x, i) => x === i))) return void 0;
|
|
6810
|
+
let out = sequence(
|
|
6811
|
+
...[...first.terms.slice(0, at), middle, ...first.terms.slice(at + 1)]
|
|
6812
|
+
);
|
|
6813
|
+
if (unusedOf(first.seq)) {
|
|
6814
|
+
out._def.valueUnused = true;
|
|
6815
|
+
}
|
|
6816
|
+
for (let j = first.wrappers.length - 1; j >= 0 && out !== void 0; j--) out = rewrap(first.wrappers[j], out);
|
|
6817
|
+
return out === void 0 ? void 0 : attempt(out);
|
|
6818
|
+
}
|
|
6819
|
+
|
|
6456
6820
|
// src/table/ops.ts
|
|
6457
6821
|
var OP_LIT = 1;
|
|
6458
6822
|
var OP_RX = 2;
|
|
@@ -6496,6 +6860,7 @@ var OP_SCOPE_PLAIN = 41;
|
|
|
6496
6860
|
var OP_LEX_BODY = 42;
|
|
6497
6861
|
var OP_LEX_PROGRAM = 43;
|
|
6498
6862
|
var OP_SOURCE_LEAF = 44;
|
|
6863
|
+
var OP_RGATE = 45;
|
|
6499
6864
|
var OP_DISPATCH = 25;
|
|
6500
6865
|
var OP_ROUTED = 26;
|
|
6501
6866
|
var OP_NAMES = {
|
|
@@ -6515,6 +6880,7 @@ var OP_NAMES = {
|
|
|
6515
6880
|
[OP_PEEK]: "PEEK",
|
|
6516
6881
|
[OP_LEAF]: "LEAF",
|
|
6517
6882
|
[OP_SOURCE_LEAF]: "SOURCE_LEAF",
|
|
6883
|
+
[OP_RGATE]: "RGATE",
|
|
6518
6884
|
[OP_EMPTY]: "EMPTY",
|
|
6519
6885
|
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
6520
6886
|
[OP_RX_TRACK]: "RX_TRACK",
|
|
@@ -6595,7 +6961,10 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
6595
6961
|
const token2 = { strategy: "token", estimatedOps: 2, body };
|
|
6596
6962
|
return token2.estimatedOps < character.estimatedOps ? token2 : character;
|
|
6597
6963
|
}
|
|
6598
|
-
function
|
|
6964
|
+
function reinstallsRuleTrivia(reference, target) {
|
|
6965
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
6966
|
+
}
|
|
6967
|
+
function directTokenBodyParser(parser2, resolve3, scope) {
|
|
6599
6968
|
const outer = parser2._def;
|
|
6600
6969
|
if (outer.tag !== "token") return void 0;
|
|
6601
6970
|
let body = outer.parser;
|
|
@@ -6605,12 +6974,13 @@ function directTokenBodyParser(parser2, resolve3) {
|
|
|
6605
6974
|
const wrapper = body._def;
|
|
6606
6975
|
if (wrapper.tag === "grammar") {
|
|
6607
6976
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
6977
|
+
if (scope !== void 0) scope.cleared = true;
|
|
6608
6978
|
body = wrapper.parser;
|
|
6609
6979
|
continue;
|
|
6610
6980
|
}
|
|
6611
6981
|
if (wrapper.tag === "lazy") {
|
|
6612
6982
|
const target = resolvedLazyTarget(body, resolve3);
|
|
6613
|
-
if (target === void 0) return void 0;
|
|
6983
|
+
if (target === void 0 || reinstallsRuleTrivia(body, target)) return void 0;
|
|
6614
6984
|
body = target;
|
|
6615
6985
|
continue;
|
|
6616
6986
|
}
|
|
@@ -6782,7 +7152,7 @@ function directNot2TokenBody(parser2, resolve3) {
|
|
|
6782
7152
|
terminal
|
|
6783
7153
|
};
|
|
6784
7154
|
}
|
|
6785
|
-
function directFixedLexNode(parser2, resolve3, active, pureOnly = false) {
|
|
7155
|
+
function directFixedLexNode(parser2, resolve3, active, pureOnly = false, cleared = false) {
|
|
6786
7156
|
let current = parser2;
|
|
6787
7157
|
const wrappers = /* @__PURE__ */ new Set();
|
|
6788
7158
|
while (!wrappers.has(current)) {
|
|
@@ -6790,7 +7160,7 @@ function directFixedLexNode(parser2, resolve3, active, pureOnly = false) {
|
|
|
6790
7160
|
const def = current._def;
|
|
6791
7161
|
if (def.tag === "lazy") {
|
|
6792
7162
|
const target = resolvedLazyTarget(current, resolve3);
|
|
6793
|
-
if (target === void 0) return void 0;
|
|
7163
|
+
if (target === void 0 || reinstallsRuleTrivia(current, target)) return void 0;
|
|
6794
7164
|
current = target;
|
|
6795
7165
|
continue;
|
|
6796
7166
|
}
|
|
@@ -6808,30 +7178,33 @@ function directFixedLexNode(parser2, resolve3, active, pureOnly = false) {
|
|
|
6808
7178
|
if (terminal !== void 0) return { kind: "terminal", terminal };
|
|
6809
7179
|
const def = current._def;
|
|
6810
7180
|
if (def.tag === "grammar") {
|
|
7181
|
+
if (def.triviaParser === void 0 && def.captureTrivia !== true && def.rootCapture !== "opaque" && def.constructionCaptureTriviaKinds === void 0) {
|
|
7182
|
+
return directFixedLexNode(def.parser, resolve3, active, pureOnly, cleared || def.clearTrivia === true);
|
|
7183
|
+
}
|
|
6811
7184
|
if (!pureOnly || def.parser._def.tag !== "token" && (def.clearTrivia !== true || def.triviaParser !== void 0 || def.captureTrivia === true || def.rootCapture === "opaque")) return void 0;
|
|
6812
|
-
return directFixedLexNode(def.parser, resolve3, active, true);
|
|
7185
|
+
return directFixedLexNode(def.parser, resolve3, active, true, cleared);
|
|
6813
7186
|
}
|
|
6814
7187
|
if (def.tag === "sequence") {
|
|
6815
7188
|
if (def.parsers.length < 2 || def.parsers.length > 5) return void 0;
|
|
6816
|
-
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve3, active, pureOnly));
|
|
7189
|
+
const parts = def.parsers.map((part) => directFixedLexNode(part, resolve3, active, pureOnly, cleared));
|
|
6817
7190
|
if (parts.some((part) => part === void 0)) return void 0;
|
|
6818
7191
|
return { kind: "sequence", parts };
|
|
6819
7192
|
}
|
|
6820
7193
|
if (def.tag === "choice") {
|
|
6821
|
-
if (def.parsers.length
|
|
6822
|
-
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve3, active, pureOnly));
|
|
7194
|
+
if (def.parsers.length < 2 || def.strategy.tag !== "firstMatch" || def.gates.some((gate2) => gate2 !== null) || def.autoNot.some((check) => check !== null)) return void 0;
|
|
7195
|
+
const arms = def.parsers.map((arm) => directFixedLexNode(arm, resolve3, active, pureOnly, cleared));
|
|
6823
7196
|
if (arms.some((arm) => arm === void 0)) return void 0;
|
|
6824
|
-
const final = classifyFinalChoice(def.parsers, resolve3);
|
|
6825
7197
|
return {
|
|
6826
7198
|
kind: "choice",
|
|
6827
7199
|
arms,
|
|
6828
|
-
|
|
7200
|
+
parsers: def.parsers,
|
|
7201
|
+
cleared,
|
|
6829
7202
|
armExpected: def.parsers.map(deriveExpected),
|
|
6830
7203
|
expected: def.parsers.flatMap(deriveExpected)
|
|
6831
7204
|
};
|
|
6832
7205
|
}
|
|
6833
7206
|
if (def.tag === "not") {
|
|
6834
|
-
const body = directFixedLexNode(def.parser, resolve3, active, true);
|
|
7207
|
+
const body = directFixedLexNode(def.parser, resolve3, active, true, cleared);
|
|
6835
7208
|
return body === void 0 ? void 0 : {
|
|
6836
7209
|
kind: "not",
|
|
6837
7210
|
body,
|
|
@@ -6839,18 +7212,28 @@ function directFixedLexNode(parser2, resolve3, active, pureOnly = false) {
|
|
|
6839
7212
|
};
|
|
6840
7213
|
}
|
|
6841
7214
|
if (def.tag === "optional") {
|
|
6842
|
-
const body = directFixedLexNode(def.parser, resolve3, active, pureOnly);
|
|
7215
|
+
const body = directFixedLexNode(def.parser, resolve3, active, pureOnly, cleared);
|
|
6843
7216
|
return body === void 0 ? void 0 : { kind: "optional", body };
|
|
6844
7217
|
}
|
|
7218
|
+
if (def.tag === "many" || def.tag === "oneOrMore") {
|
|
7219
|
+
const body = directFixedLexNode(def.parser, resolve3, active, pureOnly, cleared);
|
|
7220
|
+
return body === void 0 ? void 0 : {
|
|
7221
|
+
kind: "repeat",
|
|
7222
|
+
body,
|
|
7223
|
+
min: def.tag === "many" ? 0 : def.min,
|
|
7224
|
+
max: def.max ?? -1
|
|
7225
|
+
};
|
|
7226
|
+
}
|
|
6845
7227
|
return void 0;
|
|
6846
7228
|
} finally {
|
|
6847
7229
|
active.delete(current);
|
|
6848
7230
|
}
|
|
6849
7231
|
}
|
|
6850
7232
|
function directFixedTokenBody(parser2, resolve3) {
|
|
6851
|
-
const
|
|
7233
|
+
const scope = { cleared: false };
|
|
7234
|
+
const body = directTokenBodyParser(parser2, resolve3, scope);
|
|
6852
7235
|
if (body === void 0) return void 0;
|
|
6853
|
-
const root = directFixedLexNode(body, resolve3, /* @__PURE__ */ new Set());
|
|
7236
|
+
const root = directFixedLexNode(body, resolve3, /* @__PURE__ */ new Set(), false, scope.cleared);
|
|
6854
7237
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
6855
7238
|
}
|
|
6856
7239
|
function directBalancedTokenBody(parser2, resolve3) {
|
|
@@ -7097,13 +7480,16 @@ var Encoder = class {
|
|
|
7097
7480
|
}
|
|
7098
7481
|
case "choice": {
|
|
7099
7482
|
for (const arm of node2.arms) if (!emitNode(arm)) return false;
|
|
7100
|
-
const
|
|
7101
|
-
|
|
7102
|
-
|
|
7483
|
+
const final = classifyFinalChoice(
|
|
7484
|
+
node2.parsers,
|
|
7485
|
+
this.refResolver(),
|
|
7486
|
+
node2.cleared ? void 0 : this.activeTrivia
|
|
7487
|
+
);
|
|
7488
|
+
const classes = final.firstSets.map((first, i) => final.nullable[i] ? -1 : this.charClass(first));
|
|
7489
|
+
const exclusive = final.exclusive && classes.every((cls) => cls >= 0);
|
|
7490
|
+
words.push(LEX_NODE_CHOICE, node2.arms.length, exclusive ? 1 : 0, this.expected(node2.expected));
|
|
7103
7491
|
for (let i = 0; i < node2.arms.length; i++) {
|
|
7104
|
-
|
|
7105
|
-
words.push(first.kind === "ranges" ? this.charClass(first) : -1);
|
|
7106
|
-
words.push(this.expected(node2.armExpected[i]));
|
|
7492
|
+
words.push(classes[i], this.expected(node2.armExpected[i]));
|
|
7107
7493
|
}
|
|
7108
7494
|
return true;
|
|
7109
7495
|
}
|
|
@@ -7115,6 +7501,10 @@ var Encoder = class {
|
|
|
7115
7501
|
if (!emitNode(node2.body)) return false;
|
|
7116
7502
|
words.push(LEX_NODE_OPTIONAL);
|
|
7117
7503
|
return true;
|
|
7504
|
+
case "repeat":
|
|
7505
|
+
if (!emitNode(node2.body)) return false;
|
|
7506
|
+
words.push(LEX_NODE_REPEAT, node2.min, node2.max);
|
|
7507
|
+
return true;
|
|
7118
7508
|
}
|
|
7119
7509
|
};
|
|
7120
7510
|
if (!emitNode(body.root)) return void 0;
|
|
@@ -7442,6 +7832,33 @@ var Encoder = class {
|
|
|
7442
7832
|
return childrenOf2(def);
|
|
7443
7833
|
}
|
|
7444
7834
|
}
|
|
7835
|
+
/**
|
|
7836
|
+
* THE FIRST-CHARACTER GATE OF AN `optional`, `not` OR `peek` CHILD.
|
|
7837
|
+
*
|
|
7838
|
+
* A non-nullable child cannot match at a character outside its first set, so
|
|
7839
|
+
* the wrapper's outcome there is already decided: `optional` yields `null`,
|
|
7840
|
+
* `not` succeeds, `peek` fails with its own set. The interpreter's `optional`
|
|
7841
|
+
* makes that test itself (`repeat.ts` `startsFirstSet`); the table entered the
|
|
7842
|
+
* child — a rollback mark, the call, the child's own failure — to learn it.
|
|
7843
|
+
*
|
|
7844
|
+
* The gate is an `OP_GATE` row around the child, so every engine runs it
|
|
7845
|
+
* unchanged, a probe or tolerant parse forwards through it as for a node's
|
|
7846
|
+
* gate, and the wrapper's row keeps its layout. The engines test the class
|
|
7847
|
+
* before taking the wrapper's mark. The first set is resolved through
|
|
7848
|
+
* `winners`, the analysis a choice arm's gate uses, so a composed rule's set
|
|
7849
|
+
* is the merged one. A scalar `not` child stays bare: `scalarTerminalNotChild`
|
|
7850
|
+
* already reduces it to one recognizer call.
|
|
7851
|
+
*/
|
|
7852
|
+
lookaheadGate(p, child) {
|
|
7853
|
+
const op = this.code[child];
|
|
7854
|
+
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;
|
|
7855
|
+
const rr = this.refResolver();
|
|
7856
|
+
if (matchesEmpty(p, /* @__PURE__ */ new Set(), rr)) return child;
|
|
7857
|
+
const cls = this.charClass(firstSetOf(p, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7858
|
+
if (cls < 0) return child;
|
|
7859
|
+
const e = deriveExpected(p);
|
|
7860
|
+
return this.emit(OP_GATE, cls, child, this.expected(e.length > 0 ? e : [p._tag]));
|
|
7861
|
+
}
|
|
7445
7862
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
7446
7863
|
charClass(fs3) {
|
|
7447
7864
|
if (fs3.kind !== "ranges" || fs3.ranges.length === 0) return -1;
|
|
@@ -7453,12 +7870,19 @@ var Encoder = class {
|
|
|
7453
7870
|
this.ccIndex.set(spec, i);
|
|
7454
7871
|
return i;
|
|
7455
7872
|
}
|
|
7456
|
-
/**
|
|
7457
|
-
*
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7873
|
+
/**
|
|
7874
|
+
* The first set a node's or an attempt's fail-fast gate tests. A bare
|
|
7875
|
+
* cross-rule ref resolves through `winners` (a compose OVERRIDE may widen
|
|
7876
|
+
* it). Any other body keeps its construction-time `_meta.firstSet`, except
|
|
7877
|
+
* where that is `any`: under `compose()` a body that reaches a rule of
|
|
7878
|
+
* another piece is built before that rule exists, so its cached set is
|
|
7879
|
+
* `any` and the node got NO gate (jess's `CompoundSelector` was entered at
|
|
7880
|
+
* `{`, `Call` at `}`). The resolved set is the one a choice arm's gate uses,
|
|
7881
|
+
* over the final merged map.
|
|
7882
|
+
*/
|
|
7883
|
+
gateFirstSet(p) {
|
|
7884
|
+
const cached = p._meta.firstSet;
|
|
7885
|
+
return p._def.tag === "lazy" || cached.kind === "any" ? firstSetOf(p, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : cached;
|
|
7462
7886
|
}
|
|
7463
7887
|
/**
|
|
7464
7888
|
* Wrap one choice arm in its `autoNot` checks (`OP_REJECT`).
|
|
@@ -7586,6 +8010,50 @@ var Encoder = class {
|
|
|
7586
8010
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
7587
8011
|
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
7588
8012
|
}
|
|
8013
|
+
/**
|
|
8014
|
+
* The `OP_RGATE` operands of a choice arm that opens with `routed()`, or
|
|
8015
|
+
* `undefined`. Through `node()`/scope wrappers and first sequence terms, the
|
|
8016
|
+
* arm's next term after the routed token is found; the gate is that term's
|
|
8017
|
+
* first characters, with the trivia in force at the boundary before it, so
|
|
8018
|
+
* the arm is entered only where it can get past the token. The term must be
|
|
8019
|
+
* unable to match empty or to commit, so a miss is exactly that term failing
|
|
8020
|
+
* at the token's end with its own set.
|
|
8021
|
+
*/
|
|
8022
|
+
routedArmGate(arm) {
|
|
8023
|
+
const walk = (p, trivia2, depth) => {
|
|
8024
|
+
if (depth > 16) return void 0;
|
|
8025
|
+
const d = p._def;
|
|
8026
|
+
switch (d.tag) {
|
|
8027
|
+
case "routed":
|
|
8028
|
+
return "end";
|
|
8029
|
+
case "node":
|
|
8030
|
+
return walk(d.parser, trivia2, depth + 1);
|
|
8031
|
+
case "grammar":
|
|
8032
|
+
return walk(d.parser, d.clearTrivia === true ? void 0 : d.triviaParser ?? trivia2, depth + 1);
|
|
8033
|
+
case "sequence": {
|
|
8034
|
+
const head = d.parsers[0];
|
|
8035
|
+
if (head === void 0) return void 0;
|
|
8036
|
+
const r = walk(head, trivia2, depth + 1);
|
|
8037
|
+
if (r !== "end") return r;
|
|
8038
|
+
const next2 = d.parsers[1];
|
|
8039
|
+
return next2 === void 0 ? "end" : { next: next2, boundary: trivia2 };
|
|
8040
|
+
}
|
|
8041
|
+
default:
|
|
8042
|
+
return void 0;
|
|
8043
|
+
}
|
|
8044
|
+
};
|
|
8045
|
+
const follow = walk(arm, this.activeTrivia, 0);
|
|
8046
|
+
if (follow === void 0 || follow === "end") return void 0;
|
|
8047
|
+
const rr = this.refResolver();
|
|
8048
|
+
const { next, boundary } = follow;
|
|
8049
|
+
if (matchesEmpty(next, /* @__PURE__ */ new Set(), rr) || mayCommitFailure(next, rr, this.commitFailureMemo)) return void 0;
|
|
8050
|
+
const nextTag = next._def.tag;
|
|
8051
|
+
if (nextTag !== "literal" && nextTag !== "regex" && nextTag !== "keywords" && nextTag !== "label") return void 0;
|
|
8052
|
+
const first = firstSetOf(next, /* @__PURE__ */ new Set(), rr, boundary);
|
|
8053
|
+
const cls = this.charClass(boundary === void 0 ? first : union(first, firstSetOf(boundary, /* @__PURE__ */ new Set(), rr)));
|
|
8054
|
+
if (cls < 0) return void 0;
|
|
8055
|
+
return { cls, fx: this.expected(deriveExpected(next)) };
|
|
8056
|
+
}
|
|
7589
8057
|
node(p) {
|
|
7590
8058
|
const lazyRef = p._def.tag === "lazy";
|
|
7591
8059
|
const scopeKey = lazyRef ? this.activeTrivia : void 0;
|
|
@@ -7710,6 +8178,10 @@ var Encoder = class {
|
|
|
7710
8178
|
return head;
|
|
7711
8179
|
}
|
|
7712
8180
|
case "choice": {
|
|
8181
|
+
if (this.plan === void 0) {
|
|
8182
|
+
const factored = factorSharedEnds(d);
|
|
8183
|
+
if (factored !== void 0) return this.node(factored).ip;
|
|
8184
|
+
}
|
|
7713
8185
|
if (d.strategy.tag === "greedyClassify") {
|
|
7714
8186
|
const superIndex = d.strategy.superIndex;
|
|
7715
8187
|
const sup = this.node(d.parsers[superIndex]).ip;
|
|
@@ -7733,9 +8205,12 @@ var Encoder = class {
|
|
|
7733
8205
|
const kids = arms.map((c, k) => {
|
|
7734
8206
|
const src = order[k];
|
|
7735
8207
|
const checks = d.autoNot[src];
|
|
7736
|
-
const inner = this.node(c).ip;
|
|
7737
|
-
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
7738
8208
|
const gate2 = d.gates[src];
|
|
8209
|
+
const plain = (checks === null || checks === void 0 || checks.length === 0) && (gate2 === null || gate2 === void 0);
|
|
8210
|
+
const routedGate = plain ? this.routedArmGate(c) : void 0;
|
|
8211
|
+
const body = this.node(c).ip;
|
|
8212
|
+
const inner = routedGate === void 0 ? body : this.emit(OP_RGATE, routedGate.cls, body, routedGate.fx);
|
|
8213
|
+
const ip = checks === null || checks === void 0 || checks.length === 0 ? inner : this.reject(inner, checks);
|
|
7739
8214
|
const gated = gate2 === null || gate2 === void 0 ? ip : this.emit(OP_ARMGATE, this.fn(gate2, d.gateSrcs?.[src] ?? null), ip, this.expected(deriveExpected(c)));
|
|
7740
8215
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
7741
8216
|
});
|
|
@@ -7763,6 +8238,12 @@ var Encoder = class {
|
|
|
7763
8238
|
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
7764
8239
|
}
|
|
7765
8240
|
}
|
|
8241
|
+
if (d.gates.some((g) => g !== null && g !== void 0) && !dispatchIsExclusive(classes, this.cc)) {
|
|
8242
|
+
for (let k = 0; k < classes.length; k++) {
|
|
8243
|
+
const gate2 = d.gates[order[k]];
|
|
8244
|
+
if (gate2 !== null && gate2 !== void 0) classes[k] = -1;
|
|
8245
|
+
}
|
|
8246
|
+
}
|
|
7766
8247
|
const dispIdx = this.disp.length;
|
|
7767
8248
|
this.disp.push(classes);
|
|
7768
8249
|
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
@@ -7792,7 +8273,7 @@ var Encoder = class {
|
|
|
7792
8273
|
case "oneOrMore": {
|
|
7793
8274
|
const child = this.node(d.parser).ip;
|
|
7794
8275
|
const rr = this.refResolver();
|
|
7795
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.
|
|
8276
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.charClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7796
8277
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
7797
8278
|
const min = d.tag === "many" ? 0 : d.min;
|
|
7798
8279
|
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);
|
|
@@ -7816,7 +8297,7 @@ var Encoder = class {
|
|
|
7816
8297
|
return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep2, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep2, flags);
|
|
7817
8298
|
}
|
|
7818
8299
|
case "optional": {
|
|
7819
|
-
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
8300
|
+
const head = this.emit(OP_OPT, this.lookaheadGate(d.parser, this.node(d.parser).ip));
|
|
7820
8301
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
7821
8302
|
return head;
|
|
7822
8303
|
}
|
|
@@ -7864,8 +8345,8 @@ var Encoder = class {
|
|
|
7864
8345
|
// every CST node, so this is load-bearing, not reflection trivia.
|
|
7865
8346
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7866
8347
|
);
|
|
7867
|
-
if (matchesEmpty(d.parser)) return body;
|
|
7868
|
-
const fs3 =
|
|
8348
|
+
if (matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return body;
|
|
8349
|
+
const fs3 = this.gateFirstSet(d.parser);
|
|
7869
8350
|
if (fs3.kind === "any") return body;
|
|
7870
8351
|
const cls = this.charClass(fs3);
|
|
7871
8352
|
if (cls < 0) return body;
|
|
@@ -7957,7 +8438,7 @@ var Encoder = class {
|
|
|
7957
8438
|
// other engine reported `['not(literal)']`. It hid because `expected` is a
|
|
7958
8439
|
// TOP-LEVEL field on `RunResult` and is NOT part of the identity digest.
|
|
7959
8440
|
case "not":
|
|
7960
|
-
return this.emit(OP_NOT, this.node(d.parser).ip, this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
8441
|
+
return this.emit(OP_NOT, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(false, d.parser._tag)));
|
|
7961
8442
|
case "guard":
|
|
7962
8443
|
return this.emit(OP_GUARD, this.fn(d.predicate, d.predSrc ?? null), this.expected(["gate"]));
|
|
7963
8444
|
case "adjacency":
|
|
@@ -7978,14 +8459,14 @@ var Encoder = class {
|
|
|
7978
8459
|
return this.emit(OP_WITHCTX, this.constant(d.extra), this.node(d.parser).ip);
|
|
7979
8460
|
}
|
|
7980
8461
|
case "peek":
|
|
7981
|
-
return this.emit(OP_PEEK, this.node(d.parser).ip, this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
8462
|
+
return this.emit(OP_PEEK, this.lookaheadGate(d.parser, this.node(d.parser).ip), this.expected(assertionFailureExpected(true, d.parser._tag)));
|
|
7982
8463
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
7983
8464
|
// lowering was correct only for a choice arm.
|
|
7984
8465
|
case "attempt": {
|
|
7985
8466
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
7986
8467
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7987
|
-
const fs3 =
|
|
7988
|
-
if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8468
|
+
const fs3 = this.gateFirstSet(d.parser);
|
|
8469
|
+
if (fs3.kind === "any" || matchesEmpty(d.parser, /* @__PURE__ */ new Set(), this.refResolver())) return inner;
|
|
7989
8470
|
const cls = this.charClass(fs3);
|
|
7990
8471
|
if (cls < 0) return inner;
|
|
7991
8472
|
const e = deriveExpected(d.parser);
|
|
@@ -8053,6 +8534,7 @@ var Encoder = class {
|
|
|
8053
8534
|
const slots = (ip) => {
|
|
8054
8535
|
switch (this.code[ip]) {
|
|
8055
8536
|
case OP_GATE:
|
|
8537
|
+
case OP_RGATE:
|
|
8056
8538
|
return [ip + 2];
|
|
8057
8539
|
case OP_RULE:
|
|
8058
8540
|
case OP_OPT:
|
|
@@ -9280,6 +9762,7 @@ function childSlots(code, ip, out) {
|
|
|
9280
9762
|
case OP_LEAF:
|
|
9281
9763
|
case OP_SOURCE_LEAF:
|
|
9282
9764
|
case OP_ARMGATE:
|
|
9765
|
+
case OP_RGATE:
|
|
9283
9766
|
out.push(code[ip + 2]);
|
|
9284
9767
|
return true;
|
|
9285
9768
|
// `ROUTED fallback` — the operand is an offset or −1. The routed token itself is
|
|
@@ -9363,6 +9846,42 @@ function reachableSites(code, roots) {
|
|
|
9363
9846
|
}
|
|
9364
9847
|
return seen;
|
|
9365
9848
|
}
|
|
9849
|
+
function passCollapse(code, ip, hostCst) {
|
|
9850
|
+
const flags = code[ip + 3];
|
|
9851
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return false;
|
|
9852
|
+
if (flags !== 32 && flags !== 34) return false;
|
|
9853
|
+
let at = code[ip + 2];
|
|
9854
|
+
for (let n = 0; n < 8; n++) {
|
|
9855
|
+
const op = code[at];
|
|
9856
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[at + 3] === 0) at = code[at + 2];
|
|
9857
|
+
else if (op === OP_RULE) at = code[at + 1];
|
|
9858
|
+
else break;
|
|
9859
|
+
}
|
|
9860
|
+
return code[at] === OP_NODE;
|
|
9861
|
+
}
|
|
9862
|
+
function gatedPassCollapse(code, ip, hostCst) {
|
|
9863
|
+
const flags = code[ip + 3];
|
|
9864
|
+
if (hostCst || code[ip] !== OP_NODE || code[ip + 1] < 0 || code[ip + 4] >= 0) return void 0;
|
|
9865
|
+
if (flags !== 32 && flags !== 34) return void 0;
|
|
9866
|
+
const seq = code[ip + 2];
|
|
9867
|
+
if (code[seq] !== OP_SEQ && code[seq] !== OP_SEQV) return void 0;
|
|
9868
|
+
const n = code[seq + 1];
|
|
9869
|
+
if (n < 2) return void 0;
|
|
9870
|
+
const leads = [];
|
|
9871
|
+
const lits = [];
|
|
9872
|
+
for (let i = 0; i < n - 1; i++) {
|
|
9873
|
+
const t = code[seq + 2 + i];
|
|
9874
|
+
if (code[t] !== OP_OPT && code[t] !== OP_NOT) return void 0;
|
|
9875
|
+
const g = code[t + 1];
|
|
9876
|
+
if (code[g] === OP_GATE) leads.push(g);
|
|
9877
|
+
else if (code[g] === OP_LIT) lits.push(code[g + 1]);
|
|
9878
|
+
else return void 0;
|
|
9879
|
+
}
|
|
9880
|
+
const last = code[seq + 2 + n - 1];
|
|
9881
|
+
let at = last;
|
|
9882
|
+
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];
|
|
9883
|
+
return code[at] === OP_NODE ? { leads, lits, last } : void 0;
|
|
9884
|
+
}
|
|
9366
9885
|
function transfer(code, ip, at, hostCst) {
|
|
9367
9886
|
const op = code[ip];
|
|
9368
9887
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
@@ -9374,14 +9893,18 @@ function transfer(code, ip, at, hostCst) {
|
|
|
9374
9893
|
}
|
|
9375
9894
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
9376
9895
|
const flags = code[ip + 3];
|
|
9896
|
+
if (passCollapse(code, ip, hostCst)) return at;
|
|
9897
|
+
const gated = gatedPassCollapse(code, ip, hostCst) !== void 0;
|
|
9377
9898
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
9378
9899
|
if (directChildren) {
|
|
9379
|
-
|
|
9900
|
+
const framed2 = { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
9901
|
+
return gated ? meet(at, framed2) : framed2;
|
|
9380
9902
|
}
|
|
9381
9903
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
9382
9904
|
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
9383
9905
|
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
9384
|
-
|
|
9906
|
+
const framed = { tri: at.tri, buf: true, raw, cap };
|
|
9907
|
+
return gated ? meet(at, framed) : framed;
|
|
9385
9908
|
}
|
|
9386
9909
|
if (op === OP_TOKEN) {
|
|
9387
9910
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
@@ -9419,6 +9942,40 @@ function computeSiteLabels(code, roots, hostCst) {
|
|
|
9419
9942
|
}
|
|
9420
9943
|
return { at: (ip) => labels.get(ip) ?? TOP };
|
|
9421
9944
|
}
|
|
9945
|
+
function scopeIsIdentity(code, ip, at) {
|
|
9946
|
+
const op = code[ip];
|
|
9947
|
+
if (op !== OP_SCOPE_PLAIN && !(op === OP_SCOPE && code[ip + 3] === 0)) return false;
|
|
9948
|
+
const ki = code[ip + 1];
|
|
9949
|
+
return at.tri === (ki < 0 ? TRI_NONE : ki);
|
|
9950
|
+
}
|
|
9951
|
+
function scanHandoffNeeded(code, ip, labels) {
|
|
9952
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9953
|
+
const stack = [ip];
|
|
9954
|
+
const kids = [];
|
|
9955
|
+
while (stack.length > 0) {
|
|
9956
|
+
const at = stack.pop();
|
|
9957
|
+
if (seen.has(at)) continue;
|
|
9958
|
+
seen.add(at);
|
|
9959
|
+
const l = labels.at(at);
|
|
9960
|
+
if (l.tri === TRI_UNKNOWN) return true;
|
|
9961
|
+
const op = code[at];
|
|
9962
|
+
if (op === OP_SCAN) return true;
|
|
9963
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
9964
|
+
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;
|
|
9965
|
+
kids.length = 0;
|
|
9966
|
+
if (!childSlots(code, at, kids)) return true;
|
|
9967
|
+
for (const c of kids) stack.push(c);
|
|
9968
|
+
}
|
|
9969
|
+
return false;
|
|
9970
|
+
}
|
|
9971
|
+
function triviaLeadRanges(tri, trivia2) {
|
|
9972
|
+
if (tri === TRI_NONE) return [];
|
|
9973
|
+
if (tri < 0) return void 0;
|
|
9974
|
+
const fs3 = trivia2[tri]?._meta.firstSet;
|
|
9975
|
+
if (fs3 === void 0) return void 0;
|
|
9976
|
+
if (fs3.kind === "empty") return [];
|
|
9977
|
+
return fs3.kind === "ranges" && fs3.ranges !== void 0 ? fs3.ranges : void 0;
|
|
9978
|
+
}
|
|
9422
9979
|
|
|
9423
9980
|
// src/table/scalar-terminal.ts
|
|
9424
9981
|
function makeScalarRecognizer(op, spec) {
|
|
@@ -9456,6 +10013,12 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
9456
10013
|
const op = code[child];
|
|
9457
10014
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
9458
10015
|
}
|
|
10016
|
+
function scalarTerminalPeekChild(code, ip) {
|
|
10017
|
+
if (code[ip] !== OP_PEEK) return -1;
|
|
10018
|
+
const child = code[ip + 1];
|
|
10019
|
+
const op = code[child];
|
|
10020
|
+
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
10021
|
+
}
|
|
9459
10022
|
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
9460
10023
|
const seen = /* @__PURE__ */ new Set();
|
|
9461
10024
|
let at = ip;
|
|
@@ -9633,6 +10196,59 @@ function leadingTriviaFieldAt(code, k, ip) {
|
|
|
9633
10196
|
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
9634
10197
|
}
|
|
9635
10198
|
|
|
10199
|
+
// src/table/hold-gap.ts
|
|
10200
|
+
var WRAPPERS = /* @__PURE__ */ new Set([
|
|
10201
|
+
OP_NODE,
|
|
10202
|
+
OP_XFORM,
|
|
10203
|
+
OP_LEAF,
|
|
10204
|
+
OP_SOURCE_LEAF,
|
|
10205
|
+
OP_TOKEN,
|
|
10206
|
+
OP_SCOPE,
|
|
10207
|
+
OP_SCOPE_CAP,
|
|
10208
|
+
OP_SCOPE_PLAIN,
|
|
10209
|
+
OP_FIELD,
|
|
10210
|
+
OP_LABEL,
|
|
10211
|
+
OP_EXPECT,
|
|
10212
|
+
OP_WITHCTX,
|
|
10213
|
+
OP_RULE,
|
|
10214
|
+
OP_ATTEMPT,
|
|
10215
|
+
OP_COV
|
|
10216
|
+
]);
|
|
10217
|
+
function rowNullable(code, k, ip, memo) {
|
|
10218
|
+
const hit = memo.get(ip);
|
|
10219
|
+
if (hit !== void 0) return hit;
|
|
10220
|
+
memo.set(ip, true);
|
|
10221
|
+
const op = code[ip];
|
|
10222
|
+
const kids = [];
|
|
10223
|
+
let out = true;
|
|
10224
|
+
if (op === OP_GATE) out = false;
|
|
10225
|
+
else if (op === OP_LIT || op === OP_LIT_CI) out = k[code[ip + 1]].length === 0;
|
|
10226
|
+
else if (op === OP_RX) {
|
|
10227
|
+
const re = k[code[ip + 1]];
|
|
10228
|
+
out = !(re instanceof RegExp) || regexCanMatchEmpty(re.source);
|
|
10229
|
+
} else if (op === OP_SEQ || op === OP_SEQV || op === OP_SEQX) {
|
|
10230
|
+
childSlots(code, ip, kids);
|
|
10231
|
+
out = kids.every((c) => rowNullable(code, k, c, memo));
|
|
10232
|
+
} else if (op === OP_CHOICE) {
|
|
10233
|
+
childSlots(code, ip, kids);
|
|
10234
|
+
out = kids.length === 0 || kids.some((c) => rowNullable(code, k, c, memo));
|
|
10235
|
+
} else if (op === OP_REP || op === OP_REPV) {
|
|
10236
|
+
out = code[ip + 2] === 0 || rowNullable(code, k, code[ip + 1], memo);
|
|
10237
|
+
} else if (WRAPPERS.has(op)) {
|
|
10238
|
+
if (childSlots(code, ip, kids) && kids.length === 1) out = rowNullable(code, k, kids[0], memo);
|
|
10239
|
+
}
|
|
10240
|
+
memo.set(ip, out);
|
|
10241
|
+
return out;
|
|
10242
|
+
}
|
|
10243
|
+
function holdsGap(code, k, base, n, i, memo) {
|
|
10244
|
+
if (i < 1 || i + 1 >= n) return false;
|
|
10245
|
+
const term = code[base + i];
|
|
10246
|
+
if (code[term] !== OP_NOT && code[term] !== OP_PEEK) return false;
|
|
10247
|
+
const next = code[base + i + 1];
|
|
10248
|
+
if (code[next] === OP_ADJ || leadingTriviaFieldAt(code, k, next)) return false;
|
|
10249
|
+
return !rowNullable(code, k, next, memo);
|
|
10250
|
+
}
|
|
10251
|
+
|
|
9636
10252
|
// src/table/emit-assembly.ts
|
|
9637
10253
|
var Unemittable = class extends Error {
|
|
9638
10254
|
construct;
|
|
@@ -9710,7 +10326,13 @@ var EMITTED_PARAMS = [
|
|
|
9710
10326
|
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
9711
10327
|
// old factories ignore them.
|
|
9712
10328
|
"LEAD",
|
|
9713
|
-
"triviaFieldCapture"
|
|
10329
|
+
"triviaFieldCapture",
|
|
10330
|
+
// Appended for the deferred-commit trivia skip (`trivia-gap.ts`); old
|
|
10331
|
+
// factories ignore it.
|
|
10332
|
+
"skipDeferredTrivia",
|
|
10333
|
+
// Appended for the pass-through collapse (`run-support.ts`); old factories
|
|
10334
|
+
// ignore it.
|
|
10335
|
+
"collapseEmpty"
|
|
9714
10336
|
];
|
|
9715
10337
|
var RUNTIME_PRELUDE = `
|
|
9716
10338
|
let _pfScan=null
|
|
@@ -9731,7 +10353,7 @@ function _skipTrivia(input,cur,ctx){
|
|
|
9731
10353
|
const s=_pfScan
|
|
9732
10354
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
9733
10355
|
if(s!==null)return skipTriviaScanned(s,input,cur,ctx)
|
|
9734
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
10356
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
9735
10357
|
return advanceTrivia(input,cur,ctx)
|
|
9736
10358
|
}
|
|
9737
10359
|
function _pushLeaf(ctx,value,s,e){pushCstLeaf(ctx,{_tag:'leaf',value,span:{start:s,end:e}})}
|
|
@@ -9907,6 +10529,24 @@ ${fast}
|
|
|
9907
10529
|
${scanned}
|
|
9908
10530
|
}`;
|
|
9909
10531
|
}
|
|
10532
|
+
function emitHoldTerm(callee, dst, t, l, skip) {
|
|
10533
|
+
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
10534
|
+
if(${t}v===FAIL)return FAIL
|
|
10535
|
+
${dst}=${t}v
|
|
10536
|
+
cur=EC.e`;
|
|
10537
|
+
if (l.tri === TRI_NONE) return fast;
|
|
10538
|
+
const held = `const ${t}s=${skip}(input,cur,ctx)
|
|
10539
|
+
const ${t}v=${callee}(input,${t}s,ctx)
|
|
10540
|
+
if(${t}v===FAIL)return FAIL
|
|
10541
|
+
${dst}=${t}v
|
|
10542
|
+
cur=${t}s`;
|
|
10543
|
+
if (l.tri !== TRI_UNKNOWN) return held;
|
|
10544
|
+
return `if(ctx.trivia===undefined){
|
|
10545
|
+
${fast}
|
|
10546
|
+
}else{
|
|
10547
|
+
${held}
|
|
10548
|
+
}`;
|
|
10549
|
+
}
|
|
9910
10550
|
function leadSkip(hasTrivia, leadTrivia, skip) {
|
|
9911
10551
|
if (hasTrivia === "false") return "{}";
|
|
9912
10552
|
const call = `itemStart=${skip}(input,itemStart,ctx)`;
|
|
@@ -9938,16 +10578,17 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
9938
10578
|
})
|
|
9939
10579
|
};
|
|
9940
10580
|
}
|
|
9941
|
-
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
10581
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false, select) {
|
|
9942
10582
|
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
9943
10583
|
const swapLegal = !cfg.trackLines;
|
|
9944
10584
|
const hostCst = cfg.hostCst;
|
|
9945
|
-
const
|
|
10585
|
+
const REC2 = prog.rec === 1 && cfg.tolerant;
|
|
9946
10586
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
9947
10587
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
9948
10588
|
const reachable = [...reachableSites(code, roots)];
|
|
9949
10589
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
9950
10590
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
10591
|
+
const nullable2 = /* @__PURE__ */ new Map();
|
|
9951
10592
|
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
9952
10593
|
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
9953
10594
|
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
@@ -10013,7 +10654,7 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
10013
10654
|
const op = code[ip];
|
|
10014
10655
|
sinkBits.set(
|
|
10015
10656
|
ip,
|
|
10016
|
-
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT ||
|
|
10657
|
+
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
10017
10658
|
);
|
|
10018
10659
|
}
|
|
10019
10660
|
const sinkKids = [];
|
|
@@ -10037,6 +10678,8 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
10037
10678
|
};
|
|
10038
10679
|
const bodies = [];
|
|
10039
10680
|
const byIp = /* @__PURE__ */ new Map();
|
|
10681
|
+
const externals = [];
|
|
10682
|
+
const siteBytes = /* @__PURE__ */ new Map();
|
|
10040
10683
|
const reached = /* @__PURE__ */ new Set();
|
|
10041
10684
|
const prelude = [];
|
|
10042
10685
|
const skipDefs = [];
|
|
@@ -10172,6 +10815,18 @@ return 1
|
|
|
10172
10815
|
tokenDecisionRefs.set(dispatchIp, made);
|
|
10173
10816
|
return made;
|
|
10174
10817
|
}
|
|
10818
|
+
function gateMissTest(gip) {
|
|
10819
|
+
const resolved = t.cc[code[gip + 1]];
|
|
10820
|
+
const ci = classes.push([resolved]) - 1;
|
|
10821
|
+
classPlan.push([code[gip + 1]]);
|
|
10822
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10823
|
+
return isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`;
|
|
10824
|
+
}
|
|
10825
|
+
function lookaheadMiss(child, miss) {
|
|
10826
|
+
if (code[child] !== OP_GATE || cfg.tolerant || cfg.probe) return "";
|
|
10827
|
+
return `if(${gateMissTest(child)}){${miss}}
|
|
10828
|
+
`;
|
|
10829
|
+
}
|
|
10175
10830
|
function skipFor(l) {
|
|
10176
10831
|
if (l.tri < 0) return "_skipTrivia";
|
|
10177
10832
|
const ki = l.tri;
|
|
@@ -10182,8 +10837,8 @@ return 1
|
|
|
10182
10837
|
const nm = `_sk${skipPool.size}`;
|
|
10183
10838
|
skipPool.set(key, nm);
|
|
10184
10839
|
if (!hasScan) {
|
|
10185
|
-
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return
|
|
10186
|
-
if(needsDeferredTriviaCommit(ctx))return
|
|
10840
|
+
skipDefs.push(l.buf ? `function ${nm}(input,cur,ctx){return skipDeferredTrivia(input,cur,ctx)}` : `function ${nm}(input,cur,ctx){
|
|
10841
|
+
if(needsDeferredTriviaCommit(ctx))return skipDeferredTrivia(input,cur,ctx)
|
|
10187
10842
|
return advanceTrivia(input,cur,ctx)}`);
|
|
10188
10843
|
return nm;
|
|
10189
10844
|
}
|
|
@@ -10228,9 +10883,17 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10228
10883
|
const target = resolveAlias(ip);
|
|
10229
10884
|
const done = byIp.get(target);
|
|
10230
10885
|
if (done !== void 0) return done;
|
|
10886
|
+
if (select !== void 0 && !select.has(target)) {
|
|
10887
|
+
const ext = `_px${target}`;
|
|
10888
|
+
byIp.set(target, ext);
|
|
10889
|
+
externals.push(target);
|
|
10890
|
+
return ext;
|
|
10891
|
+
}
|
|
10231
10892
|
const fname = `_pf${target}`;
|
|
10232
10893
|
byIp.set(target, fname);
|
|
10233
|
-
|
|
10894
|
+
const body = lower(target, fname);
|
|
10895
|
+
siteBytes.set(target, body.length);
|
|
10896
|
+
bodies.push(body);
|
|
10234
10897
|
return fname;
|
|
10235
10898
|
}
|
|
10236
10899
|
function resolveAlias(ip) {
|
|
@@ -10250,9 +10913,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10250
10913
|
const op = code[ip];
|
|
10251
10914
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
10252
10915
|
if (op === OP_RULE) return code[ip + 1];
|
|
10253
|
-
if ((
|
|
10254
|
-
return code[ip + 2];
|
|
10255
|
-
}
|
|
10916
|
+
if (scopeIsIdentity(code, ip, labels.at(ip))) return code[ip + 2];
|
|
10256
10917
|
return void 0;
|
|
10257
10918
|
}
|
|
10258
10919
|
function lower(ip, fname) {
|
|
@@ -10370,28 +11031,58 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10370
11031
|
return `${head}EC.e=pos;return ''}`;
|
|
10371
11032
|
case OP_GATE: {
|
|
10372
11033
|
const child = link(code[ip + 2]);
|
|
11034
|
+
const xf = fxRef(code[ip + 3]);
|
|
11035
|
+
return `${head}
|
|
11036
|
+
if(${gateMissTest(ip)}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11037
|
+
return ${child}(input,pos,ctx)
|
|
11038
|
+
}`;
|
|
11039
|
+
}
|
|
11040
|
+
case OP_RGATE: {
|
|
11041
|
+
const child = link(code[ip + 2]);
|
|
11042
|
+
if (cfg.tolerant || cfg.probe) return `${head}
|
|
11043
|
+
return ${child}(input,pos,ctx)
|
|
11044
|
+
}`;
|
|
10373
11045
|
const resolved = t.cc[code[ip + 1]];
|
|
10374
11046
|
const ci = classes.push([resolved]) - 1;
|
|
10375
11047
|
classPlan.push([code[ip + 1]]);
|
|
10376
11048
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10377
11049
|
const xf = fxRef(code[ip + 3]);
|
|
10378
11050
|
return `${head}
|
|
10379
|
-
|
|
11051
|
+
const it=ctx._routed
|
|
11052
|
+
if(it!==undefined&&it.span.start===pos&&!classHas(${cls},lead(input,it.span.end))){ctx._fe=it.span.end;ctx._fx=${xf};return FAIL}
|
|
10380
11053
|
return ${child}(input,pos,ctx)
|
|
10381
11054
|
}`;
|
|
10382
11055
|
}
|
|
10383
|
-
case
|
|
10384
|
-
const
|
|
11056
|
+
case OP_ARMGATE: {
|
|
11057
|
+
const pred = fnRef(code[ip + 1]);
|
|
10385
11058
|
const child = link(code[ip + 2]);
|
|
11059
|
+
const xf = fxRef(code[ip + 3]);
|
|
10386
11060
|
return `${head}
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
return ${fn}(v,{start:pos,end:EC.e})
|
|
11061
|
+
if(!${pred}(ctx.state)){ctx._fc=false;ctx._fe=-1;ctx._fx=${xf};return FAIL}
|
|
11062
|
+
return ${child}(input,pos,ctx)
|
|
10390
11063
|
}`;
|
|
10391
11064
|
}
|
|
10392
|
-
case
|
|
10393
|
-
const
|
|
10394
|
-
const
|
|
11065
|
+
case OP_WITHCTX: {
|
|
11066
|
+
const ki = code[ip + 1];
|
|
11067
|
+
const child = link(code[ip + 2]);
|
|
11068
|
+
return `${head}
|
|
11069
|
+
const saved=ctx.state
|
|
11070
|
+
ctx.state=${ki < 0 ? `${fnRef(~ki)}(saved)` : kRef(ki)}
|
|
11071
|
+
try{return ${child}(input,pos,ctx)}finally{ctx.state=saved}
|
|
11072
|
+
}`;
|
|
11073
|
+
}
|
|
11074
|
+
case OP_XFORM: {
|
|
11075
|
+
const fn = fnRef(code[ip + 1]);
|
|
11076
|
+
const child = link(code[ip + 2]);
|
|
11077
|
+
return `${head}
|
|
11078
|
+
const v=${child}(input,pos,ctx)
|
|
11079
|
+
if(v===FAIL)return FAIL
|
|
11080
|
+
return ${fn}(v,{start:pos,end:EC.e})
|
|
11081
|
+
}`;
|
|
11082
|
+
}
|
|
11083
|
+
case OP_LABEL: {
|
|
11084
|
+
const child = link(code[ip + 1]);
|
|
11085
|
+
const xf = fxRef(code[ip + 2]);
|
|
10395
11086
|
return `${head}
|
|
10396
11087
|
const v=${child}(input,pos,ctx)
|
|
10397
11088
|
if(v===FAIL)ctx._fx=${xf}
|
|
@@ -10435,7 +11126,7 @@ if(v!==FAIL)return v
|
|
|
10435
11126
|
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
10436
11127
|
const es=ctx._errors
|
|
10437
11128
|
if(es!==undefined)es.push(err)
|
|
10438
|
-
${
|
|
11129
|
+
${REC2 ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
10439
11130
|
EC.e=pos
|
|
10440
11131
|
return err
|
|
10441
11132
|
}`;
|
|
@@ -10556,7 +11247,7 @@ return v
|
|
|
10556
11247
|
}
|
|
10557
11248
|
case OP_LEX_PROGRAM: {
|
|
10558
11249
|
const programId = code[ip + 1];
|
|
10559
|
-
const
|
|
11250
|
+
const run2 = hoist("lexProgram", `LEXPROG[${programId}]`);
|
|
10560
11251
|
const scanId = t.lexPrograms[programId].scan;
|
|
10561
11252
|
if (scanId !== void 0) return `${head}
|
|
10562
11253
|
const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan
|
|
@@ -10574,7 +11265,7 @@ ctx._cstTriviaLog=undefined
|
|
|
10574
11265
|
ctx._triviaLog=undefined
|
|
10575
11266
|
ctx._rootTriviaLog=undefined
|
|
10576
11267
|
let e
|
|
10577
|
-
try{e=${
|
|
11268
|
+
try{e=${run2}(input,pos,ctx,SCANS[${scanId}])}finally{
|
|
10578
11269
|
_pfScan=sScan
|
|
10579
11270
|
ctx.trivia=sTri
|
|
10580
11271
|
ctx.triviaKindLabels=sKinds
|
|
@@ -10593,7 +11284,7 @@ EC.e=e
|
|
|
10593
11284
|
return v
|
|
10594
11285
|
}`;
|
|
10595
11286
|
return `${head}
|
|
10596
|
-
const e=${
|
|
11287
|
+
const e=${run2}(input,pos,ctx)
|
|
10597
11288
|
if(e<0)return FAIL
|
|
10598
11289
|
const v=input.slice(pos,e)
|
|
10599
11290
|
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
@@ -10604,7 +11295,7 @@ return v
|
|
|
10604
11295
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
10605
11296
|
case OP_ATTEMPT: {
|
|
10606
11297
|
const child = link(code[ip + 1]);
|
|
10607
|
-
const clean = !
|
|
11298
|
+
const clean = !REC2 && failureRollbackClean(prog, ip);
|
|
10608
11299
|
const p = tmp();
|
|
10609
11300
|
return `${head}
|
|
10610
11301
|
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
@@ -10633,34 +11324,44 @@ return FAIL
|
|
|
10633
11324
|
const xf = fxRef(code[ip + 2]);
|
|
10634
11325
|
const p = tmp();
|
|
10635
11326
|
return `${head}
|
|
10636
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
10637
|
-
const v=${child}(input,pos,ctx)
|
|
11327
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11328
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
10638
11329
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
10639
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
11330
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){EC.e=pos;return null}
|
|
10640
11331
|
ctx._fe=pos
|
|
10641
11332
|
ctx._fx=${xf}
|
|
10642
11333
|
return FAIL
|
|
10643
11334
|
}`;
|
|
10644
11335
|
}
|
|
10645
11336
|
case OP_PEEK: {
|
|
11337
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
11338
|
+
if (scalarChild >= 0) {
|
|
11339
|
+
const recognize = recognizerRef(code[scalarChild + 1]);
|
|
11340
|
+
const xf2 = fxRef(code[ip + 2]);
|
|
11341
|
+
return `${head}
|
|
11342
|
+
if(${recognize}(input,pos)<0){ctx._fe=pos;ctx._fx=${xf2};return FAIL}
|
|
11343
|
+
EC.e=pos
|
|
11344
|
+
return null
|
|
11345
|
+
}`;
|
|
11346
|
+
}
|
|
10646
11347
|
const child = link(code[ip + 1]);
|
|
10647
11348
|
const xf = fxRef(code[ip + 2]);
|
|
10648
11349
|
const p = tmp();
|
|
10649
11350
|
return `${head}
|
|
10650
|
-
${emitMark(p, L.buf, L.raw, sinks)}
|
|
10651
|
-
const v=${child}(input,pos,ctx)
|
|
11351
|
+
${lookaheadMiss(code[ip + 1], `ctx._fe=pos;ctx._fx=${xf};return FAIL`)}${emitMark(p, L.buf, L.raw, sinks)}
|
|
11352
|
+
${cfg.probe ? "const pb=ctx._probe?.best\n" : ""}const v=${child}(input,pos,ctx)
|
|
10652
11353
|
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
10653
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
11354
|
+
${cfg.probe ? "if(ctx._probe!==undefined)ctx._probe.best=pb??null\n" : ""}if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10654
11355
|
EC.e=pos
|
|
10655
11356
|
return null
|
|
10656
11357
|
}`;
|
|
10657
11358
|
}
|
|
10658
11359
|
case OP_OPT: {
|
|
10659
11360
|
const child = link(code[ip + 1]);
|
|
10660
|
-
const clean = !
|
|
11361
|
+
const clean = !REC2 && failureRollbackClean(prog, ip);
|
|
10661
11362
|
const p = tmp();
|
|
10662
11363
|
return `${head}
|
|
10663
|
-
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
11364
|
+
${lookaheadMiss(code[ip + 1], "EC.e=pos;return null")}${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
10664
11365
|
ctx._fc=false
|
|
10665
11366
|
const v=${child}(input,pos,ctx)
|
|
10666
11367
|
if(v===FAIL){
|
|
@@ -10687,15 +11388,15 @@ return v
|
|
|
10687
11388
|
const childIp = code[base + i];
|
|
10688
11389
|
kids.push(code[childIp] === OP_ADJ ? "" : link(childIp));
|
|
10689
11390
|
}
|
|
10690
|
-
const sy =
|
|
11391
|
+
const sy = REC2 ? `${tmp()}sy` : "";
|
|
10691
11392
|
const pub = (i) => {
|
|
10692
11393
|
const s = sentRef(code[base + n + i]);
|
|
10693
11394
|
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
10694
11395
|
};
|
|
10695
11396
|
const parts = [head];
|
|
10696
|
-
if (
|
|
11397
|
+
if (REC2) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
10697
11398
|
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
10698
|
-
const close = () =>
|
|
11399
|
+
const close = () => REC2 ? `${parts.join("\n")}
|
|
10699
11400
|
}finally{ctx._sync=${sy}}
|
|
10700
11401
|
}` : `${parts.join("\n")}
|
|
10701
11402
|
}`;
|
|
@@ -10708,7 +11409,7 @@ return v
|
|
|
10708
11409
|
for (let i = 1; i < n; i++) {
|
|
10709
11410
|
const vn = `v${i}`;
|
|
10710
11411
|
parts.push(`let ${vn}`);
|
|
10711
|
-
if (
|
|
11412
|
+
if (REC2) parts.push(pub(i));
|
|
10712
11413
|
const childIp = code[base + i];
|
|
10713
11414
|
if (code[childIp] === OP_ADJ) {
|
|
10714
11415
|
const negated = code[childIp + 1] === 1;
|
|
@@ -10721,7 +11422,7 @@ return v
|
|
|
10721
11422
|
);
|
|
10722
11423
|
} else {
|
|
10723
11424
|
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
10724
|
-
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
11425
|
+
parts.push(holdsGap(code, k, base, n, i, nullable2) ? emitHoldTerm(callee, vn, tmp(), L, skipFor(L)) : emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
10725
11426
|
}
|
|
10726
11427
|
names.push(vn);
|
|
10727
11428
|
}
|
|
@@ -10741,7 +11442,7 @@ return v
|
|
|
10741
11442
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
10742
11443
|
const hiArr = table.hi;
|
|
10743
11444
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
10744
|
-
const directAscii =
|
|
11445
|
+
const directAscii = table.hi.length === 0;
|
|
10745
11446
|
return `${head}
|
|
10746
11447
|
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10747
11448
|
let arm=-1
|
|
@@ -10768,7 +11469,7 @@ return FAIL
|
|
|
10768
11469
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
10769
11470
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
10770
11471
|
const maskable = n <= 32;
|
|
10771
|
-
const directAsciiMask =
|
|
11472
|
+
const directAsciiMask = maskable && gates.every(isAsciiOnlyClass);
|
|
10772
11473
|
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10773
11474
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10774
11475
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
@@ -10793,7 +11494,7 @@ return FAIL
|
|
|
10793
11494
|
if (maskable) maskPlan.push(~di);
|
|
10794
11495
|
const p = tmp();
|
|
10795
11496
|
const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
|
|
10796
|
-
const rollbackMask =
|
|
11497
|
+
const rollbackMask = REC2 ? -1 : encodedRollbackMask;
|
|
10797
11498
|
const hasRollback = rollbackMask !== 0;
|
|
10798
11499
|
const startFailureExact = arms.every((_arm, i) => {
|
|
10799
11500
|
const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
|
|
@@ -10810,7 +11511,7 @@ return FAIL
|
|
|
10810
11511
|
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
10811
11512
|
const deepAt = Array.from({ length: n }, () => tmp());
|
|
10812
11513
|
const deepFx = Array.from({ length: n }, () => tmp());
|
|
10813
|
-
const
|
|
11514
|
+
const remember2 = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
10814
11515
|
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
10815
11516
|
const pretest = pretests[i];
|
|
10816
11517
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
@@ -10822,13 +11523,13 @@ return FAIL
|
|
|
10822
11523
|
if(${decision}===0){
|
|
10823
11524
|
ctx._fc=false
|
|
10824
11525
|
{const at=_pfTokEnd
|
|
10825
|
-
${
|
|
11526
|
+
${remember2(i, "at", pretest.token.expected)}}
|
|
10826
11527
|
}`;
|
|
10827
11528
|
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
10828
11529
|
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
10829
11530
|
ctx._fc=false
|
|
10830
11531
|
{const at=_pfSeqEnd
|
|
10831
|
-
${
|
|
11532
|
+
${remember2(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
10832
11533
|
}`;
|
|
10833
11534
|
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10834
11535
|
`}if(${gate2}){
|
|
@@ -10836,7 +11537,7 @@ ctx._fc=false
|
|
|
10836
11537
|
{const v=${arm}(input,pos,ctx)
|
|
10837
11538
|
if(v!==FAIL)return v}
|
|
10838
11539
|
{const at=ctx._fe??pos
|
|
10839
|
-
${
|
|
11540
|
+
${remember2(i, "at", "ctx._fx")}}
|
|
10840
11541
|
${rollbackFor(i)}
|
|
10841
11542
|
}${routeMiss}${sequenceMiss}`;
|
|
10842
11543
|
}).join("\n");
|
|
@@ -10949,7 +11650,7 @@ const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
|
10949
11650
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10950
11651
|
${startFailureExact ? "" : "let prev=0"}
|
|
10951
11652
|
${maskArms}
|
|
10952
|
-
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
11653
|
+
${startFailureExact ? "" : `if(best===pos&&prev!==0)acc=${catchName}(${n},prev,acc)`}
|
|
10953
11654
|
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
10954
11655
|
return FAIL
|
|
10955
11656
|
}
|
|
@@ -11041,14 +11742,14 @@ return [key,v]
|
|
|
11041
11742
|
const collect = op === OP_REP;
|
|
11042
11743
|
let itemCls;
|
|
11043
11744
|
let itemAscii = false;
|
|
11044
|
-
if (!
|
|
11745
|
+
if (!REC2) {
|
|
11045
11746
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
11046
11747
|
if (itemClassIndex >= 0) {
|
|
11047
11748
|
const resolved = t.cc[itemClassIndex];
|
|
11048
11749
|
const ci = classes.push([resolved]) - 1;
|
|
11049
11750
|
classPlan.push([itemClassIndex]);
|
|
11050
11751
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
11051
|
-
itemAscii =
|
|
11752
|
+
itemAscii = isAsciiOnlyClass(resolved);
|
|
11052
11753
|
}
|
|
11053
11754
|
}
|
|
11054
11755
|
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
@@ -11089,11 +11790,11 @@ ${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
11089
11790
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
11090
11791
|
}`;
|
|
11091
11792
|
const my = `${p}my`;
|
|
11092
|
-
const recFx =
|
|
11093
|
-
const sepSent =
|
|
11793
|
+
const recFx = REC2 ? fxRef(code[ip + 6]) : "";
|
|
11794
|
+
const sepSent = REC2 ? sentRef(code[ip + 7]) : "undefined";
|
|
11094
11795
|
const recSent = sep2 === void 0 ? my : sepSent === "undefined" ? `orSentinel(${my},undefined)` : `orSentinel(${sepSent}??${my},${sepSent}===undefined?undefined:${my})`;
|
|
11095
11796
|
const recGate = sep2 !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
11096
|
-
const recBranch = !
|
|
11797
|
+
const recBranch = !REC2 ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
11097
11798
|
${sep2 === void 0 ? `${rb}
|
|
11098
11799
|
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
11099
11800
|
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
@@ -11104,7 +11805,7 @@ continue
|
|
|
11104
11805
|
`;
|
|
11105
11806
|
return `${head}
|
|
11106
11807
|
const out=${collect ? "[]" : "undefined"}
|
|
11107
|
-
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${
|
|
11808
|
+
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC2 ? `const ${my}=ctx._sync
|
|
11108
11809
|
` : ""}${itemCls === void 0 ? "" : `const ${p}gate=ctx._probe===undefined
|
|
11109
11810
|
`}let cur=pos
|
|
11110
11811
|
let count=0
|
|
@@ -11143,7 +11844,7 @@ ${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
|
11143
11844
|
`}ctx._fc=false
|
|
11144
11845
|
const v=${child}(input,itemStart,ctx)
|
|
11145
11846
|
if(v===FAIL){
|
|
11146
|
-
${
|
|
11847
|
+
${REC2 ? `if(ctx._fc===true){
|
|
11147
11848
|
${rb}
|
|
11148
11849
|
return FAIL
|
|
11149
11850
|
}
|
|
@@ -11204,6 +11905,26 @@ return nd
|
|
|
11204
11905
|
const trailingTrivia = (flags & 128) !== 0;
|
|
11205
11906
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
11206
11907
|
const leanFlags = flags & ~128;
|
|
11908
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
11909
|
+
return `${head}
|
|
11910
|
+
const v=${child}(input,pos,ctx)
|
|
11911
|
+
if(v!==undefined)return v
|
|
11912
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11913
|
+
}`;
|
|
11914
|
+
}
|
|
11915
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
11916
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(labels.at(code[ip + 2]).tri, t.trivia);
|
|
11917
|
+
const gp = gated !== void 0 && triviaLead !== void 0 && triviaLead.length <= 16 ? `const gc=lead(input,pos)
|
|
11918
|
+
if(!(${[
|
|
11919
|
+
...gated.leads.map((g) => `!(${gateMissTest(g)})`),
|
|
11920
|
+
...gated.lits.map((i) => `gc===${k[i].codePointAt(0)}`),
|
|
11921
|
+
...triviaLead.map((r) => r.lo === r.hi ? `gc===${r.lo}` : `(gc>=${r.lo}&&gc<=${r.hi})`)
|
|
11922
|
+
].join("||") || "false"})){
|
|
11923
|
+
const gv=${link(gated.last)}(input,pos,ctx)
|
|
11924
|
+
if(gv!==undefined)return gv
|
|
11925
|
+
return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
11926
|
+
}
|
|
11927
|
+
` : "";
|
|
11207
11928
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
11208
11929
|
const fields = flags === 18;
|
|
11209
11930
|
const collapseChildren = flags === 34;
|
|
@@ -11238,7 +11959,7 @@ sCh.push(nd)
|
|
|
11238
11959
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
11239
11960
|
}`;
|
|
11240
11961
|
return `${head}
|
|
11241
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11962
|
+
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11242
11963
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
11243
11964
|
const flat=[]
|
|
11244
11965
|
ctx._cstBuf=undefined
|
|
@@ -11274,7 +11995,7 @@ return nd
|
|
|
11274
11995
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
11275
11996
|
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
11276
11997
|
const ty = q(type);
|
|
11277
|
-
const stArg =
|
|
11998
|
+
const stArg = "ctx.state";
|
|
11278
11999
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
11279
12000
|
let value;
|
|
11280
12001
|
if (proj >= 0) {
|
|
@@ -11313,7 +12034,7 @@ const hostKids=kids
|
|
|
11313
12034
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
11314
12035
|
const tlog=buf.tl??EMPTY_TLOG`;
|
|
11315
12036
|
return `${head}
|
|
11316
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
12037
|
+
${!hostCst && !tracked ? gp : ""}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
11317
12038
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
11318
12039
|
${openCapture}
|
|
11319
12040
|
ctx.captureTrivia=${captureWide}
|
|
@@ -11335,7 +12056,7 @@ ctx.captureTrivia=sCap
|
|
|
11335
12056
|
if(v===FAIL)return FAIL
|
|
11336
12057
|
const end=EC.e
|
|
11337
12058
|
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
11338
|
-
const st=${readsState ? "
|
|
12059
|
+
const st=${readsState ? "ctx.state" : "undefined"}
|
|
11339
12060
|
let nd
|
|
11340
12061
|
${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]
|
|
11341
12062
|
else ` : ""}{${value}}
|
|
@@ -11348,21 +12069,57 @@ return nd
|
|
|
11348
12069
|
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
11349
12070
|
}
|
|
11350
12071
|
}
|
|
12072
|
+
const served = (ip) => select === void 0 || select.has(resolveAlias(ip));
|
|
11351
12073
|
const ruleEntries = [];
|
|
11352
12074
|
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
12075
|
+
if (!served(entryIp)) continue;
|
|
11353
12076
|
const target = link(entryIp);
|
|
11354
12077
|
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
11355
12078
|
bodies.push(`const ${rn}=${target}`);
|
|
11356
12079
|
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
11357
12080
|
}
|
|
11358
12081
|
const extra = [];
|
|
11359
|
-
|
|
12082
|
+
const exported = /* @__PURE__ */ new Set();
|
|
12083
|
+
for (const ip of extraIps) {
|
|
12084
|
+
if (!served(ip)) continue;
|
|
12085
|
+
exported.add(ip);
|
|
12086
|
+
extra.push(`${ip}:${link(ip)}`);
|
|
12087
|
+
}
|
|
12088
|
+
if (select !== void 0) {
|
|
12089
|
+
const kids = [];
|
|
12090
|
+
for (const ip of reachable) {
|
|
12091
|
+
if (select.has(resolveAlias(ip))) continue;
|
|
12092
|
+
kids.length = 0;
|
|
12093
|
+
childSlots(code, ip, kids);
|
|
12094
|
+
for (const kid of kids) {
|
|
12095
|
+
const target = resolveAlias(kid);
|
|
12096
|
+
if (!select.has(target) || exported.has(target)) continue;
|
|
12097
|
+
exported.add(target);
|
|
12098
|
+
extra.push(`${target}:${link(target)}`);
|
|
12099
|
+
}
|
|
12100
|
+
}
|
|
12101
|
+
}
|
|
12102
|
+
const hybrid = select === void 0 ? "" : `,
|
|
12103
|
+
ext:[${externals.join(",")}],
|
|
12104
|
+
bind:function(xs,ps){_xScan=xs
|
|
12105
|
+
${externals.map((ip, i) => `_xp${ip}=ps[${i}]`).join("\n")}},
|
|
12106
|
+
scan:function(s){const o=_pfScan;_pfScan=s;return o}`;
|
|
12107
|
+
const scannerFor = (ip) => {
|
|
12108
|
+
const ki = labels.at(ip).tri;
|
|
12109
|
+
if (ki === TRI_UNKNOWN) return "_pfScan";
|
|
12110
|
+
if (ki === TRI_NONE) return "null";
|
|
12111
|
+
return swapLegal && !triviaLabelled[ki] && t.triviaScan[ki] != null ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
12112
|
+
};
|
|
12113
|
+
const externalDefs = select === void 0 ? "" : `let _xScan
|
|
12114
|
+
${externals.map((ip) => `let _xp${ip}
|
|
12115
|
+
function _px${ip}(input,pos,ctx){const o=_xScan(${scannerFor(ip)});const v=_xp${ip}(input,pos,ctx);_xScan(o);return v}`).join("\n")}
|
|
12116
|
+
`;
|
|
11360
12117
|
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
11361
12118
|
${prelude.join("\n")}
|
|
11362
12119
|
${skipDefs.join("\n")}
|
|
11363
12120
|
${choiceDefs.join("\n")}
|
|
11364
12121
|
${bodies.join("\n")}
|
|
11365
|
-
function _begin(ctx){
|
|
12122
|
+
${externalDefs}function _begin(ctx){
|
|
11366
12123
|
const host=ctx.build
|
|
11367
12124
|
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
11368
12125
|
_pfDepth++
|
|
@@ -11389,7 +12146,7 @@ pieces:{${ruleEntries.join(",")}},
|
|
|
11389
12146
|
byIp:{${extra.join(",")}},
|
|
11390
12147
|
end:function(){return EC.e},
|
|
11391
12148
|
begin:_begin,
|
|
11392
|
-
finish:_finish
|
|
12149
|
+
finish:_finish${hybrid}
|
|
11393
12150
|
}`;
|
|
11394
12151
|
return {
|
|
11395
12152
|
source,
|
|
@@ -11397,6 +12154,7 @@ finish:_finish
|
|
|
11397
12154
|
masks,
|
|
11398
12155
|
classes,
|
|
11399
12156
|
armExpected,
|
|
12157
|
+
siteBytes,
|
|
11400
12158
|
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
11401
12159
|
};
|
|
11402
12160
|
}
|
|
@@ -11495,20 +12253,20 @@ function lines(prefix, body, options = {}) {
|
|
|
11495
12253
|
const c = ctx;
|
|
11496
12254
|
const probe = createDetachedParseContext(false, ctx.state);
|
|
11497
12255
|
probe.lineView = c.lineView;
|
|
11498
|
-
const
|
|
12256
|
+
const run2 = [];
|
|
11499
12257
|
const parts = [];
|
|
11500
12258
|
let offset = 0;
|
|
11501
12259
|
for (let start = pos; start < input.length || start === pos; ) {
|
|
11502
12260
|
let end2 = input.indexOf("\n", start);
|
|
11503
12261
|
if (end2 < 0) end2 = input.length;
|
|
11504
12262
|
probe._columnsSplit = void 0;
|
|
11505
|
-
const head = (
|
|
12263
|
+
const head = (run2.length === 0 ? opening : prefix).parse(input, start, probe);
|
|
11506
12264
|
let content;
|
|
11507
12265
|
let joined;
|
|
11508
12266
|
if (head.ok && head.span.end <= end2) {
|
|
11509
12267
|
content = head.span.end;
|
|
11510
12268
|
joined = "prefix";
|
|
11511
|
-
} else if (
|
|
12269
|
+
} else if (run2.length === 0) {
|
|
11512
12270
|
return { ok: false, expected: head.ok ? ["line prefix"] : head.expected, span: { start, end: start } };
|
|
11513
12271
|
} else if (lazy !== void 0 && lazy.parse(input, start, probe).ok) {
|
|
11514
12272
|
content = start;
|
|
@@ -11517,7 +12275,7 @@ function lines(prefix, body, options = {}) {
|
|
|
11517
12275
|
const mark = probe._columnsSplit;
|
|
11518
12276
|
const here = columnAt(input, content, c);
|
|
11519
12277
|
const split = joined === "prefix" && mark !== void 0 && mark.at === content ? mark.split : here.split;
|
|
11520
|
-
|
|
12278
|
+
run2.push({ offset, source: content, end: end2, column: here.column + (split - here.split), split, lazy: joined === "lazy" });
|
|
11521
12279
|
const text = input.slice(content, end2);
|
|
11522
12280
|
const newline = end2 < input.length;
|
|
11523
12281
|
parts.push(newline ? `${text}
|
|
@@ -11526,11 +12284,11 @@ function lines(prefix, body, options = {}) {
|
|
|
11526
12284
|
start = end2 + 1;
|
|
11527
12285
|
if (!newline) break;
|
|
11528
12286
|
}
|
|
11529
|
-
const view = { lines:
|
|
12287
|
+
const view = { lines: run2, parent: c.lineView };
|
|
11530
12288
|
const saved = c.lineView, starts = c._lineStarts, lineIndex = c._lineIndex, scanned = c._lineScannedTo, probing = c._probe;
|
|
11531
12289
|
const errors = c._errors?.length ?? 0;
|
|
11532
12290
|
let cursor = -1;
|
|
11533
|
-
if (probing !== void 0) for (const line2 of
|
|
12291
|
+
if (probing !== void 0) for (const line2 of run2) {
|
|
11534
12292
|
if (probing.offset >= line2.source && probing.offset <= line2.end) {
|
|
11535
12293
|
cursor = line2.offset + probing.offset - line2.source;
|
|
11536
12294
|
break;
|
|
@@ -11563,8 +12321,8 @@ function lines(prefix, body, options = {}) {
|
|
|
11563
12321
|
}
|
|
11564
12322
|
const stop = result.span.end;
|
|
11565
12323
|
const index = lineIndexAt(view, stop);
|
|
11566
|
-
const line =
|
|
11567
|
-
const end = stop === line.offset && index > 0 ?
|
|
12324
|
+
const line = run2[index];
|
|
12325
|
+
const end = stop === line.offset && index > 0 ? run2[index - 1].end + 1 : stop - line.offset > line.end - line.source ? line.end + 1 : line.source + (stop - line.offset);
|
|
11568
12326
|
recordLineRangeFromContext(c, input, pos, end);
|
|
11569
12327
|
return { ok: true, value: result.value, span: { start: pos, end } };
|
|
11570
12328
|
}
|
|
@@ -11827,42 +12585,202 @@ function escapeClassChar(ch2) {
|
|
|
11827
12585
|
return ch2.replace(/[\\\]^-]/g, "\\$&");
|
|
11828
12586
|
}
|
|
11829
12587
|
|
|
11830
|
-
// src/table/
|
|
11831
|
-
function
|
|
11832
|
-
const
|
|
11833
|
-
|
|
11834
|
-
|
|
11835
|
-
|
|
11836
|
-
|
|
11837
|
-
|
|
12588
|
+
// src/table/trivia-gap.ts
|
|
12589
|
+
function skipDeferredTrivia(input, cur, ctx) {
|
|
12590
|
+
const triviaP = ctx.trivia;
|
|
12591
|
+
const plain = ctx.trackLines !== true && ctx.captureTrivia !== true;
|
|
12592
|
+
const gap = ctx._gap;
|
|
12593
|
+
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;
|
|
12594
|
+
const end = clearRunEnd(input, cur, ctx, triviaP, plain);
|
|
12595
|
+
if (end >= 0) {
|
|
12596
|
+
remember(cur, end, ctx, input, triviaP);
|
|
12597
|
+
return end;
|
|
11838
12598
|
}
|
|
11839
|
-
|
|
12599
|
+
const scan = scanTriviaCompact(input, cur, ctx);
|
|
12600
|
+
if (typeof scan !== "number") return commitTriviaScan(scan);
|
|
12601
|
+
if (plain) remember(cur, scan, ctx, input, triviaP);
|
|
12602
|
+
return scan;
|
|
11840
12603
|
}
|
|
11841
|
-
function
|
|
11842
|
-
const
|
|
11843
|
-
|
|
12604
|
+
function clearRunEnd(input, cur, ctx, triviaP, plain) {
|
|
12605
|
+
const rootKinds = ctx._rootTriviaKindIndex;
|
|
12606
|
+
const spec = triviaP?._meta.labeledTriviaSpec;
|
|
12607
|
+
if (!plain || triviaP === void 0 || spec == null || rootKinds === void 0 || ctx._triviaLog !== void 0) return -1;
|
|
12608
|
+
if (spec.rootKinds !== rootKinds) prime(spec, triviaP, rootKinds);
|
|
12609
|
+
const fast = spec.rootScan;
|
|
12610
|
+
if (fast === null) return -1;
|
|
12611
|
+
const end = fast(input, cur);
|
|
12612
|
+
return ctx._rootTriviaCapture === false || clearOf(spec.rootLeaders, input, cur, end) ? end : -1;
|
|
12613
|
+
}
|
|
12614
|
+
function remember(cur, end, ctx, input, triviaP) {
|
|
12615
|
+
const gap = ctx._gap;
|
|
12616
|
+
if (gap === void 0) {
|
|
12617
|
+
ctx._gap = { at: cur, end, input, of: triviaP, root: ctx._rootTriviaCapture, rootKinds: ctx._rootTriviaKindIndex, log: ctx._triviaLog, state: ctx.state };
|
|
12618
|
+
return;
|
|
12619
|
+
}
|
|
12620
|
+
gap.at = cur;
|
|
12621
|
+
gap.end = end;
|
|
12622
|
+
gap.input = input;
|
|
12623
|
+
gap.of = triviaP;
|
|
12624
|
+
gap.root = ctx._rootTriviaCapture;
|
|
12625
|
+
gap.rootKinds = ctx._rootTriviaKindIndex;
|
|
12626
|
+
gap.log = ctx._triviaLog;
|
|
12627
|
+
gap.state = ctx.state;
|
|
11844
12628
|
}
|
|
11845
|
-
function
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
12629
|
+
function prime(spec, triviaP, rootKinds) {
|
|
12630
|
+
const ranges = [];
|
|
12631
|
+
let bounded = true;
|
|
12632
|
+
for (const arm of spec.arms) {
|
|
12633
|
+
if (rootKinds[arm.label] === void 0) continue;
|
|
12634
|
+
const fs3 = arm.parser._meta.firstSet;
|
|
12635
|
+
if (fs3.kind === "any") bounded = false;
|
|
12636
|
+
else if (fs3.kind === "ranges") ranges.push(...fs3.ranges);
|
|
12637
|
+
}
|
|
12638
|
+
const classified = triviaP._meta.triviaScanner;
|
|
12639
|
+
spec.rootKinds = rootKinds;
|
|
12640
|
+
spec.rootLeaders = ranges;
|
|
12641
|
+
spec.rootScan = !bounded ? null : classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
12642
|
+
}
|
|
12643
|
+
function clearOf(ranges, input, from, to) {
|
|
12644
|
+
for (let i = from; i < to; i++) {
|
|
12645
|
+
const c = input.charCodeAt(i);
|
|
12646
|
+
if (c >= 55296 && c <= 57343) return false;
|
|
12647
|
+
for (const r of ranges) if (c >= r.lo && c <= r.hi) return false;
|
|
11849
12648
|
}
|
|
11850
|
-
return
|
|
11851
|
-
_tag: "leaf",
|
|
11852
|
-
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
11853
|
-
span: { start: s, end: e }
|
|
11854
|
-
};
|
|
12649
|
+
return true;
|
|
11855
12650
|
}
|
|
11856
|
-
|
|
11857
|
-
|
|
11858
|
-
|
|
11859
|
-
|
|
11860
|
-
|
|
12651
|
+
|
|
12652
|
+
// src/table/fail-clean.ts
|
|
12653
|
+
function passChild(code, ip) {
|
|
12654
|
+
switch (code[ip]) {
|
|
12655
|
+
case OP_RULE:
|
|
12656
|
+
case OP_LABEL:
|
|
12657
|
+
case OP_COV:
|
|
12658
|
+
case OP_TOKEN:
|
|
12659
|
+
return code[ip + 1];
|
|
12660
|
+
case OP_GATE:
|
|
12661
|
+
case OP_NODE:
|
|
12662
|
+
case OP_NODE_TRACK:
|
|
12663
|
+
case OP_XFORM:
|
|
12664
|
+
case OP_FIELD:
|
|
12665
|
+
case OP_SCOPE:
|
|
12666
|
+
case OP_SCOPE_CAP:
|
|
12667
|
+
case OP_SCOPE_PLAIN:
|
|
12668
|
+
case OP_WITHCTX:
|
|
12669
|
+
case OP_LEAF:
|
|
12670
|
+
case OP_SOURCE_LEAF:
|
|
12671
|
+
return code[ip + 2];
|
|
12672
|
+
default:
|
|
12673
|
+
return -1;
|
|
12674
|
+
}
|
|
12675
|
+
}
|
|
12676
|
+
function seqCount(code, ip) {
|
|
12677
|
+
const op = code[ip];
|
|
12678
|
+
return op === OP_SEQ || op === OP_SEQV ? ip + 1 : op === OP_SEQX ? ip + 2 : -1;
|
|
12679
|
+
}
|
|
12680
|
+
function failCleanAnalysis(code) {
|
|
12681
|
+
const cleanAt = new Uint8Array(code.length);
|
|
12682
|
+
const neverAt = new Uint8Array(code.length);
|
|
12683
|
+
const neverFails = (ip) => {
|
|
12684
|
+
const hit = neverAt[ip];
|
|
12685
|
+
if (hit !== 0) return hit === 1;
|
|
12686
|
+
neverAt[ip] = 3;
|
|
12687
|
+
let out = false;
|
|
12688
|
+
const op = code[ip];
|
|
12689
|
+
if (op === OP_OPT || op === OP_EMPTY || op === OP_EXPECT) out = true;
|
|
12690
|
+
else if (op === OP_REP || op === OP_REPV) out = code[ip + 2] === 0;
|
|
12691
|
+
else {
|
|
12692
|
+
const at = seqCount(code, ip);
|
|
12693
|
+
if (at >= 0) {
|
|
12694
|
+
out = true;
|
|
12695
|
+
for (let i = 1, n = code[at]; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12696
|
+
} else if (op !== OP_GATE) {
|
|
12697
|
+
const c = passChild(code, ip);
|
|
12698
|
+
out = c >= 0 && neverFails(c);
|
|
12699
|
+
}
|
|
12700
|
+
}
|
|
12701
|
+
neverAt[ip] = out ? 1 : 2;
|
|
12702
|
+
return out;
|
|
12703
|
+
};
|
|
12704
|
+
const clean = (ip) => {
|
|
12705
|
+
const hit = cleanAt[ip];
|
|
12706
|
+
if (hit !== 0) return hit === 1;
|
|
12707
|
+
cleanAt[ip] = 3;
|
|
12708
|
+
let out = false;
|
|
12709
|
+
switch (code[ip]) {
|
|
12710
|
+
// A terminal pushes its leaf only on a match; NOT/PEEK/ATTEMPT restore
|
|
12711
|
+
// their own mark; OPT, EMPTY and EXPECT do not fail uncommitted.
|
|
12712
|
+
case OP_LIT:
|
|
12713
|
+
case OP_RX:
|
|
12714
|
+
case OP_LIT_TRACK:
|
|
12715
|
+
case OP_RX_TRACK:
|
|
12716
|
+
case OP_LIT_CI:
|
|
12717
|
+
case OP_LIT_CI_TRACK:
|
|
12718
|
+
case OP_GUARD:
|
|
12719
|
+
case OP_NOT:
|
|
12720
|
+
case OP_PEEK:
|
|
12721
|
+
case OP_ATTEMPT:
|
|
12722
|
+
case OP_EMPTY:
|
|
12723
|
+
case OP_OPT:
|
|
12724
|
+
case OP_EXPECT:
|
|
12725
|
+
out = true;
|
|
12726
|
+
break;
|
|
12727
|
+
// Min 0 does not fail uncommitted; min 1 fails only with no item kept, and
|
|
12728
|
+
// restores the failed item itself.
|
|
12729
|
+
case OP_REP:
|
|
12730
|
+
case OP_REPV:
|
|
12731
|
+
out = code[ip + 2] <= 1;
|
|
12732
|
+
break;
|
|
12733
|
+
// Only the first term may fail: a later one fails after the terms before it
|
|
12734
|
+
// wrote, and after the trivia scanned in front of it.
|
|
12735
|
+
case OP_SEQ:
|
|
12736
|
+
case OP_SEQV:
|
|
12737
|
+
case OP_SEQX: {
|
|
12738
|
+
const at = seqCount(code, ip);
|
|
12739
|
+
const n = code[at];
|
|
12740
|
+
out = n > 0 && clean(code[at + 1]);
|
|
12741
|
+
for (let i = 2; out && i <= n; i++) out = neverFails(code[at + i]);
|
|
12742
|
+
break;
|
|
12743
|
+
}
|
|
12744
|
+
case OP_CHOICE: {
|
|
12745
|
+
out = true;
|
|
12746
|
+
for (let i = 0, n = code[ip + 2]; out && i < n; i++) out = clean(code[ip + 4 + i]);
|
|
12747
|
+
break;
|
|
12748
|
+
}
|
|
12749
|
+
case OP_ROUTED:
|
|
12750
|
+
out = code[ip + 1] < 0 || clean(code[ip + 1]);
|
|
12751
|
+
break;
|
|
12752
|
+
// An arm's failure and the fallback's are committed; only the selector's is
|
|
12753
|
+
// not, and without a fallback an unknown key fails after the selector wrote.
|
|
12754
|
+
case OP_DISPATCH:
|
|
12755
|
+
out = code[ip + 3] >= 0 && clean(code[ip + 1]);
|
|
12756
|
+
break;
|
|
12757
|
+
default: {
|
|
12758
|
+
const c = passChild(code, ip);
|
|
12759
|
+
out = c >= 0 && clean(c);
|
|
12760
|
+
}
|
|
12761
|
+
}
|
|
12762
|
+
cleanAt[ip] = out ? 1 : 2;
|
|
12763
|
+
return out;
|
|
12764
|
+
};
|
|
12765
|
+
return clean;
|
|
11861
12766
|
}
|
|
11862
12767
|
|
|
11863
12768
|
// src/cst/host-mode.ts
|
|
11864
12769
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
11865
12770
|
var FUSED_HOST_ELIDED = /* @__PURE__ */ Symbol.for("parseman.fusedHostElided");
|
|
12771
|
+
function assertHostModeCompatible(mode, build, hostBranchElided = true) {
|
|
12772
|
+
const isCstHost = build?._parsemanCstOutput === true;
|
|
12773
|
+
if (mode === "ast" && isCstHost && hostBranchElided) {
|
|
12774
|
+
throw new Error(
|
|
12775
|
+
"parseman: this parser was compiled for host mode \"ast\" (the default), so its nodes build through their own `build` callbacks and no positioned-CST branch was emitted. It cannot be driven with a positioned-CST host (cstBuildHost / a language-service host). Compile a second artifact from the SAME grammar with `compile(grammar, { hostMode: 'cst' })` \u2014 or, under the macro, a second `rules({ hostMode: 'cst' }, factory)` call site \u2014 and drive that one instead."
|
|
12776
|
+
);
|
|
12777
|
+
}
|
|
12778
|
+
if (mode === "cst" && !isCstHost) {
|
|
12779
|
+
throw new Error(
|
|
12780
|
+
'parseman: this parser was compiled for host mode "cst", so every node builds through a positioned-CST `ctx.build` host. Pass one (e.g. `{ build: cstBuildHost }`), or use an artifact compiled with the default `hostMode: "ast"` to get the grammar\'s own AST.'
|
|
12781
|
+
);
|
|
12782
|
+
}
|
|
12783
|
+
}
|
|
11866
12784
|
|
|
11867
12785
|
// src/grammar-metadata.ts
|
|
11868
12786
|
var GRAMMAR_COVERAGE_DEFINITIONS = /* @__PURE__ */ Symbol.for("parseman.grammarCoverageDefinitions");
|
|
@@ -12008,7 +12926,8 @@ function assemble(t, prog, cfg) {
|
|
|
12008
12926
|
const triviaScan = t.triviaScan;
|
|
12009
12927
|
const swapLegal = !cfg.trackLines;
|
|
12010
12928
|
const hostCst = cfg.hostCst;
|
|
12011
|
-
const
|
|
12929
|
+
const REC2 = prog.rec === 1 && cfg.tolerant;
|
|
12930
|
+
const PROBE = cfg.probe;
|
|
12012
12931
|
const sentinels = /* @__PURE__ */ new Map();
|
|
12013
12932
|
function sentinelFor(cls) {
|
|
12014
12933
|
if (cls < 0) return void 0;
|
|
@@ -12023,6 +12942,9 @@ function assemble(t, prog, cfg) {
|
|
|
12023
12942
|
const EC = newEndCell();
|
|
12024
12943
|
const scalarRecognizers = [];
|
|
12025
12944
|
const rawScalarSpecs = /* @__PURE__ */ new Set();
|
|
12945
|
+
function lookaheadClass(child) {
|
|
12946
|
+
return code[child] === OP_GATE && !cfg.tolerant && !cfg.probe ? cc[code[child + 1]] : null;
|
|
12947
|
+
}
|
|
12026
12948
|
function scalarFor(child) {
|
|
12027
12949
|
const spec = code[child + 1];
|
|
12028
12950
|
let recognize = scalarRecognizers[spec];
|
|
@@ -12032,17 +12954,27 @@ function assemble(t, prog, cfg) {
|
|
|
12032
12954
|
}
|
|
12033
12955
|
return recognize;
|
|
12034
12956
|
}
|
|
12035
|
-
const labelExtraIps =
|
|
12036
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) labelExtraIps.push(r[0]);
|
|
12037
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
12957
|
+
const labelExtraIps = assemblyExtraIps(prog);
|
|
12038
12958
|
const closureLabels = computeSiteLabels(
|
|
12039
12959
|
code,
|
|
12040
12960
|
[...Object.values(prog.rules), ...labelExtraIps],
|
|
12041
12961
|
hostCst
|
|
12042
12962
|
);
|
|
12043
12963
|
let SCAN = null;
|
|
12964
|
+
let HYBRID;
|
|
12965
|
+
function hybridPiece(piece) {
|
|
12966
|
+
const setScan = HYBRID.scan;
|
|
12967
|
+
return (input, pos, ctx) => {
|
|
12968
|
+
const saved = setScan(SCAN);
|
|
12969
|
+
const value = piece(input, pos, ctx);
|
|
12970
|
+
setScan(saved);
|
|
12971
|
+
return value;
|
|
12972
|
+
};
|
|
12973
|
+
}
|
|
12044
12974
|
const memo = /* @__PURE__ */ new Map();
|
|
12045
12975
|
const reached = /* @__PURE__ */ new Set();
|
|
12976
|
+
const NULLABLE = /* @__PURE__ */ new Map();
|
|
12977
|
+
const CLEAN = REC2 ? () => false : failCleanAnalysis(code);
|
|
12046
12978
|
function pushLeaf(ctx, value, s, e) {
|
|
12047
12979
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
12048
12980
|
pushCstLeaf(ctx, lf);
|
|
@@ -12241,6 +13173,22 @@ function assemble(t, prog, cfg) {
|
|
|
12241
13173
|
return node2;
|
|
12242
13174
|
};
|
|
12243
13175
|
}
|
|
13176
|
+
function passCollapseNode(child, build, readsRaw) {
|
|
13177
|
+
return (input, pos, ctx) => {
|
|
13178
|
+
const v = child(input, pos, ctx);
|
|
13179
|
+
if (v !== void 0) return v;
|
|
13180
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13181
|
+
};
|
|
13182
|
+
}
|
|
13183
|
+
function gatedPassCollapseNode(blockers, last, classic, build, readsRaw) {
|
|
13184
|
+
return (input, pos, ctx) => {
|
|
13185
|
+
const c = lead(input, pos);
|
|
13186
|
+
for (let i = 0; i < blockers.length; i++) if (classHas2(blockers[i], c)) return classic(input, pos, ctx);
|
|
13187
|
+
const v = last(input, pos, ctx);
|
|
13188
|
+
if (v !== void 0) return v;
|
|
13189
|
+
return collapseEmpty(ctx, build, input, pos, EC.e, readsRaw);
|
|
13190
|
+
};
|
|
13191
|
+
}
|
|
12244
13192
|
function plainProjectNode(child, projection, type) {
|
|
12245
13193
|
return (input, pos, ctx) => {
|
|
12246
13194
|
const sCh = ctx._cstChildren;
|
|
@@ -12332,9 +13280,7 @@ function assemble(t, prog, cfg) {
|
|
|
12332
13280
|
return s(input, cur);
|
|
12333
13281
|
}
|
|
12334
13282
|
if (s !== null) return skipTriviaScanned(s, input, cur, ctx);
|
|
12335
|
-
if (needsDeferredTriviaCommit(ctx))
|
|
12336
|
-
return commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
12337
|
-
}
|
|
13283
|
+
if (needsDeferredTriviaCommit(ctx)) return skipDeferredTrivia(input, cur, ctx);
|
|
12338
13284
|
return advanceTrivia(input, cur, ctx);
|
|
12339
13285
|
}
|
|
12340
13286
|
let TERMV;
|
|
@@ -12504,7 +13450,7 @@ function assemble(t, prog, cfg) {
|
|
|
12504
13450
|
if (next !== void 0) {
|
|
12505
13451
|
return next(input, pos, ctx, bits, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
12506
13452
|
}
|
|
12507
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13453
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12508
13454
|
ctx._fe = pos;
|
|
12509
13455
|
ctx._fx = acc ?? choiceFx;
|
|
12510
13456
|
return FAIL;
|
|
@@ -12587,7 +13533,7 @@ function assemble(t, prog, cfg) {
|
|
|
12587
13533
|
if (next !== void 0) {
|
|
12588
13534
|
return next(input, pos, ctx, c, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot, acc, prev, best);
|
|
12589
13535
|
}
|
|
12590
|
-
if (best === pos) acc = through(total, prev, acc);
|
|
13536
|
+
if (best === pos && prev !== 0) acc = through(total, prev, acc);
|
|
12591
13537
|
ctx._fe = pos;
|
|
12592
13538
|
ctx._fx = acc ?? choiceFx;
|
|
12593
13539
|
return FAIL;
|
|
@@ -12613,21 +13559,27 @@ function assemble(t, prog, cfg) {
|
|
|
12613
13559
|
}
|
|
12614
13560
|
function dispatchBranch(child, usesRouted) {
|
|
12615
13561
|
if (!usesRouted) {
|
|
12616
|
-
return (input, _pos, selEnd, key,
|
|
12617
|
-
const
|
|
13562
|
+
return (input, _pos, selEnd, key, ctx) => {
|
|
13563
|
+
const need = markCst(ctx);
|
|
13564
|
+
const mRaw = MRAW;
|
|
13565
|
+
const mTl = MTL;
|
|
13566
|
+
const mLv = MLV;
|
|
13567
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13568
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13569
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13570
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
12618
13571
|
const v = child(input, selEnd, ctx);
|
|
12619
13572
|
if (v === FAIL) {
|
|
12620
|
-
|
|
13573
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12621
13574
|
ctx._fc = true;
|
|
12622
13575
|
return FAIL;
|
|
12623
13576
|
}
|
|
12624
13577
|
return [key, v];
|
|
12625
13578
|
};
|
|
12626
13579
|
}
|
|
12627
|
-
return (input, pos, selEnd, key,
|
|
13580
|
+
return (input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
12628
13581
|
const savedRouted = ctx._routed;
|
|
12629
|
-
|
|
12630
|
-
const mark = saveTriviaMark(ctx);
|
|
13582
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12631
13583
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
12632
13584
|
let v;
|
|
12633
13585
|
try {
|
|
@@ -12636,7 +13588,7 @@ function assemble(t, prog, cfg) {
|
|
|
12636
13588
|
ctx._routed = savedRouted;
|
|
12637
13589
|
}
|
|
12638
13590
|
if (v === FAIL) {
|
|
12639
|
-
|
|
13591
|
+
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12640
13592
|
ctx._fc = true;
|
|
12641
13593
|
return FAIL;
|
|
12642
13594
|
}
|
|
@@ -12644,12 +13596,12 @@ function assemble(t, prog, cfg) {
|
|
|
12644
13596
|
};
|
|
12645
13597
|
}
|
|
12646
13598
|
function dispatchArmBlock(start, a0, a1, a2, a3, next) {
|
|
12647
|
-
return (arm, input, pos, selEnd, key,
|
|
12648
|
-
if (arm === start) return a0(input, pos, selEnd, key,
|
|
12649
|
-
if (arm === start + 1) return a1(input, pos, selEnd, key,
|
|
12650
|
-
if (arm === start + 2) return a2(input, pos, selEnd, key,
|
|
12651
|
-
if (arm === start + 3) return a3(input, pos, selEnd, key,
|
|
12652
|
-
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key,
|
|
13599
|
+
return (arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot) => {
|
|
13600
|
+
if (arm === start) return a0(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13601
|
+
if (arm === start + 1) return a1(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13602
|
+
if (arm === start + 2) return a2(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13603
|
+
if (arm === start + 3) return a3(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
13604
|
+
return next === void 0 ? FAIL : next(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12653
13605
|
};
|
|
12654
13606
|
}
|
|
12655
13607
|
function trackLinesInto(ctx, input, end) {
|
|
@@ -12666,20 +13618,68 @@ function assemble(t, prog, cfg) {
|
|
|
12666
13618
|
if (done !== void 0) return done;
|
|
12667
13619
|
const flight = inFlight.get(ip);
|
|
12668
13620
|
if (flight !== void 0) return flight.fwd;
|
|
13621
|
+
const selected = HYBRID?.byIp[ip];
|
|
13622
|
+
if (selected !== void 0) {
|
|
13623
|
+
const piece2 = scanHandoffNeeded(code, ip, closureLabels) ? hybridPiece(selected) : selected;
|
|
13624
|
+
memo.set(ip, piece2);
|
|
13625
|
+
reached.add(ip);
|
|
13626
|
+
return piece2;
|
|
13627
|
+
}
|
|
12669
13628
|
let target;
|
|
12670
13629
|
const fwd = (input, pos, ctx) => target(input, pos, ctx);
|
|
12671
13630
|
const holder = { fwd, set: (p) => {
|
|
12672
13631
|
target = p;
|
|
12673
13632
|
} };
|
|
12674
13633
|
inFlight.set(ip, holder);
|
|
12675
|
-
const
|
|
12676
|
-
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);
|
|
13634
|
+
const piece = scopeIsIdentity(code, ip, closureLabels.at(ip)) ? link(code[ip + 2]) : countedPiece(lookaheadLedNode(ip) ?? lower(ip), ip);
|
|
12677
13635
|
inFlight.delete(ip);
|
|
12678
13636
|
holder.set(piece);
|
|
12679
13637
|
memo.set(ip, piece);
|
|
12680
13638
|
reached.add(ip);
|
|
12681
13639
|
return piece;
|
|
12682
13640
|
}
|
|
13641
|
+
let FIRST_DECIDED;
|
|
13642
|
+
let NODE_BODY;
|
|
13643
|
+
const DECIDED = (_input, pos) => {
|
|
13644
|
+
EC.e = pos;
|
|
13645
|
+
return null;
|
|
13646
|
+
};
|
|
13647
|
+
function lookaheadLedNode(ip) {
|
|
13648
|
+
const op = code[ip];
|
|
13649
|
+
if (op !== OP_NODE && op !== OP_NODE_TRACK || hostCst || REC2 || cfg.probe || cfg.coverage || cfg.trackLines) return void 0;
|
|
13650
|
+
if (passCollapse(code, ip, hostCst) || gatedPassCollapse(code, ip, hostCst) !== void 0) return void 0;
|
|
13651
|
+
const body = code[ip + 2];
|
|
13652
|
+
const bop = code[body];
|
|
13653
|
+
if (bop !== OP_SEQ && bop !== OP_SEQV && bop !== OP_SEQX) return void 0;
|
|
13654
|
+
const base = bop === OP_SEQX ? body + 3 : body + 2;
|
|
13655
|
+
if (code[bop === OP_SEQX ? body + 2 : body + 1] < 2) return void 0;
|
|
13656
|
+
const first = code[base];
|
|
13657
|
+
const negative = code[first] === OP_NOT;
|
|
13658
|
+
const terminal = negative ? scalarTerminalNotChild(code, first) : code[first] === OP_PEEK ? scalarTerminalPeekChild(code, first) : -1;
|
|
13659
|
+
if (terminal < 0) return void 0;
|
|
13660
|
+
const recognize = scalarFor(terminal);
|
|
13661
|
+
const xf = fx[code[first + 2]];
|
|
13662
|
+
FIRST_DECIDED = DECIDED;
|
|
13663
|
+
NODE_BODY = lower(body);
|
|
13664
|
+
const node2 = lower(ip);
|
|
13665
|
+
NODE_BODY = void 0;
|
|
13666
|
+
return negative ? (input, pos, ctx) => {
|
|
13667
|
+
if (recognize(input, pos) >= 0) {
|
|
13668
|
+
ctx._fe = pos;
|
|
13669
|
+
ctx._fx = xf;
|
|
13670
|
+
EC.e = pos;
|
|
13671
|
+
return FAIL;
|
|
13672
|
+
}
|
|
13673
|
+
return node2(input, pos, ctx);
|
|
13674
|
+
} : (input, pos, ctx) => {
|
|
13675
|
+
if (recognize(input, pos) < 0) {
|
|
13676
|
+
ctx._fe = pos;
|
|
13677
|
+
ctx._fx = xf;
|
|
13678
|
+
return FAIL;
|
|
13679
|
+
}
|
|
13680
|
+
return node2(input, pos, ctx);
|
|
13681
|
+
};
|
|
13682
|
+
}
|
|
12683
13683
|
function lower(ip) {
|
|
12684
13684
|
const op = code[ip];
|
|
12685
13685
|
switch (op) {
|
|
@@ -13014,7 +14014,7 @@ function assemble(t, prog, cfg) {
|
|
|
13014
14014
|
const child = link(code[ip + 1]);
|
|
13015
14015
|
const xf = fx[code[ip + 2]];
|
|
13016
14016
|
const expectSpan = (ctx, pos) => prog.lines === 1 ? spanLines(ctx, pos, pos) : { start: pos, end: pos };
|
|
13017
|
-
if (
|
|
14017
|
+
if (REC2) {
|
|
13018
14018
|
return (input, pos, ctx) => {
|
|
13019
14019
|
const v = child(input, pos, ctx);
|
|
13020
14020
|
if (v !== FAIL) return v;
|
|
@@ -13210,7 +14210,12 @@ function assemble(t, prog, cfg) {
|
|
|
13210
14210
|
}
|
|
13211
14211
|
const child = link(code[ip + 1]);
|
|
13212
14212
|
const xf = fx[code[ip + 2]];
|
|
14213
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
13213
14214
|
return (input, pos, ctx) => {
|
|
14215
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14216
|
+
EC.e = pos;
|
|
14217
|
+
return null;
|
|
14218
|
+
}
|
|
13214
14219
|
const need = markCst(ctx);
|
|
13215
14220
|
const mRaw = MRAW;
|
|
13216
14221
|
const mTl = MTL;
|
|
@@ -13219,8 +14224,10 @@ function assemble(t, prog, cfg) {
|
|
|
13219
14224
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13220
14225
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13221
14226
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14227
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13222
14228
|
const v = child(input, pos, ctx);
|
|
13223
14229
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14230
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13224
14231
|
if (v === FAIL) {
|
|
13225
14232
|
EC.e = pos;
|
|
13226
14233
|
return null;
|
|
@@ -13231,9 +14238,29 @@ function assemble(t, prog, cfg) {
|
|
|
13231
14238
|
};
|
|
13232
14239
|
}
|
|
13233
14240
|
case OP_PEEK: {
|
|
14241
|
+
const scalarChild = scalarTerminalPeekChild(code, ip);
|
|
14242
|
+
if (scalarChild >= 0) {
|
|
14243
|
+
const recognize = scalarFor(scalarChild);
|
|
14244
|
+
const xf2 = fx[code[ip + 2]];
|
|
14245
|
+
return (input, pos, ctx) => {
|
|
14246
|
+
if (recognize(input, pos) < 0) {
|
|
14247
|
+
ctx._fe = pos;
|
|
14248
|
+
ctx._fx = xf2;
|
|
14249
|
+
return FAIL;
|
|
14250
|
+
}
|
|
14251
|
+
EC.e = pos;
|
|
14252
|
+
return null;
|
|
14253
|
+
};
|
|
14254
|
+
}
|
|
13234
14255
|
const child = link(code[ip + 1]);
|
|
13235
14256
|
const xf = fx[code[ip + 2]];
|
|
14257
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
13236
14258
|
return (input, pos, ctx) => {
|
|
14259
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14260
|
+
ctx._fe = pos;
|
|
14261
|
+
ctx._fx = xf;
|
|
14262
|
+
return FAIL;
|
|
14263
|
+
}
|
|
13237
14264
|
const need = markCst(ctx);
|
|
13238
14265
|
const mRaw = MRAW;
|
|
13239
14266
|
const mTl = MTL;
|
|
@@ -13242,8 +14269,10 @@ function assemble(t, prog, cfg) {
|
|
|
13242
14269
|
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13243
14270
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13244
14271
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14272
|
+
const probeBest = PROBE ? ctx._probe?.best : void 0;
|
|
13245
14273
|
const v = child(input, pos, ctx);
|
|
13246
14274
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14275
|
+
if (PROBE && ctx._probe !== void 0) ctx._probe.best = probeBest ?? null;
|
|
13247
14276
|
if (v === FAIL) {
|
|
13248
14277
|
ctx._fe = pos;
|
|
13249
14278
|
ctx._fx = xf;
|
|
@@ -13255,8 +14284,14 @@ function assemble(t, prog, cfg) {
|
|
|
13255
14284
|
}
|
|
13256
14285
|
case OP_OPT: {
|
|
13257
14286
|
const child = link(code[ip + 1]);
|
|
14287
|
+
const gate2 = lookaheadClass(code[ip + 1]);
|
|
14288
|
+
const childClean = CLEAN(code[ip + 1]);
|
|
13258
14289
|
return (input, pos, ctx) => {
|
|
13259
|
-
|
|
14290
|
+
if (gate2 !== null && !classHas2(gate2, lead(input, pos))) {
|
|
14291
|
+
EC.e = pos;
|
|
14292
|
+
return null;
|
|
14293
|
+
}
|
|
14294
|
+
const need = !childClean && markCst(ctx);
|
|
13260
14295
|
const mRaw = MRAW;
|
|
13261
14296
|
const mTl = MTL;
|
|
13262
14297
|
const mLv = MLV;
|
|
@@ -13353,8 +14388,8 @@ function assemble(t, prog, cfg) {
|
|
|
13353
14388
|
};
|
|
13354
14389
|
}
|
|
13355
14390
|
case OP_LEX_PROGRAM: {
|
|
13356
|
-
const
|
|
13357
|
-
const scanId =
|
|
14391
|
+
const run2 = t.lexPrograms[code[ip + 1]];
|
|
14392
|
+
const scanId = run2.scan;
|
|
13358
14393
|
if (scanId !== void 0) {
|
|
13359
14394
|
return (input, pos, ctx) => {
|
|
13360
14395
|
const sTrivia = ctx.trivia, sKinds = ctx.triviaKindLabels;
|
|
@@ -13375,7 +14410,7 @@ function assemble(t, prog, cfg) {
|
|
|
13375
14410
|
ctx._rootTriviaLog = void 0;
|
|
13376
14411
|
let end;
|
|
13377
14412
|
try {
|
|
13378
|
-
end =
|
|
14413
|
+
end = run2(input, pos, ctx, scans[scanId]);
|
|
13379
14414
|
} finally {
|
|
13380
14415
|
SCAN = sScan;
|
|
13381
14416
|
ctx.trivia = sTrivia;
|
|
@@ -13396,7 +14431,7 @@ function assemble(t, prog, cfg) {
|
|
|
13396
14431
|
};
|
|
13397
14432
|
}
|
|
13398
14433
|
return (input, pos, ctx) => {
|
|
13399
|
-
const end =
|
|
14434
|
+
const end = run2(input, pos, ctx);
|
|
13400
14435
|
if (end < 0) return FAIL;
|
|
13401
14436
|
const value = input.slice(pos, end);
|
|
13402
14437
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: { start: pos, end } });
|
|
@@ -13454,6 +14489,9 @@ function assemble(t, prog, cfg) {
|
|
|
13454
14489
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
13455
14490
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
13456
14491
|
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
14492
|
+
const decided = FIRST_DECIDED;
|
|
14493
|
+
FIRST_DECIDED = void 0;
|
|
14494
|
+
const linkFirst = () => decided ?? link(code[base]);
|
|
13457
14495
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
13458
14496
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
13459
14497
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -13498,8 +14536,8 @@ function assemble(t, prog, cfg) {
|
|
|
13498
14536
|
return next === void 0 ? cur : next(input, cur, ctx, values, inherited);
|
|
13499
14537
|
};
|
|
13500
14538
|
};
|
|
13501
|
-
if (
|
|
13502
|
-
const first2 =
|
|
14539
|
+
if (REC2) {
|
|
14540
|
+
const first2 = linkFirst();
|
|
13503
14541
|
const firstSync = sentinelFor(code[base + n]);
|
|
13504
14542
|
const runnerAt = (i) => {
|
|
13505
14543
|
const sync = sentinelFor(code[base + n + i]);
|
|
@@ -13535,13 +14573,13 @@ function assemble(t, prog, cfg) {
|
|
|
13535
14573
|
const bindRunners = (start) => {
|
|
13536
14574
|
const count = Math.min(4, n - start);
|
|
13537
14575
|
const at = (offset) => runnerAt(start + offset);
|
|
13538
|
-
const
|
|
14576
|
+
const never2 = () => -1;
|
|
13539
14577
|
return runnerBlock(
|
|
13540
14578
|
count,
|
|
13541
14579
|
at(0),
|
|
13542
|
-
count > 1 ? at(1) :
|
|
13543
|
-
count > 2 ? at(2) :
|
|
13544
|
-
count > 3 ? at(3) :
|
|
14580
|
+
count > 1 ? at(1) : never2,
|
|
14581
|
+
count > 2 ? at(2) : never2,
|
|
14582
|
+
count > 3 ? at(3) : never2,
|
|
13545
14583
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13546
14584
|
);
|
|
13547
14585
|
};
|
|
@@ -13591,15 +14629,31 @@ function assemble(t, prog, cfg) {
|
|
|
13591
14629
|
let hasAdj = false;
|
|
13592
14630
|
for (let i = 1; i < n; i++) {
|
|
13593
14631
|
const kidIp = code[base + i];
|
|
13594
|
-
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
14632
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp) || holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
13595
14633
|
hasAdj = true;
|
|
13596
14634
|
break;
|
|
13597
14635
|
}
|
|
13598
14636
|
}
|
|
13599
14637
|
if (hasAdj) {
|
|
13600
|
-
const first2 =
|
|
14638
|
+
const first2 = linkFirst();
|
|
13601
14639
|
const runnerAt = (i) => {
|
|
13602
14640
|
const kidIp = code[base + i];
|
|
14641
|
+
if (holdsGap(code, k, base, n, i, NULLABLE)) {
|
|
14642
|
+
const kid = link(kidIp);
|
|
14643
|
+
return (input, cur, ctx) => {
|
|
14644
|
+
if (ctx.trivia === void 0) {
|
|
14645
|
+
const v2 = kid(input, cur, ctx);
|
|
14646
|
+
if (v2 === FAIL) return -1;
|
|
14647
|
+
TERMV = v2;
|
|
14648
|
+
return EC.e;
|
|
14649
|
+
}
|
|
14650
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
14651
|
+
const v = kid(input, scanEnd, ctx);
|
|
14652
|
+
if (v === FAIL) return -1;
|
|
14653
|
+
TERMV = v;
|
|
14654
|
+
return scanEnd;
|
|
14655
|
+
};
|
|
14656
|
+
}
|
|
13603
14657
|
if (code[kidIp] !== OP_ADJ) {
|
|
13604
14658
|
const kid = link(kidIp);
|
|
13605
14659
|
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
@@ -13624,13 +14678,13 @@ function assemble(t, prog, cfg) {
|
|
|
13624
14678
|
const bindRunners = (start) => {
|
|
13625
14679
|
const count = Math.min(4, n - start);
|
|
13626
14680
|
const at = (offset) => runnerAt(start + offset);
|
|
13627
|
-
const
|
|
14681
|
+
const never2 = () => -1;
|
|
13628
14682
|
return runnerBlock(
|
|
13629
14683
|
count,
|
|
13630
14684
|
at(0),
|
|
13631
|
-
count > 1 ? at(1) :
|
|
13632
|
-
count > 2 ? at(2) :
|
|
13633
|
-
count > 3 ? at(3) :
|
|
14685
|
+
count > 1 ? at(1) : never2,
|
|
14686
|
+
count > 2 ? at(2) : never2,
|
|
14687
|
+
count > 3 ? at(3) : never2,
|
|
13634
14688
|
start + count < n ? bindRunners(start + count) : void 0
|
|
13635
14689
|
);
|
|
13636
14690
|
};
|
|
@@ -13667,7 +14721,7 @@ function assemble(t, prog, cfg) {
|
|
|
13667
14721
|
};
|
|
13668
14722
|
}
|
|
13669
14723
|
if (n === 1) {
|
|
13670
|
-
const k0 =
|
|
14724
|
+
const k0 = linkFirst();
|
|
13671
14725
|
if (fused) {
|
|
13672
14726
|
return (input, pos, ctx) => {
|
|
13673
14727
|
const v = k0(input, pos, ctx);
|
|
@@ -13689,7 +14743,7 @@ function assemble(t, prog, cfg) {
|
|
|
13689
14743
|
};
|
|
13690
14744
|
}
|
|
13691
14745
|
if (n === 2) {
|
|
13692
|
-
const k0 =
|
|
14746
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]);
|
|
13693
14747
|
if (fused) {
|
|
13694
14748
|
return (input, pos, ctx) => {
|
|
13695
14749
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13720,7 +14774,7 @@ function assemble(t, prog, cfg) {
|
|
|
13720
14774
|
};
|
|
13721
14775
|
}
|
|
13722
14776
|
if (n === 3) {
|
|
13723
|
-
const k0 =
|
|
14777
|
+
const k0 = linkFirst(), k1 = link(code[base + 1]), k2 = link(code[base + 2]);
|
|
13724
14778
|
if (fused) {
|
|
13725
14779
|
return (input, pos, ctx) => {
|
|
13726
14780
|
const v0 = k0(input, pos, ctx);
|
|
@@ -13814,7 +14868,7 @@ function assemble(t, prog, cfg) {
|
|
|
13814
14868
|
start + count < n ? bind(start + count) : void 0
|
|
13815
14869
|
);
|
|
13816
14870
|
};
|
|
13817
|
-
const first =
|
|
14871
|
+
const first = linkFirst();
|
|
13818
14872
|
const tail = bind(1);
|
|
13819
14873
|
const runDirectTerms = (input, pos, ctx, values) => {
|
|
13820
14874
|
const v0 = first(input, pos, ctx);
|
|
@@ -13853,6 +14907,8 @@ function assemble(t, prog, cfg) {
|
|
|
13853
14907
|
const n = code[ip + 2];
|
|
13854
14908
|
const choiceFx = fx[code[ip + 3]];
|
|
13855
14909
|
const base = ip + 4;
|
|
14910
|
+
for (let i = 0; i < n; i++) link(code[base + i]);
|
|
14911
|
+
const armsClean = CLEAN(ip);
|
|
13856
14912
|
if (table.exclusive) {
|
|
13857
14913
|
const ascii = table.ascii;
|
|
13858
14914
|
const hi = table.hi;
|
|
@@ -13967,7 +15023,7 @@ function assemble(t, prog, cfg) {
|
|
|
13967
15023
|
if (n === 2 || n === 3) {
|
|
13968
15024
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
13969
15025
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
13970
|
-
const predecide = !
|
|
15026
|
+
const predecide = !REC2 && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
13971
15027
|
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
13972
15028
|
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
13973
15029
|
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
@@ -13992,7 +15048,7 @@ function assemble(t, prog, cfg) {
|
|
|
13992
15048
|
if (n === 3) addGate(g2, 4);
|
|
13993
15049
|
return (input, pos, ctx) => {
|
|
13994
15050
|
const c = lead(input, pos);
|
|
13995
|
-
const need = markCst(ctx);
|
|
15051
|
+
const need = !armsClean && markCst(ctx);
|
|
13996
15052
|
const mRaw = MRAW;
|
|
13997
15053
|
const mTl = MTL;
|
|
13998
15054
|
const mLv = MLV;
|
|
@@ -14062,6 +15118,11 @@ function assemble(t, prog, cfg) {
|
|
|
14062
15118
|
}
|
|
14063
15119
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14064
15120
|
}
|
|
15121
|
+
if (prev === 0) {
|
|
15122
|
+
ctx._fe = pos;
|
|
15123
|
+
ctx._fx = choiceFx;
|
|
15124
|
+
return FAIL;
|
|
15125
|
+
}
|
|
14065
15126
|
if (best === pos && prev < 1) acc = accSet(e0, acc);
|
|
14066
15127
|
if (best === pos && prev < 2) acc = accSet(e1, acc);
|
|
14067
15128
|
if (best === pos && n === 3 && prev < 3) acc = accSet(e2, acc);
|
|
@@ -14192,7 +15253,7 @@ function assemble(t, prog, cfg) {
|
|
|
14192
15253
|
const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
|
|
14193
15254
|
const pBit = [];
|
|
14194
15255
|
const pRec = [];
|
|
14195
|
-
if (!
|
|
15256
|
+
if (!REC2 && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
14196
15257
|
for (let i = 0; i < n; i++) {
|
|
14197
15258
|
for (const terminal of largeChoiceLiteralPretest(code, k, code[base + i]) ?? []) {
|
|
14198
15259
|
pBit.push(1 << i);
|
|
@@ -14204,7 +15265,7 @@ function assemble(t, prog, cfg) {
|
|
|
14204
15265
|
if (pn !== 0) {
|
|
14205
15266
|
return (input, pos, ctx) => {
|
|
14206
15267
|
const c = lead(input, pos);
|
|
14207
|
-
const need = markCst(ctx);
|
|
15268
|
+
const need = !armsClean && markCst(ctx);
|
|
14208
15269
|
const mRaw = MRAW;
|
|
14209
15270
|
const mTl = MTL;
|
|
14210
15271
|
const mLv = MLV;
|
|
@@ -14261,7 +15322,7 @@ function assemble(t, prog, cfg) {
|
|
|
14261
15322
|
}
|
|
14262
15323
|
return (input, pos, ctx) => {
|
|
14263
15324
|
const c = lead(input, pos);
|
|
14264
|
-
const need = markCst(ctx);
|
|
15325
|
+
const need = !armsClean && markCst(ctx);
|
|
14265
15326
|
const mRaw = MRAW;
|
|
14266
15327
|
const mTl = MTL;
|
|
14267
15328
|
const mLv = MLV;
|
|
@@ -14309,7 +15370,7 @@ function assemble(t, prog, cfg) {
|
|
|
14309
15370
|
}
|
|
14310
15371
|
return (input, pos, ctx) => {
|
|
14311
15372
|
const c = lead(input, pos);
|
|
14312
|
-
const need = markCst(ctx);
|
|
15373
|
+
const need = !armsClean && markCst(ctx);
|
|
14313
15374
|
const mRaw = MRAW;
|
|
14314
15375
|
const mTl = MTL;
|
|
14315
15376
|
const mLv = MLV;
|
|
@@ -14363,6 +15424,21 @@ function assemble(t, prog, cfg) {
|
|
|
14363
15424
|
return lit(input, pos, ctx);
|
|
14364
15425
|
};
|
|
14365
15426
|
}
|
|
15427
|
+
case OP_RGATE: {
|
|
15428
|
+
const cls = cc[code[ip + 1]];
|
|
15429
|
+
const xf = fx[code[ip + 3]];
|
|
15430
|
+
const child = link(code[ip + 2]);
|
|
15431
|
+
if (cfg.tolerant || cfg.probe) return child;
|
|
15432
|
+
return (input, pos, ctx) => {
|
|
15433
|
+
const item = ctx._routed;
|
|
15434
|
+
if (item !== void 0 && item.span.start === pos && !classHas2(cls, lead(input, item.span.end))) {
|
|
15435
|
+
ctx._fe = item.span.end;
|
|
15436
|
+
ctx._fx = xf;
|
|
15437
|
+
return FAIL;
|
|
15438
|
+
}
|
|
15439
|
+
return child(input, pos, ctx);
|
|
15440
|
+
};
|
|
15441
|
+
}
|
|
14366
15442
|
case OP_ARMGATE: {
|
|
14367
15443
|
const pred = fns[code[ip + 1]];
|
|
14368
15444
|
const child = link(code[ip + 2]);
|
|
@@ -14370,7 +15446,7 @@ function assemble(t, prog, cfg) {
|
|
|
14370
15446
|
return (input, pos, ctx) => {
|
|
14371
15447
|
if (!pred(ctx.state)) {
|
|
14372
15448
|
ctx._fc = false;
|
|
14373
|
-
ctx._fe =
|
|
15449
|
+
ctx._fe = -1;
|
|
14374
15450
|
ctx._fx = xf;
|
|
14375
15451
|
return FAIL;
|
|
14376
15452
|
}
|
|
@@ -14428,10 +15504,11 @@ function assemble(t, prog, cfg) {
|
|
|
14428
15504
|
const itemFx = reportItem ? fx[code[ip + 6]] : EMPTY_FX2;
|
|
14429
15505
|
const collect = op === OP_REP;
|
|
14430
15506
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
14431
|
-
const itemClass = !
|
|
15507
|
+
const itemClass = !REC2 && itemClassIndex >= 0 ? cc[itemClassIndex] : void 0;
|
|
14432
15508
|
const itemMayStart = itemClass === void 0 ? void 0 : (input, pos) => classHas2(itemClass, lead(input, pos));
|
|
14433
15509
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
14434
|
-
|
|
15510
|
+
const itemClean = sepIp < 0 && CLEAN(code[ip + 1]) && !rowNullable(code, k, code[ip + 1], NULLABLE);
|
|
15511
|
+
if (REC2) {
|
|
14435
15512
|
const itemFx2 = fx[code[ip + 6]];
|
|
14436
15513
|
const sepSent = sentinelFor(code[ip + 7]);
|
|
14437
15514
|
return (input, pos, ctx) => {
|
|
@@ -14527,6 +15604,8 @@ function assemble(t, prog, cfg) {
|
|
|
14527
15604
|
const out = collect ? [] : void 0;
|
|
14528
15605
|
const hasTrivia = ctx.trivia !== void 0;
|
|
14529
15606
|
const needMark = rollbackNeeded(ctx);
|
|
15607
|
+
const markLater = needMark && (!itemClean || hasTrivia);
|
|
15608
|
+
const markFirst = needMark && (!itemClean || hasTrivia && skipBeforeFirst);
|
|
14530
15609
|
const gateItems = itemMayStart !== void 0 && ctx._probe === void 0;
|
|
14531
15610
|
let cur = pos;
|
|
14532
15611
|
let count = 0;
|
|
@@ -14534,14 +15613,15 @@ function assemble(t, prog, cfg) {
|
|
|
14534
15613
|
if (max >= 0 && count >= max) break;
|
|
14535
15614
|
if (sep2 !== void 0 && count > 0 && count >= min && cur >= input.length) break;
|
|
14536
15615
|
if (count >= min && sep2 === void 0 && !hasTrivia && gateItems && !itemMayStart(input, cur)) break;
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
const
|
|
14540
|
-
const
|
|
14541
|
-
const
|
|
14542
|
-
const
|
|
14543
|
-
const
|
|
14544
|
-
const
|
|
15616
|
+
const markIt = count > 0 ? markLater : markFirst;
|
|
15617
|
+
if (markIt) markCst(ctx);
|
|
15618
|
+
const mRaw = markIt ? MRAW : 0;
|
|
15619
|
+
const mTl = markIt ? MTL : 0;
|
|
15620
|
+
const mLv = markIt ? MLV : 0;
|
|
15621
|
+
const mFl = markIt ? ctx._fields?.length ?? 0 : 0;
|
|
15622
|
+
const mEr = markIt ? ctx._errors?.length ?? 0 : 0;
|
|
15623
|
+
const mLog = markIt ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15624
|
+
const mRoot = markIt ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14545
15625
|
let itemStart = cur;
|
|
14546
15626
|
let sepEnd = -1;
|
|
14547
15627
|
const viaRepItem = sep2 === void 0 && count >= min && (count > 0 || skipBeforeFirst);
|
|
@@ -14553,7 +15633,7 @@ function assemble(t, prog, cfg) {
|
|
|
14553
15633
|
if (sepLeads) LEAD.at = cur;
|
|
14554
15634
|
const sv = sep2(input, sp, ctx);
|
|
14555
15635
|
if (sv === FAIL) {
|
|
14556
|
-
if (
|
|
15636
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14557
15637
|
if (committed3(ctx)) return FAIL;
|
|
14558
15638
|
break;
|
|
14559
15639
|
}
|
|
@@ -14564,25 +15644,25 @@ function assemble(t, prog, cfg) {
|
|
|
14564
15644
|
itemStart = skipTrivia(input, itemStart, ctx);
|
|
14565
15645
|
}
|
|
14566
15646
|
if (itemStart >= input.length && viaRepItem) {
|
|
14567
|
-
if (
|
|
15647
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14568
15648
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14569
15649
|
break;
|
|
14570
15650
|
}
|
|
14571
15651
|
if (count >= min && gateItems && !itemMayStart(input, itemStart)) {
|
|
14572
|
-
if (
|
|
15652
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14573
15653
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14574
15654
|
break;
|
|
14575
15655
|
}
|
|
14576
15656
|
ctx._fc = false;
|
|
14577
15657
|
const v = child(input, itemStart, ctx);
|
|
14578
15658
|
if (v === FAIL) {
|
|
14579
|
-
if (
|
|
15659
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14580
15660
|
if (committed3(ctx)) return FAIL;
|
|
14581
15661
|
if (trailingAllowed && sepEnd >= 0) cur = sepEnd;
|
|
14582
15662
|
break;
|
|
14583
15663
|
}
|
|
14584
15664
|
if (EC.e === itemStart && viaRepItem) {
|
|
14585
|
-
if (
|
|
15665
|
+
if (markIt) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14586
15666
|
break;
|
|
14587
15667
|
}
|
|
14588
15668
|
if (out !== void 0) out.push(v);
|
|
@@ -14656,7 +15736,14 @@ function assemble(t, prog, cfg) {
|
|
|
14656
15736
|
const runArm = n === 0 ? void 0 : bindArms(0);
|
|
14657
15737
|
const runOther = other === void 0 ? void 0 : dispatchBranch(other, otherRouted);
|
|
14658
15738
|
return (input, pos, ctx) => {
|
|
14659
|
-
const
|
|
15739
|
+
const need = markCst(ctx);
|
|
15740
|
+
const mRaw = MRAW;
|
|
15741
|
+
const mTl = MTL;
|
|
15742
|
+
const mLv = MLV;
|
|
15743
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
15744
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
15745
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
15746
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
14660
15747
|
const selVal = selector(input, pos, ctx);
|
|
14661
15748
|
if (selVal === FAIL) return FAIL;
|
|
14662
15749
|
const selEnd = EC.e;
|
|
@@ -14668,9 +15755,9 @@ function assemble(t, prog, cfg) {
|
|
|
14668
15755
|
ctx._fx = expected;
|
|
14669
15756
|
return FAIL;
|
|
14670
15757
|
}
|
|
14671
|
-
return runOther(input, pos, selEnd, key,
|
|
15758
|
+
return runOther(input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14672
15759
|
}
|
|
14673
|
-
return runArm(arm, input, pos, selEnd, key,
|
|
15760
|
+
return runArm(arm, input, pos, selEnd, key, ctx, need, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
14674
15761
|
};
|
|
14675
15762
|
}
|
|
14676
15763
|
/* ── node ────────────────────────────────────────────────────────────── */
|
|
@@ -14706,7 +15793,8 @@ function assemble(t, prog, cfg) {
|
|
|
14706
15793
|
return nd;
|
|
14707
15794
|
};
|
|
14708
15795
|
}
|
|
14709
|
-
const child = link(code[ip + 2]);
|
|
15796
|
+
const child = NODE_BODY ?? link(code[ip + 2]);
|
|
15797
|
+
NODE_BODY = void 0;
|
|
14710
15798
|
const proj = code[ip + 4];
|
|
14711
15799
|
const buildIdx = code[ip + 1];
|
|
14712
15800
|
const type = k[code[ip + 5]];
|
|
@@ -14730,6 +15818,30 @@ function assemble(t, prog, cfg) {
|
|
|
14730
15818
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
14731
15819
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
14732
15820
|
}
|
|
15821
|
+
if (build !== void 0 && passCollapse(code, ip, hostCst)) {
|
|
15822
|
+
return passCollapseNode(child, build, flags === 32);
|
|
15823
|
+
}
|
|
15824
|
+
const gated = build !== void 0 && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : void 0;
|
|
15825
|
+
const triviaLead = gated === void 0 ? void 0 : triviaLeadRanges(closureLabels.at(code[ip + 2]).tri, trivia2);
|
|
15826
|
+
if (build !== void 0 && gated !== void 0 && triviaLead !== void 0) {
|
|
15827
|
+
const classic = flags === 32 ? collapseBuildNode(child, build) : childrenOnlyCollapseBuildNode(child, build);
|
|
15828
|
+
return gatedPassCollapseNode(
|
|
15829
|
+
[
|
|
15830
|
+
...gated.leads.map((g) => cc[code[g + 1]]),
|
|
15831
|
+
resolveClass(encodeClassSpec([
|
|
15832
|
+
...triviaLead,
|
|
15833
|
+
...gated.lits.map((i) => {
|
|
15834
|
+
const c = k[i].codePointAt(0);
|
|
15835
|
+
return { lo: c, hi: c };
|
|
15836
|
+
})
|
|
15837
|
+
]))
|
|
15838
|
+
],
|
|
15839
|
+
link(gated.last),
|
|
15840
|
+
classic,
|
|
15841
|
+
build,
|
|
15842
|
+
flags === 32
|
|
15843
|
+
);
|
|
15844
|
+
}
|
|
14733
15845
|
if (build !== void 0 && proj < 0 && flags === 32) {
|
|
14734
15846
|
return collapseBuildNode(child, build);
|
|
14735
15847
|
}
|
|
@@ -14776,7 +15888,7 @@ function assemble(t, prog, cfg) {
|
|
|
14776
15888
|
if (v === FAIL) return FAIL;
|
|
14777
15889
|
const end = EC.e;
|
|
14778
15890
|
const span = tracked ? spanLines(ctx, pos, end) : { start: pos, end };
|
|
14779
|
-
const st = readsState
|
|
15891
|
+
const st = readsState ? ctx.state : void 0;
|
|
14780
15892
|
let nd;
|
|
14781
15893
|
if (unwrap && kids.length === 1) {
|
|
14782
15894
|
nd = unwrapChild(kids[0]);
|
|
@@ -14789,10 +15901,10 @@ function assemble(t, prog, cfg) {
|
|
|
14789
15901
|
) {
|
|
14790
15902
|
nd = kids[0];
|
|
14791
15903
|
} else if (proj >= 0) {
|
|
14792
|
-
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog,
|
|
15904
|
+
nd = hostCst && host !== void 0 ? host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags) : projectChild(kids, proj, type);
|
|
14793
15905
|
} else if (build !== void 0) {
|
|
14794
15906
|
if (hostCst && host !== void 0) {
|
|
14795
|
-
nd = host(type, kids, fieldMap, span, rawKids, tlog,
|
|
15907
|
+
nd = host(type, kids, fieldMap, span, rawKids, tlog, ctx.state, tags);
|
|
14796
15908
|
} else {
|
|
14797
15909
|
nd = build(kids, fieldMap, span, rawKids, captureWide ? tlog : EMPTY_TL2, st);
|
|
14798
15910
|
}
|
|
@@ -14843,9 +15955,7 @@ function assemble(t, prog, cfg) {
|
|
|
14843
15955
|
let emitRefusal;
|
|
14844
15956
|
let emitReached;
|
|
14845
15957
|
{
|
|
14846
|
-
const extraIps =
|
|
14847
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
14848
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15958
|
+
const extraIps = assemblyExtraIps(prog);
|
|
14849
15959
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
14850
15960
|
for (const ip of reachableSites(code, roots)) {
|
|
14851
15961
|
if (code[ip] === OP_DISPATCH) {
|
|
@@ -14880,6 +15990,8 @@ function assemble(t, prog, cfg) {
|
|
|
14880
15990
|
}
|
|
14881
15991
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
14882
15992
|
if (notChild >= 0) scalarFor(notChild);
|
|
15993
|
+
const peekChild = scalarTerminalPeekChild(code, ip);
|
|
15994
|
+
if (peekChild >= 0) scalarFor(peekChild);
|
|
14883
15995
|
}
|
|
14884
15996
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
14885
15997
|
if (pre !== void 0) {
|
|
@@ -14926,7 +16038,7 @@ function assemble(t, prog, cfg) {
|
|
|
14926
16038
|
lead,
|
|
14927
16039
|
asciiFoldKey,
|
|
14928
16040
|
ROUTED_FX,
|
|
14929
|
-
|
|
16041
|
+
REC2 ? prog.cc.map((_, i) => sentinelFor(i)) : EMPTY_SENTS,
|
|
14930
16042
|
matchesAt,
|
|
14931
16043
|
recoverScan,
|
|
14932
16044
|
orSentinel,
|
|
@@ -14938,9 +16050,12 @@ function assemble(t, prog, cfg) {
|
|
|
14938
16050
|
adjacencyHolds,
|
|
14939
16051
|
t.lexPrograms,
|
|
14940
16052
|
LEAD,
|
|
14941
|
-
triviaFieldCapture
|
|
16053
|
+
triviaFieldCapture,
|
|
16054
|
+
skipDeferredTrivia,
|
|
16055
|
+
collapseEmpty
|
|
14942
16056
|
);
|
|
14943
16057
|
emitReached = new Set(pre.reached);
|
|
16058
|
+
if (emitted.ext !== void 0) HYBRID = emitted;
|
|
14944
16059
|
}
|
|
14945
16060
|
try {
|
|
14946
16061
|
if (emitted !== void 0) throw new ServedByBuild();
|
|
@@ -15010,7 +16125,7 @@ function assemble(t, prog, cfg) {
|
|
|
15010
16125
|
// — a strict one emits no reader — and through the SAME `sentinelFor` memo
|
|
15011
16126
|
// the closure pieces use, so both engines resync to the same combinator
|
|
15012
16127
|
// object rather than to two separately constructed ones.
|
|
15013
|
-
|
|
16128
|
+
REC2 ? prog.cc.map((_, i) => sentinelFor(i)) : EMPTY_SENTS,
|
|
15014
16129
|
matchesAt,
|
|
15015
16130
|
recoverScan,
|
|
15016
16131
|
orSentinel,
|
|
@@ -15022,7 +16137,9 @@ function assemble(t, prog, cfg) {
|
|
|
15022
16137
|
adjacencyHolds,
|
|
15023
16138
|
t.lexPrograms,
|
|
15024
16139
|
LEAD,
|
|
15025
|
-
triviaFieldCapture
|
|
16140
|
+
triviaFieldCapture,
|
|
16141
|
+
skipDeferredTrivia,
|
|
16142
|
+
collapseEmpty
|
|
15026
16143
|
);
|
|
15027
16144
|
emitReached = em.reached;
|
|
15028
16145
|
} catch (e) {
|
|
@@ -15033,7 +16150,7 @@ function assemble(t, prog, cfg) {
|
|
|
15033
16150
|
}
|
|
15034
16151
|
function pieceAt(ip) {
|
|
15035
16152
|
const em = emitted;
|
|
15036
|
-
if (em !== void 0) {
|
|
16153
|
+
if (em !== void 0 && HYBRID === void 0) {
|
|
15037
16154
|
const p = em.byIp[ip];
|
|
15038
16155
|
if (p === void 0) throw new Error(`table emitter: no emitted body for site ${ip}`);
|
|
15039
16156
|
return p;
|
|
@@ -15063,6 +16180,37 @@ function assemble(t, prog, cfg) {
|
|
|
15063
16180
|
}
|
|
15064
16181
|
const scans = scansArr;
|
|
15065
16182
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
16183
|
+
if (HYBRID !== void 0) {
|
|
16184
|
+
const em = HYBRID;
|
|
16185
|
+
em.bind(
|
|
16186
|
+
(s) => {
|
|
16187
|
+
const saved = SCAN;
|
|
16188
|
+
SCAN = s;
|
|
16189
|
+
return saved;
|
|
16190
|
+
},
|
|
16191
|
+
em.ext.map((ip) => link(ip))
|
|
16192
|
+
);
|
|
16193
|
+
const pieces2 = {};
|
|
16194
|
+
for (const [name, entryIp] of Object.entries(prog.rules)) {
|
|
16195
|
+
pieces2[name] = em.pieces[name] ?? link(entryIp);
|
|
16196
|
+
}
|
|
16197
|
+
for (const ip of emitReached) reached.add(ip);
|
|
16198
|
+
return {
|
|
16199
|
+
pieces: pieces2,
|
|
16200
|
+
end: () => EC.e,
|
|
16201
|
+
begin: (ctx) => {
|
|
16202
|
+
begin(ctx);
|
|
16203
|
+
em.begin(ctx);
|
|
16204
|
+
},
|
|
16205
|
+
finish: () => {
|
|
16206
|
+
em.finish();
|
|
16207
|
+
finish();
|
|
16208
|
+
},
|
|
16209
|
+
scanSkip,
|
|
16210
|
+
reached,
|
|
16211
|
+
emitRefusal: void 0
|
|
16212
|
+
};
|
|
16213
|
+
}
|
|
15066
16214
|
if (emitted !== void 0) {
|
|
15067
16215
|
const em = emitted;
|
|
15068
16216
|
return {
|
|
@@ -15098,6 +16246,26 @@ function assemble(t, prog, cfg) {
|
|
|
15098
16246
|
}
|
|
15099
16247
|
return { pieces, end: () => EC.e, begin, finish, scanSkip, reached, emitRefusal };
|
|
15100
16248
|
}
|
|
16249
|
+
var SITE_COUNTS;
|
|
16250
|
+
function countedPiece(piece, ip) {
|
|
16251
|
+
const counts = SITE_COUNTS;
|
|
16252
|
+
if (counts === void 0) return piece;
|
|
16253
|
+
return (input, pos, ctx) => {
|
|
16254
|
+
counts[ip]++;
|
|
16255
|
+
return piece(input, pos, ctx);
|
|
16256
|
+
};
|
|
16257
|
+
}
|
|
16258
|
+
function countSiteVisits(prog, parse2, fns = prog.fns) {
|
|
16259
|
+
const counts = new Int32Array(prog.code.length);
|
|
16260
|
+
const profiled = ownTableProgram({ ...prog, fns, asm: [] });
|
|
16261
|
+
SITE_COUNTS = counts;
|
|
16262
|
+
try {
|
|
16263
|
+
parse2(tableRules(profiled));
|
|
16264
|
+
} finally {
|
|
16265
|
+
SITE_COUNTS = void 0;
|
|
16266
|
+
}
|
|
16267
|
+
return counts;
|
|
16268
|
+
}
|
|
15101
16269
|
var AssemblyCache = class {
|
|
15102
16270
|
t;
|
|
15103
16271
|
prog;
|
|
@@ -15249,7 +16417,7 @@ function emitClassPool(classes) {
|
|
|
15249
16417
|
if (classes.length < 2) return array;
|
|
15250
16418
|
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
15251
16419
|
if (delimiter === void 0) return array;
|
|
15252
|
-
const split =
|
|
16420
|
+
const split = `/* @__PURE__ */ ${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
15253
16421
|
return split.length < array.length ? split : array;
|
|
15254
16422
|
}
|
|
15255
16423
|
function emitConst(v) {
|
|
@@ -15311,9 +16479,7 @@ function defaultAssemblyCfgs(prog) {
|
|
|
15311
16479
|
function emitAssemblies(prog, cfgs) {
|
|
15312
16480
|
if (cfgs.length === 0) return ["a:[],"];
|
|
15313
16481
|
const t = resolveTable(prog);
|
|
15314
|
-
const extraIps =
|
|
15315
|
-
for (const s of prog.scans ?? []) for (const r of scanRefs(s)) extraIps.push(r[0]);
|
|
15316
|
-
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
16482
|
+
const extraIps = assemblyExtraIps(prog);
|
|
15317
16483
|
const out = [];
|
|
15318
16484
|
const seen = /* @__PURE__ */ new Set();
|
|
15319
16485
|
for (const cfg of cfgs) {
|
|
@@ -15322,7 +16488,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
15322
16488
|
seen.add(key);
|
|
15323
16489
|
let em;
|
|
15324
16490
|
try {
|
|
15325
|
-
em = emitAssemblySource(t, prog, cfg, extraIps, true);
|
|
16491
|
+
em = emitAssemblySource(t, prog, cfg, extraIps, true, cfg.select);
|
|
15326
16492
|
} catch (e) {
|
|
15327
16493
|
if (e instanceof Unemittable) continue;
|
|
15328
16494
|
throw e;
|
|
@@ -16117,36 +17283,36 @@ function findRegexFragments(visited) {
|
|
|
16117
17283
|
if (branches.length >= 2) runs.add(branches.join("|"));
|
|
16118
17284
|
for (let i = 0; i < branches.length; i++) {
|
|
16119
17285
|
for (let n = 2; n <= Math.min(MAX_RUN, branches.length - i); n++) {
|
|
16120
|
-
const
|
|
16121
|
-
if (
|
|
16122
|
-
runs.add(
|
|
17286
|
+
const run2 = branches.slice(i, i + n).join("|");
|
|
17287
|
+
if (run2.length < 4) continue;
|
|
17288
|
+
runs.add(run2);
|
|
16123
17289
|
}
|
|
16124
17290
|
}
|
|
16125
17291
|
}
|
|
16126
|
-
for (const
|
|
16127
|
-
let e = byRun.get(
|
|
17292
|
+
for (const run2 of runs) {
|
|
17293
|
+
let e = byRun.get(run2);
|
|
16128
17294
|
if (e === void 0) {
|
|
16129
|
-
e = { occ: [], nodes: /* @__PURE__ */ new Set(), branches:
|
|
16130
|
-
byRun.set(
|
|
17295
|
+
e = { occ: [], nodes: /* @__PURE__ */ new Set(), branches: run2.split("|").length };
|
|
17296
|
+
byRun.set(run2, e);
|
|
16131
17297
|
}
|
|
16132
17298
|
if (e.nodes.has(v.p)) continue;
|
|
16133
17299
|
e.nodes.add(v.p);
|
|
16134
17300
|
e.occ.push({ site: v.site, source: d.source });
|
|
16135
17301
|
}
|
|
16136
17302
|
}
|
|
16137
|
-
const candidates = [...byRun.entries()].filter(([, e]) => e.occ.length >= 2).map(([
|
|
17303
|
+
const candidates = [...byRun.entries()].filter(([, e]) => e.occ.length >= 2).map(([run2, e]) => ({ run: run2, e, savings: (e.occ.length - 1) * run2.length })).sort((a, b) => b.e.occ.length - a.e.occ.length || b.savings - a.savings || b.run.length - a.run.length);
|
|
16138
17304
|
const kept = [];
|
|
16139
17305
|
for (const c of candidates) {
|
|
16140
17306
|
if (kept.some((k) => k.e.occ.length >= c.e.occ.length && `|${k.run}|`.includes(`|${c.run}|`))) continue;
|
|
16141
17307
|
kept.push(c);
|
|
16142
17308
|
}
|
|
16143
|
-
return kept.map(({ run, e }) => ({
|
|
17309
|
+
return kept.map(({ run: run2, e }) => ({
|
|
16144
17310
|
kind: "regex-fragment",
|
|
16145
|
-
id: `regex-fragment:${
|
|
16146
|
-
fragment:
|
|
17311
|
+
id: `regex-fragment:${run2}`,
|
|
17312
|
+
fragment: run2,
|
|
16147
17313
|
branches: e.branches,
|
|
16148
17314
|
count: e.occ.length,
|
|
16149
|
-
savings: (e.occ.length - 1) *
|
|
17315
|
+
savings: (e.occ.length - 1) * run2.length,
|
|
16150
17316
|
sources: e.occ.map((o) => `/${o.source}/`),
|
|
16151
17317
|
sites: e.occ.map((o) => o.site),
|
|
16152
17318
|
suggestion: `this ${e.branches}-branch alternation is re-spelled in ${e.occ.length} DISTINCT regex() terminals. Hoist it to one shared source string and interpolate it (\`new RegExp(\\\`\u2026\\\${OP}\u2026\\\`)\`) or lift the shared part into its own terminal \u2014 an edit to the operator set currently has to land in ${e.occ.length} places, and the analysis cannot tell you when one of them drifts.`
|
|
@@ -16879,8 +18045,46 @@ function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
|
16879
18045
|
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16880
18046
|
}
|
|
16881
18047
|
|
|
18048
|
+
// src/table/select-hot.ts
|
|
18049
|
+
var LOOP = 8;
|
|
18050
|
+
var ROUNDS = 60;
|
|
18051
|
+
var CAP = 1e12;
|
|
18052
|
+
function selectHotSites(code, entries, siteBytes, budget, profile) {
|
|
18053
|
+
const selected = /* @__PURE__ */ new Set();
|
|
18054
|
+
if (budget <= 0) return selected;
|
|
18055
|
+
const weight = profile === void 0 ? staticWeights(code, entries) : void 0;
|
|
18056
|
+
const w = (ip) => (weight !== void 0 ? weight.get(ip) : profile[ip]) ?? 0;
|
|
18057
|
+
const ranked = [...siteBytes.keys()].sort((a, b) => w(b) / siteBytes.get(b) - w(a) / siteBytes.get(a) || a - b);
|
|
18058
|
+
let spent = 0;
|
|
18059
|
+
for (const ip of ranked) {
|
|
18060
|
+
if (w(ip) === 0) break;
|
|
18061
|
+
const bytes = siteBytes.get(ip);
|
|
18062
|
+
if (spent + bytes > budget) continue;
|
|
18063
|
+
spent += bytes;
|
|
18064
|
+
selected.add(ip);
|
|
18065
|
+
}
|
|
18066
|
+
return selected;
|
|
18067
|
+
}
|
|
18068
|
+
function staticWeights(code, entries) {
|
|
18069
|
+
let weight = /* @__PURE__ */ new Map();
|
|
18070
|
+
const kids = [];
|
|
18071
|
+
for (let round = 0; round < ROUNDS; round++) {
|
|
18072
|
+
const next = /* @__PURE__ */ new Map();
|
|
18073
|
+
for (const ip of entries) next.set(ip, 1);
|
|
18074
|
+
for (const [ip, w] of weight) {
|
|
18075
|
+
kids.length = 0;
|
|
18076
|
+
childSlots(code, ip, kids);
|
|
18077
|
+
const op = code[ip];
|
|
18078
|
+
const scale = op === OP_REP || op === OP_REPV ? LOOP : op === OP_CHOICE || op === OP_DISPATCH ? 1 / Math.max(1, kids.length) : 1;
|
|
18079
|
+
for (const kid of kids) next.set(kid, Math.min(CAP, (next.get(kid) ?? 0) + w * scale));
|
|
18080
|
+
}
|
|
18081
|
+
weight = next;
|
|
18082
|
+
}
|
|
18083
|
+
return weight;
|
|
18084
|
+
}
|
|
18085
|
+
|
|
16882
18086
|
// src/table/compile-rule-map.ts
|
|
16883
|
-
var
|
|
18087
|
+
var SUPERCOMPILE_GROWTH = 1.05;
|
|
16884
18088
|
function resolveHostMode(ruleMap, explicit) {
|
|
16885
18089
|
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16886
18090
|
}
|
|
@@ -16977,14 +18181,45 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
16977
18181
|
entry: null,
|
|
16978
18182
|
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
16979
18183
|
fnSources: sources,
|
|
16980
|
-
...options.
|
|
18184
|
+
...options.select !== void 0 && options.select.size > 0 ? { assemblies: [{ ...defaultAssemblyCfgs(artifact)[0], select: options.select }] } : {},
|
|
16981
18185
|
...metadataSource === void 0 ? {} : { metadataSource }
|
|
16982
18186
|
});
|
|
16983
18187
|
const replacement = replacementWithMetadata();
|
|
18188
|
+
const selectAssembly = (budget, profile) => {
|
|
18189
|
+
const none = { sites: /* @__PURE__ */ new Set(), bytes: 0 };
|
|
18190
|
+
if (hostMode !== "ast" || prog.lines === 1) return none;
|
|
18191
|
+
const table = resolveTable(artifact);
|
|
18192
|
+
const cfg = defaultAssemblyCfgs(artifact)[0];
|
|
18193
|
+
const roots = assemblyExtraIps(artifact);
|
|
18194
|
+
let siteBytes, fixed;
|
|
18195
|
+
try {
|
|
18196
|
+
siteBytes = emitAssemblySource(table, artifact, cfg, roots, true).siteBytes;
|
|
18197
|
+
fixed = emitAssemblySource(table, artifact, cfg, roots, true, /* @__PURE__ */ new Set()).source.length;
|
|
18198
|
+
} catch (e) {
|
|
18199
|
+
if (e instanceof Unemittable) return { ...none, refusal: e.construct };
|
|
18200
|
+
throw e;
|
|
18201
|
+
}
|
|
18202
|
+
const ceiling = budget / SUPERCOMPILE_GROWTH;
|
|
18203
|
+
if (ceiling <= fixed) return none;
|
|
18204
|
+
let target = ceiling;
|
|
18205
|
+
for (; ; ) {
|
|
18206
|
+
const sites = selectHotSites(artifact.code, Object.values(artifact.rules), siteBytes, target - fixed, profile);
|
|
18207
|
+
if (sites.size === 0) {
|
|
18208
|
+
return {
|
|
18209
|
+
...none,
|
|
18210
|
+
refusal: `a site within its ${Math.floor(ceiling)} B selection ceiling (the prelude alone is ${fixed} B)`
|
|
18211
|
+
};
|
|
18212
|
+
}
|
|
18213
|
+
const bytes = emitAssemblySource(table, artifact, cfg, roots, true, sites).source.length;
|
|
18214
|
+
if (bytes <= ceiling) return { sites, bytes: Math.ceil(bytes * SUPERCOMPILE_GROWTH) };
|
|
18215
|
+
target *= Math.min(ceiling / bytes, 0.99);
|
|
18216
|
+
}
|
|
18217
|
+
};
|
|
16984
18218
|
return {
|
|
16985
18219
|
keys: ruleMap.map(([key]) => key),
|
|
16986
18220
|
replacement,
|
|
16987
18221
|
replacementWithMetadata,
|
|
18222
|
+
selectAssembly,
|
|
16988
18223
|
hostMode,
|
|
16989
18224
|
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
16990
18225
|
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
@@ -17066,16 +18301,16 @@ function ownSource(fn) {
|
|
|
17066
18301
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
17067
18302
|
}
|
|
17068
18303
|
function compile(target, second, third) {
|
|
17069
|
-
if (!
|
|
18304
|
+
if (!isCombinator2(target)) return compileMap(target, second);
|
|
17070
18305
|
return compileRoot(target, second, third);
|
|
17071
18306
|
}
|
|
17072
|
-
function
|
|
18307
|
+
function isCombinator2(x) {
|
|
17073
18308
|
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
17074
18309
|
}
|
|
17075
18310
|
function compileMap(grammar, opts = {}) {
|
|
17076
18311
|
const entries = [];
|
|
17077
18312
|
for (const [key, value] of Object.entries(grammar)) {
|
|
17078
|
-
if (!
|
|
18313
|
+
if (!isCombinator2(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
17079
18314
|
if (value._def.tag === "lazy") {
|
|
17080
18315
|
try {
|
|
17081
18316
|
value._def.thunk();
|
|
@@ -17139,7 +18374,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
17139
18374
|
const emitOpts = { fnSources: sources };
|
|
17140
18375
|
const source = printable ? emitTableModule(artifact, { name: "grammar", ...emitOpts }) : "";
|
|
17141
18376
|
const inlineExpression = printable ? emitTableExpression(artifact, { entry: ENTRY, runtimeRef: opts.runtimeRef ?? "tableRules", ...emitOpts }) : null;
|
|
17142
|
-
const
|
|
18377
|
+
const runOnce2 = (input, pos, ctx) => entry(input, pos, ctx);
|
|
17143
18378
|
return {
|
|
17144
18379
|
source,
|
|
17145
18380
|
inlineExpression,
|
|
@@ -17153,10 +18388,10 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
17153
18388
|
// parser runs where a combinator does. A caller probing many positions
|
|
17154
18389
|
// passes one context and pays for none per call.
|
|
17155
18390
|
parse(input, pos = 0, ctx) {
|
|
17156
|
-
return
|
|
18391
|
+
return runOnce2(input, pos, ctx ?? createParseContext());
|
|
17157
18392
|
},
|
|
17158
18393
|
parseWithContext(input, parseCtx, pos = 0) {
|
|
17159
|
-
return
|
|
18394
|
+
return runOnce2(input, pos, parseCtx);
|
|
17160
18395
|
},
|
|
17161
18396
|
/**
|
|
17162
18397
|
* NO LONGER REFUSES. It used to throw unless the caller passed
|
|
@@ -17172,7 +18407,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
17172
18407
|
const errors = [];
|
|
17173
18408
|
ctx._errors = errors;
|
|
17174
18409
|
ctx._tolerant = true;
|
|
17175
|
-
const r =
|
|
18410
|
+
const r = runOnce2(input, pos, ctx);
|
|
17176
18411
|
return { ...r, errors };
|
|
17177
18412
|
}
|
|
17178
18413
|
};
|
|
@@ -17620,7 +18855,7 @@ function fieldOptionsSrc(def) {
|
|
|
17620
18855
|
}
|
|
17621
18856
|
|
|
17622
18857
|
// src/version.ts
|
|
17623
|
-
var PARSEMAN_VERSION = "0.
|
|
18858
|
+
var PARSEMAN_VERSION = "0.58.0";
|
|
17624
18859
|
|
|
17625
18860
|
// src/compiler/compile-linkable-table.ts
|
|
17626
18861
|
function isLocal(rule) {
|
|
@@ -17713,6 +18948,337 @@ function cstBuildHost(typeOrOptions, children3, _fields, span, rawChildren, triv
|
|
|
17713
18948
|
cstBuildHost._parsemanCstOutput = true;
|
|
17714
18949
|
var COMPOSED_PIECES = /* @__PURE__ */ Symbol.for("parseman.composedPieces");
|
|
17715
18950
|
|
|
18951
|
+
// src/cst/trivia-entries.ts
|
|
18952
|
+
var EMPTY_INDICES = Object.freeze([]);
|
|
18953
|
+
var EMPTY_GAPS = Object.freeze([]);
|
|
18954
|
+
var SELECTED_ROOT_STRIDE = 5;
|
|
18955
|
+
function buildRootTriviaIndex(log, labels) {
|
|
18956
|
+
const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
|
|
18957
|
+
const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
|
|
18958
|
+
const ownedRangeStart = (i) => log[markerOffset(i)];
|
|
18959
|
+
const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
|
|
18960
|
+
const markerStart = (i) => log[markerOffset(i) + 2];
|
|
18961
|
+
const markerEnd = (i) => log[markerOffset(i) + 3];
|
|
18962
|
+
const markerKind = (i) => log[markerOffset(i) + 4];
|
|
18963
|
+
const entries = {
|
|
18964
|
+
length,
|
|
18965
|
+
labels,
|
|
18966
|
+
stride: SELECTED_ROOT_STRIDE,
|
|
18967
|
+
start: markerStart,
|
|
18968
|
+
end: markerEnd,
|
|
18969
|
+
insertIndex: () => void 0,
|
|
18970
|
+
kindIndex: markerKind,
|
|
18971
|
+
kind(i) {
|
|
18972
|
+
return labels[markerKind(i)];
|
|
18973
|
+
},
|
|
18974
|
+
text(i, input) {
|
|
18975
|
+
return input.slice(markerStart(i), markerEnd(i));
|
|
18976
|
+
}
|
|
18977
|
+
};
|
|
18978
|
+
const lowerBound = (offset, by) => {
|
|
18979
|
+
let lo = 0;
|
|
18980
|
+
let hi = length;
|
|
18981
|
+
while (lo < hi) {
|
|
18982
|
+
const mid = lo + hi >>> 1;
|
|
18983
|
+
if (by(mid) < offset) lo = mid + 1;
|
|
18984
|
+
else hi = mid;
|
|
18985
|
+
}
|
|
18986
|
+
return lo;
|
|
18987
|
+
};
|
|
18988
|
+
const gapRowsAt = (offset, direction) => {
|
|
18989
|
+
const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
|
|
18990
|
+
let first = lowerBound(offset, edge);
|
|
18991
|
+
if (first === length || edge(first) !== offset) return void 0;
|
|
18992
|
+
const start = ownedRangeStart(first);
|
|
18993
|
+
const end = ownedRangeEnd(first);
|
|
18994
|
+
while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
|
|
18995
|
+
let last = first + 1;
|
|
18996
|
+
while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
|
|
18997
|
+
return [first, last];
|
|
18998
|
+
};
|
|
18999
|
+
const indices = (first, last) => {
|
|
19000
|
+
const out = [];
|
|
19001
|
+
for (let i = first; i < last; i++) out.push(i);
|
|
19002
|
+
return out;
|
|
19003
|
+
};
|
|
19004
|
+
const makeGap = (first, last) => {
|
|
19005
|
+
const start = ownedRangeStart(first);
|
|
19006
|
+
const end = ownedRangeEnd(first);
|
|
19007
|
+
let entryIndices;
|
|
19008
|
+
return {
|
|
19009
|
+
start,
|
|
19010
|
+
end,
|
|
19011
|
+
get entryIndices() {
|
|
19012
|
+
return entryIndices ??= indices(first, last);
|
|
19013
|
+
},
|
|
19014
|
+
hasKind(kind) {
|
|
19015
|
+
for (let i = first; i < last; i++) {
|
|
19016
|
+
if (labels[markerKind(i)] === kind) return true;
|
|
19017
|
+
}
|
|
19018
|
+
return false;
|
|
19019
|
+
},
|
|
19020
|
+
text(input) {
|
|
19021
|
+
return input.slice(start, end);
|
|
19022
|
+
}
|
|
19023
|
+
};
|
|
19024
|
+
};
|
|
19025
|
+
let maps;
|
|
19026
|
+
const getMaps = () => {
|
|
19027
|
+
if (maps !== void 0) return maps;
|
|
19028
|
+
const before = /* @__PURE__ */ new Map();
|
|
19029
|
+
const after = /* @__PURE__ */ new Map();
|
|
19030
|
+
const beforeGaps = /* @__PURE__ */ new Map();
|
|
19031
|
+
const afterGaps = /* @__PURE__ */ new Map();
|
|
19032
|
+
const gaps = [];
|
|
19033
|
+
for (let first = 0; first < length; ) {
|
|
19034
|
+
let last = first + 1;
|
|
19035
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
19036
|
+
const gap = makeGap(first, last);
|
|
19037
|
+
gaps.push(gap);
|
|
19038
|
+
afterGaps.set(gap.start, gap);
|
|
19039
|
+
beforeGaps.set(gap.end, gap);
|
|
19040
|
+
after.set(gap.start, [...gap.entryIndices]);
|
|
19041
|
+
before.set(gap.end, [...gap.entryIndices]);
|
|
19042
|
+
first = last;
|
|
19043
|
+
}
|
|
19044
|
+
maps = { before, after, beforeGaps, afterGaps, gaps };
|
|
19045
|
+
return maps;
|
|
19046
|
+
};
|
|
19047
|
+
return {
|
|
19048
|
+
entries,
|
|
19049
|
+
labels,
|
|
19050
|
+
get before() {
|
|
19051
|
+
return getMaps().before;
|
|
19052
|
+
},
|
|
19053
|
+
get after() {
|
|
19054
|
+
return getMaps().after;
|
|
19055
|
+
},
|
|
19056
|
+
entryIndicesBefore(offset) {
|
|
19057
|
+
const rows = gapRowsAt(offset, "before");
|
|
19058
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
19059
|
+
},
|
|
19060
|
+
entryIndicesAfter(offset) {
|
|
19061
|
+
const rows = gapRowsAt(offset, "after");
|
|
19062
|
+
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
19063
|
+
},
|
|
19064
|
+
gapBefore(offset) {
|
|
19065
|
+
const rows = gapRowsAt(offset, "before");
|
|
19066
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
19067
|
+
},
|
|
19068
|
+
gapAfter(offset) {
|
|
19069
|
+
const rows = gapRowsAt(offset, "after");
|
|
19070
|
+
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
19071
|
+
},
|
|
19072
|
+
gaps() {
|
|
19073
|
+
return getMaps().gaps;
|
|
19074
|
+
},
|
|
19075
|
+
gapsWithKind(kind) {
|
|
19076
|
+
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
19077
|
+
const matches2 = [];
|
|
19078
|
+
for (let first = 0; first < length; ) {
|
|
19079
|
+
let last = first + 1;
|
|
19080
|
+
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
19081
|
+
let matched = false;
|
|
19082
|
+
for (let i = first; i < last && !matched; i++) {
|
|
19083
|
+
const label2 = labels[markerKind(i)];
|
|
19084
|
+
for (const kind2 of kinds) {
|
|
19085
|
+
if (label2 === kind2) {
|
|
19086
|
+
matched = true;
|
|
19087
|
+
break;
|
|
19088
|
+
}
|
|
19089
|
+
}
|
|
19090
|
+
}
|
|
19091
|
+
if (matched) matches2.push(makeGap(first, last));
|
|
19092
|
+
first = last;
|
|
19093
|
+
}
|
|
19094
|
+
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
19095
|
+
}
|
|
19096
|
+
};
|
|
19097
|
+
}
|
|
19098
|
+
|
|
19099
|
+
// src/functional/run.ts
|
|
19100
|
+
var SELECT_EXAMPLE = "run(entry, input, { rootTrivia: { select: ['blockComment', 'lineComment'] } })";
|
|
19101
|
+
var REMOVED_RUN_RESULT_FIELDS = [
|
|
19102
|
+
[
|
|
19103
|
+
"triviaMap",
|
|
19104
|
+
`It was a dense root-trivia index built on every parse; root trivia is now an OPT-IN sparse capture, because most grammars paid for an index they never read. Migration: name the trivia labels your grammar defines \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia\`, whose \`.index\` carries the labels and gap lookups \`triviaMap\` exposed.`
|
|
19105
|
+
],
|
|
19106
|
+
[
|
|
19107
|
+
"triviaLog",
|
|
19108
|
+
`It was the flat \`start, end[, kindIndex]\` log every other trivia view was derived from, and it is no longer allocated at all \u2014 not empty, absent. Migration: request the labels you need \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia.rows\`. Do NOT reuse a stride-2/3 reader: rows are a different width and a different unit (one row per SELECTED marker, not one per trivia chunk), so an old loop reads confidently wrong offsets rather than failing.`
|
|
19109
|
+
],
|
|
19110
|
+
[
|
|
19111
|
+
"triviaKindLabels",
|
|
19112
|
+
`It was already optional, so nothing ever flagged its disappearance \u2014 and \`triviaKindMask(undefined, \u2026)\` means "capture everything", so reading it now silently WIDENS capture instead of erroring. Migration: request labels \u2014 ${SELECT_EXAMPLE} \u2014 then the set you asked for is \`RunResult.rootTrivia.select\` and the resolved table is \`RunResult.rootTrivia.index.labels\`.`
|
|
19113
|
+
]
|
|
19114
|
+
];
|
|
19115
|
+
var RunResultRecord = class {
|
|
19116
|
+
constructor(ok, value, span, expected, errors, unconsumedFrom) {
|
|
19117
|
+
this.ok = ok;
|
|
19118
|
+
this.value = value;
|
|
19119
|
+
this.span = span;
|
|
19120
|
+
this.expected = expected;
|
|
19121
|
+
this.errors = errors;
|
|
19122
|
+
this.unconsumedFrom = unconsumedFrom;
|
|
19123
|
+
}
|
|
19124
|
+
};
|
|
19125
|
+
var RunResultWithRootTrivia = class {
|
|
19126
|
+
constructor(ok, value, span, expected, errors, rootTrivia, unconsumedFrom) {
|
|
19127
|
+
this.ok = ok;
|
|
19128
|
+
this.value = value;
|
|
19129
|
+
this.span = span;
|
|
19130
|
+
this.expected = expected;
|
|
19131
|
+
this.errors = errors;
|
|
19132
|
+
this.rootTrivia = rootTrivia;
|
|
19133
|
+
this.unconsumedFrom = unconsumedFrom;
|
|
19134
|
+
}
|
|
19135
|
+
};
|
|
19136
|
+
for (const proto of [RunResultRecord.prototype, RunResultWithRootTrivia.prototype]) {
|
|
19137
|
+
for (const [name, detail] of REMOVED_RUN_RESULT_FIELDS) {
|
|
19138
|
+
Object.defineProperty(proto, name, {
|
|
19139
|
+
configurable: true,
|
|
19140
|
+
enumerable: false,
|
|
19141
|
+
get() {
|
|
19142
|
+
throw new TypeError(
|
|
19143
|
+
`RunResult.${name} was REMOVED in parseman 0.44.0 and has no default replacement. ${detail}`
|
|
19144
|
+
);
|
|
19145
|
+
}
|
|
19146
|
+
});
|
|
19147
|
+
}
|
|
19148
|
+
}
|
|
19149
|
+
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
19150
|
+
function ambientTriviaFromRunnable(r) {
|
|
19151
|
+
if (!r) return void 0;
|
|
19152
|
+
if (typeof r === "function") return r._meta?.grammarTrivia;
|
|
19153
|
+
if (r._meta.isTrivia) return void 0;
|
|
19154
|
+
return r._meta.grammarTrivia ?? (r._def.tag === "grammar" ? r._def.triviaParser : void 0);
|
|
19155
|
+
}
|
|
19156
|
+
function triviaKindLabelsFromRunnable(r) {
|
|
19157
|
+
if (!r) return void 0;
|
|
19158
|
+
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
19159
|
+
const grammarTrivia = r._meta.grammarTrivia;
|
|
19160
|
+
return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
|
|
19161
|
+
}
|
|
19162
|
+
function rootTriviaClassifiedFromRunnable(r) {
|
|
19163
|
+
if (!r) return false;
|
|
19164
|
+
if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
|
|
19165
|
+
const grammarTrivia = r._meta.grammarTrivia;
|
|
19166
|
+
return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
|
|
19167
|
+
}
|
|
19168
|
+
function makeSelectedRootLabelIndex(labels) {
|
|
19169
|
+
const index = /* @__PURE__ */ Object.create(null);
|
|
19170
|
+
for (let i = 0; i < labels.length; i++) {
|
|
19171
|
+
if (index[labels[i]] === void 0) index[labels[i]] = i;
|
|
19172
|
+
}
|
|
19173
|
+
return index;
|
|
19174
|
+
}
|
|
19175
|
+
function growSpanEnd(span, input, end) {
|
|
19176
|
+
if (span.endLine === void 0 || span.endColumn === void 0) {
|
|
19177
|
+
return { start: span.start, end };
|
|
19178
|
+
}
|
|
19179
|
+
let line = span.endLine;
|
|
19180
|
+
let column = span.endColumn;
|
|
19181
|
+
for (let i = span.end; i < end; i++) {
|
|
19182
|
+
if (input.charCodeAt(i) === 10) {
|
|
19183
|
+
line++;
|
|
19184
|
+
column = 1;
|
|
19185
|
+
} else {
|
|
19186
|
+
column++;
|
|
19187
|
+
}
|
|
19188
|
+
}
|
|
19189
|
+
return { ...span, end, endLine: line, endColumn: column };
|
|
19190
|
+
}
|
|
19191
|
+
function runOnce(entry, input, options) {
|
|
19192
|
+
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
19193
|
+
throw new TypeError(
|
|
19194
|
+
`run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
|
|
19195
|
+
);
|
|
19196
|
+
}
|
|
19197
|
+
const rootTriviaSelection = options.rootTrivia?.select;
|
|
19198
|
+
const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
|
|
19199
|
+
const selectedRootLog = captureRootTrivia ? [] : void 0;
|
|
19200
|
+
const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
|
|
19201
|
+
const errors = [];
|
|
19202
|
+
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
19203
|
+
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
19204
|
+
const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
|
|
19205
|
+
if (captureRootTrivia && triviaKindLabels === void 0) {
|
|
19206
|
+
throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
|
|
19207
|
+
}
|
|
19208
|
+
if (captureRootTrivia) {
|
|
19209
|
+
for (const label2 of rootTriviaSelection) {
|
|
19210
|
+
if (!triviaKindLabels.includes(label2)) {
|
|
19211
|
+
throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label2)}.`);
|
|
19212
|
+
}
|
|
19213
|
+
}
|
|
19214
|
+
}
|
|
19215
|
+
if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
|
|
19216
|
+
throw new TypeError(
|
|
19217
|
+
"run(): rootTrivia.select requires classifiedTrivia() at the root."
|
|
19218
|
+
);
|
|
19219
|
+
}
|
|
19220
|
+
const stamped = entry;
|
|
19221
|
+
assertHostModeCompatible(
|
|
19222
|
+
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
19223
|
+
options.build,
|
|
19224
|
+
typeof entry === "function" && stamped[FUSED_HOST_ELIDED] === true
|
|
19225
|
+
);
|
|
19226
|
+
const ctx = createParseContext();
|
|
19227
|
+
if (captureRootTrivia) {
|
|
19228
|
+
ctx._rootTriviaLog = selectedRootLog;
|
|
19229
|
+
ctx._rootTriviaKindIndex = selectedRootLabelIndex;
|
|
19230
|
+
ctx._rootTriviaStrictScopes = true;
|
|
19231
|
+
}
|
|
19232
|
+
ctx._errors = errors;
|
|
19233
|
+
ctx.build = options.build;
|
|
19234
|
+
ctx.state = options.state;
|
|
19235
|
+
if (grammarTrivia !== void 0) ctx.trivia = grammarTrivia;
|
|
19236
|
+
if (triviaKindLabels) ctx.triviaKindLabels = triviaKindLabels;
|
|
19237
|
+
if (grammarScanSkip !== void 0) ctx.scanSkip = grammarScanSkip;
|
|
19238
|
+
if (options.triviaCaptureMask !== void 0) ctx._triviaCaptureMask = options.triviaCaptureMask;
|
|
19239
|
+
if (options.tolerant) {
|
|
19240
|
+
ctx._tolerant = true;
|
|
19241
|
+
ctx._rec = REC;
|
|
19242
|
+
}
|
|
19243
|
+
if (options.instrumentation !== void 0) {
|
|
19244
|
+
ctx._grammarCoverage = options.instrumentation._grammarCoverage;
|
|
19245
|
+
ctx._grammarTrace = options.instrumentation._grammarTrace;
|
|
19246
|
+
}
|
|
19247
|
+
const r = invoke(entry, input, 0, ctx);
|
|
19248
|
+
const value = r.ok ? r.value : void 0;
|
|
19249
|
+
let span = r.span ?? { start: 0, end: 0 };
|
|
19250
|
+
const expected = r.ok ? [] : r.expected ?? [];
|
|
19251
|
+
let unconsumedFrom = null;
|
|
19252
|
+
if (r.ok) {
|
|
19253
|
+
let pos = span.end;
|
|
19254
|
+
const tail = options.trivia ?? ambientTriviaFromRunnable(entry);
|
|
19255
|
+
if (tail !== void 0 && pos < input.length) {
|
|
19256
|
+
const t = invoke(tail, input, pos, createParseContext());
|
|
19257
|
+
if (t.ok && t.span.end > pos) {
|
|
19258
|
+
span = growSpanEnd(span, input, t.span.end);
|
|
19259
|
+
pos = t.span.end;
|
|
19260
|
+
}
|
|
19261
|
+
}
|
|
19262
|
+
unconsumedFrom = pos < input.length ? pos : null;
|
|
19263
|
+
}
|
|
19264
|
+
return selectedRootLog !== void 0 && selectedRootLog.length > 0 ? new RunResultWithRootTrivia(
|
|
19265
|
+
r.ok,
|
|
19266
|
+
value,
|
|
19267
|
+
span,
|
|
19268
|
+
expected,
|
|
19269
|
+
errors,
|
|
19270
|
+
{
|
|
19271
|
+
rows: selectedRootLog,
|
|
19272
|
+
select: rootTriviaSelection,
|
|
19273
|
+
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
19274
|
+
},
|
|
19275
|
+
unconsumedFrom
|
|
19276
|
+
) : new RunResultRecord(r.ok, value, span, expected, errors, unconsumedFrom);
|
|
19277
|
+
}
|
|
19278
|
+
function run(entry, input, options = {}) {
|
|
19279
|
+
return runOnce(entry, input, options);
|
|
19280
|
+
}
|
|
19281
|
+
|
|
17716
19282
|
// src/combinators/gate.ts
|
|
17717
19283
|
function gate(predicate) {
|
|
17718
19284
|
const meta = {
|
|
@@ -18212,7 +19778,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
18212
19778
|
if (!keyArg || !parserArg || extraArg !== void 0 || keyArg.type === "SpreadElement" || parserArg.type === "SpreadElement") return null;
|
|
18213
19779
|
const key = anyValue(keyArg, scope, code, mfs);
|
|
18214
19780
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
18215
|
-
if (!
|
|
19781
|
+
if (!isCombinator3(parserValue)) return null;
|
|
18216
19782
|
const opts = { caseInsensitive: factory.caseInsensitive };
|
|
18217
19783
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
18218
19784
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
@@ -18223,7 +19789,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
18223
19789
|
const [parserArg] = node2.arguments;
|
|
18224
19790
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
18225
19791
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
18226
|
-
if (!
|
|
19792
|
+
if (!isCombinator3(parserValue)) return null;
|
|
18227
19793
|
return otherwise(parserValue);
|
|
18228
19794
|
}
|
|
18229
19795
|
if (callee.name === "when") {
|
|
@@ -18233,24 +19799,24 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
18233
19799
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
18234
19800
|
const opts = dispatchWhenOptions(optsArg === void 0 ? void 0 : anyValue(optsArg, scope, code, mfs));
|
|
18235
19801
|
if (opts === null) return null;
|
|
18236
|
-
if (!
|
|
19802
|
+
if (!isCombinator3(parserValue)) return null;
|
|
18237
19803
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
18238
19804
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
18239
19805
|
if (isDispatchMatcher(key)) return when(key, parserValue, opts);
|
|
18240
19806
|
}
|
|
18241
19807
|
return null;
|
|
18242
19808
|
}
|
|
18243
|
-
function
|
|
19809
|
+
function isCombinator3(v) {
|
|
18244
19810
|
return !!v && typeof v === "object" && "_def" in v;
|
|
18245
19811
|
}
|
|
18246
19812
|
function isDispatchArm(v) {
|
|
18247
19813
|
if (!v || typeof v !== "object") return false;
|
|
18248
19814
|
const rec = v;
|
|
18249
|
-
if (rec.kind === "otherwise") return
|
|
19815
|
+
if (rec.kind === "otherwise") return isCombinator3(rec.parser);
|
|
18250
19816
|
if (rec.kind === "whenMatcher") {
|
|
18251
|
-
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" &&
|
|
19817
|
+
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" && isCombinator3(rec.parser);
|
|
18252
19818
|
}
|
|
18253
|
-
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" &&
|
|
19819
|
+
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" && isCombinator3(rec.parser);
|
|
18254
19820
|
}
|
|
18255
19821
|
function isDispatchMatcher(v) {
|
|
18256
19822
|
if (!v || typeof v !== "object") return false;
|
|
@@ -18265,7 +19831,7 @@ function scopeGet(scope, name, mfs) {
|
|
|
18265
19831
|
if (mfs && entry.mfSrcs.length > 0) mfs.push(...entry.mfSrcs);
|
|
18266
19832
|
return entry.combi;
|
|
18267
19833
|
}
|
|
18268
|
-
if (
|
|
19834
|
+
if (isCombinator3(entry)) return entry;
|
|
18269
19835
|
return null;
|
|
18270
19836
|
}
|
|
18271
19837
|
function unwrapStaticExpr(expr) {
|
|
@@ -18317,7 +19883,7 @@ function scopedStaticValue(expr, scope) {
|
|
|
18317
19883
|
return { found: true, value };
|
|
18318
19884
|
}
|
|
18319
19885
|
function staticNodeOptionsFromValue(value) {
|
|
18320
|
-
if (value === null || typeof value !== "object" || Array.isArray(value) ||
|
|
19886
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator3(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
18321
19887
|
const opts = {};
|
|
18322
19888
|
const rec = value;
|
|
18323
19889
|
for (const name of Object.keys(rec)) {
|
|
@@ -18411,7 +19977,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18411
19977
|
const [parserArg, fnArg] = node2.arguments;
|
|
18412
19978
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
18413
19979
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
18414
|
-
if (!
|
|
19980
|
+
if (!isCombinator3(inner)) return null;
|
|
18415
19981
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
18416
19982
|
mfs.push(fnSrc);
|
|
18417
19983
|
try {
|
|
@@ -18426,7 +19992,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18426
19992
|
const [parserArg, fnArg] = node2.arguments;
|
|
18427
19993
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
18428
19994
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
18429
|
-
if (!
|
|
19995
|
+
if (!isCombinator3(inner)) return null;
|
|
18430
19996
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
18431
19997
|
mfs.push(fnSrc);
|
|
18432
19998
|
try {
|
|
@@ -18447,7 +20013,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18447
20013
|
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
18448
20014
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
18449
20015
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
18450
|
-
if (!
|
|
20016
|
+
if (!isCombinator3(inner)) return null;
|
|
18451
20017
|
const be = buildArg;
|
|
18452
20018
|
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
18453
20019
|
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
@@ -18521,7 +20087,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18521
20087
|
const opts = anyValue(optsArg, scope, code, []);
|
|
18522
20088
|
if (!opts || typeof opts !== "object") return null;
|
|
18523
20089
|
const root = anyValue(rootArg, scope, code, mfs);
|
|
18524
|
-
if (!
|
|
20090
|
+
if (!isCombinator3(root)) return null;
|
|
18525
20091
|
try {
|
|
18526
20092
|
return parser(opts, root);
|
|
18527
20093
|
} catch {
|
|
@@ -18533,10 +20099,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18533
20099
|
if (!itemArg || !sepArg || itemArg.type === "SpreadElement" || sepArg.type === "SpreadElement") return null;
|
|
18534
20100
|
const itemMfs = [];
|
|
18535
20101
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18536
|
-
if (!
|
|
20102
|
+
if (!isCombinator3(itemCombi)) return null;
|
|
18537
20103
|
const sepMfs = [];
|
|
18538
20104
|
const sepCombi = anyValue(sepArg, scope, code, sepMfs);
|
|
18539
|
-
if (!
|
|
20105
|
+
if (!isCombinator3(sepCombi)) return null;
|
|
18540
20106
|
let opts;
|
|
18541
20107
|
if (optsArg) {
|
|
18542
20108
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18556,7 +20122,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18556
20122
|
if (!itemArg || itemArg.type === "SpreadElement") return null;
|
|
18557
20123
|
const itemMfs = [];
|
|
18558
20124
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18559
|
-
if (!
|
|
20125
|
+
if (!isCombinator3(itemCombi)) return null;
|
|
18560
20126
|
let opts;
|
|
18561
20127
|
if (optsArg) {
|
|
18562
20128
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18578,7 +20144,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18578
20144
|
const [innerArg] = node2.arguments;
|
|
18579
20145
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18580
20146
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18581
|
-
if (!
|
|
20147
|
+
if (!isCombinator3(inner)) return null;
|
|
18582
20148
|
try {
|
|
18583
20149
|
return not(inner);
|
|
18584
20150
|
} catch {
|
|
@@ -18589,7 +20155,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18589
20155
|
const [innerArg] = node2.arguments;
|
|
18590
20156
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18591
20157
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18592
|
-
if (!
|
|
20158
|
+
if (!isCombinator3(inner)) return null;
|
|
18593
20159
|
try {
|
|
18594
20160
|
return peek(inner);
|
|
18595
20161
|
} catch {
|
|
@@ -18614,7 +20180,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18614
20180
|
const [sentinelArg, optsArg] = node2.arguments;
|
|
18615
20181
|
if (!sentinelArg || sentinelArg.type === "SpreadElement") return null;
|
|
18616
20182
|
const sentinel = anyValue(sentinelArg, scope, code, []);
|
|
18617
|
-
if (!
|
|
20183
|
+
if (!isCombinator3(sentinel)) return null;
|
|
18618
20184
|
const opts = scanOptions(optsArg, scope, code);
|
|
18619
20185
|
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18620
20186
|
try {
|
|
@@ -18645,7 +20211,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18645
20211
|
const extraSrc = stripTsFromSource(extraArg, code);
|
|
18646
20212
|
mfs.push(extraSrc);
|
|
18647
20213
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18648
|
-
if (!
|
|
20214
|
+
if (!isCombinator3(inner)) return null;
|
|
18649
20215
|
try {
|
|
18650
20216
|
const extraType = unwrapStaticExpr(extraArg).type;
|
|
18651
20217
|
const derives = extraType === "ArrowFunctionExpression" || extraType === "FunctionExpression";
|
|
@@ -18663,7 +20229,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18663
20229
|
const [selectorArg, ...armArgs] = node2.arguments;
|
|
18664
20230
|
if (!selectorArg || selectorArg.type === "SpreadElement") return null;
|
|
18665
20231
|
const selector = anyValue(selectorArg, scope, code, mfs);
|
|
18666
|
-
if (!
|
|
20232
|
+
if (!isCombinator3(selector)) return null;
|
|
18667
20233
|
const arms = [];
|
|
18668
20234
|
for (const arg of armArgs) {
|
|
18669
20235
|
if (arg.type === "SpreadElement") return null;
|
|
@@ -18690,12 +20256,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18690
20256
|
const gateSrc = stripTsFromSource(parts.gate, code);
|
|
18691
20257
|
mfs.push(gateSrc);
|
|
18692
20258
|
const combi = anyValue(parts.combinator, scope, code, mfs);
|
|
18693
|
-
if (!
|
|
20259
|
+
if (!isCombinator3(combi)) return null;
|
|
18694
20260
|
arms.push({ gate: () => true, combinator: combi });
|
|
18695
20261
|
gateSrcs.push(gateSrc);
|
|
18696
20262
|
} else {
|
|
18697
20263
|
const combi = anyValue(argNode, scope, code, mfs);
|
|
18698
|
-
if (!
|
|
20264
|
+
if (!isCombinator3(combi)) return null;
|
|
18699
20265
|
arms.push(combi);
|
|
18700
20266
|
gateSrcs.push(null);
|
|
18701
20267
|
}
|
|
@@ -18843,7 +20409,7 @@ function evaluateExpr(node2, scope, code, mapFnSources) {
|
|
|
18843
20409
|
function evaluateCombinatorArray(node2, scope, code) {
|
|
18844
20410
|
const val = anyValue(node2, scope, code, []);
|
|
18845
20411
|
if (!Array.isArray(val) || val.length === 0) return null;
|
|
18846
|
-
if (!val.every(
|
|
20412
|
+
if (!val.every(isCombinator3)) return null;
|
|
18847
20413
|
return val;
|
|
18848
20414
|
}
|
|
18849
20415
|
function collectRuleKeys(retObj) {
|
|
@@ -18921,7 +20487,7 @@ function evalBodyStatements(statements, scope, code, out) {
|
|
|
18921
20487
|
return false;
|
|
18922
20488
|
}
|
|
18923
20489
|
const thisDeclMfSrcs = bodyMfs.slice(before);
|
|
18924
|
-
if (
|
|
20490
|
+
if (isCombinator3(val)) scope.set(name, { combi: val, mfSrcs: thisDeclMfSrcs });
|
|
18925
20491
|
else if (isDispatchArm(val)) scope.set(name, { value: val, mfSrcs: thisDeclMfSrcs });
|
|
18926
20492
|
else scope.set(name, val);
|
|
18927
20493
|
}
|
|
@@ -18976,7 +20542,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18976
20542
|
const definitions = {};
|
|
18977
20543
|
for (const [key, e] of finalByKey) {
|
|
18978
20544
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
18979
|
-
if (!
|
|
20545
|
+
if (!isCombinator3(val)) throw ABORT;
|
|
18980
20546
|
definitions[key] = val;
|
|
18981
20547
|
}
|
|
18982
20548
|
return definitions;
|
|
@@ -18991,7 +20557,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18991
20557
|
return map;
|
|
18992
20558
|
}
|
|
18993
20559
|
function isDefinableRef2(v) {
|
|
18994
|
-
return
|
|
20560
|
+
return isCombinator3(v) && typeof v.define === "function" && v._def.tag === "lazy";
|
|
18995
20561
|
}
|
|
18996
20562
|
function evaluateRefDeclaration(init, name, scope) {
|
|
18997
20563
|
if (init.type !== "CallExpression") return null;
|
|
@@ -19011,12 +20577,12 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
19011
20577
|
if (mem.property.type !== "Identifier" || mem.property.name !== "define") return false;
|
|
19012
20578
|
if (mem.object.type !== "Identifier" || !mem.object.name) return false;
|
|
19013
20579
|
const target = scope.get(mem.object.name);
|
|
19014
|
-
const refCombi = isScopeEntry(target) ? target.combi :
|
|
20580
|
+
const refCombi = isScopeEntry(target) ? target.combi : isCombinator3(target) ? target : null;
|
|
19015
20581
|
if (!refCombi || !isDefinableRef2(refCombi)) return false;
|
|
19016
20582
|
const args = callExpr.arguments;
|
|
19017
20583
|
if (args.length !== 1 || args[0].type === "SpreadElement") return false;
|
|
19018
20584
|
const inner = anyValue(args[0], scope, code, []);
|
|
19019
|
-
if (!
|
|
20585
|
+
if (!isCombinator3(inner)) return false;
|
|
19020
20586
|
try {
|
|
19021
20587
|
refCombi.define(inner);
|
|
19022
20588
|
} catch {
|
|
@@ -19788,19 +21354,14 @@ function fallback(emitted, reason, before) {
|
|
|
19788
21354
|
}
|
|
19789
21355
|
};
|
|
19790
21356
|
}
|
|
19791
|
-
function supercompileRuleMapReplacement(prog, replacement) {
|
|
21357
|
+
function supercompileRuleMapReplacement(prog, replacement, select) {
|
|
19792
21358
|
const cfg = defaultAssemblyCfgs(prog)[0];
|
|
19793
21359
|
if (cfg === void 0) return replacement;
|
|
19794
|
-
const extraIps =
|
|
19795
|
-
for (const scan of prog.scans ?? []) {
|
|
19796
|
-
for (const ref2 of scan.skip) extraIps.push(ref2[0]);
|
|
19797
|
-
if (scan.sentinel !== void 0) extraIps.push(scan.sentinel[0]);
|
|
19798
|
-
}
|
|
19799
|
-
for (const set of prog.scanSkip ?? []) for (const ref2 of set) extraIps.push(ref2[0]);
|
|
21360
|
+
const extraIps = assemblyExtraIps(prog);
|
|
19800
21361
|
let canonical2;
|
|
19801
21362
|
let candidate;
|
|
19802
21363
|
try {
|
|
19803
|
-
canonical2 = emitAssemblySource(resolveTable(prog), prog, cfg, extraIps, true);
|
|
21364
|
+
canonical2 = emitAssemblySource(resolveTable(prog), prog, cfg, extraIps, true, select);
|
|
19804
21365
|
candidate = supercompileEmittedAssembly(prog, cfg, extraIps, canonical2);
|
|
19805
21366
|
} catch {
|
|
19806
21367
|
return replacement;
|
|
@@ -20103,6 +21664,7 @@ ${nested}
|
|
|
20103
21664
|
}
|
|
20104
21665
|
|
|
20105
21666
|
// src/plugin/ir-eval.ts
|
|
21667
|
+
var INERT_BUILDER = /* @__PURE__ */ Symbol("parseman.inertBuilder");
|
|
20106
21668
|
function evalRulesIR(ir) {
|
|
20107
21669
|
return evalIR(ir, rules);
|
|
20108
21670
|
}
|
|
@@ -20142,9 +21704,11 @@ function evalIR(ir, rulesImpl) {
|
|
|
20142
21704
|
if (staticError !== void 0 && staticError.length > 0) {
|
|
20143
21705
|
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
20144
21706
|
}
|
|
20145
|
-
const
|
|
21707
|
+
const inert = (() => {
|
|
20146
21708
|
throw new Error("IR node build requires static re-lowering");
|
|
20147
|
-
})
|
|
21709
|
+
});
|
|
21710
|
+
inert[INERT_BUILDER] = type;
|
|
21711
|
+
const n = node(type, child, inert, opts);
|
|
20148
21712
|
n._def.buildSrc = src;
|
|
20149
21713
|
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
20150
21714
|
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
@@ -20287,7 +21851,41 @@ function evalIR(ir, rulesImpl) {
|
|
|
20287
21851
|
// src/plugin/index.ts
|
|
20288
21852
|
import { createHash } from "node:crypto";
|
|
20289
21853
|
var TABLE_RUNTIME_SPECIFIER = "parseman/table";
|
|
21854
|
+
var CARRIED_SIDECAR_SUFFIX = ".parseman.json";
|
|
21855
|
+
var _sidecarCache = /* @__PURE__ */ new Map();
|
|
21856
|
+
function readCarriedSidecar(artifact) {
|
|
21857
|
+
const file = artifact + CARRIED_SIDECAR_SUFFIX;
|
|
21858
|
+
let mtimeMs;
|
|
21859
|
+
try {
|
|
21860
|
+
mtimeMs = fs2.statSync(file).mtimeMs;
|
|
21861
|
+
} catch {
|
|
21862
|
+
return null;
|
|
21863
|
+
}
|
|
21864
|
+
const hit = _sidecarCache.get(file);
|
|
21865
|
+
if (hit && hit.mtimeMs === mtimeMs) return hit.sidecar;
|
|
21866
|
+
let sidecar = null;
|
|
21867
|
+
try {
|
|
21868
|
+
const parsed = JSON.parse(fs2.readFileSync(file, "utf8"));
|
|
21869
|
+
const exports = typeof parsed === "object" && parsed !== null ? parsed.exports : void 0;
|
|
21870
|
+
if (typeof exports === "object" && exports !== null) sidecar = parsed;
|
|
21871
|
+
} catch {
|
|
21872
|
+
}
|
|
21873
|
+
_sidecarCache.set(file, { mtimeMs, sidecar });
|
|
21874
|
+
return sidecar;
|
|
21875
|
+
}
|
|
21876
|
+
var corpusCache = /* @__PURE__ */ new Map();
|
|
21877
|
+
function corpusTexts(profile) {
|
|
21878
|
+
return profile.files.map((file) => {
|
|
21879
|
+
const mtimeMs = fs2.statSync(file).mtimeMs;
|
|
21880
|
+
const hit = corpusCache.get(file);
|
|
21881
|
+
if (hit !== void 0 && hit.mtimeMs === mtimeMs) return hit.text;
|
|
21882
|
+
const text = fs2.readFileSync(file, "utf8");
|
|
21883
|
+
corpusCache.set(file, { mtimeMs, text });
|
|
21884
|
+
return text;
|
|
21885
|
+
});
|
|
21886
|
+
}
|
|
20290
21887
|
var PARSEMAN_MODULE = "parseman";
|
|
21888
|
+
var DEFAULT_ASSEMBLY_BUDGET = 0.25;
|
|
20291
21889
|
function reasonSuffix(runtimeOnly) {
|
|
20292
21890
|
return runtimeOnly === void 0 || runtimeOnly.length === 0 ? "" : ` \u2014 ${runtimeOnly.join("; ")}`;
|
|
20293
21891
|
}
|
|
@@ -20393,30 +21991,101 @@ function parseModuleCached(filePath) {
|
|
|
20393
21991
|
_moduleParseCache.set(filePath, { mtimeMs, parsed });
|
|
20394
21992
|
return parsed;
|
|
20395
21993
|
}
|
|
20396
|
-
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
|
|
20400
|
-
|
|
20401
|
-
|
|
20402
|
-
|
|
20403
|
-
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
|
|
20409
|
-
|
|
20410
|
-
|
|
20411
|
-
|
|
20412
|
-
|
|
20413
|
-
|
|
20414
|
-
|
|
20415
|
-
|
|
20416
|
-
if (!
|
|
20417
|
-
|
|
20418
|
-
|
|
20419
|
-
|
|
21994
|
+
function reexportSource(body, exported) {
|
|
21995
|
+
for (const st of body) {
|
|
21996
|
+
if (st.type !== "ExportNamedDeclaration") continue;
|
|
21997
|
+
for (const sp of st.specifiers ?? []) {
|
|
21998
|
+
const exp = sp.exported;
|
|
21999
|
+
if ((exp?.name ?? exp?.value) !== exported) continue;
|
|
22000
|
+
const local = sp.local;
|
|
22001
|
+
const name = local?.name ?? local?.value;
|
|
22002
|
+
if (name === void 0) return null;
|
|
22003
|
+
const from = st.source?.value;
|
|
22004
|
+
return from !== void 0 ? { source: from, imported: name } : extractImportBindings(body).get(name) ?? null;
|
|
22005
|
+
}
|
|
22006
|
+
}
|
|
22007
|
+
return null;
|
|
22008
|
+
}
|
|
22009
|
+
async function followCarried(sinks, moduleId, name) {
|
|
22010
|
+
for (let hop = 0; hop < 64; hop++) {
|
|
22011
|
+
const own = sinks.get(moduleId)?.get(name);
|
|
22012
|
+
if (own !== void 0) return own;
|
|
22013
|
+
const code = this.getModuleInfo(moduleId)?.code;
|
|
22014
|
+
if (!code) return void 0;
|
|
22015
|
+
const parsed = parseSync5(moduleId, code);
|
|
22016
|
+
if (parsed.errors.length > 0) return void 0;
|
|
22017
|
+
const next = reexportSource(parsed.program.body, name);
|
|
22018
|
+
if (next === null) return void 0;
|
|
22019
|
+
const resolved = await this.resolve(next.source, moduleId);
|
|
22020
|
+
if (resolved === null || resolved.external) return void 0;
|
|
22021
|
+
moduleId = resolved.id;
|
|
22022
|
+
name = next.imported;
|
|
22023
|
+
}
|
|
22024
|
+
return void 0;
|
|
22025
|
+
}
|
|
22026
|
+
async function emitCarriedSidecars(sinks, bundle) {
|
|
22027
|
+
const recorders = /* @__PURE__ */ new Map();
|
|
22028
|
+
for (const [moduleId, sink] of sinks) for (const name of sink.keys()) (recorders.get(name) ?? recorders.set(name, []).get(name)).push(moduleId);
|
|
22029
|
+
for (const chunk of Object.values(bundle)) {
|
|
22030
|
+
if (chunk.type !== "chunk") continue;
|
|
22031
|
+
const exports = {};
|
|
22032
|
+
for (const name of chunk.exports ?? []) {
|
|
22033
|
+
const followed = chunk.facadeModuleId ? await followCarried.call(this, sinks, chunk.facadeModuleId, name) : void 0;
|
|
22034
|
+
if (followed !== void 0) {
|
|
22035
|
+
exports[name] = followed;
|
|
22036
|
+
continue;
|
|
22037
|
+
}
|
|
22038
|
+
const ids = recorders.get(name);
|
|
22039
|
+
if (ids === void 0) continue;
|
|
22040
|
+
const own = ids.filter((m) => chunk.moduleIds?.includes(m));
|
|
22041
|
+
const moduleId = own.length === 1 ? own[0] : own.length === 0 && ids.length === 1 ? ids[0] : void 0;
|
|
22042
|
+
if (moduleId !== void 0) exports[name] = sinks.get(moduleId).get(name);
|
|
22043
|
+
}
|
|
22044
|
+
if (Object.keys(exports).length === 0) continue;
|
|
22045
|
+
const sidecar = { parseman: PARSEMAN_VERSION, exports };
|
|
22046
|
+
this.emitFile({ type: "asset", fileName: chunk.fileName + CARRIED_SIDECAR_SUFFIX, source: JSON.stringify(sidecar) });
|
|
22047
|
+
}
|
|
22048
|
+
}
|
|
22049
|
+
var SIDECAR_FRAMEWORKS = /* @__PURE__ */ new Set(["rollup", "rolldown", "vite"]);
|
|
22050
|
+
var plugin_default = createUnplugin((opts = {}, meta) => {
|
|
22051
|
+
const sinks = SIDECAR_FRAMEWORKS.has(meta.framework) ? /* @__PURE__ */ new Map() : void 0;
|
|
22052
|
+
const generateBundle = sinks === void 0 ? void 0 : {
|
|
22053
|
+
generateBundle(_options, bundle) {
|
|
22054
|
+
return emitCarriedSidecars.call(this, sinks, bundle);
|
|
22055
|
+
}
|
|
22056
|
+
};
|
|
22057
|
+
return {
|
|
22058
|
+
name: "parseman",
|
|
22059
|
+
...generateBundle === void 0 ? {} : { rollup: generateBundle, rolldown: generateBundle, vite: generateBundle },
|
|
22060
|
+
// Run BEFORE the bundler's TS/JS transform — otherwise esbuild (Vite) strips
|
|
22061
|
+
// the `with { type: 'macro' }` import attribute before we ever see it, and the
|
|
22062
|
+
// macro silently never fires.
|
|
22063
|
+
enforce: "pre",
|
|
22064
|
+
transformInclude(id) {
|
|
22065
|
+
return /\.[jt]sx?$/.test(id) && !id.includes("node_modules");
|
|
22066
|
+
},
|
|
22067
|
+
transform(code, id) {
|
|
22068
|
+
if (!code.includes("parseman")) return null;
|
|
22069
|
+
if (!code.includes("macro")) return null;
|
|
22070
|
+
for (const file of opts.assemblyProfile?.files ?? []) this?.addWatchFile?.(file);
|
|
22071
|
+
const moduleAliases = /* @__PURE__ */ new Set([PARSEMAN_MODULE, ...opts.moduleAliases ?? []]);
|
|
22072
|
+
const sink = sinks && /* @__PURE__ */ new Map();
|
|
22073
|
+
const result = transformMacro(code, id, moduleAliases, opts.warnUnloweredRegex === true, opts.recovery === true, opts.grammarCoverage === true, opts.assemblyProfile, opts.assemblyBudget, sink);
|
|
22074
|
+
if (sinks && sink) {
|
|
22075
|
+
if (sink.size > 0) sinks.set(id, sink);
|
|
22076
|
+
else sinks.delete(id);
|
|
22077
|
+
}
|
|
22078
|
+
if (result?.warnings.length) {
|
|
22079
|
+
for (const w of result.warnings) {
|
|
22080
|
+
if (typeof this?.warn === "function") this.warn(`[parseman] ${w}`);
|
|
22081
|
+
else console.warn(`[parseman] ${w}`);
|
|
22082
|
+
}
|
|
22083
|
+
}
|
|
22084
|
+
if (!result) return null;
|
|
22085
|
+
return { code: result.code, map: result.map };
|
|
22086
|
+
}
|
|
22087
|
+
};
|
|
22088
|
+
});
|
|
20420
22089
|
function exportLocalName(body, exported) {
|
|
20421
22090
|
for (const st of body) {
|
|
20422
22091
|
if (st.type !== "ExportNamedDeclaration") continue;
|
|
@@ -20562,17 +22231,17 @@ function lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recov
|
|
|
20562
22231
|
_sourceLowering.delete(file);
|
|
20563
22232
|
}
|
|
20564
22233
|
}
|
|
20565
|
-
function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSEMAN_MODULE]), warnUnloweredRegex = false, recovery = false, grammarCoverage = false) {
|
|
22234
|
+
function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSEMAN_MODULE]), warnUnloweredRegex = false, recovery = false, grammarCoverage = false, assemblyProfile, assemblyBudget = DEFAULT_ASSEMBLY_BUDGET, carriedSink) {
|
|
20566
22235
|
const depth = degradationCaptureDepth();
|
|
20567
22236
|
try {
|
|
20568
|
-
return transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recovery, grammarCoverage);
|
|
22237
|
+
return transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recovery, grammarCoverage, assemblyProfile, assemblyBudget, carriedSink);
|
|
20569
22238
|
} finally {
|
|
20570
22239
|
setReducerResolver(null);
|
|
20571
22240
|
setBuilderImportResolver(null);
|
|
20572
22241
|
for (const d of unwindDegradationCapture(depth)) console.warn(formatDegradation(d));
|
|
20573
22242
|
}
|
|
20574
22243
|
}
|
|
20575
|
-
function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recovery, grammarCoverage) {
|
|
22244
|
+
function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recovery, grammarCoverage, assemblyProfile, assemblyBudgetShare, carriedSink) {
|
|
20576
22245
|
let result;
|
|
20577
22246
|
try {
|
|
20578
22247
|
result = parseSync5(id, code);
|
|
@@ -21175,17 +22844,36 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21175
22844
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
21176
22845
|
const resolveModulePieces = (module, exportName, seen, unresolved, local = false) => {
|
|
21177
22846
|
const { file } = module;
|
|
22847
|
+
const fail = (why) => {
|
|
22848
|
+
unresolved.why ??= `${exportName} in ${file}: ${why}`;
|
|
22849
|
+
return null;
|
|
22850
|
+
};
|
|
22851
|
+
const sidecarItems = module.source || local ? void 0 : readCarriedSidecar(file)?.exports[exportName];
|
|
22852
|
+
if (sidecarItems !== void 0) {
|
|
22853
|
+
const list = [];
|
|
22854
|
+
for (const item of sidecarItems) {
|
|
22855
|
+
if ("ir" in item) {
|
|
22856
|
+
list.push(item);
|
|
22857
|
+
continue;
|
|
22858
|
+
}
|
|
22859
|
+
const sub = resolveGrammarModule(file, item.from);
|
|
22860
|
+
if (sub === null) return fail(`its carried pieces name \`${item.name}\` from '${item.from}', a module that could not be found`);
|
|
22861
|
+
if (seen.has(sub.file)) continue;
|
|
22862
|
+
const pieces = resolveModulePieces(sub, item.name, new Set(seen).add(sub.file), unresolved);
|
|
22863
|
+
if (pieces === null) return fail(`its carried pieces name \`${item.name}\` from '${item.from}', which could not be resolved`);
|
|
22864
|
+
list.push(...pieces);
|
|
22865
|
+
}
|
|
22866
|
+
return list;
|
|
22867
|
+
}
|
|
21178
22868
|
const mod = module.source ? lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recovery) : parseModuleCached(file);
|
|
21179
22869
|
if (!mod) return null;
|
|
21180
22870
|
const localFor = local ? exportName : exportLocalName(mod.body, exportName);
|
|
21181
22871
|
const initNode = localFor ? topLevelInit(mod.body, localFor) : null;
|
|
21182
22872
|
const literalRange = initNode ? findCarriedPiecesLiteral(initNode) : null;
|
|
21183
|
-
if (!literalRange)
|
|
22873
|
+
if (!literalRange) {
|
|
22874
|
+
return initNode !== null && !module.source && mod.src.slice(initNode.start, initNode.end).includes("tableRules(") ? fail(`is a compiled grammar with no carried pieces \u2014 no inline literal, and no entry in ${path2.basename(file)}${CARRIED_SIDECAR_SUFFIX}. Rebuild it with this parseman, and keep that file beside the artifact`) : null;
|
|
22875
|
+
}
|
|
21184
22876
|
const literal2 = mod.src.slice(literalRange.start, literalRange.end);
|
|
21185
|
-
const fail = (why) => {
|
|
21186
|
-
unresolved.why ??= `${exportName} in ${file}: ${why}`;
|
|
21187
|
-
return null;
|
|
21188
|
-
};
|
|
21189
22877
|
const imports = extractImportBindings(mod.body);
|
|
21190
22878
|
const stubNames = [];
|
|
21191
22879
|
const stubVals = [];
|
|
@@ -21234,6 +22922,27 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21234
22922
|
importedPiecesCache.set(localName, result2);
|
|
21235
22923
|
return result2;
|
|
21236
22924
|
};
|
|
22925
|
+
const sinkCarried = (name, list) => {
|
|
22926
|
+
if (carriedSink === void 0) return false;
|
|
22927
|
+
const out = [];
|
|
22928
|
+
for (const it of list) {
|
|
22929
|
+
if (!isSpread(it)) {
|
|
22930
|
+
out.push(it);
|
|
22931
|
+
continue;
|
|
22932
|
+
}
|
|
22933
|
+
const b = importBindings.get(it.__spreadLocal);
|
|
22934
|
+
if (b === void 0) return false;
|
|
22935
|
+
if (!b.source.startsWith(".") && !path2.isAbsolute(b.source)) {
|
|
22936
|
+
out.push({ from: b.source, name: b.imported });
|
|
22937
|
+
continue;
|
|
22938
|
+
}
|
|
22939
|
+
const pieces = importedPieces(it.__spreadLocal);
|
|
22940
|
+
if (pieces === null) return false;
|
|
22941
|
+
out.push(...pieces);
|
|
22942
|
+
}
|
|
22943
|
+
carriedSink.set(name, out);
|
|
22944
|
+
return true;
|
|
22945
|
+
};
|
|
21237
22946
|
const carriedRuleMaps = (items) => {
|
|
21238
22947
|
const pieces = [];
|
|
21239
22948
|
let trackLines = false;
|
|
@@ -21398,9 +23107,10 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21398
23107
|
carried,
|
|
21399
23108
|
reflection: compiled.reflection
|
|
21400
23109
|
});
|
|
23110
|
+
const select = selectAssembly(init.start, "compose()", compiled, !declaresLeaf());
|
|
21401
23111
|
return {
|
|
21402
|
-
replacement: compiled
|
|
21403
|
-
exportedReplacement: compiled
|
|
23112
|
+
replacement: assembledReplacement(compiled, reflectionMetadata, select),
|
|
23113
|
+
exportedReplacement: assembledReplacement(compiled, exportedMetadata, select),
|
|
21404
23114
|
carried,
|
|
21405
23115
|
...composing ? { trivia: composing } : {},
|
|
21406
23116
|
...importedFactories.length ? { importedFactories } : {},
|
|
@@ -21416,6 +23126,42 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21416
23126
|
warn(init.start, "compose(): a carried piece has no re-lowerable IR; leaving the runtime compose() in place");
|
|
21417
23127
|
return null;
|
|
21418
23128
|
};
|
|
23129
|
+
let assemblyBudget = Math.floor(code.length * assemblyBudgetShare);
|
|
23130
|
+
let leafDeclared;
|
|
23131
|
+
const declaresLeaf = () => leafDeclared ??= body.some((stmt) => {
|
|
23132
|
+
const vd = unwrapVd(stmt);
|
|
23133
|
+
return vd !== null && vd.declarations.some((d) => d.init != null && isComposeLeafCall(d.init));
|
|
23134
|
+
});
|
|
23135
|
+
const selectAssembly = (pos, label2, compiled, terminal) => {
|
|
23136
|
+
if (!terminal || grammarCoverage) return /* @__PURE__ */ new Set();
|
|
23137
|
+
const { sites, bytes, refusal } = compiled.selectAssembly(assemblyBudget, profileOf(compiled));
|
|
23138
|
+
if (refusal !== void 0) {
|
|
23139
|
+
warnings.push(`${id}:${lineOf(pos)} \u2014 ${label2}: its precompiled assembly cannot emit ${refusal}; the artifact runs on the closure engine`);
|
|
23140
|
+
}
|
|
23141
|
+
assemblyBudget -= bytes;
|
|
23142
|
+
return sites;
|
|
23143
|
+
};
|
|
23144
|
+
const profileOf = (compiled) => {
|
|
23145
|
+
if (assemblyProfile === void 0 || compiled.hostMode !== "ast" || compiled.prog.lines === 1 || !(assemblyProfile.entry in compiled.prog.rules)) return void 0;
|
|
23146
|
+
let parsed = 0;
|
|
23147
|
+
const fns = compiled.prog.fns.map((fn) => {
|
|
23148
|
+
const type = fn?.[INERT_BUILDER];
|
|
23149
|
+
return type === void 0 ? fn : (children3, _fields, span) => ({ type, span, children: children3 });
|
|
23150
|
+
});
|
|
23151
|
+
const counts = countSiteVisits(compiled.prog, (rules2) => {
|
|
23152
|
+
const entry = rules2[assemblyProfile.entry];
|
|
23153
|
+
for (const text of corpusTexts(assemblyProfile)) {
|
|
23154
|
+
try {
|
|
23155
|
+
if (run(entry, text).ok) parsed++;
|
|
23156
|
+
} catch {
|
|
23157
|
+
}
|
|
23158
|
+
}
|
|
23159
|
+
}, fns);
|
|
23160
|
+
if (parsed > 0) return counts;
|
|
23161
|
+
warnings.push(`${id} \u2014 assemblyProfile: no corpus file parsed from rule "${assemblyProfile.entry}"; using the static ranking`);
|
|
23162
|
+
return void 0;
|
|
23163
|
+
};
|
|
23164
|
+
const assembledReplacement = (compiled, metadata, select) => select.size === 0 ? compiled.replacementWithMetadata(metadata) : supercompileRuleMapReplacement(compiled.prog, compiled.replacementWithMetadata(metadata, { select }), select);
|
|
21419
23165
|
const compileComposeLeafCall = (init) => {
|
|
21420
23166
|
const args = init.arguments;
|
|
21421
23167
|
const arr = args[0];
|
|
@@ -21494,12 +23240,10 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21494
23240
|
if (compiled !== null) {
|
|
21495
23241
|
usedTableRuntime = true;
|
|
21496
23242
|
return {
|
|
21497
|
-
replacement:
|
|
21498
|
-
compiled
|
|
21499
|
-
compiled.
|
|
21500
|
-
|
|
21501
|
-
{ precompileDefault: true }
|
|
21502
|
-
)
|
|
23243
|
+
replacement: assembledReplacement(
|
|
23244
|
+
compiled,
|
|
23245
|
+
staticTableMetadataSource({ reflection: compiled.reflection, leaf: true }),
|
|
23246
|
+
selectAssembly(init.start, "composeLeaf()", compiled, true)
|
|
21503
23247
|
),
|
|
21504
23248
|
...importedFactories.length ? { importedFactories } : {}
|
|
21505
23249
|
};
|
|
@@ -21618,6 +23362,7 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21618
23362
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
21619
23363
|
if (ir) carriedMetadata = [{ ns, ir, ...compiledRules.trackLines ? { trackLines: true } : {} }];
|
|
21620
23364
|
else warn(init.start, `${varName}: exported grammar could not be serialized to IR, so it carries no composable pieces \u2014 a downstream compose() of this grammar will fall back to runtime. Re-run with PARSEMAN_IR_DEBUG=1 to print the combinator that blocked serialization.`);
|
|
23365
|
+
if (carriedMetadata !== void 0 && sinkCarried(varName, carriedMetadata)) carriedMetadata = void 0;
|
|
21621
23366
|
}
|
|
21622
23367
|
const replacement = compiledRules.replacement !== null ? compiledRules.replacementWithMetadata(staticTableMetadataSource({
|
|
21623
23368
|
...carriedMetadata === void 0 ? {} : { carried: carriedMetadata },
|
|
@@ -21642,7 +23387,7 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
21642
23387
|
continue;
|
|
21643
23388
|
}
|
|
21644
23389
|
localComposedCarried.set(varName, fused.carried);
|
|
21645
|
-
const replacement = exportPrefix ? fused.exportedReplacement : fused.replacement;
|
|
23390
|
+
const replacement = exportPrefix && !sinkCarried(varName, fused.carried) ? fused.exportedReplacement : fused.replacement;
|
|
21646
23391
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
21647
23392
|
markUsedImportedFactories(fused.importedFactories);
|
|
21648
23393
|
continue;
|
|
@@ -21932,6 +23677,7 @@ ${lines2.join("\n")}`);
|
|
|
21932
23677
|
};
|
|
21933
23678
|
}
|
|
21934
23679
|
export {
|
|
23680
|
+
CARRIED_SIDECAR_SUFFIX,
|
|
21935
23681
|
plugin_default as default,
|
|
21936
23682
|
transformMacro
|
|
21937
23683
|
};
|