parseman 0.49.0 → 0.50.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/commitment.d.ts +2 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +1931 -861
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/analysis/rebuild.d.ts.map +1 -1
- package/dist/cli/index.js +1235 -164
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/trivia-skip.d.ts +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +16 -0
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/degradation.d.ts +0 -2
- package/dist/compiler/degradation.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +185 -20
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/cst/capture-buffer.d.ts +5 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1348 -279
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +2 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +48 -0
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1940 -385
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +2 -1
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +28 -7
- package/dist/spec/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +6 -5
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +6 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +1298 -231
- package/dist/table/index.js.map +3 -3
- package/dist/table/ops.d.ts +3 -2
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +15 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +30 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +8 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/commitment.ts +19 -8
- package/src/analysis/rebuild.ts +1 -0
- package/src/combinators/trivia-skip.ts +2 -2
- package/src/compiler/build-arity.ts +50 -0
- package/src/compiler/degradation.ts +0 -6
- package/src/compiler/ir-serialize.ts +6 -4
- package/src/compiler/token-alphabet.ts +322 -28
- package/src/cst/capture-buffer.ts +34 -11
- package/src/plugin/entry-supercompiler.ts +567 -0
- package/src/plugin/evaluator.ts +10 -0
- package/src/plugin/index.ts +7 -3
- package/src/table/assemble.ts +125 -42
- package/src/table/compile-rule-map.ts +8 -7
- package/src/table/compile.ts +7 -8
- package/src/table/emit-assembly.ts +646 -126
- package/src/table/emit.ts +1 -1
- package/src/table/encode.ts +132 -7
- package/src/table/ops.ts +3 -2
- package/src/table/program.ts +44 -3
- package/src/table/scalar-terminal.ts +213 -1
- package/src/table/site-labels.ts +22 -9
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as fs2 from "node:fs";
|
|
3
3
|
import * as path2 from "node:path";
|
|
4
4
|
import { createUnplugin } from "unplugin";
|
|
5
|
-
import { parseSync as
|
|
5
|
+
import { parseSync as parseSync5 } from "oxc-parser";
|
|
6
6
|
import { ResolverFactory } from "oxc-resolver";
|
|
7
7
|
import MagicString from "magic-string";
|
|
8
8
|
|
|
@@ -27,9 +27,9 @@ function classifyFinalChoice(arms, resolve3) {
|
|
|
27
27
|
break;
|
|
28
28
|
}
|
|
29
29
|
let ownsHigh = false;
|
|
30
|
-
for (const
|
|
31
|
-
if (
|
|
32
|
-
for (let code = Math.max(0,
|
|
30
|
+
for (const range2 of first.ranges) {
|
|
31
|
+
if (range2.hi >= 128) ownsHigh = true;
|
|
32
|
+
for (let code = Math.max(0, range2.lo); code <= Math.min(127, range2.hi); code++) {
|
|
33
33
|
if (ascii[code] !== 0) {
|
|
34
34
|
exclusive = false;
|
|
35
35
|
break;
|
|
@@ -551,10 +551,10 @@ function beginCstNodeCapture(ctx) {
|
|
|
551
551
|
}
|
|
552
552
|
function finishCstBuf(buf) {
|
|
553
553
|
if (!buf) return { children: EMPTY, rawChildren: EMPTY, triviaLog: EMPTY_TL };
|
|
554
|
-
const
|
|
555
|
-
const rawChildren = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
|
|
554
|
+
const children3 = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY);
|
|
555
|
+
const rawChildren = buf.noRaw === true ? EMPTY : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY);
|
|
556
556
|
const triviaLog = buf.tl ?? EMPTY_TL;
|
|
557
|
-
return { children:
|
|
557
|
+
return { children: children3, rawChildren, triviaLog };
|
|
558
558
|
}
|
|
559
559
|
function endCstNodeCapture(ctx, saved) {
|
|
560
560
|
const materialized = finishCstBuf(ctx._cstBuf);
|
|
@@ -584,7 +584,8 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
584
584
|
b.single = void 0;
|
|
585
585
|
} else b.single = built;
|
|
586
586
|
}
|
|
587
|
-
if (b.
|
|
587
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
|
|
588
|
+
else if (b.raw) b.raw.push(rawEntry2);
|
|
588
589
|
else if (b.rawSingle !== void 0) {
|
|
589
590
|
b.raw = [b.rawSingle, rawEntry2];
|
|
590
591
|
b.rawSingle = void 0;
|
|
@@ -598,6 +599,7 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
598
599
|
function cstRawLen(ctx) {
|
|
599
600
|
const b = ctx._cstBuf;
|
|
600
601
|
if (b) {
|
|
602
|
+
if (b.noRaw === true) return b.rawLen ?? 0;
|
|
601
603
|
if (b.raw) return b.raw.length;
|
|
602
604
|
return b.rawSingle !== void 0 ? 1 : 0;
|
|
603
605
|
}
|
|
@@ -657,19 +659,37 @@ function rollbackCstCaptureAt(ctx, raw, tlog, leaves, fields, errors) {
|
|
|
657
659
|
if (ctx._errors && errors !== void 0 && ctx._errors.length !== errors) ctx._errors.length = errors;
|
|
658
660
|
const b = ctx._cstBuf;
|
|
659
661
|
if (b) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
+
if (b.noRaw === true) {
|
|
663
|
+
if (b.rawLen !== raw) b.rawLen = raw;
|
|
664
|
+
} else {
|
|
665
|
+
const rawList = b.raw;
|
|
666
|
+
if (rawList) {
|
|
667
|
+
if (raw === 0) b.raw = void 0;
|
|
668
|
+
else if (raw === 1) {
|
|
669
|
+
b.rawSingle = rawList[0];
|
|
670
|
+
b.raw = void 0;
|
|
671
|
+
} else if (rawList.length !== raw) rawList.length = raw;
|
|
672
|
+
} else if (raw === 0) b.rawSingle = void 0;
|
|
673
|
+
}
|
|
674
|
+
const childList = b.ch;
|
|
675
|
+
if (childList) {
|
|
676
|
+
if (leaves === 0) b.ch = void 0;
|
|
677
|
+
else if (leaves === 1) {
|
|
678
|
+
b.single = childList[0];
|
|
679
|
+
b.ch = void 0;
|
|
680
|
+
} else if (childList.length !== leaves) childList.length = leaves;
|
|
681
|
+
} else if (leaves === 0) b.single = void 0;
|
|
662
682
|
if (b.tl) {
|
|
663
683
|
if (tlog === 0) b.tl = void 0;
|
|
664
684
|
else if (b.tl.length !== tlog) b.tl.length = tlog;
|
|
665
685
|
}
|
|
666
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
686
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
667
687
|
return;
|
|
668
688
|
}
|
|
669
689
|
if (ctx._cstRawChildren && ctx._cstRawChildren.length !== raw) ctx._cstRawChildren.length = raw;
|
|
670
690
|
if (ctx._cstTriviaLog && ctx._cstTriviaLog.length !== tlog) ctx._cstTriviaLog.length = tlog;
|
|
671
691
|
if (ctx._cstLeaves && ctx._cstLeaves.length !== leaves) ctx._cstLeaves.length = leaves;
|
|
672
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
692
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
673
693
|
}
|
|
674
694
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
675
695
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -2158,15 +2178,22 @@ function canConsumeNewline(n) {
|
|
|
2158
2178
|
return n.parts.some(canConsumeNewline);
|
|
2159
2179
|
}
|
|
2160
2180
|
}
|
|
2181
|
+
function regexCanMatchEmpty(source) {
|
|
2182
|
+
try {
|
|
2183
|
+
return nullable(parseRegex(source));
|
|
2184
|
+
} catch {
|
|
2185
|
+
return true;
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2161
2188
|
function firstSetFromRegex(source) {
|
|
2162
|
-
let
|
|
2189
|
+
let ast2;
|
|
2163
2190
|
try {
|
|
2164
|
-
|
|
2191
|
+
ast2 = parseRegex(source);
|
|
2165
2192
|
} catch {
|
|
2166
2193
|
return { firstSet: any(), canMatchNewline: true };
|
|
2167
2194
|
}
|
|
2168
|
-
if (nullable(
|
|
2169
|
-
return { firstSet: firstSet(
|
|
2195
|
+
if (nullable(ast2)) return { firstSet: any(), canMatchNewline: canConsumeNewline(ast2) };
|
|
2196
|
+
return { firstSet: firstSet(ast2), canMatchNewline: canConsumeNewline(ast2) };
|
|
2170
2197
|
}
|
|
2171
2198
|
|
|
2172
2199
|
// src/combinators/regex.ts
|
|
@@ -3789,21 +3816,21 @@ function when(key, parser2, opts = {}) {
|
|
|
3789
3816
|
function otherwise(parser2) {
|
|
3790
3817
|
return { kind: "otherwise", parser: parser2, usesRouted: parserUsesRouted(parser2) };
|
|
3791
3818
|
}
|
|
3792
|
-
function routed(
|
|
3819
|
+
function routed(fallback2) {
|
|
3793
3820
|
return {
|
|
3794
3821
|
_tag: "routed",
|
|
3795
3822
|
_meta: {
|
|
3796
3823
|
// The routed token is whatever the selector matched, so the first set stays
|
|
3797
3824
|
// `any` even with a fallback — `any` already subsumes the fallback's.
|
|
3798
3825
|
firstSet: { kind: "any" },
|
|
3799
|
-
canMatchNewline:
|
|
3826
|
+
canMatchNewline: fallback2?._meta.canMatchNewline ?? false,
|
|
3800
3827
|
isTrivia: false
|
|
3801
3828
|
},
|
|
3802
|
-
_def:
|
|
3829
|
+
_def: fallback2 === void 0 ? { tag: "routed" } : { tag: "routed", fallback: fallback2 },
|
|
3803
3830
|
parse(_input, pos, ctx) {
|
|
3804
3831
|
const item = ctx._routed;
|
|
3805
3832
|
if (item === void 0 || pos !== item.span.start) {
|
|
3806
|
-
if (
|
|
3833
|
+
if (fallback2 !== void 0) return fallback2.parse(_input, pos, ctx);
|
|
3807
3834
|
return { ok: false, expected: ["routed()"], span: { start: pos, end: pos } };
|
|
3808
3835
|
}
|
|
3809
3836
|
if (cstCaptureActive(ctx)) {
|
|
@@ -3817,7 +3844,7 @@ function dispatch(selector, ...arms) {
|
|
|
3817
3844
|
if (parserUsesRouted(selector)) {
|
|
3818
3845
|
throw new Error("parseman: routed() can only appear inside a dispatch() branch");
|
|
3819
3846
|
}
|
|
3820
|
-
let
|
|
3847
|
+
let fallback2;
|
|
3821
3848
|
let fallbackUsesRouted = false;
|
|
3822
3849
|
const matchers = [];
|
|
3823
3850
|
const cases = [];
|
|
@@ -3825,9 +3852,9 @@ function dispatch(selector, ...arms) {
|
|
|
3825
3852
|
for (let i = 0; i < arms.length; i++) {
|
|
3826
3853
|
const arm = arms[i];
|
|
3827
3854
|
if (arm.kind === "otherwise") {
|
|
3828
|
-
if (
|
|
3855
|
+
if (fallback2 !== void 0) throw new Error("parseman: dispatch() accepts at most one otherwise() arm");
|
|
3829
3856
|
if (i !== arms.length - 1) throw new Error("parseman: otherwise() must be the last dispatch() arm");
|
|
3830
|
-
|
|
3857
|
+
fallback2 = arm.parser;
|
|
3831
3858
|
fallbackUsesRouted = arm.usesRouted === true;
|
|
3832
3859
|
continue;
|
|
3833
3860
|
}
|
|
@@ -3860,7 +3887,7 @@ function dispatch(selector, ...arms) {
|
|
|
3860
3887
|
}
|
|
3861
3888
|
const meta = {
|
|
3862
3889
|
firstSet: selector._meta.firstSet,
|
|
3863
|
-
canMatchNewline: selector._meta.canMatchNewline || cases.some((entry) => entry.parser._meta.canMatchNewline) || matchers.some((entry) => entry.parser._meta.canMatchNewline) || (
|
|
3890
|
+
canMatchNewline: selector._meta.canMatchNewline || cases.some((entry) => entry.parser._meta.canMatchNewline) || matchers.some((entry) => entry.parser._meta.canMatchNewline) || (fallback2?._meta.canMatchNewline ?? false),
|
|
3864
3891
|
isTrivia: false
|
|
3865
3892
|
};
|
|
3866
3893
|
const byKey = /* @__PURE__ */ new Map();
|
|
@@ -3879,7 +3906,7 @@ function dispatch(selector, ...arms) {
|
|
|
3879
3906
|
selector,
|
|
3880
3907
|
cases,
|
|
3881
3908
|
...matchers.length === 0 ? {} : { matchers },
|
|
3882
|
-
...
|
|
3909
|
+
...fallback2 === void 0 ? {} : { otherwise: fallback2, ...fallbackUsesRouted ? { otherwiseUsesRouted: true } : {} }
|
|
3883
3910
|
},
|
|
3884
3911
|
parse(input, pos, ctx) {
|
|
3885
3912
|
if (parserUsesRouted(selector)) {
|
|
@@ -3888,7 +3915,7 @@ function dispatch(selector, ...arms) {
|
|
|
3888
3915
|
const selectorMark = saveTriviaMark(ctx);
|
|
3889
3916
|
const selected = selector.parse(input, pos, ctx);
|
|
3890
3917
|
if (!selected.ok) return selected;
|
|
3891
|
-
const branch = byKey.get(selected.value) ?? (byFoldedKey.size === 0 ? void 0 : byFoldedKey.get(asciiFoldKey(selected.value))) ?? matchers.find((matcher) => matchesDispatchMatcher(selected.value, matcher)) ?? (
|
|
3918
|
+
const branch = byKey.get(selected.value) ?? (byFoldedKey.size === 0 ? void 0 : byFoldedKey.get(asciiFoldKey(selected.value))) ?? matchers.find((matcher) => matchesDispatchMatcher(selected.value, matcher)) ?? (fallback2 === void 0 ? void 0 : { keys: [], parser: fallback2, caseInsensitive: false, usesRouted: fallbackUsesRouted });
|
|
3892
3919
|
if (branch === void 0) {
|
|
3893
3920
|
const expected = cases.flatMap((entry) => entry.keys.map((key) => JSON.stringify(key)));
|
|
3894
3921
|
return { ok: false, expected, span: { start: selected.span.end, end: selected.span.end } };
|
|
@@ -4385,6 +4412,7 @@ var SINGLE_IDENT_ARROW_RE = /^[A-Za-z_$][\w$]*\s*=>/;
|
|
|
4385
4412
|
var PARAM_LIST_OPEN_RE = /^(?:function\b[^(]*)?\(/;
|
|
4386
4413
|
var NATIVE_CODE_RE = /\{\s*\[native code\]\s*\}/;
|
|
4387
4414
|
var PARAM_HEAD_RE = /^[A-Za-z_$][\w$]*\s*\??\s*/;
|
|
4415
|
+
var PARAM_NAME_RE = /^([A-Za-z_$][\w$]*)\s*\??\s*/;
|
|
4388
4416
|
function confirmedBuildArity(src) {
|
|
4389
4417
|
const s = src.trim();
|
|
4390
4418
|
if (NATIVE_CODE_RE.test(s)) return null;
|
|
@@ -4400,6 +4428,34 @@ function confirmedBuildArity(src) {
|
|
|
4400
4428
|
}
|
|
4401
4429
|
return parts.length;
|
|
4402
4430
|
}
|
|
4431
|
+
function confirmedBuildParamUnused(src, index) {
|
|
4432
|
+
if (!Number.isInteger(index) || index < 0) return false;
|
|
4433
|
+
const s = src.trim();
|
|
4434
|
+
if (NATIVE_CODE_RE.test(s) || /\b(?:arguments|eval|Function)\b/.test(s) || /\bwith\s*\(/.test(s)) return false;
|
|
4435
|
+
let names;
|
|
4436
|
+
const single = /^([A-Za-z_$][\w$]*)\s*=>/.exec(s);
|
|
4437
|
+
if (single) {
|
|
4438
|
+
names = [single[1]];
|
|
4439
|
+
} else {
|
|
4440
|
+
const inner = paramListText(s);
|
|
4441
|
+
if (inner === null || inner.trim() === "") return false;
|
|
4442
|
+
const parts = splitTopLevel(inner);
|
|
4443
|
+
if (parts === null) return false;
|
|
4444
|
+
names = [];
|
|
4445
|
+
for (const part of parts) {
|
|
4446
|
+
const trimmed = part.trim();
|
|
4447
|
+
if (!isConfirmableParam(trimmed)) return false;
|
|
4448
|
+
const name2 = PARAM_NAME_RE.exec(trimmed)?.[1];
|
|
4449
|
+
if (name2 === void 0) return false;
|
|
4450
|
+
names.push(name2);
|
|
4451
|
+
}
|
|
4452
|
+
}
|
|
4453
|
+
const name = names[index];
|
|
4454
|
+
if (name === void 0) return false;
|
|
4455
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4456
|
+
const uses = s.match(new RegExp(`(^|[^A-Za-z0-9_$])${escaped}(?=$|[^A-Za-z0-9_$])`, "g"));
|
|
4457
|
+
return uses?.length === 1;
|
|
4458
|
+
}
|
|
4403
4459
|
function paramListText(s) {
|
|
4404
4460
|
const open = PARAM_LIST_OPEN_RE.exec(s);
|
|
4405
4461
|
if (!open) return null;
|
|
@@ -4537,6 +4593,7 @@ function confirmedArityForDef(def) {
|
|
|
4537
4593
|
}
|
|
4538
4594
|
function buildReadsRaw(def) {
|
|
4539
4595
|
if (!def.build) return true;
|
|
4596
|
+
if (def.buildRawUnused === true) return false;
|
|
4540
4597
|
const arity = confirmedArityForDef(def);
|
|
4541
4598
|
if (arity === null) return true;
|
|
4542
4599
|
return arity >= 4;
|
|
@@ -4647,11 +4704,11 @@ function normalizeProject(project) {
|
|
|
4647
4704
|
}
|
|
4648
4705
|
return project;
|
|
4649
4706
|
}
|
|
4650
|
-
function projectChild(
|
|
4651
|
-
if (!(project in
|
|
4707
|
+
function projectChild(children3, project, type) {
|
|
4708
|
+
if (!(project in children3)) {
|
|
4652
4709
|
throw new Error(`node(${JSON.stringify(type)}) project child ${project} was not captured`);
|
|
4653
4710
|
}
|
|
4654
|
-
return unwrapChild(
|
|
4711
|
+
return unwrapChild(children3[project]);
|
|
4655
4712
|
}
|
|
4656
4713
|
function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
4657
4714
|
const hasExplicitType = typeof typeOrCombinator === "string";
|
|
@@ -4723,14 +4780,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4723
4780
|
const fields = effFields ? buildFieldMap(ctx._fields) : void 0;
|
|
4724
4781
|
ctx._fields = savedFields;
|
|
4725
4782
|
ctx._triviaCaptureMask = savedMask;
|
|
4726
|
-
const { children:
|
|
4783
|
+
const { children: children3, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
4727
4784
|
if (!r.ok) return r;
|
|
4728
4785
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4729
4786
|
const nodeType = def.type ?? missingInferredType();
|
|
4730
4787
|
const cstOutput = cstOutputHost(ctx.build);
|
|
4731
4788
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
4732
4789
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
4733
|
-
const built = unwrap &&
|
|
4790
|
+
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 };
|
|
4734
4791
|
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 };
|
|
4735
4792
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
4736
4793
|
pushCstChild(ctx, built, rawEntry2);
|
|
@@ -4957,6 +5014,399 @@ function firstSetToString(fs3) {
|
|
|
4957
5014
|
return fs3.ranges.map((r) => r.lo === r.hi ? ch(r.lo) : `${ch(r.lo)}-${ch(r.hi)}`).join(",");
|
|
4958
5015
|
}
|
|
4959
5016
|
|
|
5017
|
+
// src/analysis/commitment.ts
|
|
5018
|
+
function mayFail(p, seen = /* @__PURE__ */ new Set()) {
|
|
5019
|
+
if (seen.has(p)) return true;
|
|
5020
|
+
seen.add(p);
|
|
5021
|
+
const d = p._def;
|
|
5022
|
+
switch (d.tag) {
|
|
5023
|
+
case "literal":
|
|
5024
|
+
return d.value.length > 0;
|
|
5025
|
+
case "trivia":
|
|
5026
|
+
return false;
|
|
5027
|
+
// `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
|
|
5028
|
+
// repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
|
|
5029
|
+
// that has selected an arm and then failed inside it breaks out past every
|
|
5030
|
+
// enclosing repeat, straight to the fallible boundary. So these are total
|
|
5031
|
+
// exactly when their body cannot commit. (Measured: treating them as
|
|
5032
|
+
// unconditionally total left an extra zero-width leaf in
|
|
5033
|
+
// `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
|
|
5034
|
+
// build fired and this one had deleted.)
|
|
5035
|
+
case "optional":
|
|
5036
|
+
case "many":
|
|
5037
|
+
return mayCommitFailure(d.parser);
|
|
5038
|
+
case "sepBy":
|
|
5039
|
+
return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
|
|
5040
|
+
case "oneOrMore":
|
|
5041
|
+
return mayFail(d.parser, seen);
|
|
5042
|
+
case "sequence":
|
|
5043
|
+
return d.parsers.some((x) => mayFail(x, seen));
|
|
5044
|
+
// Delegating wrappers: as fallible as what they wrap.
|
|
5045
|
+
case "node":
|
|
5046
|
+
case "transform":
|
|
5047
|
+
case "label":
|
|
5048
|
+
case "field":
|
|
5049
|
+
case "expect":
|
|
5050
|
+
case "withCtx":
|
|
5051
|
+
case "grammar":
|
|
5052
|
+
case "token":
|
|
5053
|
+
case "leaf":
|
|
5054
|
+
return mayFail(d.parser, seen);
|
|
5055
|
+
case "lazy": {
|
|
5056
|
+
try {
|
|
5057
|
+
return mayFail(d.thunk(), seen);
|
|
5058
|
+
} catch {
|
|
5059
|
+
return true;
|
|
5060
|
+
}
|
|
5061
|
+
}
|
|
5062
|
+
// An adjacency assertion is a TEST — failing is its whole job.
|
|
5063
|
+
case "adjacency":
|
|
5064
|
+
return true;
|
|
5065
|
+
default:
|
|
5066
|
+
return true;
|
|
5067
|
+
}
|
|
5068
|
+
}
|
|
5069
|
+
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
|
|
5070
|
+
if (seen.has(p)) return false;
|
|
5071
|
+
seen.add(p);
|
|
5072
|
+
const d = p._def;
|
|
5073
|
+
switch (d.tag) {
|
|
5074
|
+
// Atomic / non-capturing-then-failing: a failure happens before any push.
|
|
5075
|
+
case "literal":
|
|
5076
|
+
case "regex":
|
|
5077
|
+
case "keywords":
|
|
5078
|
+
case "guard":
|
|
5079
|
+
// Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
|
|
5080
|
+
case "adjacency":
|
|
5081
|
+
case "not":
|
|
5082
|
+
// peek(): emitted under a non-capturing probe ctx and zero-width on both
|
|
5083
|
+
// outcomes, so it can never leave a partial capture behind.
|
|
5084
|
+
case "peek":
|
|
5085
|
+
case "trivia":
|
|
5086
|
+
case "token":
|
|
5087
|
+
case "leaf":
|
|
5088
|
+
case "scanTo":
|
|
5089
|
+
case "unknown":
|
|
5090
|
+
return false;
|
|
5091
|
+
// node() captures into its own private buffers and rolls them back on
|
|
5092
|
+
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
5093
|
+
case "node":
|
|
5094
|
+
return false;
|
|
5095
|
+
// choice/firstMatch already roll back each failed arm; on overall failure
|
|
5096
|
+
// nothing committed remains.
|
|
5097
|
+
case "choice":
|
|
5098
|
+
return false;
|
|
5099
|
+
case "dispatch":
|
|
5100
|
+
return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
|
|
5101
|
+
case "attempt":
|
|
5102
|
+
return false;
|
|
5103
|
+
// optional never fails; many/oneOrMore only "fail" with zero captured items.
|
|
5104
|
+
case "optional":
|
|
5105
|
+
case "many":
|
|
5106
|
+
case "oneOrMore":
|
|
5107
|
+
return false;
|
|
5108
|
+
// sepBy emits its own per-iteration rollback in emitSepBy.
|
|
5109
|
+
case "sepBy":
|
|
5110
|
+
return false;
|
|
5111
|
+
// A sequence is the real case: an earlier capturing term followed by a term
|
|
5112
|
+
// that can fail leaves the earlier captures buffered.
|
|
5113
|
+
//
|
|
5114
|
+
// BOTH halves of that sentence are load-bearing, and the second half is what
|
|
5115
|
+
// this walk exists to exploit. "Some earlier term captures" alone was the old
|
|
5116
|
+
// test, and it is true of very nearly every sequence in a real grammar — a
|
|
5117
|
+
// sequence almost always opens with a literal or a node. The rollback is only
|
|
5118
|
+
// reachable if something AFTER the capture can still fail; once the remainder
|
|
5119
|
+
// is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
|
|
5120
|
+
// failure path left to roll back from, and the save+restore is dead code.
|
|
5121
|
+
//
|
|
5122
|
+
// `captured` tracks whether anything is in the buffers yet as the scan moves
|
|
5123
|
+
// left to right. Two things put it there:
|
|
5124
|
+
// - a term that captures (`capturesLeaf`/`hasNodeDef`), and
|
|
5125
|
+
// - the inter-term TRIVIA scan, which under `capturing` pushes into
|
|
5126
|
+
// `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
|
|
5127
|
+
// i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
|
|
5128
|
+
// path (the "matched empty, so leave the whitespace out of the span"
|
|
5129
|
+
// branch); a term that FAILS breaks straight out with the trivia still
|
|
5130
|
+
// buffered, so from boundary 1 onward the buffers are dirty regardless of
|
|
5131
|
+
// what the earlier terms did.
|
|
5132
|
+
// Each term is also asked about itself: a nested sequence can leave its own
|
|
5133
|
+
// partial capture behind, and its terms are emitted inline into this same
|
|
5134
|
+
// block with no boundary of their own to roll them back.
|
|
5135
|
+
case "sequence": {
|
|
5136
|
+
const parts = d.parsers;
|
|
5137
|
+
let captured = false;
|
|
5138
|
+
for (let i = 0; i < parts.length; i++) {
|
|
5139
|
+
const part = parts[i];
|
|
5140
|
+
if (i > 0 && triviaActive) captured = true;
|
|
5141
|
+
if (captured && mayFail(part)) return true;
|
|
5142
|
+
if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
|
|
5143
|
+
if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
|
|
5144
|
+
}
|
|
5145
|
+
return false;
|
|
5146
|
+
}
|
|
5147
|
+
// Delegating wrappers: defer to the wrapped parser.
|
|
5148
|
+
case "transform":
|
|
5149
|
+
case "label":
|
|
5150
|
+
case "field":
|
|
5151
|
+
case "expect":
|
|
5152
|
+
case "withCtx":
|
|
5153
|
+
case "grammar":
|
|
5154
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
5155
|
+
case "recover":
|
|
5156
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
5157
|
+
case "lazy": {
|
|
5158
|
+
try {
|
|
5159
|
+
return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
|
|
5160
|
+
} catch {
|
|
5161
|
+
return true;
|
|
5162
|
+
}
|
|
5163
|
+
}
|
|
5164
|
+
// Unknown shapes: be safe and keep the rollback.
|
|
5165
|
+
default:
|
|
5166
|
+
return true;
|
|
5167
|
+
}
|
|
5168
|
+
}
|
|
5169
|
+
function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
5170
|
+
if (seen.has(p)) return false;
|
|
5171
|
+
seen.add(p);
|
|
5172
|
+
const d = p._def;
|
|
5173
|
+
switch (d.tag) {
|
|
5174
|
+
case "literal":
|
|
5175
|
+
case "regex":
|
|
5176
|
+
case "keywords":
|
|
5177
|
+
case "node":
|
|
5178
|
+
case "token":
|
|
5179
|
+
case "routed":
|
|
5180
|
+
case "leaf":
|
|
5181
|
+
return true;
|
|
5182
|
+
case "not":
|
|
5183
|
+
case "peek":
|
|
5184
|
+
case "guard":
|
|
5185
|
+
case "adjacency":
|
|
5186
|
+
case "trivia":
|
|
5187
|
+
case "unknown":
|
|
5188
|
+
return false;
|
|
5189
|
+
case "sequence":
|
|
5190
|
+
case "choice":
|
|
5191
|
+
return d.parsers.some((x) => capturesLeaf(x, seen));
|
|
5192
|
+
case "dispatch":
|
|
5193
|
+
return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
|
|
5194
|
+
case "sepBy":
|
|
5195
|
+
return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
|
|
5196
|
+
case "many":
|
|
5197
|
+
case "oneOrMore":
|
|
5198
|
+
case "optional":
|
|
5199
|
+
case "attempt":
|
|
5200
|
+
case "transform":
|
|
5201
|
+
case "label":
|
|
5202
|
+
case "field":
|
|
5203
|
+
case "expect":
|
|
5204
|
+
case "withCtx":
|
|
5205
|
+
case "grammar":
|
|
5206
|
+
case "recover":
|
|
5207
|
+
return capturesLeaf(d.parser, seen);
|
|
5208
|
+
case "scanTo":
|
|
5209
|
+
return true;
|
|
5210
|
+
case "lazy": {
|
|
5211
|
+
try {
|
|
5212
|
+
return capturesLeaf(d.thunk(), seen);
|
|
5213
|
+
} catch {
|
|
5214
|
+
return true;
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
default:
|
|
5218
|
+
return true;
|
|
5219
|
+
}
|
|
5220
|
+
}
|
|
5221
|
+
function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
5222
|
+
if (seen.has(p)) return false;
|
|
5223
|
+
seen.add(p);
|
|
5224
|
+
const d = p._def;
|
|
5225
|
+
switch (d.tag) {
|
|
5226
|
+
case "node":
|
|
5227
|
+
return true;
|
|
5228
|
+
case "lazy": {
|
|
5229
|
+
try {
|
|
5230
|
+
return hasNodeDef(d.thunk(), seen);
|
|
5231
|
+
} catch {
|
|
5232
|
+
return false;
|
|
5233
|
+
}
|
|
5234
|
+
}
|
|
5235
|
+
case "grammar":
|
|
5236
|
+
case "trivia":
|
|
5237
|
+
case "token":
|
|
5238
|
+
case "leaf":
|
|
5239
|
+
case "label":
|
|
5240
|
+
case "field":
|
|
5241
|
+
case "optional":
|
|
5242
|
+
case "many":
|
|
5243
|
+
case "oneOrMore":
|
|
5244
|
+
case "not":
|
|
5245
|
+
case "peek":
|
|
5246
|
+
case "transform":
|
|
5247
|
+
return hasNodeDef(d.parser, seen);
|
|
5248
|
+
case "sequence":
|
|
5249
|
+
case "choice":
|
|
5250
|
+
return d.parsers.some((x) => hasNodeDef(x, seen));
|
|
5251
|
+
case "dispatch":
|
|
5252
|
+
return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
|
|
5253
|
+
case "sepBy":
|
|
5254
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
5255
|
+
case "scanTo":
|
|
5256
|
+
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
|
|
5257
|
+
case "recover":
|
|
5258
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
5259
|
+
case "expect":
|
|
5260
|
+
return hasNodeDef(d.parser, seen);
|
|
5261
|
+
case "withCtx":
|
|
5262
|
+
return hasNodeDef(d.parser, seen);
|
|
5263
|
+
default:
|
|
5264
|
+
return false;
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
5268
|
+
if (seen.has(p)) return false;
|
|
5269
|
+
seen.add(p);
|
|
5270
|
+
const d = p._def;
|
|
5271
|
+
switch (d.tag) {
|
|
5272
|
+
case "node":
|
|
5273
|
+
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
5274
|
+
case "lazy": {
|
|
5275
|
+
try {
|
|
5276
|
+
return hasDirectBuildDef(d.thunk(), seen);
|
|
5277
|
+
} catch {
|
|
5278
|
+
return false;
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
case "grammar":
|
|
5282
|
+
case "trivia":
|
|
5283
|
+
case "token":
|
|
5284
|
+
case "leaf":
|
|
5285
|
+
case "label":
|
|
5286
|
+
case "field":
|
|
5287
|
+
case "optional":
|
|
5288
|
+
case "many":
|
|
5289
|
+
case "oneOrMore":
|
|
5290
|
+
case "attempt":
|
|
5291
|
+
case "not":
|
|
5292
|
+
case "peek":
|
|
5293
|
+
case "withCtx":
|
|
5294
|
+
case "expect":
|
|
5295
|
+
case "transform":
|
|
5296
|
+
return hasDirectBuildDef(d.parser, seen);
|
|
5297
|
+
case "sequence":
|
|
5298
|
+
case "choice":
|
|
5299
|
+
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
5300
|
+
case "dispatch":
|
|
5301
|
+
return hasDirectBuildDef(d.selector, seen) || d.cases.some((x) => hasDirectBuildDef(x.parser, seen)) || (d.matchers ? d.matchers.some((x) => hasDirectBuildDef(x.parser, seen)) : false) || (d.otherwise ? hasDirectBuildDef(d.otherwise, seen) : false);
|
|
5302
|
+
case "sepBy":
|
|
5303
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
5304
|
+
case "scanTo":
|
|
5305
|
+
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
|
|
5306
|
+
case "recover":
|
|
5307
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
5308
|
+
case "routed":
|
|
5309
|
+
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
5310
|
+
default:
|
|
5311
|
+
return false;
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
|
|
5315
|
+
if (seen.has(p)) return false;
|
|
5316
|
+
seen.add(p);
|
|
5317
|
+
const d = p._def;
|
|
5318
|
+
switch (d.tag) {
|
|
5319
|
+
case "dispatch":
|
|
5320
|
+
return true;
|
|
5321
|
+
case "choice":
|
|
5322
|
+
case "sequence":
|
|
5323
|
+
return d.parsers.some((x) => mayCommitFailure(x, seen, resolve3));
|
|
5324
|
+
case "many":
|
|
5325
|
+
case "oneOrMore":
|
|
5326
|
+
case "optional":
|
|
5327
|
+
case "attempt":
|
|
5328
|
+
case "transform":
|
|
5329
|
+
case "label":
|
|
5330
|
+
case "field":
|
|
5331
|
+
case "grammar":
|
|
5332
|
+
case "node":
|
|
5333
|
+
return mayCommitFailure(d.parser, seen, resolve3);
|
|
5334
|
+
case "sepBy":
|
|
5335
|
+
return mayCommitFailure(d.parser, seen, resolve3) || mayCommitFailure(d.separator, seen, resolve3);
|
|
5336
|
+
case "token":
|
|
5337
|
+
case "leaf":
|
|
5338
|
+
return mayCommitFailure(d.parser, seen, resolve3);
|
|
5339
|
+
case "withCtx":
|
|
5340
|
+
return mayCommitFailure(d.parser, seen, resolve3);
|
|
5341
|
+
case "scanTo":
|
|
5342
|
+
return mayCommitFailure(d.sentinel, seen, resolve3) || d.skip.some((x) => mayCommitFailure(x, seen, resolve3));
|
|
5343
|
+
case "lazy": {
|
|
5344
|
+
try {
|
|
5345
|
+
return mayCommitFailure(d.thunk(), seen, resolve3);
|
|
5346
|
+
} catch {
|
|
5347
|
+
const name = p._ruleName;
|
|
5348
|
+
const target = name === void 0 ? void 0 : resolve3?.(name);
|
|
5349
|
+
return target === void 0 ? true : mayCommitFailure(target, seen, resolve3);
|
|
5350
|
+
}
|
|
5351
|
+
}
|
|
5352
|
+
case "unknown":
|
|
5353
|
+
return true;
|
|
5354
|
+
default:
|
|
5355
|
+
return false;
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
5358
|
+
function hasSemanticReduction(roots, externalRefs) {
|
|
5359
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5360
|
+
const visit = (parser2) => {
|
|
5361
|
+
if (seen.has(parser2)) return false;
|
|
5362
|
+
seen.add(parser2);
|
|
5363
|
+
const def = parser2._def;
|
|
5364
|
+
if (def.tag === "transform" && !def.recognitionOnly) return true;
|
|
5365
|
+
if (def.tag === "choice" && def.gates.some(Boolean)) return true;
|
|
5366
|
+
if (def.tag === "guard" || def.tag === "withCtx") return true;
|
|
5367
|
+
if (def.tag === "node" && def.build !== void 0) return true;
|
|
5368
|
+
if (def.tag === "lazy") {
|
|
5369
|
+
if (externalRefs?.has(parser2)) return false;
|
|
5370
|
+
try {
|
|
5371
|
+
return visit(def.thunk());
|
|
5372
|
+
} catch {
|
|
5373
|
+
return true;
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
return childrenOf2(def).some(visit);
|
|
5377
|
+
};
|
|
5378
|
+
return roots.some(visit);
|
|
5379
|
+
}
|
|
5380
|
+
function classifyRuleMap(ruleMap) {
|
|
5381
|
+
const externalRefs = /* @__PURE__ */ new Set();
|
|
5382
|
+
const scanned = /* @__PURE__ */ new Set();
|
|
5383
|
+
const scanExternal = (p) => {
|
|
5384
|
+
if (scanned.has(p)) return;
|
|
5385
|
+
scanned.add(p);
|
|
5386
|
+
const def = p._def;
|
|
5387
|
+
if (def.tag === "lazy") {
|
|
5388
|
+
let resolved;
|
|
5389
|
+
try {
|
|
5390
|
+
resolved = def.thunk();
|
|
5391
|
+
} catch {
|
|
5392
|
+
resolved = void 0;
|
|
5393
|
+
}
|
|
5394
|
+
if (resolved === void 0) {
|
|
5395
|
+
if (p._ruleName) externalRefs.add(p);
|
|
5396
|
+
return;
|
|
5397
|
+
}
|
|
5398
|
+
scanExternal(resolved);
|
|
5399
|
+
return;
|
|
5400
|
+
}
|
|
5401
|
+
for (const child of childrenOf2(def)) scanExternal(child);
|
|
5402
|
+
};
|
|
5403
|
+
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
5404
|
+
return {
|
|
5405
|
+
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
5406
|
+
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs)
|
|
5407
|
+
};
|
|
5408
|
+
}
|
|
5409
|
+
|
|
4960
5410
|
// src/table/ops.ts
|
|
4961
5411
|
var OP_LIT = 1;
|
|
4962
5412
|
var OP_RX = 2;
|
|
@@ -5273,11 +5723,11 @@ function fixedTreeRunner(words, matchers, classes, expected) {
|
|
|
5273
5723
|
}
|
|
5274
5724
|
if (op >= LEX_NODE_SEQUENCE2 && op <= LEX_NODE_SEQUENCE5) {
|
|
5275
5725
|
const count = op - LEX_NODE_SEQUENCE2 + 2;
|
|
5276
|
-
const
|
|
5277
|
-
if (count === 2) stack.push(sequence2(
|
|
5278
|
-
else if (count === 3) stack.push(sequence3(
|
|
5279
|
-
else if (count === 4) stack.push(sequence4(
|
|
5280
|
-
else stack.push(sequence5(
|
|
5726
|
+
const nodes2 = Array.from({ length: count }, pop).reverse();
|
|
5727
|
+
if (count === 2) stack.push(sequence2(nodes2[0], nodes2[1]));
|
|
5728
|
+
else if (count === 3) stack.push(sequence3(nodes2[0], nodes2[1], nodes2[2]));
|
|
5729
|
+
else if (count === 4) stack.push(sequence4(nodes2[0], nodes2[1], nodes2[2], nodes2[3]));
|
|
5730
|
+
else stack.push(sequence5(nodes2[0], nodes2[1], nodes2[2], nodes2[3], nodes2[4]));
|
|
5281
5731
|
continue;
|
|
5282
5732
|
}
|
|
5283
5733
|
if (op >= LEX_NODE_CHOICE2 && op <= LEX_NODE_CHOICE8) {
|
|
@@ -5512,8 +5962,26 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
|
5512
5962
|
}
|
|
5513
5963
|
}
|
|
5514
5964
|
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
5515
|
-
function ownTableProgram(prog, resolved) {
|
|
5516
|
-
|
|
5965
|
+
function ownTableProgram(prog, resolved, caches = {}) {
|
|
5966
|
+
const runtime = prog[TABLE_RUNTIME];
|
|
5967
|
+
return {
|
|
5968
|
+
...prog,
|
|
5969
|
+
[TABLE_RUNTIME]: {
|
|
5970
|
+
resolved,
|
|
5971
|
+
choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
|
|
5972
|
+
nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
|
|
5973
|
+
failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
|
|
5974
|
+
}
|
|
5975
|
+
};
|
|
5976
|
+
}
|
|
5977
|
+
function choiceRollbackMask(prog, ip) {
|
|
5978
|
+
return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
|
|
5979
|
+
}
|
|
5980
|
+
function choiceCannotCommit(prog, ip) {
|
|
5981
|
+
return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
|
|
5982
|
+
}
|
|
5983
|
+
function failureRollbackClean(prog, ip) {
|
|
5984
|
+
return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
|
|
5517
5985
|
}
|
|
5518
5986
|
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
5519
5987
|
var WIDE_CLASS_PREFIX_HI = 0;
|
|
@@ -5529,22 +5997,22 @@ function validateClassRange(lo, hi) {
|
|
|
5529
5997
|
}
|
|
5530
5998
|
function encodeClassSpec(ranges) {
|
|
5531
5999
|
let wide = false;
|
|
5532
|
-
for (const
|
|
5533
|
-
validateClassRange(
|
|
5534
|
-
if (
|
|
6000
|
+
for (const range2 of ranges) {
|
|
6001
|
+
validateClassRange(range2.lo, range2.hi);
|
|
6002
|
+
if (range2.hi > 65535) wide = true;
|
|
5535
6003
|
}
|
|
5536
6004
|
if (!wide) {
|
|
5537
6005
|
let spec2 = "";
|
|
5538
|
-
for (const
|
|
6006
|
+
for (const range2 of ranges) spec2 += String.fromCharCode(range2.lo, range2.hi);
|
|
5539
6007
|
return spec2;
|
|
5540
6008
|
}
|
|
5541
6009
|
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
5542
|
-
for (const
|
|
6010
|
+
for (const range2 of ranges) {
|
|
5543
6011
|
spec += String.fromCharCode(
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
6012
|
+
range2.lo >>> 16,
|
|
6013
|
+
range2.lo & 65535,
|
|
6014
|
+
range2.hi >>> 16,
|
|
6015
|
+
range2.hi & 65535
|
|
5548
6016
|
);
|
|
5549
6017
|
}
|
|
5550
6018
|
return spec;
|
|
@@ -5688,7 +6156,6 @@ function directArrayProjection(fn, fnSrc, arity) {
|
|
|
5688
6156
|
|
|
5689
6157
|
// src/table/encode.ts
|
|
5690
6158
|
import {
|
|
5691
|
-
assertLexicalCapabilityClosure,
|
|
5692
6159
|
collectLexicalCapabilities,
|
|
5693
6160
|
winnerWrapsReference as winnerWrapsReference2
|
|
5694
6161
|
} from "../compiler/token-capability.js";
|
|
@@ -6070,6 +6537,9 @@ var Encoder = class {
|
|
|
6070
6537
|
lexIndex = /* @__PURE__ */ new Map();
|
|
6071
6538
|
lexPrograms = [];
|
|
6072
6539
|
lexProgramIndex = /* @__PURE__ */ new Map();
|
|
6540
|
+
choiceRollbackMasks = /* @__PURE__ */ new Map();
|
|
6541
|
+
nonCommittingChoiceSites = /* @__PURE__ */ new Set();
|
|
6542
|
+
failureRollbackCleanSites = /* @__PURE__ */ new Set();
|
|
6073
6543
|
labels = void 0;
|
|
6074
6544
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
6075
6545
|
activeTrivia = void 0;
|
|
@@ -6480,6 +6950,71 @@ var Encoder = class {
|
|
|
6480
6950
|
const w = this.winners;
|
|
6481
6951
|
return w === void 0 ? void 0 : (name) => w[name];
|
|
6482
6952
|
}
|
|
6953
|
+
/**
|
|
6954
|
+
* Whether a failed ordered-choice arm can leave state that the enclosing
|
|
6955
|
+
* choice must restore before trying its successor.
|
|
6956
|
+
*
|
|
6957
|
+
* `mayLeavePartialCapture` is the existing sound CST/trivia proof. The extra
|
|
6958
|
+
* writer census covers the side sinks that proof deliberately does not model:
|
|
6959
|
+
* fields, recovered errors, and interpreted scanners. Strict assemblies do
|
|
6960
|
+
* not run repeat recovery, but these rows can still publish through a caller's
|
|
6961
|
+
* context. Cycles are safe to stop: revisiting the same combinator cannot
|
|
6962
|
+
* discover a writer the first traversal did not already reach.
|
|
6963
|
+
*/
|
|
6964
|
+
failureNeedsRollback(p, autoNot) {
|
|
6965
|
+
const refName = p._ruleName;
|
|
6966
|
+
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
6967
|
+
const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
|
|
6968
|
+
const sideWriterMemo = /* @__PURE__ */ new Map();
|
|
6969
|
+
const hasSideWriter = (current, seen = /* @__PURE__ */ new Set()) => {
|
|
6970
|
+
const cached = sideWriterMemo.get(current);
|
|
6971
|
+
if (cached !== void 0) return { found: cached, complete: true };
|
|
6972
|
+
if (seen.has(current)) return { found: false, complete: false };
|
|
6973
|
+
const next = new Set(seen);
|
|
6974
|
+
next.add(current);
|
|
6975
|
+
const def = current._def;
|
|
6976
|
+
let result;
|
|
6977
|
+
switch (def.tag) {
|
|
6978
|
+
case "field":
|
|
6979
|
+
case "expect":
|
|
6980
|
+
case "recover":
|
|
6981
|
+
case "scanTo":
|
|
6982
|
+
case "unknown":
|
|
6983
|
+
result = { found: true, complete: true };
|
|
6984
|
+
break;
|
|
6985
|
+
case "lazy": {
|
|
6986
|
+
const name = current._ruleName;
|
|
6987
|
+
const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
|
|
6988
|
+
if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
|
|
6989
|
+
result = hasSideWriter(resolvedWinner, next);
|
|
6990
|
+
break;
|
|
6991
|
+
}
|
|
6992
|
+
try {
|
|
6993
|
+
result = hasSideWriter(def.thunk(), next);
|
|
6994
|
+
} catch {
|
|
6995
|
+
result = { found: true, complete: true };
|
|
6996
|
+
}
|
|
6997
|
+
break;
|
|
6998
|
+
}
|
|
6999
|
+
default: {
|
|
7000
|
+
let complete = true;
|
|
7001
|
+
result = { found: false, complete: true };
|
|
7002
|
+
for (const child of childrenOf2(def)) {
|
|
7003
|
+
const childResult = hasSideWriter(child, next);
|
|
7004
|
+
if (childResult.found) {
|
|
7005
|
+
result = { found: true, complete: true };
|
|
7006
|
+
break;
|
|
7007
|
+
}
|
|
7008
|
+
complete &&= childResult.complete;
|
|
7009
|
+
}
|
|
7010
|
+
if (!result.found) result = { found: false, complete };
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
if (result.found || result.complete) sideWriterMemo.set(current, result.found);
|
|
7014
|
+
return result;
|
|
7015
|
+
};
|
|
7016
|
+
return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || hasSideWriter(root).found || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
|
|
7017
|
+
}
|
|
6483
7018
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
6484
7019
|
charClass(fs3) {
|
|
6485
7020
|
if (fs3.kind !== "ranges" || fs3.ranges.length === 0) return -1;
|
|
@@ -6765,9 +7300,39 @@ var Encoder = class {
|
|
|
6765
7300
|
});
|
|
6766
7301
|
const rr = this.refResolver();
|
|
6767
7302
|
const finalChoice = classifyFinalChoice(arms, rr);
|
|
6768
|
-
const
|
|
7303
|
+
const transactionalFirst = arms.map((arm, i) => {
|
|
7304
|
+
if (!finalChoice.nullable[i]) return void 0;
|
|
7305
|
+
const def = arm._def;
|
|
7306
|
+
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
7307
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
7308
|
+
});
|
|
7309
|
+
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
7310
|
+
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
7311
|
+
if (transactionalFirst.some((first) => first !== void 0) && classes.every((cls) => cls >= 0)) {
|
|
7312
|
+
let overlap = false;
|
|
7313
|
+
for (let i = 0; i < gateFirst.length && !overlap; i++) {
|
|
7314
|
+
for (let j = i + 1; j < gateFirst.length; j++) {
|
|
7315
|
+
if (intersects(gateFirst[i], gateFirst[j])) {
|
|
7316
|
+
overlap = true;
|
|
7317
|
+
break;
|
|
7318
|
+
}
|
|
7319
|
+
}
|
|
7320
|
+
}
|
|
7321
|
+
if (!overlap) for (let i = 0; i < classes.length; i++) {
|
|
7322
|
+
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
7323
|
+
}
|
|
7324
|
+
}
|
|
6769
7325
|
const dispIdx = this.disp.length;
|
|
6770
7326
|
this.disp.push(classes);
|
|
7327
|
+
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
7328
|
+
if (rollbackMask === 0) {
|
|
7329
|
+
for (let i = 0; i < arms.length; i++) {
|
|
7330
|
+
const src = order[i];
|
|
7331
|
+
if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
|
|
7332
|
+
rollbackMask |= 1 << i;
|
|
7333
|
+
}
|
|
7334
|
+
}
|
|
7335
|
+
}
|
|
6771
7336
|
const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
|
|
6772
7337
|
this.code[head + 1] = dispIdx;
|
|
6773
7338
|
this.code[head + 2] = kids.length;
|
|
@@ -6776,6 +7341,10 @@ var Encoder = class {
|
|
|
6776
7341
|
this.code[head + 4 + i] = kids[i];
|
|
6777
7342
|
this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
|
|
6778
7343
|
}
|
|
7344
|
+
this.choiceRollbackMasks.set(head, rollbackMask);
|
|
7345
|
+
if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
|
|
7346
|
+
this.nonCommittingChoiceSites.add(head);
|
|
7347
|
+
}
|
|
6779
7348
|
return head;
|
|
6780
7349
|
}
|
|
6781
7350
|
case "many":
|
|
@@ -6805,8 +7374,11 @@ var Encoder = class {
|
|
|
6805
7374
|
}
|
|
6806
7375
|
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);
|
|
6807
7376
|
}
|
|
6808
|
-
case "optional":
|
|
6809
|
-
|
|
7377
|
+
case "optional": {
|
|
7378
|
+
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
7379
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
7380
|
+
return head;
|
|
7381
|
+
}
|
|
6810
7382
|
case "transform": {
|
|
6811
7383
|
const inner = d.parser._def;
|
|
6812
7384
|
if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
|
|
@@ -6965,6 +7537,7 @@ var Encoder = class {
|
|
|
6965
7537
|
// lowering was correct only for a choice arm.
|
|
6966
7538
|
case "attempt": {
|
|
6967
7539
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
7540
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
6968
7541
|
const fs3 = d.parser._meta.firstSet;
|
|
6969
7542
|
if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
6970
7543
|
const cls = this.charClass(fs3);
|
|
@@ -7133,6 +7706,10 @@ var Encoder = class {
|
|
|
7133
7706
|
...this.rec ? { rec: 1 } : {},
|
|
7134
7707
|
...this.cov === void 0 ? {} : { cov: this.cov },
|
|
7135
7708
|
lines: this.track ? 1 : 0
|
|
7709
|
+
}, void 0, {
|
|
7710
|
+
choiceRollbackMasks: this.choiceRollbackMasks,
|
|
7711
|
+
failureRollbackCleanSites: this.failureRollbackCleanSites,
|
|
7712
|
+
nonCommittingChoiceSites: this.nonCommittingChoiceSites
|
|
7136
7713
|
});
|
|
7137
7714
|
}
|
|
7138
7715
|
};
|
|
@@ -7177,7 +7754,6 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
7177
7754
|
const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
|
|
7178
7755
|
const resolveLexical = (name) => ruleMap[name];
|
|
7179
7756
|
const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
|
|
7180
|
-
assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
|
|
7181
7757
|
const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
|
|
7182
7758
|
enc.winners = ruleMap;
|
|
7183
7759
|
for (const name of names) enc.encodeRule(name, ruleMap[name]);
|
|
@@ -8310,13 +8886,17 @@ var TRI_NONE = -1;
|
|
|
8310
8886
|
var CAP_UNKNOWN = 0;
|
|
8311
8887
|
var CAP_OFF = 1;
|
|
8312
8888
|
var CAP_ON = 2;
|
|
8313
|
-
var
|
|
8889
|
+
var RAW_UNKNOWN = 0;
|
|
8890
|
+
var RAW_CAPTURE = 1;
|
|
8891
|
+
var RAW_OMIT = 2;
|
|
8892
|
+
var TOP = { tri: TRI_UNKNOWN, buf: false, raw: RAW_UNKNOWN, cap: CAP_UNKNOWN };
|
|
8314
8893
|
function meet(a, b) {
|
|
8315
8894
|
const tri = a.tri === b.tri ? a.tri : TRI_UNKNOWN;
|
|
8316
8895
|
const buf = a.buf && b.buf;
|
|
8896
|
+
const raw = a.raw === b.raw ? a.raw : RAW_UNKNOWN;
|
|
8317
8897
|
const cap = a.cap === b.cap ? a.cap : CAP_UNKNOWN;
|
|
8318
|
-
if (tri === a.tri && buf === a.buf && cap === a.cap) return a;
|
|
8319
|
-
return { tri, buf, cap };
|
|
8898
|
+
if (tri === a.tri && buf === a.buf && raw === a.raw && cap === a.cap) return a;
|
|
8899
|
+
return { tri, buf, raw, cap };
|
|
8320
8900
|
}
|
|
8321
8901
|
function reachableSites(code, roots) {
|
|
8322
8902
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -8339,25 +8919,26 @@ function transfer(code, ip, at, hostCst) {
|
|
|
8339
8919
|
const tri = ki < 0 ? TRI_NONE : ki;
|
|
8340
8920
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
8341
8921
|
if (tri === at.tri && cap === at.cap) return at;
|
|
8342
|
-
return { tri, buf: at.buf, cap };
|
|
8922
|
+
return { tri, buf: at.buf, raw: at.raw, cap };
|
|
8343
8923
|
}
|
|
8344
8924
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
8345
8925
|
const flags = code[ip + 3];
|
|
8346
8926
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
|
|
8347
8927
|
if (directChildren) {
|
|
8348
|
-
return { tri: at.tri, buf: false, cap: CAP_OFF };
|
|
8928
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
8349
8929
|
}
|
|
8350
8930
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
8351
|
-
|
|
8352
|
-
|
|
8931
|
+
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
8932
|
+
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
8933
|
+
return { tri: at.tri, buf: true, raw, cap };
|
|
8353
8934
|
}
|
|
8354
8935
|
if (op === OP_TOKEN) {
|
|
8355
8936
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
8356
|
-
return { tri: TRI_NONE, buf: false, cap: at.cap };
|
|
8937
|
+
return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
8357
8938
|
}
|
|
8358
8939
|
if (op === OP_LEAF) {
|
|
8359
8940
|
if (!at.buf) return at;
|
|
8360
|
-
return { tri: at.tri, buf: false, cap: at.cap };
|
|
8941
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
8361
8942
|
}
|
|
8362
8943
|
return at;
|
|
8363
8944
|
}
|
|
@@ -8424,6 +9005,162 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
8424
9005
|
const op = code[child];
|
|
8425
9006
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
8426
9007
|
}
|
|
9008
|
+
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
9009
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9010
|
+
let at = ip;
|
|
9011
|
+
let depth = 0;
|
|
9012
|
+
while (!seen.has(at)) {
|
|
9013
|
+
seen.add(at);
|
|
9014
|
+
const op = code[at];
|
|
9015
|
+
if (op === OP_LIT || op === OP_RX) return depth >= minDepth ? at : -1;
|
|
9016
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || throughAttempt && op === OP_ATTEMPT) {
|
|
9017
|
+
at = code[at + 1];
|
|
9018
|
+
depth++;
|
|
9019
|
+
continue;
|
|
9020
|
+
}
|
|
9021
|
+
if (throughPeek && op === OP_PEEK) {
|
|
9022
|
+
at = code[at + 1];
|
|
9023
|
+
depth++;
|
|
9024
|
+
continue;
|
|
9025
|
+
}
|
|
9026
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
9027
|
+
at = code[at + 2];
|
|
9028
|
+
depth++;
|
|
9029
|
+
continue;
|
|
9030
|
+
}
|
|
9031
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
9032
|
+
if (code[at + 1] < 1) return -1;
|
|
9033
|
+
at = code[at + 2];
|
|
9034
|
+
depth++;
|
|
9035
|
+
continue;
|
|
9036
|
+
}
|
|
9037
|
+
if (op === OP_SEQX) {
|
|
9038
|
+
if (code[at + 2] < 1) return -1;
|
|
9039
|
+
at = code[at + 3];
|
|
9040
|
+
depth++;
|
|
9041
|
+
continue;
|
|
9042
|
+
}
|
|
9043
|
+
return -1;
|
|
9044
|
+
}
|
|
9045
|
+
return -1;
|
|
9046
|
+
}
|
|
9047
|
+
function leadingScalarSequence(code, ip) {
|
|
9048
|
+
const wholeScalar = (start) => {
|
|
9049
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
9050
|
+
let at2 = start;
|
|
9051
|
+
while (!seen2.has(at2)) {
|
|
9052
|
+
seen2.add(at2);
|
|
9053
|
+
const op = code[at2];
|
|
9054
|
+
if (op === OP_LIT || op === OP_RX) return at2;
|
|
9055
|
+
if (op === OP_RULE || op === OP_TOKEN || op === OP_ATTEMPT) {
|
|
9056
|
+
at2 = code[at2 + 1];
|
|
9057
|
+
continue;
|
|
9058
|
+
}
|
|
9059
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
9060
|
+
at2 = code[at2 + 2];
|
|
9061
|
+
continue;
|
|
9062
|
+
}
|
|
9063
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
9064
|
+
if (code[at2 + 1] !== 1) return -1;
|
|
9065
|
+
at2 = code[at2 + 2];
|
|
9066
|
+
continue;
|
|
9067
|
+
}
|
|
9068
|
+
if (op === OP_SEQX) {
|
|
9069
|
+
if (code[at2 + 2] !== 1) return -1;
|
|
9070
|
+
at2 = code[at2 + 3];
|
|
9071
|
+
continue;
|
|
9072
|
+
}
|
|
9073
|
+
return -1;
|
|
9074
|
+
}
|
|
9075
|
+
return -1;
|
|
9076
|
+
};
|
|
9077
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9078
|
+
let at = ip;
|
|
9079
|
+
let ambientTrivia;
|
|
9080
|
+
while (!seen.has(at)) {
|
|
9081
|
+
seen.add(at);
|
|
9082
|
+
const op = code[at];
|
|
9083
|
+
if (op === OP_RULE) {
|
|
9084
|
+
at = code[at + 1];
|
|
9085
|
+
continue;
|
|
9086
|
+
}
|
|
9087
|
+
if (op === OP_SCOPE_PLAIN) {
|
|
9088
|
+
ambientTrivia = code[at + 1];
|
|
9089
|
+
at = code[at + 2];
|
|
9090
|
+
continue;
|
|
9091
|
+
}
|
|
9092
|
+
if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
9093
|
+
at = code[at + 2];
|
|
9094
|
+
continue;
|
|
9095
|
+
}
|
|
9096
|
+
const n = op === OP_SEQ || op === OP_SEQV ? code[at + 1] : op === OP_SEQX ? code[at + 2] : 0;
|
|
9097
|
+
if (n < 3 || ambientTrivia === void 0) return void 0;
|
|
9098
|
+
const base = op === OP_SEQX ? at + 3 : at + 2;
|
|
9099
|
+
const terminals = [
|
|
9100
|
+
wholeScalar(code[base]),
|
|
9101
|
+
wholeScalar(code[base + 1]),
|
|
9102
|
+
wholeScalar(code[base + 2])
|
|
9103
|
+
];
|
|
9104
|
+
return terminals.every((terminal) => terminal >= 0) ? { terminals, trivia: ambientTrivia } : void 0;
|
|
9105
|
+
}
|
|
9106
|
+
return void 0;
|
|
9107
|
+
}
|
|
9108
|
+
function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
|
|
9109
|
+
const active = /* @__PURE__ */ new Set();
|
|
9110
|
+
const walk = (at, depth) => {
|
|
9111
|
+
if (active.has(at)) return void 0;
|
|
9112
|
+
active.add(at);
|
|
9113
|
+
try {
|
|
9114
|
+
const op = code[at];
|
|
9115
|
+
if (op === OP_LIT) {
|
|
9116
|
+
const value = constants[code[at + 1]];
|
|
9117
|
+
return depth >= minDepth && typeof value === "string" && value.length > 0 ? [at] : void 0;
|
|
9118
|
+
}
|
|
9119
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
|
|
9120
|
+
return walk(code[at + 1], depth + 1);
|
|
9121
|
+
}
|
|
9122
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
9123
|
+
return walk(code[at + 2], depth + 1);
|
|
9124
|
+
}
|
|
9125
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
9126
|
+
return code[at + 1] < 1 ? void 0 : walk(code[at + 2], depth + 1);
|
|
9127
|
+
}
|
|
9128
|
+
if (op === OP_SEQX) {
|
|
9129
|
+
return code[at + 2] < 1 ? void 0 : walk(code[at + 3], depth + 1);
|
|
9130
|
+
}
|
|
9131
|
+
if (op !== OP_CHOICE) return void 0;
|
|
9132
|
+
const n = code[at + 2];
|
|
9133
|
+
if (n < 1) return void 0;
|
|
9134
|
+
const out = [];
|
|
9135
|
+
for (let i = 0; i < n; i++) {
|
|
9136
|
+
const branch = walk(code[at + 4 + i], depth + 1);
|
|
9137
|
+
if (branch === void 0) return void 0;
|
|
9138
|
+
for (const terminal of branch) {
|
|
9139
|
+
const value = constants[code[terminal + 1]];
|
|
9140
|
+
let covered = false;
|
|
9141
|
+
for (let j = 0; j < out.length; j++) {
|
|
9142
|
+
const prior = constants[code[out[j] + 1]];
|
|
9143
|
+
if (value.startsWith(prior)) {
|
|
9144
|
+
covered = true;
|
|
9145
|
+
break;
|
|
9146
|
+
}
|
|
9147
|
+
}
|
|
9148
|
+
if (covered) continue;
|
|
9149
|
+
for (let j = out.length - 1; j >= 0; j--) {
|
|
9150
|
+
const prior = constants[code[out[j] + 1]];
|
|
9151
|
+
if (prior.startsWith(value)) out.splice(j, 1);
|
|
9152
|
+
}
|
|
9153
|
+
out.push(terminal);
|
|
9154
|
+
if (out.length > limit) return void 0;
|
|
9155
|
+
}
|
|
9156
|
+
}
|
|
9157
|
+
return out;
|
|
9158
|
+
} finally {
|
|
9159
|
+
active.delete(at);
|
|
9160
|
+
}
|
|
9161
|
+
};
|
|
9162
|
+
return walk(ip, 0);
|
|
9163
|
+
}
|
|
8427
9164
|
|
|
8428
9165
|
// src/table/emit-assembly.ts
|
|
8429
9166
|
var Unemittable = class extends Error {
|
|
@@ -8505,6 +9242,16 @@ let _pfScan=null
|
|
|
8505
9242
|
let _pfHost
|
|
8506
9243
|
let _pfDepth=0
|
|
8507
9244
|
const _pfFrames=[]
|
|
9245
|
+
let _pfTokInput
|
|
9246
|
+
let _pfTokPos=-1
|
|
9247
|
+
let _pfTokBody=-1
|
|
9248
|
+
let _pfTokPacked=-1
|
|
9249
|
+
let _pfTokValue
|
|
9250
|
+
let _pfTokDispatch=-1
|
|
9251
|
+
let _pfTokArm=-1
|
|
9252
|
+
let _pfTokEnd=-1
|
|
9253
|
+
let _pfSeqEnd=-1
|
|
9254
|
+
function _asciiFoldCode(c){return c>=65&&c<=90?c+32:c}
|
|
8508
9255
|
function _skipTrivia(input,cur,ctx){
|
|
8509
9256
|
const s=_pfScan
|
|
8510
9257
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
@@ -8570,6 +9317,40 @@ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=
|
|
|
8570
9317
|
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
8571
9318
|
}
|
|
8572
9319
|
`;
|
|
9320
|
+
var NO_RAW_RUNTIME_PRELUDE = `
|
|
9321
|
+
function _pushLeafNoRawBuf(ctx,value,s,e){
|
|
9322
|
+
const l={_tag:'leaf',value,span:{start:s,end:e}}
|
|
9323
|
+
const b=ctx._cstBuf
|
|
9324
|
+
if(b.ch!==undefined)b.ch.push(l)
|
|
9325
|
+
else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
|
|
9326
|
+
else b.single=l
|
|
9327
|
+
b.rawLen++
|
|
9328
|
+
}
|
|
9329
|
+
function _pushNodeNoRawBuf(ctx,value){
|
|
9330
|
+
const b=ctx._cstBuf
|
|
9331
|
+
if(b.ch!==undefined)b.ch.push(value)
|
|
9332
|
+
else if(b.single!==undefined){b.ch=[b.single,value];b.single=undefined}
|
|
9333
|
+
else b.single=value
|
|
9334
|
+
b.rawLen++
|
|
9335
|
+
}
|
|
9336
|
+
function _rbNoRawBuf(ctx,raw,tl,lv,lg,rt){
|
|
9337
|
+
const b=ctx._cstBuf
|
|
9338
|
+
if(b.rawLen!==raw)b.rawLen=raw
|
|
9339
|
+
const ch=b.ch
|
|
9340
|
+
if(ch!==undefined){
|
|
9341
|
+
if(lv===0)b.ch=undefined
|
|
9342
|
+
else if(lv===1){b.single=ch[0];b.ch=undefined}
|
|
9343
|
+
else if(ch.length!==lv)ch.length=lv
|
|
9344
|
+
}else if(lv===0)b.single=undefined
|
|
9345
|
+
const bt=b.tl
|
|
9346
|
+
if(bt!==undefined){
|
|
9347
|
+
if(tl===0)b.tl=undefined
|
|
9348
|
+
else if(bt.length!==tl)bt.length=tl
|
|
9349
|
+
}
|
|
9350
|
+
if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=lg
|
|
9351
|
+
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
9352
|
+
}
|
|
9353
|
+
`;
|
|
8573
9354
|
function q(s) {
|
|
8574
9355
|
return JSON.stringify(s);
|
|
8575
9356
|
}
|
|
@@ -8582,11 +9363,12 @@ function sinkReads(t, s) {
|
|
|
8582
9363
|
${t}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${s.er ? `
|
|
8583
9364
|
${t}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
8584
9365
|
}
|
|
8585
|
-
function emitMark(t, buf, s = NO_SINKS, decl = true) {
|
|
9366
|
+
function emitMark(t, buf, rawMode, s = NO_SINKS, decl = true) {
|
|
8586
9367
|
if (buf) {
|
|
9368
|
+
const raw = rawMode === RAW_OMIT ? `${t}raw=b.rawLen` : rawMode === RAW_CAPTURE ? `const r=b.raw;${t}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${t}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
8587
9369
|
return `${decl ? `let ${t}raw=0,${t}tl=0,${t}lv=0,${t}lg=0,${t}rt=0${sinkSlots(t, s)}
|
|
8588
9370
|
` : ""}{const b=ctx._cstBuf
|
|
8589
|
-
|
|
9371
|
+
${raw}
|
|
8590
9372
|
const h=b.ch;${t}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8591
9373
|
const l=b.tl;${t}tl=l!==undefined?l.length:0
|
|
8592
9374
|
${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
@@ -8596,7 +9378,7 @@ ${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t,
|
|
|
8596
9378
|
` : `${t}n=false
|
|
8597
9379
|
`}{const b=ctx._cstBuf
|
|
8598
9380
|
if(b!==undefined){
|
|
8599
|
-
const r=b.raw;${t}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
9381
|
+
const r=b.raw;${t}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
8600
9382
|
const h=b.ch;${t}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
8601
9383
|
const l=b.tl;${t}tl=l!==undefined?l.length:0
|
|
8602
9384
|
${t}n=true
|
|
@@ -8611,14 +9393,16 @@ ${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
8611
9393
|
${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t, s)}
|
|
8612
9394
|
}}`;
|
|
8613
9395
|
}
|
|
8614
|
-
function emitRollback(t, buf, s = NO_SINKS) {
|
|
9396
|
+
function emitRollback(t, buf, rawMode, s = NO_SINKS) {
|
|
8615
9397
|
const fd = s.fd ? `
|
|
8616
9398
|
if(ctx._fields!==undefined&&ctx._fields.length!==${t}fd)ctx._fields.length=${t}fd` : "";
|
|
8617
9399
|
const er = s.er ? `
|
|
8618
9400
|
if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}er` : "";
|
|
8619
|
-
if (buf) return `
|
|
8620
|
-
if (
|
|
8621
|
-
return `
|
|
9401
|
+
if (buf && rawMode === RAW_OMIT) return `_rbNoRawBuf(ctx,${t}raw,${t}tl,${t}lv,${t}lg,${t}rt)${fd}${er}`;
|
|
9402
|
+
if (buf && rawMode === RAW_CAPTURE) return `_rbBuf(ctx,${t}raw,${t}tl,${t}lv,${t}lg,${t}rt)${fd}${er}`;
|
|
9403
|
+
if (buf) return `rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)`;
|
|
9404
|
+
if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,undefined,undefined,${t}lg,${t}rt)`;
|
|
9405
|
+
return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
|
|
8622
9406
|
}
|
|
8623
9407
|
function emitTerm(callee, dst, t, l, skip) {
|
|
8624
9408
|
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
@@ -8676,37 +9460,111 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
8676
9460
|
})
|
|
8677
9461
|
};
|
|
8678
9462
|
}
|
|
8679
|
-
function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
8680
|
-
const { code, k, disp, dsp, triviaLabelled } = t;
|
|
9463
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
9464
|
+
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
8681
9465
|
const swapLegal = !cfg.trackLines;
|
|
8682
9466
|
const hostCst = cfg.hostCst;
|
|
8683
9467
|
const REC2 = prog.rec === 1 && cfg.tolerant;
|
|
8684
9468
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
8685
9469
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
9470
|
+
const reachable = [...reachableSites(code, roots)];
|
|
8686
9471
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
8687
9472
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
9473
|
+
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
9474
|
+
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
9475
|
+
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
9476
|
+
const tokenChoiceCandidates = /* @__PURE__ */ new Map();
|
|
9477
|
+
const tokenChoiceDispatches = /* @__PURE__ */ new Set();
|
|
9478
|
+
const tokenChoiceBodies = /* @__PURE__ */ new Set();
|
|
8688
9479
|
if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
8689
|
-
for (const ip of
|
|
8690
|
-
if (code[ip]
|
|
8691
|
-
|
|
8692
|
-
|
|
9480
|
+
for (const ip of reachable) {
|
|
9481
|
+
if (code[ip] === OP_NODE) {
|
|
9482
|
+
const child = scalarTerminalNodeChild(code, ip);
|
|
9483
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
9484
|
+
continue;
|
|
9485
|
+
}
|
|
9486
|
+
if (code[ip] !== OP_CHOICE || disp[code[ip + 1]].exclusive) continue;
|
|
9487
|
+
const n = code[ip + 2];
|
|
9488
|
+
for (let i = 0; i < n; i++) {
|
|
9489
|
+
const armIp = code[ip + 4 + i];
|
|
9490
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
9491
|
+
if (n === 2 || n === 3) {
|
|
9492
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
9493
|
+
continue;
|
|
9494
|
+
}
|
|
9495
|
+
if (child >= 0) {
|
|
9496
|
+
const spec = k[code[child + 1]];
|
|
9497
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
9498
|
+
largeChoiceScalarSpecs.add(code[child + 1]);
|
|
9499
|
+
continue;
|
|
9500
|
+
}
|
|
9501
|
+
}
|
|
9502
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
9503
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
9504
|
+
const value = k[code[terminal + 1]];
|
|
9505
|
+
return typeof value === "string" && value.length >= 2;
|
|
9506
|
+
})) {
|
|
9507
|
+
largeChoiceLiteralFamilies.set(armIp, family);
|
|
9508
|
+
}
|
|
9509
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
9510
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t.triviaScan[sequence6.trivia] != null)) {
|
|
9511
|
+
largeChoiceScalarSequences.set(armIp, sequence6);
|
|
9512
|
+
}
|
|
9513
|
+
}
|
|
9514
|
+
let candidate;
|
|
9515
|
+
let ambiguous = false;
|
|
9516
|
+
for (let i = 0; i < n; i++) {
|
|
9517
|
+
const armIp = code[ip + 4 + i];
|
|
9518
|
+
if (code[armIp] !== OP_XFORM) continue;
|
|
9519
|
+
const dispatchIp = code[armIp + 2];
|
|
9520
|
+
if (code[dispatchIp] !== OP_DISPATCH) continue;
|
|
9521
|
+
const selectorIp = code[dispatchIp + 1];
|
|
9522
|
+
if (code[selectorIp] !== OP_LEX_BODY) continue;
|
|
9523
|
+
if (candidate !== void 0) {
|
|
9524
|
+
ambiguous = true;
|
|
9525
|
+
break;
|
|
9526
|
+
}
|
|
9527
|
+
candidate = { arm: i, dispatchIp };
|
|
9528
|
+
}
|
|
9529
|
+
if (!ambiguous && candidate !== void 0) {
|
|
9530
|
+
tokenChoiceCandidates.set(ip, candidate);
|
|
9531
|
+
tokenChoiceDispatches.add(candidate.dispatchIp);
|
|
9532
|
+
tokenChoiceBodies.add(code[code[candidate.dispatchIp + 1] + 1]);
|
|
9533
|
+
}
|
|
8693
9534
|
}
|
|
8694
9535
|
}
|
|
8695
|
-
const
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
9536
|
+
const needsNoRawPrelude = !hostCst && reachable.some((ip) => {
|
|
9537
|
+
const op = code[ip];
|
|
9538
|
+
return (op === OP_NODE || op === OP_NODE_TRACK) && code[ip + 1] >= 0 && code[ip + 4] < 0 && (code[ip + 3] & 2) !== 0;
|
|
9539
|
+
});
|
|
9540
|
+
const sinkSites = reachable;
|
|
9541
|
+
const sinkBits = /* @__PURE__ */ new Map();
|
|
9542
|
+
for (const ip of sinkSites) {
|
|
9543
|
+
const op = code[ip];
|
|
9544
|
+
sinkBits.set(
|
|
9545
|
+
ip,
|
|
9546
|
+
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC2 && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
9547
|
+
);
|
|
9548
|
+
}
|
|
9549
|
+
const sinkKids = [];
|
|
9550
|
+
let sinkChanged = true;
|
|
9551
|
+
while (sinkChanged) {
|
|
9552
|
+
sinkChanged = false;
|
|
9553
|
+
for (const ip of sinkSites) {
|
|
9554
|
+
let bits = sinkBits.get(ip) ?? 0;
|
|
9555
|
+
sinkKids.length = 0;
|
|
9556
|
+
childSlots(code, ip, sinkKids);
|
|
9557
|
+
for (let i = 0; i < sinkKids.length; i++) bits |= sinkBits.get(sinkKids[i]) ?? 0;
|
|
9558
|
+
if (bits !== sinkBits.get(ip)) {
|
|
9559
|
+
sinkBits.set(ip, bits);
|
|
9560
|
+
sinkChanged = true;
|
|
8704
9561
|
}
|
|
8705
|
-
if (op === OP_FIELD) fd = true;
|
|
8706
|
-
else if (op === OP_EXPECT) er = true;
|
|
8707
9562
|
}
|
|
8708
|
-
|
|
8709
|
-
|
|
9563
|
+
}
|
|
9564
|
+
const sinksAt = (ip) => {
|
|
9565
|
+
const bits = sinkBits.get(ip) ?? 0;
|
|
9566
|
+
return bits === 0 ? NO_SINKS : { fd: (bits & 1) !== 0, er: (bits & 2) !== 0 };
|
|
9567
|
+
};
|
|
8710
9568
|
const bodies = [];
|
|
8711
9569
|
const byIp = /* @__PURE__ */ new Map();
|
|
8712
9570
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -8733,9 +9591,117 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
8733
9591
|
const fxRef = (i) => hoist("fx", `FX[${i}]`);
|
|
8734
9592
|
const fnRef = (i) => hoist("fn", `FNS[${i}]`);
|
|
8735
9593
|
const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
|
|
9594
|
+
const scalarSequenceRefs = /* @__PURE__ */ new Map();
|
|
9595
|
+
const scalarSequenceRef = (sequence6) => {
|
|
9596
|
+
const key = `${sequence6.trivia}:${sequence6.terminals.map((terminal) => code[terminal + 1]).join(",")}`;
|
|
9597
|
+
const prior = scalarSequenceRefs.get(key);
|
|
9598
|
+
if (prior !== void 0) return prior;
|
|
9599
|
+
const recognizers = sequence6.terminals.map((terminal) => recognizerRef(code[terminal + 1]));
|
|
9600
|
+
const expected = sequence6.terminals.map((terminal) => fxRef(code[terminal + 2]));
|
|
9601
|
+
const scan = sequence6.trivia < 0 ? void 0 : hoist("ts", `TRIVIASCAN[${sequence6.trivia}]`);
|
|
9602
|
+
const name = `_sd${scalarSequenceRefs.size}_`;
|
|
9603
|
+
const steps = recognizers.map((recognize, i) => `${i === 0 ? "let " : ""}at=${i === 0 ? "pos" : scan === void 0 ? "cur" : `${scan}(input,cur)`}
|
|
9604
|
+
${i === 0 ? "let " : ""}cur=${recognize}(input,at)
|
|
9605
|
+
if(cur<0){_pfSeqEnd=at;return ${~i}}`).join("\n");
|
|
9606
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
9607
|
+
${steps}
|
|
9608
|
+
return cur
|
|
9609
|
+
}`);
|
|
9610
|
+
const made = { name, expected };
|
|
9611
|
+
scalarSequenceRefs.set(key, made);
|
|
9612
|
+
return made;
|
|
9613
|
+
};
|
|
8736
9614
|
const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
|
|
8737
9615
|
let uid = 0;
|
|
8738
9616
|
const tmp = () => `_t${uid++}_`;
|
|
9617
|
+
const dispatchClaim = (m) => {
|
|
9618
|
+
switch (m[0]) {
|
|
9619
|
+
case 0:
|
|
9620
|
+
return `key.startsWith(${q(m[1])})`;
|
|
9621
|
+
case 1:
|
|
9622
|
+
return `key.endsWith(${q(m[1])})`;
|
|
9623
|
+
case 3:
|
|
9624
|
+
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
9625
|
+
case 4:
|
|
9626
|
+
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
9627
|
+
default: {
|
|
9628
|
+
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
9629
|
+
try {
|
|
9630
|
+
new RegExp(m[1], m[2]);
|
|
9631
|
+
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
9632
|
+
} catch {
|
|
9633
|
+
}
|
|
9634
|
+
}
|
|
9635
|
+
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
9636
|
+
}
|
|
9637
|
+
}
|
|
9638
|
+
};
|
|
9639
|
+
const tokenDecisionRefs = /* @__PURE__ */ new Map();
|
|
9640
|
+
function tokenDecisionFor(dispatchIp) {
|
|
9641
|
+
const prior = tokenDecisionRefs.get(dispatchIp);
|
|
9642
|
+
if (prior !== void 0) return prior;
|
|
9643
|
+
const selectorIp = code[dispatchIp + 1];
|
|
9644
|
+
const body = code[selectorIp + 1];
|
|
9645
|
+
const lineFlags = code[selectorIp + 4];
|
|
9646
|
+
const hasSuffix = (lineFlags & 4) !== 0;
|
|
9647
|
+
const di = code[dispatchIp + 2];
|
|
9648
|
+
const spec = dsp[di];
|
|
9649
|
+
const n = code[dispatchIp + 5];
|
|
9650
|
+
validateDispatchSpec(spec, n, code[dispatchIp + 4]);
|
|
9651
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
9652
|
+
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
9653
|
+
const expected = hoist("dx", `DSP[${di}].expected`);
|
|
9654
|
+
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
9655
|
+
` : "";
|
|
9656
|
+
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
9657
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
9658
|
+
}
|
|
9659
|
+
`;
|
|
9660
|
+
const foldedEntries = [...spec.byFold.entries()];
|
|
9661
|
+
const fixedFunctionChoice = spec.byKey.size === 0 && foldedEntries.length === 1 && spec.match.length === 1 && spec.match[0][0] === 2 && spec.match[0][1] === "^(?!(?:url|calc)\\($).+\\($" && spec.match[0][2] === "i" && code[dispatchIp + 3] < 0;
|
|
9662
|
+
const foldedRangeEquals = (value) => {
|
|
9663
|
+
const folded = value.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
9664
|
+
return `e-pos===${folded.length}&&${[...folded].map((c, i) => {
|
|
9665
|
+
const cc = c.charCodeAt(0);
|
|
9666
|
+
return `_asciiFoldCode(input.charCodeAt(pos+${i}))===${cc}`;
|
|
9667
|
+
}).join("&&")}`;
|
|
9668
|
+
};
|
|
9669
|
+
const classify = fixedFunctionChoice ? (() => {
|
|
9670
|
+
const [exact, exactArm] = foldedEntries[0];
|
|
9671
|
+
const genericArm = spec.match[0][3];
|
|
9672
|
+
return `let arm
|
|
9673
|
+
if(${foldedRangeEquals(exact)})arm=${exactArm}
|
|
9674
|
+
else if(sm&&e>pos+1){
|
|
9675
|
+
let clean=true
|
|
9676
|
+
for(let i=pos;i<e;i++){const c=input.charCodeAt(i);if(c===10||c===13||c===0x2028||c===0x2029){clean=false;break}}
|
|
9677
|
+
if(clean&&!(${foldedRangeEquals("url(")})&&!(${foldedRangeEquals("calc(")}))arm=${genericArm}
|
|
9678
|
+
}`;
|
|
9679
|
+
})() : `const key=input.slice(pos,e)
|
|
9680
|
+
let arm=${bk}.get(key)
|
|
9681
|
+
${fold}${chain}`;
|
|
9682
|
+
const name = `_td${tokenDecisionRefs.size}_`;
|
|
9683
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
9684
|
+
const r=${recognize}(input,pos)
|
|
9685
|
+
if(r<0)return -1
|
|
9686
|
+
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
9687
|
+
${classify}
|
|
9688
|
+
if(arm===undefined){
|
|
9689
|
+
${code[dispatchIp + 3] < 0 ? "_pfTokEnd=e;return 0" : `arm=${n}`}
|
|
9690
|
+
}
|
|
9691
|
+
${fixedFunctionChoice ? "const key=input.slice(pos,e)" : ""}
|
|
9692
|
+
_pfTokInput=input
|
|
9693
|
+
_pfTokPos=pos
|
|
9694
|
+
_pfTokBody=${body}
|
|
9695
|
+
_pfTokPacked=r
|
|
9696
|
+
_pfTokValue=key
|
|
9697
|
+
_pfTokDispatch=${dispatchIp}
|
|
9698
|
+
_pfTokArm=arm
|
|
9699
|
+
return 1
|
|
9700
|
+
}`);
|
|
9701
|
+
const made = { name, expected };
|
|
9702
|
+
tokenDecisionRefs.set(dispatchIp, made);
|
|
9703
|
+
return made;
|
|
9704
|
+
}
|
|
8739
9705
|
function skipFor(l) {
|
|
8740
9706
|
if (l.tri < 0) return "_skipTrivia";
|
|
8741
9707
|
const ki = l.tri;
|
|
@@ -8823,7 +9789,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
8823
9789
|
const op = code[ip];
|
|
8824
9790
|
const head = `function ${fname}(input,pos,ctx){`;
|
|
8825
9791
|
const L = labels.at(ip);
|
|
8826
|
-
const
|
|
9792
|
+
const sinks = sinksAt(ip);
|
|
9793
|
+
const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
|
|
8827
9794
|
const captureLeaf = (value) => {
|
|
8828
9795
|
const call = `${pushLeaf}(ctx,${value},pos,e)`;
|
|
8829
9796
|
return L.buf ? call : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${call}`;
|
|
@@ -8987,12 +9954,12 @@ return err
|
|
|
8987
9954
|
}
|
|
8988
9955
|
case OP_ROUTED: {
|
|
8989
9956
|
const fb = code[ip + 1];
|
|
8990
|
-
const
|
|
9957
|
+
const fallback2 = fb >= 0 ? link(fb) : void 0;
|
|
8991
9958
|
const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
|
|
8992
9959
|
return `${head}
|
|
8993
9960
|
const it=ctx._routed
|
|
8994
9961
|
if(it===undefined||pos!==it.span.start){
|
|
8995
|
-
${
|
|
9962
|
+
${fallback2 !== void 0 ? `return ${fallback2}(input,pos,ctx)` : "ctx._fe=pos;ctx._fx=ROUTED_FX;return FAIL"}
|
|
8996
9963
|
}
|
|
8997
9964
|
${L.buf ? push : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${push}`}
|
|
8998
9965
|
EC.e=it.span.end
|
|
@@ -9074,20 +10041,24 @@ return out
|
|
|
9074
10041
|
}`;
|
|
9075
10042
|
}
|
|
9076
10043
|
case OP_LEX_BODY: {
|
|
9077
|
-
const
|
|
10044
|
+
const body = code[ip + 1];
|
|
10045
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
9078
10046
|
const expected = fxRef(code[ip + 2]);
|
|
9079
10047
|
const suffixExpected = fxRef(code[ip + 3]);
|
|
9080
10048
|
const lineFlags = code[ip + 4];
|
|
9081
10049
|
const hasSuffix = (lineFlags & 4) !== 0;
|
|
10050
|
+
const pending = tokenChoiceBodies.has(body);
|
|
9082
10051
|
return `${head}
|
|
9083
|
-
const
|
|
10052
|
+
${pending ? `const tp=_pfTokBody===${body}&&_pfTokInput===input&&_pfTokPos===pos
|
|
10053
|
+
const r=tp?_pfTokPacked:${recognize}(input,pos)` : `const r=${recognize}(input,pos)`}
|
|
9084
10054
|
if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
|
|
9085
10055
|
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
9086
10056
|
${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
|
|
9087
10057
|
${hasSuffix ? "ctx._fc=false" : ""}
|
|
9088
10058
|
${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
|
|
9089
10059
|
${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
|
|
9090
|
-
const v
|
|
10060
|
+
const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
|
|
10061
|
+
${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
|
|
9091
10062
|
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
9092
10063
|
EC.e=e
|
|
9093
10064
|
return v
|
|
@@ -9143,12 +10114,13 @@ return v
|
|
|
9143
10114
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
9144
10115
|
case OP_ATTEMPT: {
|
|
9145
10116
|
const child = link(code[ip + 1]);
|
|
10117
|
+
const clean = !REC2 && failureRollbackClean(prog, ip);
|
|
9146
10118
|
const p = tmp();
|
|
9147
10119
|
return `${head}
|
|
9148
|
-
${emitMark(p, L.buf, sinks)}
|
|
10120
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
9149
10121
|
const v=${child}(input,pos,ctx)
|
|
9150
10122
|
if(v!==FAIL)return v
|
|
9151
|
-
${emitRollback(p, L.buf, sinks)}
|
|
10123
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
9152
10124
|
if(ctx._fc===true)return FAIL
|
|
9153
10125
|
ctx._fe=pos
|
|
9154
10126
|
return FAIL
|
|
@@ -9171,9 +10143,9 @@ return FAIL
|
|
|
9171
10143
|
const xf = fxRef(code[ip + 2]);
|
|
9172
10144
|
const p = tmp();
|
|
9173
10145
|
return `${head}
|
|
9174
|
-
${emitMark(p, L.buf, sinks)}
|
|
10146
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
9175
10147
|
const v=${child}(input,pos,ctx)
|
|
9176
|
-
${emitRollback(p, L.buf, sinks)}
|
|
10148
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9177
10149
|
if(v===FAIL){EC.e=pos;return null}
|
|
9178
10150
|
ctx._fe=pos
|
|
9179
10151
|
ctx._fx=${xf}
|
|
@@ -9185,9 +10157,9 @@ return FAIL
|
|
|
9185
10157
|
const xf = fxRef(code[ip + 2]);
|
|
9186
10158
|
const p = tmp();
|
|
9187
10159
|
return `${head}
|
|
9188
|
-
${emitMark(p, L.buf, sinks)}
|
|
10160
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
9189
10161
|
const v=${child}(input,pos,ctx)
|
|
9190
|
-
${emitRollback(p, L.buf, sinks)}
|
|
10162
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
9191
10163
|
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
9192
10164
|
EC.e=pos
|
|
9193
10165
|
return null
|
|
@@ -9195,14 +10167,15 @@ return null
|
|
|
9195
10167
|
}
|
|
9196
10168
|
case OP_OPT: {
|
|
9197
10169
|
const child = link(code[ip + 1]);
|
|
10170
|
+
const clean = !REC2 && failureRollbackClean(prog, ip);
|
|
9198
10171
|
const p = tmp();
|
|
9199
10172
|
return `${head}
|
|
9200
|
-
${emitMark(p, L.buf, sinks)}
|
|
10173
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
9201
10174
|
ctx._fc=false
|
|
9202
10175
|
const v=${child}(input,pos,ctx)
|
|
9203
10176
|
if(v===FAIL){
|
|
9204
10177
|
if(ctx._fc===true)return FAIL
|
|
9205
|
-
${emitRollback(p, L.buf, sinks)}
|
|
10178
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
9206
10179
|
EC.e=pos
|
|
9207
10180
|
return null
|
|
9208
10181
|
}
|
|
@@ -9301,57 +10274,193 @@ return FAIL
|
|
|
9301
10274
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
9302
10275
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
9303
10276
|
const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10277
|
+
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10278
|
+
const pretests = Array.from({ length: n }, (_, i) => {
|
|
10279
|
+
if (tokenCandidate?.arm === i) {
|
|
10280
|
+
return { token: tokenDecisionFor(tokenCandidate.dispatchIp) };
|
|
10281
|
+
}
|
|
10282
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 2, true, true);
|
|
10283
|
+
if (terminal >= 0) {
|
|
10284
|
+
const spec = code[terminal + 1];
|
|
10285
|
+
if ((n === 2 || n === 3 ? scalarSpecs : largeChoiceScalarSpecs).has(spec)) {
|
|
10286
|
+
return { scalar: [recognizerRef(spec)] };
|
|
10287
|
+
}
|
|
10288
|
+
}
|
|
10289
|
+
const family = largeChoiceLiteralFamilies.get(code[base + i]);
|
|
10290
|
+
if (family !== void 0) {
|
|
10291
|
+
return { scalar: family.map((member) => recognizerRef(code[member + 1])) };
|
|
10292
|
+
}
|
|
10293
|
+
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
10294
|
+
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
10295
|
+
});
|
|
9304
10296
|
const maskable = n <= 32;
|
|
9305
10297
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
9306
10298
|
if (maskable) maskPlan.push(~di);
|
|
9307
10299
|
const p = tmp();
|
|
9308
|
-
const
|
|
9309
|
-
|
|
10300
|
+
const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
|
|
10301
|
+
const rollbackMask = REC2 ? -1 : encodedRollbackMask;
|
|
10302
|
+
const hasRollback = rollbackMask !== 0;
|
|
10303
|
+
const startFailureExact = arms.every((_arm, i) => {
|
|
10304
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
|
|
10305
|
+
if (terminal < 0) return false;
|
|
10306
|
+
const op2 = code[terminal];
|
|
10307
|
+
const spec = k[code[terminal + 1]];
|
|
10308
|
+
const terminalFx = fx[code[terminal + 2]];
|
|
10309
|
+
const armFx = fx[code[base + n + i]];
|
|
10310
|
+
if (terminalFx.length !== armFx.length || terminalFx.some((expected2, at) => expected2 !== armFx[at])) return false;
|
|
10311
|
+
if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
|
|
10312
|
+
return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
|
|
10313
|
+
});
|
|
10314
|
+
const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
|
|
10315
|
+
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
10316
|
+
const deepAt = Array.from({ length: n }, () => tmp());
|
|
10317
|
+
const deepFx = Array.from({ length: n }, () => tmp());
|
|
10318
|
+
const remember = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
10319
|
+
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
10320
|
+
const pretest = pretests[i];
|
|
10321
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10322
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
10323
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
10324
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
10325
|
+
const gate2 = ascii ? `(bits&${1 << i})!==0${condition}` : `(${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}`;
|
|
10326
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
10327
|
+
if(${decision}===0){
|
|
10328
|
+
ctx._fc=false
|
|
10329
|
+
{const at=_pfTokEnd
|
|
10330
|
+
${remember(i, "at", pretest.token.expected)}}
|
|
10331
|
+
}`;
|
|
10332
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
10333
|
+
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
10334
|
+
ctx._fc=false
|
|
10335
|
+
{const at=_pfSeqEnd
|
|
10336
|
+
${remember(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
10337
|
+
}`;
|
|
10338
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10339
|
+
`}if(${gate2}){
|
|
10340
|
+
ctx._fc=false
|
|
10341
|
+
{const v=${arm}(input,pos,ctx)
|
|
10342
|
+
if(v!==FAIL)return v}
|
|
10343
|
+
{const at=ctx._fe??pos
|
|
10344
|
+
${remember(i, "at", "ctx._fx")}}
|
|
10345
|
+
${rollbackFor(i)}
|
|
10346
|
+
}${routeMiss}${sequenceMiss}`;
|
|
10347
|
+
}).join("\n");
|
|
10348
|
+
const merge = deepAt.map((at, i) => `{const at=${at}??pos
|
|
10349
|
+
const ex=${at}===undefined?${expected[i]}:${deepFx[i]}
|
|
10350
|
+
if(at>best){best=at;acc=_accSet(ex,undefined)}
|
|
10351
|
+
else if(at===best)acc=_accSet(ex,acc)
|
|
10352
|
+
}`).join("\n");
|
|
10353
|
+
const finish = `let best=pos,acc
|
|
10354
|
+
${merge}
|
|
10355
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
10356
|
+
return FAIL`;
|
|
10357
|
+
return `${head}
|
|
10358
|
+
const c=lead(input,pos)
|
|
10359
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10360
|
+
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
10361
|
+
${maskable ? `if(c<128){
|
|
10362
|
+
const bits=${maskName}[c<0?128:c]
|
|
10363
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10364
|
+
${lazyArms(true)}
|
|
10365
|
+
}else{
|
|
10366
|
+
${lazyArms(false)}
|
|
10367
|
+
}
|
|
10368
|
+
` : lazyArms(false)}
|
|
10369
|
+
${finish}
|
|
10370
|
+
}`;
|
|
10371
|
+
}
|
|
10372
|
+
const needsCatch = maskable || startFailureExact;
|
|
10373
|
+
const catchName = needsCatch ? `_cx${uid++}_` : "";
|
|
10374
|
+
if (needsCatch) {
|
|
9310
10375
|
const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
|
|
9311
10376
|
choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
|
|
9312
10377
|
${catchCases}
|
|
9313
10378
|
}return acc}`);
|
|
9314
10379
|
}
|
|
9315
10380
|
const maskArms = maskable ? arms.map((arm, i) => {
|
|
9316
|
-
|
|
10381
|
+
const pretest = pretests[i];
|
|
10382
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10383
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
10384
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
10385
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
10386
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
10387
|
+
if(${decision}===0){
|
|
10388
|
+
ctx._fc=false
|
|
10389
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
10390
|
+
prev=${i + 1}`}
|
|
10391
|
+
{const at=_pfTokEnd
|
|
10392
|
+
if(at>best){best=at;acc=undefined}
|
|
10393
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)}
|
|
10394
|
+
}`;
|
|
10395
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
10396
|
+
else if((bits&${1 << i})!==0&&${decision}<0){
|
|
10397
|
+
ctx._fc=false
|
|
10398
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
10399
|
+
prev=${i + 1}`}
|
|
10400
|
+
{const at=_pfSeqEnd
|
|
10401
|
+
if(at>best){best=at;acc=undefined}
|
|
10402
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)}
|
|
10403
|
+
}`;
|
|
10404
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10405
|
+
`}if((bits&${1 << i})!==0${condition}){
|
|
9317
10406
|
ctx._fc=false
|
|
9318
10407
|
{const v=${arm}(input,pos,ctx)
|
|
9319
10408
|
if(v!==FAIL)return v}
|
|
9320
|
-
if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
9321
|
-
prev=${i + 1}
|
|
10409
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
10410
|
+
prev=${i + 1}`}
|
|
9322
10411
|
{const at=ctx._fe??pos
|
|
9323
10412
|
if(at>best){best=at;acc=undefined}
|
|
9324
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
9325
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
9326
|
-
${
|
|
9327
|
-
}`;
|
|
10413
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
10414
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
10415
|
+
${rollbackFor(i)}
|
|
10416
|
+
}${routeMiss}${sequenceMiss}`;
|
|
9328
10417
|
}).join("\n") : "";
|
|
9329
|
-
const generalArms = arms.map((arm, i) =>
|
|
10418
|
+
const generalArms = arms.map((arm, i) => {
|
|
10419
|
+
const pretest = pretests[i];
|
|
10420
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10421
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
10422
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
10423
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
10424
|
+
const miss = pretest?.sequence !== void 0 ? `else if(${decision}<0){
|
|
10425
|
+
ctx._fc=false
|
|
10426
|
+
const at=_pfSeqEnd
|
|
10427
|
+
if(at>best){best=at;acc=undefined}
|
|
10428
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)
|
|
10429
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}` : pretest?.token === void 0 ? startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)` : `else if(${decision}===0){
|
|
10430
|
+
ctx._fc=false
|
|
10431
|
+
const at=_pfTokEnd
|
|
10432
|
+
if(at>best){best=at;acc=undefined}
|
|
10433
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)
|
|
10434
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
|
|
10435
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
10436
|
+
`}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
|
|
9330
10437
|
ctx._fc=false
|
|
9331
10438
|
{const v=${arm}(input,pos,ctx)
|
|
9332
10439
|
if(v!==FAIL)return v}
|
|
9333
10440
|
{const at=ctx._fe??pos
|
|
9334
10441
|
if(at>best){best=at;acc=undefined}
|
|
9335
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
9336
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
9337
|
-
${
|
|
9338
|
-
}
|
|
10442
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
10443
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
10444
|
+
${rollbackFor(i)}
|
|
10445
|
+
}${miss}`;
|
|
10446
|
+
}).join("\n");
|
|
9339
10447
|
return `${head}
|
|
9340
10448
|
const c=lead(input,pos)
|
|
9341
|
-
${emitMark(p, L.buf, sinks)}
|
|
10449
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
9342
10450
|
let acc
|
|
9343
10451
|
let best=pos
|
|
9344
10452
|
${maskable ? `if(c<128){
|
|
9345
10453
|
const bits=${maskName}[c<0?128:c]
|
|
9346
|
-
|
|
10454
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10455
|
+
${startFailureExact ? "" : "let prev=0"}
|
|
9347
10456
|
${maskArms}
|
|
9348
|
-
if(best===pos)acc=${catchName}(${n},prev,acc)
|
|
9349
|
-
ctx._fe=pos;ctx._fx
|
|
10457
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
10458
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
9350
10459
|
return FAIL
|
|
9351
10460
|
}
|
|
9352
10461
|
` : ""}
|
|
9353
10462
|
${generalArms}
|
|
9354
|
-
ctx._fe=pos;ctx._fx
|
|
10463
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
9355
10464
|
return FAIL
|
|
9356
10465
|
}`;
|
|
9357
10466
|
}
|
|
@@ -9370,30 +10479,8 @@ return FAIL
|
|
|
9370
10479
|
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
9371
10480
|
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
9372
10481
|
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
9373
|
-
const claims = (m) => {
|
|
9374
|
-
switch (m[0]) {
|
|
9375
|
-
case 0:
|
|
9376
|
-
return `key.startsWith(${q(m[1])})`;
|
|
9377
|
-
case 1:
|
|
9378
|
-
return `key.endsWith(${q(m[1])})`;
|
|
9379
|
-
case 3:
|
|
9380
|
-
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
9381
|
-
case 4:
|
|
9382
|
-
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
9383
|
-
default: {
|
|
9384
|
-
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
9385
|
-
try {
|
|
9386
|
-
new RegExp(m[1], m[2]);
|
|
9387
|
-
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
9388
|
-
} catch {
|
|
9389
|
-
}
|
|
9390
|
-
}
|
|
9391
|
-
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
9392
|
-
}
|
|
9393
|
-
}
|
|
9394
|
-
};
|
|
9395
10482
|
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
9396
|
-
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${
|
|
10483
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
9397
10484
|
}
|
|
9398
10485
|
`;
|
|
9399
10486
|
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
@@ -9401,33 +10488,43 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}
|
|
|
9401
10488
|
const m1 = tmp();
|
|
9402
10489
|
const m2 = tmp();
|
|
9403
10490
|
const routedCall = (target) => `{const savedRouted=ctx._routed
|
|
9404
|
-
${emitRollback(m1, L.buf, sinks)}
|
|
9405
|
-
${emitMark(m2, L.buf, sinks, false)}
|
|
10491
|
+
${emitRollback(m1, L.buf, L.raw, sinks)}
|
|
10492
|
+
${emitMark(m2, L.buf, L.raw, sinks, false)}
|
|
9406
10493
|
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
9407
10494
|
try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
|
|
9408
10495
|
break}`;
|
|
9409
10496
|
const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
|
|
9410
10497
|
const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
|
|
9411
10498
|
const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
|
|
10499
|
+
const armSelection = tokenChoiceDispatches.has(ip) ? `const tp=_pfTokDispatch===${ip}&&_pfTokInput===input&&_pfTokPos===pos
|
|
10500
|
+
let arm
|
|
10501
|
+
if(tp){
|
|
10502
|
+
arm=_pfTokArm
|
|
10503
|
+
_pfTokDispatch=-1
|
|
10504
|
+
_pfTokInput=undefined
|
|
10505
|
+
if(arm===${n})arm=undefined
|
|
10506
|
+
}else{
|
|
10507
|
+
arm=${bk}.get(key)
|
|
10508
|
+
${fold}${chain}}` : `let arm=${bk}.get(key)
|
|
10509
|
+
${fold}${chain}`;
|
|
9412
10510
|
return `${head}
|
|
9413
|
-
${emitMark(m1, L.buf, sinks)}
|
|
10511
|
+
${emitMark(m1, L.buf, L.raw, sinks)}
|
|
9414
10512
|
const sv=${selector}(input,pos,ctx)
|
|
9415
10513
|
if(sv===FAIL)return FAIL
|
|
9416
10514
|
const selEnd=EC.e
|
|
9417
10515
|
const key=sv
|
|
9418
|
-
|
|
9419
|
-
${fold}${chain}
|
|
10516
|
+
${armSelection}
|
|
9420
10517
|
if(arm===undefined){
|
|
9421
10518
|
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
|
|
9422
10519
|
}
|
|
9423
|
-
${emitMark(m2, L.buf, sinks)}
|
|
10520
|
+
${emitMark(m2, L.buf, L.raw, sinks)}
|
|
9424
10521
|
let v
|
|
9425
10522
|
switch(arm){
|
|
9426
10523
|
${armCases}
|
|
9427
10524
|
${fallbackCase}
|
|
9428
10525
|
}
|
|
9429
10526
|
if(v===FAIL){
|
|
9430
|
-
${emitRollback(m2, L.buf, sinks)}
|
|
10527
|
+
${emitRollback(m2, L.buf, L.raw, sinks)}
|
|
9431
10528
|
ctx._fc=true
|
|
9432
10529
|
return FAIL
|
|
9433
10530
|
}
|
|
@@ -9463,23 +10560,25 @@ return [key,v]
|
|
|
9463
10560
|
const skip = skipFor(L);
|
|
9464
10561
|
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
9465
10562
|
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
9466
|
-
const pfd = sinks.fd ? `${p}fd` : "
|
|
10563
|
+
const pfd = sinks.fd ? `${p}fd` : "undefined";
|
|
9467
10564
|
const per = sinks.er ? `${p}er` : "undefined";
|
|
9468
|
-
const
|
|
10565
|
+
const rbHelper = L.raw === RAW_OMIT ? "_rbNoRawBuf" : "_rbBuf";
|
|
10566
|
+
const rb = L.buf && L.raw !== 0 ? `${rbHelper}(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
9469
10567
|
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
9470
|
-
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
10568
|
+
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : L.buf ? `rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
9471
10569
|
const markSinks = `${sinks.fd ? `
|
|
9472
10570
|
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
9473
10571
|
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
10572
|
+
const markRaw = L.raw === RAW_OMIT ? `${p}raw=b.rawLen` : L.raw === RAW_CAPTURE ? `const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
9474
10573
|
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
9475
|
-
|
|
10574
|
+
${markRaw}
|
|
9476
10575
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
9477
10576
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
9478
10577
|
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
9479
10578
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
9480
10579
|
const b=ctx._cstBuf
|
|
9481
10580
|
if(b!==undefined){
|
|
9482
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
10581
|
+
const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
9483
10582
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
9484
10583
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
9485
10584
|
}else{
|
|
@@ -9586,7 +10685,7 @@ const leaf={_tag:'leaf',value,span:{start:pos,end}}
|
|
|
9586
10685
|
const kids=[leaf],rawKids=[leaf],span={start:pos,end}
|
|
9587
10686
|
EC.e=end
|
|
9588
10687
|
const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
|
|
9589
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
10688
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,ctx._cstBuf!==undefined&&ctx._cstBuf.noRaw===true?undefined:ctx._cstBuf!==undefined||ctx._cstRawChildren!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
9590
10689
|
EC.e=end
|
|
9591
10690
|
return nd
|
|
9592
10691
|
}`;
|
|
@@ -9608,7 +10707,22 @@ return nd
|
|
|
9608
10707
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
|
|
9609
10708
|
const fields = flags === 18;
|
|
9610
10709
|
const collapseChildren = flags === 34;
|
|
9611
|
-
const publish = `if(sBuf!==undefined){
|
|
10710
|
+
const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
|
|
10711
|
+
if(sBuf.rawOnly!==true){
|
|
10712
|
+
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
10713
|
+
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
10714
|
+
else sBuf.single=nd
|
|
10715
|
+
}
|
|
10716
|
+
const rawNd=rawEntry(nd,input,pos,end)
|
|
10717
|
+
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
10718
|
+
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
10719
|
+
else sBuf.rawSingle=rawNd
|
|
10720
|
+
}else if(sCh!==undefined){
|
|
10721
|
+
sCh.push(nd)
|
|
10722
|
+
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
10723
|
+
}` : `if(sBuf!==undefined){
|
|
10724
|
+
if(sBuf.noRaw===true)_pushNodeNoRawBuf(ctx,nd)
|
|
10725
|
+
else{
|
|
9612
10726
|
if(sBuf.rawOnly!==true){
|
|
9613
10727
|
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
9614
10728
|
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
@@ -9618,6 +10732,7 @@ const rawNd=rawEntry(nd,input,pos,end)
|
|
|
9618
10732
|
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
9619
10733
|
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
9620
10734
|
else sBuf.rawSingle=rawNd
|
|
10735
|
+
}
|
|
9621
10736
|
}else if(sCh!==undefined){
|
|
9622
10737
|
sCh.push(nd)
|
|
9623
10738
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
@@ -9656,6 +10771,7 @@ return nd
|
|
|
9656
10771
|
const wantFields = hasFields || hostCst;
|
|
9657
10772
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
9658
10773
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
10774
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
9659
10775
|
const ty = q(type);
|
|
9660
10776
|
const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
|
|
9661
10777
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
@@ -9669,7 +10785,12 @@ return nd
|
|
|
9669
10785
|
value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
|
|
9670
10786
|
}
|
|
9671
10787
|
const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
|
|
9672
|
-
const openCapture =
|
|
10788
|
+
const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
|
|
10789
|
+
ctx._cstBuf=buf
|
|
10790
|
+
ctx._cstChildren=undefined
|
|
10791
|
+
ctx._cstLeaves=undefined
|
|
10792
|
+
ctx._cstRawChildren=undefined
|
|
10793
|
+
ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
|
|
9673
10794
|
ctx._cstBuf=buf
|
|
9674
10795
|
ctx._cstChildren=undefined
|
|
9675
10796
|
ctx._cstLeaves=undefined
|
|
@@ -9680,7 +10801,10 @@ ctx._cstChildren=undefined
|
|
|
9680
10801
|
ctx._cstLeaves=undefined
|
|
9681
10802
|
ctx._cstRawChildren=undefined
|
|
9682
10803
|
ctx._cstTriviaLog=undefined`;
|
|
9683
|
-
const finishCapture =
|
|
10804
|
+
const finishCapture = omitsRaw ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
10805
|
+
const hostKids=kids
|
|
10806
|
+
const rawKids=EMPTY_CH
|
|
10807
|
+
const tlog=buf.tl??EMPTY_TLOG` : keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
9684
10808
|
const hostKids=kids
|
|
9685
10809
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
9686
10810
|
const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
@@ -9714,7 +10838,7 @@ const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):unde
|
|
|
9714
10838
|
let nd
|
|
9715
10839
|
${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]
|
|
9716
10840
|
else ` : ""}{${value}}
|
|
9717
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
10841
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,sBuf!==undefined?(sBuf.noRaw===true?undefined:rawEntry(nd,input,pos,end)):sRaw!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
9718
10842
|
EC.e=end
|
|
9719
10843
|
return nd
|
|
9720
10844
|
}`;
|
|
@@ -9732,7 +10856,7 @@ return nd
|
|
|
9732
10856
|
}
|
|
9733
10857
|
const extra = [];
|
|
9734
10858
|
for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
|
|
9735
|
-
const source = `${RUNTIME_PRELUDE}
|
|
10859
|
+
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
9736
10860
|
${prelude.join("\n")}
|
|
9737
10861
|
${skipDefs.join("\n")}
|
|
9738
10862
|
${choiceDefs.join("\n")}
|
|
@@ -9747,7 +10871,13 @@ _pfHost=host
|
|
|
9747
10871
|
function _finish(){
|
|
9748
10872
|
if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
|
|
9749
10873
|
_pfDepth--
|
|
9750
|
-
if(_pfDepth===0)
|
|
10874
|
+
if(_pfDepth===0){
|
|
10875
|
+
_pfTokInput=undefined
|
|
10876
|
+
_pfTokBody=-1
|
|
10877
|
+
_pfTokValue=undefined
|
|
10878
|
+
_pfTokDispatch=-1
|
|
10879
|
+
return
|
|
10880
|
+
}
|
|
9751
10881
|
const prior=_pfFrames.pop()
|
|
9752
10882
|
_pfScan=prior[0]
|
|
9753
10883
|
_pfHost=prior[1]
|
|
@@ -10109,6 +11239,17 @@ function assemble(t, prog, cfg) {
|
|
|
10109
11239
|
}
|
|
10110
11240
|
return recognize;
|
|
10111
11241
|
}
|
|
11242
|
+
const labelExtraIps = [];
|
|
11243
|
+
for (const s of prog.scans ?? []) {
|
|
11244
|
+
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
11245
|
+
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
11246
|
+
}
|
|
11247
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
11248
|
+
const closureLabels = computeSiteLabels(
|
|
11249
|
+
code,
|
|
11250
|
+
[...Object.values(prog.rules), ...labelExtraIps],
|
|
11251
|
+
hostCst
|
|
11252
|
+
);
|
|
10112
11253
|
let SCAN = null;
|
|
10113
11254
|
const memo = /* @__PURE__ */ new Map();
|
|
10114
11255
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -10154,12 +11295,12 @@ function assemble(t, prog, cfg) {
|
|
|
10154
11295
|
return node2;
|
|
10155
11296
|
};
|
|
10156
11297
|
}
|
|
10157
|
-
function capturedFlatChildren(
|
|
10158
|
-
if (
|
|
10159
|
-
if (
|
|
11298
|
+
function capturedFlatChildren(children3) {
|
|
11299
|
+
if (children3.length === 0) return EMPTY_CH;
|
|
11300
|
+
if (children3[0] !== void 0) return children3;
|
|
10160
11301
|
let first = 1;
|
|
10161
|
-
while (first <
|
|
10162
|
-
return first ===
|
|
11302
|
+
while (first < children3.length && children3[first] === void 0) first++;
|
|
11303
|
+
return first === children3.length ? EMPTY_CH : children3.slice(first);
|
|
10163
11304
|
}
|
|
10164
11305
|
function childrenOnlyBuildNode(child, build) {
|
|
10165
11306
|
return (input, pos, ctx) => {
|
|
@@ -10354,7 +11495,7 @@ function assemble(t, prog, cfg) {
|
|
|
10354
11495
|
const b = ctx._cstBuf;
|
|
10355
11496
|
if (b !== void 0) {
|
|
10356
11497
|
const raw = b.raw;
|
|
10357
|
-
MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
11498
|
+
MRAW = b.noRaw === true ? b.rawLen ?? 0 : raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
10358
11499
|
const ch2 = b.ch;
|
|
10359
11500
|
MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
|
|
10360
11501
|
const tl = b.tl;
|
|
@@ -10438,6 +11579,31 @@ function assemble(t, prog, cfg) {
|
|
|
10438
11579
|
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
10439
11580
|
return cur;
|
|
10440
11581
|
}
|
|
11582
|
+
function nextTermBuffered(child, input, cur, ctx) {
|
|
11583
|
+
if (ctx.trivia === void 0) {
|
|
11584
|
+
const v2 = child(input, cur, ctx);
|
|
11585
|
+
if (v2 === FAIL) return -1;
|
|
11586
|
+
TERMV = v2;
|
|
11587
|
+
return EC.e;
|
|
11588
|
+
}
|
|
11589
|
+
const before = ctx._cstBuf;
|
|
11590
|
+
const beforeTl = before.tl;
|
|
11591
|
+
const mTl = beforeTl === void 0 ? 0 : beforeTl.length;
|
|
11592
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
11593
|
+
const mRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
11594
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
11595
|
+
const scanned = ctx._cstBuf;
|
|
11596
|
+
const scannedTl = scanned.tl;
|
|
11597
|
+
const scanTl = scannedTl === void 0 ? 0 : scannedTl.length;
|
|
11598
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
11599
|
+
const scanRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
11600
|
+
const v = child(input, scanEnd, ctx);
|
|
11601
|
+
if (v === FAIL) return -1;
|
|
11602
|
+
TERMV = v;
|
|
11603
|
+
if (EC.e > scanEnd) return EC.e;
|
|
11604
|
+
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
11605
|
+
return cur;
|
|
11606
|
+
}
|
|
10441
11607
|
function committed3(c) {
|
|
10442
11608
|
return c._fc === true;
|
|
10443
11609
|
}
|
|
@@ -10708,7 +11874,8 @@ function assemble(t, prog, cfg) {
|
|
|
10708
11874
|
target = p;
|
|
10709
11875
|
} };
|
|
10710
11876
|
inFlight.set(ip, holder);
|
|
10711
|
-
const
|
|
11877
|
+
const op = code[ip];
|
|
11878
|
+
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);
|
|
10712
11879
|
inFlight.delete(ip);
|
|
10713
11880
|
holder.set(piece);
|
|
10714
11881
|
memo.set(ip, piece);
|
|
@@ -11160,11 +12327,11 @@ function assemble(t, prog, cfg) {
|
|
|
11160
12327
|
}
|
|
11161
12328
|
case OP_ROUTED: {
|
|
11162
12329
|
const fb = code[ip + 1];
|
|
11163
|
-
const
|
|
12330
|
+
const fallback2 = fb >= 0 ? link(fb) : void 0;
|
|
11164
12331
|
return (input, pos, ctx) => {
|
|
11165
12332
|
const item = ctx._routed;
|
|
11166
12333
|
if (item === void 0 || pos !== item.span.start) {
|
|
11167
|
-
if (
|
|
12334
|
+
if (fallback2 !== void 0) return fallback2(input, pos, ctx);
|
|
11168
12335
|
ctx._fe = pos;
|
|
11169
12336
|
ctx._fx = ROUTED_FX;
|
|
11170
12337
|
return FAIL;
|
|
@@ -11451,6 +12618,7 @@ function assemble(t, prog, cfg) {
|
|
|
11451
12618
|
const reducer = fused ? code[ip + 1] : -1;
|
|
11452
12619
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
11453
12620
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
12621
|
+
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
11454
12622
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
11455
12623
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
11456
12624
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -11505,7 +12673,7 @@ function assemble(t, prog, cfg) {
|
|
|
11505
12673
|
const kid = link(kidIp);
|
|
11506
12674
|
return (input, cur, ctx, inherited) => {
|
|
11507
12675
|
ctx._sync = sync ?? inherited;
|
|
11508
|
-
return
|
|
12676
|
+
return step(kid, input, cur, ctx);
|
|
11509
12677
|
};
|
|
11510
12678
|
}
|
|
11511
12679
|
const negated = code[kidIp + 1] === 1;
|
|
@@ -11590,7 +12758,7 @@ function assemble(t, prog, cfg) {
|
|
|
11590
12758
|
const kidIp = code[base + i];
|
|
11591
12759
|
if (code[kidIp] !== OP_ADJ) {
|
|
11592
12760
|
const kid = link(kidIp);
|
|
11593
|
-
return (input, cur, ctx) =>
|
|
12761
|
+
return (input, cur, ctx) => step(kid, input, cur, ctx);
|
|
11594
12762
|
}
|
|
11595
12763
|
const negated = code[kidIp + 1] === 1;
|
|
11596
12764
|
const ki = code[kidIp + 2];
|
|
@@ -11679,7 +12847,7 @@ function assemble(t, prog, cfg) {
|
|
|
11679
12847
|
return (input, pos, ctx) => {
|
|
11680
12848
|
const v0 = k0(input, pos, ctx);
|
|
11681
12849
|
if (v0 === FAIL) return FAIL;
|
|
11682
|
-
const cur =
|
|
12850
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11683
12851
|
if (cur < 0) return FAIL;
|
|
11684
12852
|
EC.e = cur;
|
|
11685
12853
|
return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
|
|
@@ -11689,7 +12857,7 @@ function assemble(t, prog, cfg) {
|
|
|
11689
12857
|
return (input, pos, ctx) => {
|
|
11690
12858
|
const v0 = k0(input, pos, ctx);
|
|
11691
12859
|
if (v0 === FAIL) return FAIL;
|
|
11692
|
-
const cur =
|
|
12860
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11693
12861
|
if (cur < 0) return FAIL;
|
|
11694
12862
|
EC.e = cur;
|
|
11695
12863
|
return [v0, TERMV];
|
|
@@ -11698,7 +12866,7 @@ function assemble(t, prog, cfg) {
|
|
|
11698
12866
|
return (input, pos, ctx) => {
|
|
11699
12867
|
const v0 = k0(input, pos, ctx);
|
|
11700
12868
|
if (v0 === FAIL) return FAIL;
|
|
11701
|
-
const cur =
|
|
12869
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
11702
12870
|
if (cur < 0) return FAIL;
|
|
11703
12871
|
EC.e = cur;
|
|
11704
12872
|
return void 0;
|
|
@@ -11710,10 +12878,10 @@ function assemble(t, prog, cfg) {
|
|
|
11710
12878
|
return (input, pos, ctx) => {
|
|
11711
12879
|
const v0 = k0(input, pos, ctx);
|
|
11712
12880
|
if (v0 === FAIL) return FAIL;
|
|
11713
|
-
let cur =
|
|
12881
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11714
12882
|
if (cur < 0) return FAIL;
|
|
11715
12883
|
const v1 = TERMV;
|
|
11716
|
-
cur =
|
|
12884
|
+
cur = step(k2, input, cur, ctx);
|
|
11717
12885
|
if (cur < 0) return FAIL;
|
|
11718
12886
|
EC.e = cur;
|
|
11719
12887
|
return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
|
|
@@ -11723,10 +12891,10 @@ function assemble(t, prog, cfg) {
|
|
|
11723
12891
|
return (input, pos, ctx) => {
|
|
11724
12892
|
const v0 = k0(input, pos, ctx);
|
|
11725
12893
|
if (v0 === FAIL) return FAIL;
|
|
11726
|
-
let cur =
|
|
12894
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11727
12895
|
if (cur < 0) return FAIL;
|
|
11728
12896
|
const v1 = TERMV;
|
|
11729
|
-
cur =
|
|
12897
|
+
cur = step(k2, input, cur, ctx);
|
|
11730
12898
|
if (cur < 0) return FAIL;
|
|
11731
12899
|
EC.e = cur;
|
|
11732
12900
|
return [v0, v1, TERMV];
|
|
@@ -11735,9 +12903,9 @@ function assemble(t, prog, cfg) {
|
|
|
11735
12903
|
return (input, pos, ctx) => {
|
|
11736
12904
|
const v0 = k0(input, pos, ctx);
|
|
11737
12905
|
if (v0 === FAIL) return FAIL;
|
|
11738
|
-
let cur =
|
|
12906
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
11739
12907
|
if (cur < 0) return FAIL;
|
|
11740
|
-
cur =
|
|
12908
|
+
cur = step(k2, input, cur, ctx);
|
|
11741
12909
|
if (cur < 0) return FAIL;
|
|
11742
12910
|
EC.e = cur;
|
|
11743
12911
|
return void 0;
|
|
@@ -11745,43 +12913,43 @@ function assemble(t, prog, cfg) {
|
|
|
11745
12913
|
}
|
|
11746
12914
|
const block = (count, k0, k1, k2, k3, next) => {
|
|
11747
12915
|
if (count === 1) return (input, cur, ctx, values) => {
|
|
11748
|
-
cur =
|
|
12916
|
+
cur = step(k0, input, cur, ctx);
|
|
11749
12917
|
if (cur < 0) return -1;
|
|
11750
12918
|
if (values !== void 0) values.push(TERMV);
|
|
11751
12919
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11752
12920
|
};
|
|
11753
12921
|
if (count === 2) return (input, cur, ctx, values) => {
|
|
11754
|
-
cur =
|
|
12922
|
+
cur = step(k0, input, cur, ctx);
|
|
11755
12923
|
if (cur < 0) return -1;
|
|
11756
12924
|
if (values !== void 0) values.push(TERMV);
|
|
11757
|
-
cur =
|
|
12925
|
+
cur = step(k1, input, cur, ctx);
|
|
11758
12926
|
if (cur < 0) return -1;
|
|
11759
12927
|
if (values !== void 0) values.push(TERMV);
|
|
11760
12928
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11761
12929
|
};
|
|
11762
12930
|
if (count === 3) return (input, cur, ctx, values) => {
|
|
11763
|
-
cur =
|
|
12931
|
+
cur = step(k0, input, cur, ctx);
|
|
11764
12932
|
if (cur < 0) return -1;
|
|
11765
12933
|
if (values !== void 0) values.push(TERMV);
|
|
11766
|
-
cur =
|
|
12934
|
+
cur = step(k1, input, cur, ctx);
|
|
11767
12935
|
if (cur < 0) return -1;
|
|
11768
12936
|
if (values !== void 0) values.push(TERMV);
|
|
11769
|
-
cur =
|
|
12937
|
+
cur = step(k2, input, cur, ctx);
|
|
11770
12938
|
if (cur < 0) return -1;
|
|
11771
12939
|
if (values !== void 0) values.push(TERMV);
|
|
11772
12940
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
11773
12941
|
};
|
|
11774
12942
|
return (input, cur, ctx, values) => {
|
|
11775
|
-
cur =
|
|
12943
|
+
cur = step(k0, input, cur, ctx);
|
|
11776
12944
|
if (cur < 0) return -1;
|
|
11777
12945
|
if (values !== void 0) values.push(TERMV);
|
|
11778
|
-
cur =
|
|
12946
|
+
cur = step(k1, input, cur, ctx);
|
|
11779
12947
|
if (cur < 0) return -1;
|
|
11780
12948
|
if (values !== void 0) values.push(TERMV);
|
|
11781
|
-
cur =
|
|
12949
|
+
cur = step(k2, input, cur, ctx);
|
|
11782
12950
|
if (cur < 0) return -1;
|
|
11783
12951
|
if (values !== void 0) values.push(TERMV);
|
|
11784
|
-
cur =
|
|
12952
|
+
cur = step(k3, input, cur, ctx);
|
|
11785
12953
|
if (cur < 0) return -1;
|
|
11786
12954
|
if (values !== void 0) values.push(TERMV);
|
|
11787
12955
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
@@ -11952,6 +13120,13 @@ function assemble(t, prog, cfg) {
|
|
|
11952
13120
|
if (n === 2 || n === 3) {
|
|
11953
13121
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
11954
13122
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
13123
|
+
const predecide = !hostCst && !REC2 && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
13124
|
+
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
13125
|
+
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
13126
|
+
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
13127
|
+
const p0 = p0ip < 0 ? void 0 : scalarFor(p0ip);
|
|
13128
|
+
const p1 = p1ip < 0 ? void 0 : scalarFor(p1ip);
|
|
13129
|
+
const p2 = p2ip < 0 ? void 0 : scalarFor(p2ip);
|
|
11955
13130
|
const e0 = fx[code[base + n]];
|
|
11956
13131
|
const e1 = fx[code[base + n + 1]];
|
|
11957
13132
|
const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
|
|
@@ -11981,7 +13156,10 @@ function assemble(t, prog, cfg) {
|
|
|
11981
13156
|
let acc;
|
|
11982
13157
|
let best = pos;
|
|
11983
13158
|
if (c < 128) {
|
|
11984
|
-
|
|
13159
|
+
let bits = mask[c < 0 ? 128 : c];
|
|
13160
|
+
if ((bits & 1) !== 0 && p0 !== void 0 && p0(input, pos) < 0) bits &= ~1;
|
|
13161
|
+
if ((bits & 2) !== 0 && p1 !== void 0 && p1(input, pos) < 0) bits &= ~2;
|
|
13162
|
+
if ((bits & 4) !== 0 && p2 !== void 0 && p2(input, pos) < 0) bits &= ~4;
|
|
11985
13163
|
let prev = 0;
|
|
11986
13164
|
if ((bits & 1) !== 0) {
|
|
11987
13165
|
ctx._fc = false;
|
|
@@ -12044,7 +13222,7 @@ function assemble(t, prog, cfg) {
|
|
|
12044
13222
|
ctx._fx = acc ?? choiceFx;
|
|
12045
13223
|
return FAIL;
|
|
12046
13224
|
}
|
|
12047
|
-
if (g0 === null || classHas2(g0, c)) {
|
|
13225
|
+
if ((g0 === null || classHas2(g0, c)) && (p0 === void 0 || p0(input, pos) >= 0)) {
|
|
12048
13226
|
ctx._fc = false;
|
|
12049
13227
|
const v = a0(input, pos, ctx);
|
|
12050
13228
|
if (v !== FAIL) return v;
|
|
@@ -12060,7 +13238,7 @@ function assemble(t, prog, cfg) {
|
|
|
12060
13238
|
}
|
|
12061
13239
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12062
13240
|
} else if (best === pos) acc = accSet(e0, acc);
|
|
12063
|
-
if (g1 === null || classHas2(g1, c)) {
|
|
13241
|
+
if ((g1 === null || classHas2(g1, c)) && (p1 === void 0 || p1(input, pos) >= 0)) {
|
|
12064
13242
|
ctx._fc = false;
|
|
12065
13243
|
const v = a1(input, pos, ctx);
|
|
12066
13244
|
if (v !== FAIL) return v;
|
|
@@ -12077,7 +13255,7 @@ function assemble(t, prog, cfg) {
|
|
|
12077
13255
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12078
13256
|
} else if (best === pos) acc = accSet(e1, acc);
|
|
12079
13257
|
if (n === 3) {
|
|
12080
|
-
if (g2 === null || classHas2(g2, c)) {
|
|
13258
|
+
if ((g2 === null || classHas2(g2, c)) && (p2 === void 0 || p2(input, pos) >= 0)) {
|
|
12081
13259
|
ctx._fc = false;
|
|
12082
13260
|
const v = a2(input, pos, ctx);
|
|
12083
13261
|
if (v !== FAIL) return v;
|
|
@@ -12650,20 +13828,14 @@ function assemble(t, prog, cfg) {
|
|
|
12650
13828
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
12651
13829
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
12652
13830
|
const rawOnly = !keepChildren;
|
|
13831
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
12653
13832
|
return (input, pos, ctx) => {
|
|
12654
13833
|
const host = HOST;
|
|
12655
13834
|
const sCh = ctx._cstChildren;
|
|
12656
|
-
const sLv = ctx._cstLeaves;
|
|
12657
|
-
const sRaw = ctx._cstRawChildren;
|
|
12658
|
-
const sTl = ctx._cstTriviaLog;
|
|
12659
13835
|
const sCap = ctx.captureTrivia;
|
|
12660
13836
|
const sBuf = ctx._cstBuf;
|
|
12661
|
-
const buf = rawOnly ? { rawOnly: true } : {};
|
|
13837
|
+
const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
|
|
12662
13838
|
ctx._cstBuf = buf;
|
|
12663
|
-
ctx._cstChildren = void 0;
|
|
12664
|
-
ctx._cstLeaves = void 0;
|
|
12665
|
-
ctx._cstRawChildren = void 0;
|
|
12666
|
-
ctx._cstTriviaLog = void 0;
|
|
12667
13839
|
ctx.captureTrivia = captureWide;
|
|
12668
13840
|
const savedFields = ctx._fields;
|
|
12669
13841
|
ctx._fields = wantFields ? [] : void 0;
|
|
@@ -12678,13 +13850,9 @@ function assemble(t, prog, cfg) {
|
|
|
12678
13850
|
if (structural) ctx._triviaCaptureMask = savedMask;
|
|
12679
13851
|
const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
12680
13852
|
const hostKids = kids;
|
|
12681
|
-
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
13853
|
+
const rawKids = omitsRaw ? EMPTY_CH : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
12682
13854
|
const tlog = buf.tl ?? EMPTY_TLOG;
|
|
12683
13855
|
ctx._cstBuf = sBuf;
|
|
12684
|
-
ctx._cstChildren = sCh;
|
|
12685
|
-
ctx._cstLeaves = sLv;
|
|
12686
|
-
ctx._cstRawChildren = sRaw;
|
|
12687
|
-
ctx._cstTriviaLog = sTl;
|
|
12688
13856
|
ctx.captureTrivia = sCap;
|
|
12689
13857
|
if (v === FAIL) return FAIL;
|
|
12690
13858
|
const end = EC.e;
|
|
@@ -12775,6 +13943,34 @@ function assemble(t, prog, cfg) {
|
|
|
12775
13943
|
rawScalarSpecs.add(code[child + 1]);
|
|
12776
13944
|
scalarFor(child);
|
|
12777
13945
|
}
|
|
13946
|
+
} else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]].exclusive) {
|
|
13947
|
+
const n = code[ip + 2];
|
|
13948
|
+
for (let i = 0; i < n; i++) {
|
|
13949
|
+
const armIp = code[ip + 4 + i];
|
|
13950
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
13951
|
+
if (n === 2 || n === 3) {
|
|
13952
|
+
if (child >= 0) scalarFor(child);
|
|
13953
|
+
continue;
|
|
13954
|
+
}
|
|
13955
|
+
if (child >= 0) {
|
|
13956
|
+
const spec = k[code[child + 1]];
|
|
13957
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
13958
|
+
scalarFor(child);
|
|
13959
|
+
continue;
|
|
13960
|
+
}
|
|
13961
|
+
}
|
|
13962
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
13963
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
13964
|
+
const value = k[code[terminal + 1]];
|
|
13965
|
+
return typeof value === "string" && value.length >= 2;
|
|
13966
|
+
})) {
|
|
13967
|
+
for (const terminal of family) scalarFor(terminal);
|
|
13968
|
+
}
|
|
13969
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
13970
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
|
|
13971
|
+
for (const terminal of sequence6.terminals) scalarFor(terminal);
|
|
13972
|
+
}
|
|
13973
|
+
}
|
|
12778
13974
|
}
|
|
12779
13975
|
}
|
|
12780
13976
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
@@ -13196,7 +14392,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
13196
14392
|
seen.add(key);
|
|
13197
14393
|
let em;
|
|
13198
14394
|
try {
|
|
13199
|
-
em = emitAssemblySource(t, prog, cfg, extraIps);
|
|
14395
|
+
em = emitAssemblySource(t, prog, cfg, extraIps, true);
|
|
13200
14396
|
} catch (e) {
|
|
13201
14397
|
if (e instanceof Unemittable) continue;
|
|
13202
14398
|
throw e;
|
|
@@ -13655,10 +14851,10 @@ function boundaryMatches(boundary, ch2) {
|
|
|
13655
14851
|
if (/\s/.test(ch2)) return true;
|
|
13656
14852
|
continue;
|
|
13657
14853
|
}
|
|
13658
|
-
const
|
|
13659
|
-
if (
|
|
14854
|
+
const range2 = /^(.|\\u[0-9a-f]{4})-(.|\\u[0-9a-f]{4})$/.exec(m);
|
|
14855
|
+
if (range2 !== null) {
|
|
13660
14856
|
const dec = (t) => t.startsWith("\\u") ? parseInt(t.slice(2), 16) : t.codePointAt(0);
|
|
13661
|
-
if (cp >= dec(
|
|
14857
|
+
if (cp >= dec(range2[1]) && cp <= dec(range2[2])) return true;
|
|
13662
14858
|
continue;
|
|
13663
14859
|
}
|
|
13664
14860
|
if (m === ch2) return true;
|
|
@@ -14732,7 +15928,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
14732
15928
|
};
|
|
14733
15929
|
const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
|
|
14734
15930
|
const artifact = closureArtifact(prog);
|
|
14735
|
-
const entry = tableRules(
|
|
15931
|
+
const entry = tableRules(prog)[ENTRY];
|
|
14736
15932
|
const offered = opts.fnSources ?? mapFnSources;
|
|
14737
15933
|
const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
|
|
14738
15934
|
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
|
|
@@ -14781,106 +15977,6 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
14781
15977
|
};
|
|
14782
15978
|
}
|
|
14783
15979
|
|
|
14784
|
-
// src/analysis/commitment.ts
|
|
14785
|
-
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
14786
|
-
if (seen.has(p)) return false;
|
|
14787
|
-
seen.add(p);
|
|
14788
|
-
const d = p._def;
|
|
14789
|
-
switch (d.tag) {
|
|
14790
|
-
case "node":
|
|
14791
|
-
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
14792
|
-
case "lazy": {
|
|
14793
|
-
try {
|
|
14794
|
-
return hasDirectBuildDef(d.thunk(), seen);
|
|
14795
|
-
} catch {
|
|
14796
|
-
return false;
|
|
14797
|
-
}
|
|
14798
|
-
}
|
|
14799
|
-
case "grammar":
|
|
14800
|
-
case "trivia":
|
|
14801
|
-
case "token":
|
|
14802
|
-
case "leaf":
|
|
14803
|
-
case "label":
|
|
14804
|
-
case "field":
|
|
14805
|
-
case "optional":
|
|
14806
|
-
case "many":
|
|
14807
|
-
case "oneOrMore":
|
|
14808
|
-
case "attempt":
|
|
14809
|
-
case "not":
|
|
14810
|
-
case "peek":
|
|
14811
|
-
case "withCtx":
|
|
14812
|
-
case "expect":
|
|
14813
|
-
case "transform":
|
|
14814
|
-
return hasDirectBuildDef(d.parser, seen);
|
|
14815
|
-
case "sequence":
|
|
14816
|
-
case "choice":
|
|
14817
|
-
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
14818
|
-
case "dispatch":
|
|
14819
|
-
return hasDirectBuildDef(d.selector, seen) || d.cases.some((x) => hasDirectBuildDef(x.parser, seen)) || (d.matchers ? d.matchers.some((x) => hasDirectBuildDef(x.parser, seen)) : false) || (d.otherwise ? hasDirectBuildDef(d.otherwise, seen) : false);
|
|
14820
|
-
case "sepBy":
|
|
14821
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
14822
|
-
case "scanTo":
|
|
14823
|
-
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
|
|
14824
|
-
case "recover":
|
|
14825
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
14826
|
-
case "routed":
|
|
14827
|
-
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
14828
|
-
default:
|
|
14829
|
-
return false;
|
|
14830
|
-
}
|
|
14831
|
-
}
|
|
14832
|
-
function hasSemanticReduction(roots, externalRefs) {
|
|
14833
|
-
const seen = /* @__PURE__ */ new Set();
|
|
14834
|
-
const visit = (parser2) => {
|
|
14835
|
-
if (seen.has(parser2)) return false;
|
|
14836
|
-
seen.add(parser2);
|
|
14837
|
-
const def = parser2._def;
|
|
14838
|
-
if (def.tag === "transform" && !def.recognitionOnly) return true;
|
|
14839
|
-
if (def.tag === "choice" && def.gates.some(Boolean)) return true;
|
|
14840
|
-
if (def.tag === "guard" || def.tag === "withCtx") return true;
|
|
14841
|
-
if (def.tag === "node" && def.build !== void 0) return true;
|
|
14842
|
-
if (def.tag === "lazy") {
|
|
14843
|
-
if (externalRefs?.has(parser2)) return false;
|
|
14844
|
-
try {
|
|
14845
|
-
return visit(def.thunk());
|
|
14846
|
-
} catch {
|
|
14847
|
-
return true;
|
|
14848
|
-
}
|
|
14849
|
-
}
|
|
14850
|
-
return childrenOf2(def).some(visit);
|
|
14851
|
-
};
|
|
14852
|
-
return roots.some(visit);
|
|
14853
|
-
}
|
|
14854
|
-
function classifyRuleMap(ruleMap) {
|
|
14855
|
-
const externalRefs = /* @__PURE__ */ new Set();
|
|
14856
|
-
const scanned = /* @__PURE__ */ new Set();
|
|
14857
|
-
const scanExternal = (p) => {
|
|
14858
|
-
if (scanned.has(p)) return;
|
|
14859
|
-
scanned.add(p);
|
|
14860
|
-
const def = p._def;
|
|
14861
|
-
if (def.tag === "lazy") {
|
|
14862
|
-
let resolved;
|
|
14863
|
-
try {
|
|
14864
|
-
resolved = def.thunk();
|
|
14865
|
-
} catch {
|
|
14866
|
-
resolved = void 0;
|
|
14867
|
-
}
|
|
14868
|
-
if (resolved === void 0) {
|
|
14869
|
-
if (p._ruleName) externalRefs.add(p);
|
|
14870
|
-
return;
|
|
14871
|
-
}
|
|
14872
|
-
scanExternal(resolved);
|
|
14873
|
-
return;
|
|
14874
|
-
}
|
|
14875
|
-
for (const child of childrenOf2(def)) scanExternal(child);
|
|
14876
|
-
};
|
|
14877
|
-
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
14878
|
-
return {
|
|
14879
|
-
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
14880
|
-
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs)
|
|
14881
|
-
};
|
|
14882
|
-
}
|
|
14883
|
-
|
|
14884
15980
|
// src/combinators/withCtx.ts
|
|
14885
15981
|
function withCtx(extra, combinator) {
|
|
14886
15982
|
const meta = {
|
|
@@ -15023,7 +16119,7 @@ function evalRuleMapIR(ir) {
|
|
|
15023
16119
|
l._def.fnSrc = src;
|
|
15024
16120
|
return l;
|
|
15025
16121
|
};
|
|
15026
|
-
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports) => {
|
|
16122
|
+
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
15027
16123
|
if (staticError !== void 0 && staticError.length > 0) {
|
|
15028
16124
|
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
15029
16125
|
}
|
|
@@ -15033,6 +16129,7 @@ function evalRuleMapIR(ir) {
|
|
|
15033
16129
|
n._def.buildSrc = src;
|
|
15034
16130
|
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
15035
16131
|
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
16132
|
+
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
15036
16133
|
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
15037
16134
|
return n;
|
|
15038
16135
|
};
|
|
@@ -15425,12 +16522,13 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
15425
16522
|
}
|
|
15426
16523
|
if (def.buildSrc !== void 0) {
|
|
15427
16524
|
const tail = [];
|
|
15428
|
-
if (def.buildStaticError !== void 0 || def.buildSigSrc !== void 0 || def.buildImports !== void 0) {
|
|
16525
|
+
if (def.buildStaticError !== void 0 || def.buildSigSrc !== void 0 || def.buildImports !== void 0 || def.buildRawUnused === true) {
|
|
15429
16526
|
if (!opts) tail.push("undefined");
|
|
15430
16527
|
tail.push(def.buildStaticError === void 0 ? "undefined" : JSON.stringify(def.buildStaticError));
|
|
15431
16528
|
}
|
|
15432
|
-
if (def.buildSigSrc !== void 0 || def.buildImports !== void 0) tail.push(def.buildSigSrc === void 0 ? "undefined" : JSON.stringify(def.buildSigSrc));
|
|
15433
|
-
if (def.buildImports !== void 0) tail.push(JSON.stringify(def.buildImports));
|
|
16529
|
+
if (def.buildSigSrc !== void 0 || def.buildImports !== void 0 || def.buildRawUnused === true) tail.push(def.buildSigSrc === void 0 ? "undefined" : JSON.stringify(def.buildSigSrc));
|
|
16530
|
+
if (def.buildImports !== void 0 || def.buildRawUnused === true) tail.push(def.buildImports === void 0 ? "undefined" : JSON.stringify(def.buildImports));
|
|
16531
|
+
if (def.buildRawUnused === true) tail.push("true");
|
|
15434
16532
|
const trailing = tail.length > 0 ? `, ${tail.join(", ")}` : "";
|
|
15435
16533
|
return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts}${trailing})`;
|
|
15436
16534
|
}
|
|
@@ -15499,7 +16597,7 @@ function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
|
15499
16597
|
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
15500
16598
|
reflection: collectGrammarReflection(ruleMap),
|
|
15501
16599
|
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
15502
|
-
rules: tableRules(
|
|
16600
|
+
rules: tableRules(prog),
|
|
15503
16601
|
prog: artifact
|
|
15504
16602
|
};
|
|
15505
16603
|
}
|
|
@@ -15571,13 +16669,13 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
15571
16669
|
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
15572
16670
|
reflection: collectGrammarReflection(ruleMap),
|
|
15573
16671
|
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
15574
|
-
rules: tableRules(
|
|
16672
|
+
rules: tableRules(prog),
|
|
15575
16673
|
prog: artifact
|
|
15576
16674
|
};
|
|
15577
16675
|
}
|
|
15578
16676
|
|
|
15579
16677
|
// src/version.ts
|
|
15580
|
-
var PARSEMAN_VERSION = "0.
|
|
16678
|
+
var PARSEMAN_VERSION = "0.50.0";
|
|
15581
16679
|
|
|
15582
16680
|
// src/compiler/compile-linkable-table.ts
|
|
15583
16681
|
function isLocal(rule) {
|
|
@@ -15653,16 +16751,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
15653
16751
|
}
|
|
15654
16752
|
return typeof collapse === "function" ? collapse : void 0;
|
|
15655
16753
|
}
|
|
15656
|
-
function buildCstNode(type,
|
|
15657
|
-
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...
|
|
16754
|
+
function buildCstNode(type, children3, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
16755
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children3] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children3] };
|
|
15658
16756
|
}
|
|
15659
|
-
function cstBuildHost(typeOrOptions,
|
|
16757
|
+
function cstBuildHost(typeOrOptions, children3, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
15660
16758
|
if (typeof typeOrOptions === "string") {
|
|
15661
|
-
return buildCstNode(typeOrOptions,
|
|
16759
|
+
return buildCstNode(typeOrOptions, children3 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
15662
16760
|
}
|
|
15663
16761
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
15664
16762
|
const materializeTags = typeOrOptions?.tags === true;
|
|
15665
|
-
const host = (type,
|
|
16763
|
+
const host = (type, children4, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children4 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
15666
16764
|
host._parsemanCstOutput = true;
|
|
15667
16765
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
15668
16766
|
return host;
|
|
@@ -15818,39 +16916,39 @@ function directBuilderBindings(src) {
|
|
|
15818
16916
|
if (selfName?.type === "Identifier" && typeof selfName.name === "string") allowed.add(selfName.name);
|
|
15819
16917
|
const structural = /* @__PURE__ */ new Set();
|
|
15820
16918
|
const free = /* @__PURE__ */ new Set();
|
|
15821
|
-
const reportUnsupportedNode = (
|
|
15822
|
-
structural.add(`unsupported ${
|
|
16919
|
+
const reportUnsupportedNode = (ast2) => {
|
|
16920
|
+
structural.add(`unsupported ${ast2.type}`);
|
|
15823
16921
|
};
|
|
15824
|
-
const read = (
|
|
15825
|
-
if (typeof
|
|
15826
|
-
if (
|
|
16922
|
+
const read = (ast2, allowedNames) => {
|
|
16923
|
+
if (typeof ast2.name === "string" && allowedNames.has(ast2.name)) return;
|
|
16924
|
+
if (ast2.name === "arguments") {
|
|
15827
16925
|
structural.add("unsupported arguments");
|
|
15828
16926
|
return;
|
|
15829
16927
|
}
|
|
15830
|
-
if (typeof
|
|
16928
|
+
if (typeof ast2.name === "string") free.add(ast2.name);
|
|
15831
16929
|
else structural.add("unsupported identifier");
|
|
15832
16930
|
};
|
|
15833
16931
|
const expression = (node2, allowedNames) => {
|
|
15834
|
-
const
|
|
15835
|
-
if (!
|
|
15836
|
-
switch (
|
|
16932
|
+
const ast2 = astChild(node2);
|
|
16933
|
+
if (!ast2) return;
|
|
16934
|
+
switch (ast2.type) {
|
|
15837
16935
|
case "Literal":
|
|
15838
16936
|
return;
|
|
15839
16937
|
case "Identifier":
|
|
15840
|
-
read(
|
|
16938
|
+
read(ast2, allowedNames);
|
|
15841
16939
|
return;
|
|
15842
16940
|
case "ParenthesizedExpression":
|
|
15843
16941
|
case "ChainExpression":
|
|
15844
16942
|
case "TSAsExpression":
|
|
15845
16943
|
case "TSTypeAssertion":
|
|
15846
16944
|
case "TSNonNullExpression":
|
|
15847
|
-
expression(
|
|
16945
|
+
expression(ast2.expression, allowedNames);
|
|
15848
16946
|
return;
|
|
15849
16947
|
case "ArrayExpression":
|
|
15850
|
-
for (const element of astArray(
|
|
16948
|
+
for (const element of astArray(ast2.elements)) expression(element, allowedNames);
|
|
15851
16949
|
return;
|
|
15852
16950
|
case "ObjectExpression":
|
|
15853
|
-
for (const property of astArray(
|
|
16951
|
+
for (const property of astArray(ast2.properties)) {
|
|
15854
16952
|
if (property.type === "SpreadElement") {
|
|
15855
16953
|
expression(property.argument, allowedNames);
|
|
15856
16954
|
continue;
|
|
@@ -15864,109 +16962,109 @@ function directBuilderBindings(src) {
|
|
|
15864
16962
|
}
|
|
15865
16963
|
return;
|
|
15866
16964
|
case "MemberExpression":
|
|
15867
|
-
expression(
|
|
15868
|
-
if (
|
|
16965
|
+
expression(ast2.object, allowedNames);
|
|
16966
|
+
if (ast2.computed === true) expression(ast2.property, allowedNames);
|
|
15869
16967
|
return;
|
|
15870
16968
|
case "CallExpression":
|
|
15871
16969
|
case "NewExpression":
|
|
15872
|
-
expression(
|
|
15873
|
-
for (const argument of astArray(
|
|
16970
|
+
expression(ast2.callee, allowedNames);
|
|
16971
|
+
for (const argument of astArray(ast2.arguments)) expression(argument, allowedNames);
|
|
15874
16972
|
return;
|
|
15875
16973
|
case "UnaryExpression":
|
|
15876
16974
|
case "UpdateExpression":
|
|
15877
|
-
expression(
|
|
16975
|
+
expression(ast2.argument, allowedNames);
|
|
15878
16976
|
return;
|
|
15879
16977
|
case "BinaryExpression":
|
|
15880
16978
|
case "LogicalExpression":
|
|
15881
16979
|
case "AssignmentExpression":
|
|
15882
|
-
expression(
|
|
15883
|
-
expression(
|
|
16980
|
+
expression(ast2.left, allowedNames);
|
|
16981
|
+
expression(ast2.right, allowedNames);
|
|
15884
16982
|
return;
|
|
15885
16983
|
case "ConditionalExpression":
|
|
15886
|
-
expression(
|
|
15887
|
-
expression(
|
|
15888
|
-
expression(
|
|
16984
|
+
expression(ast2.test, allowedNames);
|
|
16985
|
+
expression(ast2.consequent, allowedNames);
|
|
16986
|
+
expression(ast2.alternate, allowedNames);
|
|
15889
16987
|
return;
|
|
15890
16988
|
case "SequenceExpression":
|
|
15891
|
-
for (const value of astArray(
|
|
16989
|
+
for (const value of astArray(ast2.expressions)) expression(value, allowedNames);
|
|
15892
16990
|
return;
|
|
15893
16991
|
case "TemplateLiteral":
|
|
15894
|
-
for (const value of astArray(
|
|
16992
|
+
for (const value of astArray(ast2.expressions)) expression(value, allowedNames);
|
|
15895
16993
|
return;
|
|
15896
16994
|
case "SpreadElement":
|
|
15897
|
-
expression(
|
|
16995
|
+
expression(ast2.argument, allowedNames);
|
|
15898
16996
|
return;
|
|
15899
16997
|
case "ArrowFunctionExpression": {
|
|
15900
16998
|
const nested = new Set(allowedNames);
|
|
15901
|
-
for (const param of astArray(
|
|
16999
|
+
for (const param of astArray(ast2.params)) {
|
|
15902
17000
|
if (param.type !== "Identifier" || typeof param.name !== "string") {
|
|
15903
17001
|
reportUnsupportedNode(param);
|
|
15904
17002
|
continue;
|
|
15905
17003
|
}
|
|
15906
17004
|
nested.add(param.name);
|
|
15907
17005
|
}
|
|
15908
|
-
const nestedBody = astChild(
|
|
17006
|
+
const nestedBody = astChild(ast2.body);
|
|
15909
17007
|
if (nestedBody?.type === "BlockStatement") {
|
|
15910
17008
|
statement(nestedBody, nested);
|
|
15911
17009
|
return;
|
|
15912
17010
|
}
|
|
15913
|
-
expression(
|
|
17011
|
+
expression(ast2.body, nested);
|
|
15914
17012
|
return;
|
|
15915
17013
|
}
|
|
15916
17014
|
default:
|
|
15917
|
-
reportUnsupportedNode(
|
|
17015
|
+
reportUnsupportedNode(ast2);
|
|
15918
17016
|
return;
|
|
15919
17017
|
}
|
|
15920
17018
|
};
|
|
15921
17019
|
const statement = (node2, names) => {
|
|
15922
|
-
const
|
|
15923
|
-
if (!
|
|
15924
|
-
switch (
|
|
17020
|
+
const ast2 = astChild(node2);
|
|
17021
|
+
if (!ast2) return;
|
|
17022
|
+
switch (ast2.type) {
|
|
15925
17023
|
case "VariableDeclaration":
|
|
15926
|
-
for (const d of astArray(
|
|
17024
|
+
for (const d of astArray(ast2.declarations)) {
|
|
15927
17025
|
expression(d.init, names);
|
|
15928
17026
|
const idAst = astChild(d.id);
|
|
15929
17027
|
if (idAst?.type === "Identifier" && typeof idAst.name === "string") names.add(idAst.name);
|
|
15930
|
-
else reportUnsupportedNode(idAst ??
|
|
17028
|
+
else reportUnsupportedNode(idAst ?? ast2);
|
|
15931
17029
|
}
|
|
15932
17030
|
return;
|
|
15933
17031
|
case "ReturnStatement":
|
|
15934
|
-
expression(
|
|
17032
|
+
expression(ast2.argument, names);
|
|
15935
17033
|
return;
|
|
15936
17034
|
case "ExpressionStatement":
|
|
15937
|
-
expression(
|
|
17035
|
+
expression(ast2.expression, names);
|
|
15938
17036
|
return;
|
|
15939
17037
|
case "ThrowStatement":
|
|
15940
|
-
expression(
|
|
17038
|
+
expression(ast2.argument, names);
|
|
15941
17039
|
return;
|
|
15942
17040
|
case "IfStatement":
|
|
15943
|
-
expression(
|
|
15944
|
-
statement(
|
|
15945
|
-
if (
|
|
17041
|
+
expression(ast2.test, names);
|
|
17042
|
+
statement(ast2.consequent, new Set(names));
|
|
17043
|
+
if (ast2.alternate) statement(ast2.alternate, new Set(names));
|
|
15946
17044
|
return;
|
|
15947
17045
|
case "ForStatement": {
|
|
15948
17046
|
const inner = new Set(names);
|
|
15949
|
-
if (
|
|
15950
|
-
const initAst = astChild(
|
|
17047
|
+
if (ast2.init) {
|
|
17048
|
+
const initAst = astChild(ast2.init);
|
|
15951
17049
|
if (initAst?.type === "VariableDeclaration") statement(initAst, inner);
|
|
15952
17050
|
else expression(initAst, inner);
|
|
15953
17051
|
}
|
|
15954
|
-
if (
|
|
15955
|
-
if (
|
|
15956
|
-
statement(
|
|
17052
|
+
if (ast2.test) expression(ast2.test, inner);
|
|
17053
|
+
if (ast2.update) expression(ast2.update, inner);
|
|
17054
|
+
statement(ast2.body, inner);
|
|
15957
17055
|
return;
|
|
15958
17056
|
}
|
|
15959
17057
|
case "ForOfStatement":
|
|
15960
17058
|
case "ForInStatement": {
|
|
15961
17059
|
const inner = new Set(names);
|
|
15962
|
-
statement(
|
|
15963
|
-
expression(
|
|
15964
|
-
statement(
|
|
17060
|
+
statement(ast2.left, inner);
|
|
17061
|
+
expression(ast2.right, names);
|
|
17062
|
+
statement(ast2.body, inner);
|
|
15965
17063
|
return;
|
|
15966
17064
|
}
|
|
15967
17065
|
case "BlockStatement": {
|
|
15968
17066
|
const inner = new Set(names);
|
|
15969
|
-
for (const s of astArray(
|
|
17067
|
+
for (const s of astArray(ast2.body)) statement(s, inner);
|
|
15970
17068
|
return;
|
|
15971
17069
|
}
|
|
15972
17070
|
case "BreakStatement":
|
|
@@ -15974,7 +17072,7 @@ function directBuilderBindings(src) {
|
|
|
15974
17072
|
case "EmptyStatement":
|
|
15975
17073
|
return;
|
|
15976
17074
|
default:
|
|
15977
|
-
reportUnsupportedNode(
|
|
17075
|
+
reportUnsupportedNode(ast2);
|
|
15978
17076
|
return;
|
|
15979
17077
|
}
|
|
15980
17078
|
};
|
|
@@ -16413,6 +17511,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
16413
17511
|
try {
|
|
16414
17512
|
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
16415
17513
|
if (combi._def.tag === "node" && buildSrc !== void 0) {
|
|
17514
|
+
const authorDeclaredBuildArity = opts?.buildArity !== void 0;
|
|
16416
17515
|
combi._def.buildSrc = buildSrc;
|
|
16417
17516
|
if (explicitType !== void 0 && firstArg.type === "Identifier") {
|
|
16418
17517
|
combi._def.typeSrc = firstArg.name;
|
|
@@ -16427,6 +17526,9 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
16427
17526
|
if (resolved.reason !== void 0) combi._def.buildArityUnresolved = resolved.reason;
|
|
16428
17527
|
}
|
|
16429
17528
|
const analysisSrc = combi._def.buildSigSrc ?? buildSrc;
|
|
17529
|
+
if (!authorDeclaredBuildArity && confirmedBuildParamUnused(analysisSrc, 3)) {
|
|
17530
|
+
combi._def.buildRawUnused = true;
|
|
17531
|
+
}
|
|
16430
17532
|
const report = directBuilderBindings(analysisSrc);
|
|
16431
17533
|
const isInlineBuilder = combi._def.buildSigSrc === void 0;
|
|
16432
17534
|
const carriedImports = [];
|
|
@@ -16980,8 +18082,8 @@ var SCOPE_TYPES = /* @__PURE__ */ new Set([
|
|
|
16980
18082
|
"ClassExpression",
|
|
16981
18083
|
"StaticBlock"
|
|
16982
18084
|
]);
|
|
16983
|
-
function newScope(start, end, parent,
|
|
16984
|
-
const s = { start, end, bindings: /* @__PURE__ */ new Map(), children: [], parent, isFunction };
|
|
18085
|
+
function newScope(start, end, parent, isFunction2) {
|
|
18086
|
+
const s = { start, end, bindings: /* @__PURE__ */ new Map(), children: [], parent, isFunction: isFunction2 };
|
|
16985
18087
|
parent?.children.push(s);
|
|
16986
18088
|
return s;
|
|
16987
18089
|
}
|
|
@@ -17567,6 +18669,456 @@ function findFreeIdentifiers(code, filename) {
|
|
|
17567
18669
|
}).map(({ name, line, column, enclosing }) => ({ name, line, column, enclosing }));
|
|
17568
18670
|
}
|
|
17569
18671
|
|
|
18672
|
+
// src/plugin/entry-supercompiler.ts
|
|
18673
|
+
import { parseSync as parseSync4 } from "oxc-parser";
|
|
18674
|
+
var PIECE = /^_pf(\d+)$/;
|
|
18675
|
+
var WRAP = "function __parseman_supercompile__(){\n";
|
|
18676
|
+
var SUFFIX = "\n}";
|
|
18677
|
+
function ast(value) {
|
|
18678
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
18679
|
+
}
|
|
18680
|
+
function nodes(value) {
|
|
18681
|
+
return Array.isArray(value) ? value.filter((v) => ast(v) !== void 0) : [];
|
|
18682
|
+
}
|
|
18683
|
+
function nameOf(node2) {
|
|
18684
|
+
return node2?.type === "Identifier" && typeof node2.name === "string" ? node2.name : void 0;
|
|
18685
|
+
}
|
|
18686
|
+
function range(node2) {
|
|
18687
|
+
if (typeof node2.start !== "number" || typeof node2.end !== "number") throw new Error("entry supercompiler: AST node without range");
|
|
18688
|
+
return { start: node2.start - WRAP.length, end: node2.end - WRAP.length };
|
|
18689
|
+
}
|
|
18690
|
+
function children2(node2) {
|
|
18691
|
+
const out = [];
|
|
18692
|
+
for (const [key, value] of Object.entries(node2)) {
|
|
18693
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
18694
|
+
if (Array.isArray(value)) {
|
|
18695
|
+
for (const child of value) {
|
|
18696
|
+
const c = ast(child);
|
|
18697
|
+
if (c !== void 0) out.push(c);
|
|
18698
|
+
}
|
|
18699
|
+
} else {
|
|
18700
|
+
const c = ast(value);
|
|
18701
|
+
if (c !== void 0) out.push(c);
|
|
18702
|
+
}
|
|
18703
|
+
}
|
|
18704
|
+
return out;
|
|
18705
|
+
}
|
|
18706
|
+
function isFunction(node2) {
|
|
18707
|
+
return node2.type === "FunctionDeclaration" || node2.type === "FunctionExpression" || node2.type === "ArrowFunctionExpression";
|
|
18708
|
+
}
|
|
18709
|
+
function isDirectCallUse(call, parent, statement) {
|
|
18710
|
+
if (parent === void 0) return false;
|
|
18711
|
+
if (parent.type === "VariableDeclarator") {
|
|
18712
|
+
const declarations = statement.type === "VariableDeclaration" ? nodes(statement.declarations) : [];
|
|
18713
|
+
return declarations.length === 1 && declarations[0] === parent && parent.init === call;
|
|
18714
|
+
}
|
|
18715
|
+
if (parent.type === "AssignmentExpression") {
|
|
18716
|
+
return statement.type === "ExpressionStatement" && statement.expression === parent && nameOf(ast(parent.left)) !== void 0 && parent.right === call && parent.operator === "=";
|
|
18717
|
+
}
|
|
18718
|
+
if (parent.type === "ReturnStatement") return statement === parent && parent.argument === call;
|
|
18719
|
+
return false;
|
|
18720
|
+
}
|
|
18721
|
+
function isListStatement(statement, parent) {
|
|
18722
|
+
if (parent?.type === "BlockStatement") return nodes(parent.body).includes(statement);
|
|
18723
|
+
if (parent?.type === "SwitchCase") return nodes(parent.consequent).includes(statement);
|
|
18724
|
+
return false;
|
|
18725
|
+
}
|
|
18726
|
+
function hasInlineScopeHazard(fn) {
|
|
18727
|
+
if (fn.node.async === true || fn.node.generator === true) return true;
|
|
18728
|
+
let hazard = false;
|
|
18729
|
+
const walk = (node2) => {
|
|
18730
|
+
if (hazard) return;
|
|
18731
|
+
if (node2.type === "Identifier" && node2.name === "arguments") hazard = true;
|
|
18732
|
+
else if (node2.type === "ThisExpression") hazard = true;
|
|
18733
|
+
else if (node2.type === "VariableDeclaration" && node2.kind === "var") hazard = true;
|
|
18734
|
+
else if (node2.type === "MetaProperty" && nameOf(ast(node2.meta)) === "new" && nameOf(ast(node2.property)) === "target") hazard = true;
|
|
18735
|
+
else for (const child of children2(node2)) walk(child);
|
|
18736
|
+
};
|
|
18737
|
+
walk(fn.body);
|
|
18738
|
+
return hazard;
|
|
18739
|
+
}
|
|
18740
|
+
function hasInlineSignature(fn) {
|
|
18741
|
+
const params = nodes(fn.node.params);
|
|
18742
|
+
return params.length === 3 && nameOf(params[0]) === "input" && nameOf(params[1]) === "pos" && nameOf(params[2]) === "ctx";
|
|
18743
|
+
}
|
|
18744
|
+
function render2(source, start, end, edits) {
|
|
18745
|
+
const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
18746
|
+
let at = start;
|
|
18747
|
+
let out = "";
|
|
18748
|
+
for (const edit of ordered) {
|
|
18749
|
+
if (edit.start < at || edit.end < edit.start || edit.start < start || edit.end > end) {
|
|
18750
|
+
throw new Error("entry supercompiler: overlapping or out-of-range structured edit");
|
|
18751
|
+
}
|
|
18752
|
+
out += source.slice(at, edit.start) + edit.text;
|
|
18753
|
+
at = edit.end;
|
|
18754
|
+
}
|
|
18755
|
+
return out + source.slice(at, end);
|
|
18756
|
+
}
|
|
18757
|
+
function recursiveMembers(fns) {
|
|
18758
|
+
let next = 0;
|
|
18759
|
+
const index = /* @__PURE__ */ new Map();
|
|
18760
|
+
const low = /* @__PURE__ */ new Map();
|
|
18761
|
+
const stack = [];
|
|
18762
|
+
const on = /* @__PURE__ */ new Set();
|
|
18763
|
+
const recursive = /* @__PURE__ */ new Set();
|
|
18764
|
+
const visit = (ip) => {
|
|
18765
|
+
index.set(ip, next);
|
|
18766
|
+
low.set(ip, next);
|
|
18767
|
+
next++;
|
|
18768
|
+
stack.push(ip);
|
|
18769
|
+
on.add(ip);
|
|
18770
|
+
for (const call of fns.get(ip)?.calls ?? []) {
|
|
18771
|
+
if (!fns.has(call.callee)) continue;
|
|
18772
|
+
if (!index.has(call.callee)) {
|
|
18773
|
+
visit(call.callee);
|
|
18774
|
+
low.set(ip, Math.min(low.get(ip), low.get(call.callee)));
|
|
18775
|
+
} else if (on.has(call.callee)) low.set(ip, Math.min(low.get(ip), index.get(call.callee)));
|
|
18776
|
+
}
|
|
18777
|
+
if (low.get(ip) !== index.get(ip)) return;
|
|
18778
|
+
const component = [];
|
|
18779
|
+
for (; ; ) {
|
|
18780
|
+
const member = stack.pop();
|
|
18781
|
+
on.delete(member);
|
|
18782
|
+
component.push(member);
|
|
18783
|
+
if (member === ip) break;
|
|
18784
|
+
}
|
|
18785
|
+
if (component.length > 1 || component.some((member) => fns.get(member).calls.some((c) => c.callee === member))) {
|
|
18786
|
+
for (const member of component) recursive.add(member);
|
|
18787
|
+
}
|
|
18788
|
+
};
|
|
18789
|
+
for (const ip of fns.keys()) if (!index.has(ip)) visit(ip);
|
|
18790
|
+
return recursive;
|
|
18791
|
+
}
|
|
18792
|
+
function fallback(emitted, reason, before) {
|
|
18793
|
+
return {
|
|
18794
|
+
...emitted,
|
|
18795
|
+
supercompile: {
|
|
18796
|
+
...before,
|
|
18797
|
+
activated: false,
|
|
18798
|
+
reason,
|
|
18799
|
+
functionsAfter: before.functionsBefore,
|
|
18800
|
+
pieceCallsAfter: before.pieceCallsBefore,
|
|
18801
|
+
sourceAfter: before.sourceBefore,
|
|
18802
|
+
regions: before.functionsBefore,
|
|
18803
|
+
largestRegionSource: 0,
|
|
18804
|
+
protocolRegions: { node: 0, repv: 0, nodeAndRepv: 0 }
|
|
18805
|
+
}
|
|
18806
|
+
};
|
|
18807
|
+
}
|
|
18808
|
+
function supercompileRuleMapReplacement(prog, replacement) {
|
|
18809
|
+
const cfg = defaultAssemblyCfgs(prog)[0];
|
|
18810
|
+
if (cfg === void 0) return replacement;
|
|
18811
|
+
const extraIps = [];
|
|
18812
|
+
for (const scan of prog.scans ?? []) {
|
|
18813
|
+
for (const ref2 of scan.skip) extraIps.push(ref2[0]);
|
|
18814
|
+
if (scan.sentinel !== void 0) extraIps.push(scan.sentinel[0]);
|
|
18815
|
+
}
|
|
18816
|
+
for (const set of prog.scanSkip ?? []) for (const ref2 of set) extraIps.push(ref2[0]);
|
|
18817
|
+
let canonical2;
|
|
18818
|
+
let candidate;
|
|
18819
|
+
try {
|
|
18820
|
+
canonical2 = emitAssemblySource(resolveTable(prog), prog, cfg, extraIps, true);
|
|
18821
|
+
candidate = supercompileEmittedAssembly(prog, cfg, extraIps, canonical2);
|
|
18822
|
+
} catch {
|
|
18823
|
+
return replacement;
|
|
18824
|
+
}
|
|
18825
|
+
if (!candidate.supercompile.activated) return replacement;
|
|
18826
|
+
const prefix = "const __parseman_macro_replacement__=";
|
|
18827
|
+
const parsed = parseSync4("parseman-entry-supercompile-replacement.js", prefix + replacement);
|
|
18828
|
+
if (parsed.errors.length > 0) return replacement;
|
|
18829
|
+
const program = parsed.program;
|
|
18830
|
+
const declaration = nodes(program.body)[0];
|
|
18831
|
+
const declarator = nodes(declaration?.declarations)[0];
|
|
18832
|
+
const call = ast(declarator?.init);
|
|
18833
|
+
const table = nodes(call?.arguments)[0];
|
|
18834
|
+
if (declaration?.type !== "VariableDeclaration" || declarator?.type !== "VariableDeclarator" || call?.type !== "CallExpression" || table?.type !== "ObjectExpression") return replacement;
|
|
18835
|
+
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" && nameOf(ast(prop.key)) === key);
|
|
18836
|
+
const assembliesProp = property(table, "a");
|
|
18837
|
+
const assemblies = nodes(ast(assembliesProp?.value)?.elements);
|
|
18838
|
+
if (assembliesProp === void 0 || assemblies.length !== 1 || assemblies[0]?.type !== "ObjectExpression") return replacement;
|
|
18839
|
+
const factoryProp = property(assemblies[0], "factory");
|
|
18840
|
+
const factory = ast(factoryProp?.value);
|
|
18841
|
+
const body = ast(factory?.body);
|
|
18842
|
+
if (factory?.type !== "FunctionExpression" || body?.type !== "BlockStatement") return replacement;
|
|
18843
|
+
if (typeof body.start !== "number" || typeof body.end !== "number") return replacement;
|
|
18844
|
+
const start = body.start - prefix.length + 1;
|
|
18845
|
+
const end = body.end - prefix.length - 1;
|
|
18846
|
+
if (replacement.slice(start, end) !== canonical2.source + "\n") return replacement;
|
|
18847
|
+
const transformed = replacement.slice(0, start) + candidate.source + "\n" + replacement.slice(end);
|
|
18848
|
+
const checked = parseSync4("parseman-entry-supercompile-replacement-result.js", prefix + transformed);
|
|
18849
|
+
return checked.errors.length === 0 ? transformed : replacement;
|
|
18850
|
+
}
|
|
18851
|
+
function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
18852
|
+
const source = emitted.source;
|
|
18853
|
+
const parsed = parseSync4("parseman-entry-supercompile.js", WRAP + source + SUFFIX);
|
|
18854
|
+
if (parsed.errors.length > 0) {
|
|
18855
|
+
const zero = { functionsBefore: 0, pieceCallsBefore: 0, sourceBefore: source.length, barriers: {} };
|
|
18856
|
+
return fallback(emitted, "canonical emitted source did not parse", zero);
|
|
18857
|
+
}
|
|
18858
|
+
const program = parsed.program;
|
|
18859
|
+
const wrapper = nodes(program.body)[0];
|
|
18860
|
+
const wrapperBody = ast(wrapper?.body);
|
|
18861
|
+
if (wrapper?.type !== "FunctionDeclaration" || wrapperBody?.type !== "BlockStatement") {
|
|
18862
|
+
const zero = { functionsBefore: 0, pieceCallsBefore: 0, sourceBefore: source.length, barriers: {} };
|
|
18863
|
+
return fallback(emitted, "missing compiler wrapper", zero);
|
|
18864
|
+
}
|
|
18865
|
+
const fns = /* @__PURE__ */ new Map();
|
|
18866
|
+
for (const statement of nodes(wrapperBody.body)) {
|
|
18867
|
+
if (statement.type !== "FunctionDeclaration") continue;
|
|
18868
|
+
const name = nameOf(ast(statement.id));
|
|
18869
|
+
const hit = name === void 0 ? void 0 : PIECE.exec(name);
|
|
18870
|
+
const body = ast(statement.body);
|
|
18871
|
+
if (hit !== void 0 && hit !== null && body?.type === "BlockStatement") {
|
|
18872
|
+
const ip = Number(hit[1]);
|
|
18873
|
+
fns.set(ip, { ip, name, node: statement, body, calls: [] });
|
|
18874
|
+
}
|
|
18875
|
+
}
|
|
18876
|
+
const externalRefs = /* @__PURE__ */ new Set();
|
|
18877
|
+
let reservedCollision = false;
|
|
18878
|
+
const allCalls = [];
|
|
18879
|
+
const walk = (node2, current, parent, statement, statementParent) => {
|
|
18880
|
+
if (isFunction(node2) && node2 !== current?.node) {
|
|
18881
|
+
const own = node2.type === "FunctionDeclaration" ? nameOf(ast(node2.id)) : void 0;
|
|
18882
|
+
const hit = own === void 0 ? void 0 : PIECE.exec(own);
|
|
18883
|
+
if (hit !== void 0 && hit !== null) {
|
|
18884
|
+
const fn = fns.get(Number(hit[1]));
|
|
18885
|
+
if (fn !== void 0) {
|
|
18886
|
+
for (const child of children2(node2)) {
|
|
18887
|
+
if (child !== ast(node2.id)) walk(child, fn, node2, void 0, void 0);
|
|
18888
|
+
}
|
|
18889
|
+
return;
|
|
18890
|
+
}
|
|
18891
|
+
}
|
|
18892
|
+
current = void 0;
|
|
18893
|
+
}
|
|
18894
|
+
let owner2 = statement;
|
|
18895
|
+
let ownerParent = statementParent;
|
|
18896
|
+
if (parent?.type === "BlockStatement" && nodes(parent.body).includes(node2)) {
|
|
18897
|
+
owner2 = node2;
|
|
18898
|
+
ownerParent = parent;
|
|
18899
|
+
}
|
|
18900
|
+
if (parent?.type === "SwitchCase" && nodes(parent.consequent).includes(node2)) {
|
|
18901
|
+
owner2 = node2;
|
|
18902
|
+
ownerParent = parent;
|
|
18903
|
+
}
|
|
18904
|
+
if (node2.type === "CallExpression") {
|
|
18905
|
+
const calleeName = nameOf(ast(node2.callee));
|
|
18906
|
+
const hit = calleeName === void 0 ? void 0 : PIECE.exec(calleeName);
|
|
18907
|
+
if (hit !== void 0 && hit !== null) {
|
|
18908
|
+
const callee = Number(hit[1]);
|
|
18909
|
+
const args = nodes(node2.arguments);
|
|
18910
|
+
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 && nameOf(args[0]) === "input" && nameOf(args[2]) === "ctx" && isDirectCallUse(node2, parent, owner2) && isListStatement(owner2, ownerParent);
|
|
18911
|
+
if (current === void 0 || owner2 === void 0) externalRefs.add(callee);
|
|
18912
|
+
else {
|
|
18913
|
+
const call = { caller: current.ip, callee, node: node2, statement: owner2, args, transformable };
|
|
18914
|
+
current.calls.push(call);
|
|
18915
|
+
allCalls.push(call);
|
|
18916
|
+
}
|
|
18917
|
+
}
|
|
18918
|
+
}
|
|
18919
|
+
if (node2.type === "Identifier") {
|
|
18920
|
+
if (typeof node2.name === "string" && /^_z\d/.test(node2.name)) reservedCollision = true;
|
|
18921
|
+
const hit = typeof node2.name === "string" ? PIECE.exec(node2.name) : null;
|
|
18922
|
+
if (hit !== null) {
|
|
18923
|
+
const isDecl = parent?.type === "FunctionDeclaration" && parent.id === node2;
|
|
18924
|
+
const isCall = parent?.type === "CallExpression" && parent.callee === node2;
|
|
18925
|
+
if (!isDecl && !isCall) externalRefs.add(Number(hit[1]));
|
|
18926
|
+
}
|
|
18927
|
+
}
|
|
18928
|
+
for (const child of children2(node2)) walk(child, current, node2, owner2, ownerParent);
|
|
18929
|
+
};
|
|
18930
|
+
for (const statement of nodes(wrapperBody.body)) walk(statement, void 0, wrapperBody, void 0, void 0);
|
|
18931
|
+
if (reservedCollision) {
|
|
18932
|
+
const before2 = { functionsBefore: fns.size, pieceCallsBefore: allCalls.length, sourceBefore: source.length, barriers: { name: 1 } };
|
|
18933
|
+
return fallback(emitted, "canonical source uses the reserved _z<N> supercompiler prefix", before2);
|
|
18934
|
+
}
|
|
18935
|
+
const pieceCallsBefore = allCalls.length;
|
|
18936
|
+
const recursive = recursiveMembers(fns);
|
|
18937
|
+
const incoming = /* @__PURE__ */ new Map();
|
|
18938
|
+
for (const call of allCalls) {
|
|
18939
|
+
const list = incoming.get(call.callee) ?? [];
|
|
18940
|
+
list.push(call);
|
|
18941
|
+
incoming.set(call.callee, list);
|
|
18942
|
+
}
|
|
18943
|
+
const publicRoots = /* @__PURE__ */ new Set([...Object.values(prog.rules), ...extraIps]);
|
|
18944
|
+
const barrier = /* @__PURE__ */ new Map();
|
|
18945
|
+
for (const ip of fns.keys()) {
|
|
18946
|
+
if (publicRoots.has(ip) || externalRefs.has(ip)) barrier.set(ip, "public");
|
|
18947
|
+
else if (recursive.has(ip)) barrier.set(ip, "recursive");
|
|
18948
|
+
else if (prog.code[ip] === OP_ATTEMPT || prog.code[ip] === OP_SCAN) barrier.set(ip, "effect");
|
|
18949
|
+
else if (hasInlineScopeHazard(fns.get(ip))) barrier.set(ip, "scope");
|
|
18950
|
+
else if (!hasInlineSignature(fns.get(ip))) barrier.set(ip, "shape");
|
|
18951
|
+
else if ((incoming.get(ip)?.length ?? 0) !== 1) barrier.set(ip, "shared");
|
|
18952
|
+
else if (!incoming.get(ip)[0].transformable) barrier.set(ip, "shape");
|
|
18953
|
+
}
|
|
18954
|
+
const roots = [...fns.keys()].filter((ip) => barrier.has(ip));
|
|
18955
|
+
const owner = /* @__PURE__ */ new Map();
|
|
18956
|
+
const absorb = (ip, root) => {
|
|
18957
|
+
if (owner.has(ip)) return;
|
|
18958
|
+
owner.set(ip, root);
|
|
18959
|
+
for (const call of fns.get(ip)?.calls ?? []) {
|
|
18960
|
+
if (!fns.has(call.callee) || barrier.has(call.callee) || !call.transformable) continue;
|
|
18961
|
+
absorb(call.callee, root);
|
|
18962
|
+
}
|
|
18963
|
+
};
|
|
18964
|
+
for (const root of roots) absorb(root, root);
|
|
18965
|
+
for (const ip of fns.keys()) if (!owner.has(ip)) {
|
|
18966
|
+
barrier.set(ip, "shared");
|
|
18967
|
+
absorb(ip, ip);
|
|
18968
|
+
}
|
|
18969
|
+
let serial = 0;
|
|
18970
|
+
const src = (node2) => {
|
|
18971
|
+
const r = range(node2);
|
|
18972
|
+
return source.slice(r.start, r.end);
|
|
18973
|
+
};
|
|
18974
|
+
const renderBody = (ip, embedded) => {
|
|
18975
|
+
const fn = fns.get(ip);
|
|
18976
|
+
const bodyRange = range(fn.body);
|
|
18977
|
+
const start = bodyRange.start + 1;
|
|
18978
|
+
const end = bodyRange.end - 1;
|
|
18979
|
+
const edits = [];
|
|
18980
|
+
const callsByStatement = /* @__PURE__ */ new Map();
|
|
18981
|
+
for (const call of fn.calls) {
|
|
18982
|
+
if (owner.get(call.callee) !== owner.get(ip) || barrier.has(call.callee) || !call.transformable) continue;
|
|
18983
|
+
const list = callsByStatement.get(call.statement) ?? [];
|
|
18984
|
+
list.push(call);
|
|
18985
|
+
callsByStatement.set(call.statement, list);
|
|
18986
|
+
}
|
|
18987
|
+
const returns = [];
|
|
18988
|
+
const collectReturns = (node2) => {
|
|
18989
|
+
if (node2 !== fn.body && isFunction(node2)) return;
|
|
18990
|
+
if (node2.type === "ReturnStatement") returns.push(node2);
|
|
18991
|
+
for (const child of children2(node2)) collectReturns(child);
|
|
18992
|
+
};
|
|
18993
|
+
if (embedded !== void 0) collectReturns(fn.body);
|
|
18994
|
+
const callPrefix = (call) => {
|
|
18995
|
+
const id = serial++;
|
|
18996
|
+
const result = `_z${id}r`;
|
|
18997
|
+
const label2 = `_z${id}`;
|
|
18998
|
+
const at = `_z${id}p`;
|
|
18999
|
+
const nested = renderBody(call.callee, { result, label: label2 });
|
|
19000
|
+
return {
|
|
19001
|
+
value: result,
|
|
19002
|
+
prefix: `let ${result},${at}=${src(call.args[1])}
|
|
19003
|
+
${label2}:{let pos=${at}
|
|
19004
|
+
${nested}
|
|
19005
|
+
}
|
|
19006
|
+
`
|
|
19007
|
+
};
|
|
19008
|
+
};
|
|
19009
|
+
for (const [statement, calls] of callsByStatement) {
|
|
19010
|
+
let prefix = "";
|
|
19011
|
+
const replacements = [];
|
|
19012
|
+
for (const call of calls) {
|
|
19013
|
+
const made = callPrefix(call);
|
|
19014
|
+
prefix += made.prefix;
|
|
19015
|
+
const cr = range(call.node);
|
|
19016
|
+
replacements.push({ start: cr.start, end: cr.end, text: made.value });
|
|
19017
|
+
}
|
|
19018
|
+
if (statement.type === "ReturnStatement" && embedded !== void 0) {
|
|
19019
|
+
const sr = range(statement);
|
|
19020
|
+
const arg = ast(statement.argument);
|
|
19021
|
+
const value = arg === void 0 ? "undefined" : render2(source, range(arg).start, range(arg).end, replacements);
|
|
19022
|
+
edits.push({ start: sr.start, end: sr.end, text: `{${prefix}${embedded.result}=${value};break ${embedded.label}}` });
|
|
19023
|
+
} else {
|
|
19024
|
+
const sr = range(statement);
|
|
19025
|
+
edits.push({ start: sr.start, end: sr.start, text: prefix });
|
|
19026
|
+
edits.push(...replacements);
|
|
19027
|
+
}
|
|
19028
|
+
}
|
|
19029
|
+
if (embedded !== void 0) {
|
|
19030
|
+
for (const statement of returns) {
|
|
19031
|
+
if (callsByStatement.has(statement)) continue;
|
|
19032
|
+
const sr = range(statement);
|
|
19033
|
+
const arg = ast(statement.argument);
|
|
19034
|
+
edits.push({
|
|
19035
|
+
start: sr.start,
|
|
19036
|
+
end: sr.end,
|
|
19037
|
+
text: `{${embedded.result}=${arg === void 0 ? "undefined" : src(arg)};break ${embedded.label}}`
|
|
19038
|
+
});
|
|
19039
|
+
}
|
|
19040
|
+
}
|
|
19041
|
+
return render2(source, start, end, edits);
|
|
19042
|
+
};
|
|
19043
|
+
const regionSizes = /* @__PURE__ */ new Map();
|
|
19044
|
+
const regionProtocol = /* @__PURE__ */ new Map();
|
|
19045
|
+
for (const [ip, root] of owner) {
|
|
19046
|
+
const r = range(fns.get(ip).node);
|
|
19047
|
+
regionSizes.set(root, (regionSizes.get(root) ?? 0) + r.end - r.start);
|
|
19048
|
+
const op = prog.code[ip];
|
|
19049
|
+
const bits = (op === OP_NODE || op === OP_NODE_TRACK ? 1 : 0) | (op === OP_REPV ? 2 : 0);
|
|
19050
|
+
regionProtocol.set(root, (regionProtocol.get(root) ?? 0) | bits);
|
|
19051
|
+
}
|
|
19052
|
+
const oversized = /* @__PURE__ */ new Set();
|
|
19053
|
+
for (const [ip, size] of regionSizes) if (size > 18e4) oversized.add(ip);
|
|
19054
|
+
if (oversized.size > 0) {
|
|
19055
|
+
const counts2 = Object.fromEntries([...barrier.values()].map((k) => [k, 0]));
|
|
19056
|
+
for (const kind of barrier.values()) counts2[kind] = (counts2[kind] ?? 0) + 1;
|
|
19057
|
+
const before2 = { functionsBefore: fns.size, pieceCallsBefore, sourceBefore: source.length, barriers: counts2 };
|
|
19058
|
+
return fallback(emitted, "a region exceeded the 180KB source cap", before2);
|
|
19059
|
+
}
|
|
19060
|
+
const topEdits = [];
|
|
19061
|
+
for (const [ip, fn] of fns) {
|
|
19062
|
+
if (owner.get(ip) === ip) {
|
|
19063
|
+
const br = range(fn.body);
|
|
19064
|
+
topEdits.push({ start: br.start + 1, end: br.end - 1, text: renderBody(ip, void 0) });
|
|
19065
|
+
} else {
|
|
19066
|
+
const fr = range(fn.node);
|
|
19067
|
+
topEdits.push({ start: fr.start, end: fr.end, text: "" });
|
|
19068
|
+
}
|
|
19069
|
+
}
|
|
19070
|
+
const candidate = render2(source, 0, source.length, topEdits);
|
|
19071
|
+
const counts = {};
|
|
19072
|
+
for (const kind of barrier.values()) counts[kind] = (counts[kind] ?? 0) + 1;
|
|
19073
|
+
const before = { functionsBefore: fns.size, pieceCallsBefore, sourceBefore: source.length, barriers: counts };
|
|
19074
|
+
if (candidate.length > Math.ceil(source.length * 1.05)) {
|
|
19075
|
+
return fallback(emitted, `candidate exceeded the 5% total source cap (${candidate.length} > ${Math.ceil(source.length * 1.05)})`, before);
|
|
19076
|
+
}
|
|
19077
|
+
const functionsAfter = roots.length;
|
|
19078
|
+
const removed = fns.size - functionsAfter;
|
|
19079
|
+
const checked = parseSync4("parseman-entry-supercompile-result.js", WRAP + candidate + SUFFIX);
|
|
19080
|
+
if (checked.errors.length > 0) return fallback(emitted, "structured candidate did not parse", before);
|
|
19081
|
+
const declared = /* @__PURE__ */ new Set();
|
|
19082
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
19083
|
+
const checkRefs = (node2, parent) => {
|
|
19084
|
+
if (node2.type === "FunctionDeclaration") {
|
|
19085
|
+
const name = nameOf(ast(node2.id));
|
|
19086
|
+
if (name !== void 0 && PIECE.test(name)) declared.add(name);
|
|
19087
|
+
}
|
|
19088
|
+
if (node2.type === "Identifier" && typeof node2.name === "string" && PIECE.test(node2.name)) {
|
|
19089
|
+
const isDeclaration = parent?.type === "FunctionDeclaration" && parent.id === node2;
|
|
19090
|
+
if (!isDeclaration) referenced.add(node2.name);
|
|
19091
|
+
}
|
|
19092
|
+
for (const child of children2(node2)) checkRefs(child, node2);
|
|
19093
|
+
};
|
|
19094
|
+
checkRefs(checked.program);
|
|
19095
|
+
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19096
|
+
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19097
|
+
}
|
|
19098
|
+
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19099
|
+
const protocolRegions = {
|
|
19100
|
+
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19101
|
+
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19102
|
+
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19103
|
+
};
|
|
19104
|
+
return {
|
|
19105
|
+
...emitted,
|
|
19106
|
+
source: candidate,
|
|
19107
|
+
supercompile: {
|
|
19108
|
+
...before,
|
|
19109
|
+
activated: removed > 0,
|
|
19110
|
+
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19111
|
+
functionsAfter,
|
|
19112
|
+
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19113
|
+
sourceAfter: candidate.length,
|
|
19114
|
+
regions: roots.length,
|
|
19115
|
+
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19116
|
+
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19117
|
+
protocolRegions
|
|
19118
|
+
}
|
|
19119
|
+
};
|
|
19120
|
+
}
|
|
19121
|
+
|
|
17570
19122
|
// src/plugin/index.ts
|
|
17571
19123
|
import { createHash } from "node:crypto";
|
|
17572
19124
|
var TABLE_RUNTIME_SPECIFIER = "parseman/table";
|
|
@@ -17669,7 +19221,7 @@ function parseModuleCached(filePath) {
|
|
|
17669
19221
|
let parsed = null;
|
|
17670
19222
|
try {
|
|
17671
19223
|
const src = fs2.readFileSync(filePath, "utf8");
|
|
17672
|
-
const r =
|
|
19224
|
+
const r = parseSync5(filePath, src);
|
|
17673
19225
|
if (r.errors.length === 0) parsed = { body: r.program.body, src };
|
|
17674
19226
|
} catch {
|
|
17675
19227
|
}
|
|
@@ -17818,7 +19370,7 @@ function lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recov
|
|
|
17818
19370
|
const source = fs2.readFileSync(file, "utf8");
|
|
17819
19371
|
const transformed = transformMacro(source, file, moduleAliases, warnUnloweredRegex, recovery);
|
|
17820
19372
|
if (!transformed || transformed.warnings.length > 0) return null;
|
|
17821
|
-
const parsed =
|
|
19373
|
+
const parsed = parseSync5(file, transformed.code);
|
|
17822
19374
|
parsedModule = parsed.errors.length === 0 ? { body: parsed.program.body, src: transformed.code } : null;
|
|
17823
19375
|
return parsedModule;
|
|
17824
19376
|
} catch {
|
|
@@ -17841,7 +19393,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
17841
19393
|
function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recovery, grammarCoverage) {
|
|
17842
19394
|
let result;
|
|
17843
19395
|
try {
|
|
17844
|
-
result =
|
|
19396
|
+
result = parseSync5(id, code);
|
|
17845
19397
|
} catch {
|
|
17846
19398
|
return null;
|
|
17847
19399
|
}
|
|
@@ -18462,9 +20014,12 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
18462
20014
|
if (compiled !== null) {
|
|
18463
20015
|
usedTableRuntime = true;
|
|
18464
20016
|
return {
|
|
18465
|
-
replacement:
|
|
18466
|
-
|
|
18467
|
-
|
|
20017
|
+
replacement: supercompileRuleMapReplacement(
|
|
20018
|
+
compiled.prog,
|
|
20019
|
+
compiled.replacementWithMetadata(
|
|
20020
|
+
staticTableMetadataSource({ reflection: compiled.reflection, leaf: true }),
|
|
20021
|
+
{ precompileDefault: true }
|
|
20022
|
+
)
|
|
18468
20023
|
),
|
|
18469
20024
|
...importedFactories.length ? { importedFactories } : {}
|
|
18470
20025
|
};
|