parseman 0.47.0 → 0.47.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.cjs +133 -45
- package/dist/analysis/diagnostics.cjs.map +2 -2
- package/dist/analysis/diagnostics.js +133 -45
- package/dist/analysis/diagnostics.js.map +2 -2
- package/dist/cli/index.cjs +133 -45
- package/dist/cli/index.cjs.map +2 -2
- package/dist/cli/index.js +133 -45
- package/dist/cli/index.js.map +2 -2
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +5 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/index.cjs +134 -46
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +134 -46
- package/dist/index.js.map +2 -2
- package/dist/language-service/index.cjs +3 -1
- package/dist/language-service/index.cjs.map +1 -1
- package/dist/language-service/index.js +3 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.cjs +134 -46
- package/dist/plugin/index.cjs.map +2 -2
- package/dist/plugin/index.js +134 -46
- package/dist/plugin/index.js.map +2 -2
- package/dist/spec/index.cjs +55 -7
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.js +55 -7
- package/dist/spec/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +2 -2
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.cjs +1566 -1478
- package/dist/table/index.cjs.map +3 -3
- package/dist/table/index.js +1566 -1478
- package/dist/table/index.js.map +3 -3
- package/dist/table/ops.d.ts +8 -1
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +4 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/combinators/first-set.ts +29 -3
- package/src/combinators/sequence.ts +23 -7
- package/src/combinators/trivia-skip.ts +31 -0
- package/src/table/assemble.ts +30 -18
- package/src/table/child-slots.ts +2 -2
- package/src/table/emit-assembly.ts +36 -25
- package/src/table/emit.ts +12 -1
- package/src/table/encode.ts +4 -4
- package/src/table/exec.ts +20 -12
- package/src/table/ops.ts +9 -1
- package/src/table/program.ts +22 -1
- package/src/table/site-labels.ts +2 -2
- package/src/table/stamp.ts +2 -2
- package/src/version.ts +1 -1
package/dist/table/index.cjs
CHANGED
|
@@ -87,6 +87,13 @@ function empty() {
|
|
|
87
87
|
function matchesEmpty(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
88
88
|
if (seen.has(p)) return true;
|
|
89
89
|
seen.add(p);
|
|
90
|
+
try {
|
|
91
|
+
return matchesEmptyBody(p, seen, resolve);
|
|
92
|
+
} finally {
|
|
93
|
+
seen.delete(p);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function matchesEmptyBody(p, seen, resolve) {
|
|
90
97
|
const me = (c) => matchesEmpty(c, seen, resolve);
|
|
91
98
|
const d = p._def;
|
|
92
99
|
switch (d.tag) {
|
|
@@ -188,6 +195,13 @@ function sequenceFirstSet(parsers) {
|
|
|
188
195
|
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
189
196
|
if (seen.has(p)) return any();
|
|
190
197
|
seen.add(p);
|
|
198
|
+
try {
|
|
199
|
+
return firstSetBody(p, seen, resolve);
|
|
200
|
+
} finally {
|
|
201
|
+
seen.delete(p);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function firstSetBody(p, seen, resolve) {
|
|
191
205
|
const fs = (c) => firstSetOf(c, seen, resolve);
|
|
192
206
|
const empties = (c) => matchesEmpty(c, /* @__PURE__ */ new Set(), resolve);
|
|
193
207
|
const d = p._def;
|
|
@@ -1514,6 +1528,23 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1514
1528
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1515
1529
|
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1516
1530
|
}
|
|
1531
|
+
function removeNumberRange(values, start, end) {
|
|
1532
|
+
if (values === void 0 || end <= start) return;
|
|
1533
|
+
if (values.length > end) values.copyWithin(start, end);
|
|
1534
|
+
values.length -= end - start;
|
|
1535
|
+
}
|
|
1536
|
+
function rollbackScannedTriviaAt(ctx, tlogStart, tlogEnd, logStart, logEnd, rootLogStart, rootLogEnd) {
|
|
1537
|
+
const b = ctx._cstBuf;
|
|
1538
|
+
if (b !== void 0) {
|
|
1539
|
+
const tlog = b.tl;
|
|
1540
|
+
removeNumberRange(tlog, tlogStart, tlogEnd);
|
|
1541
|
+
if (tlog !== void 0 && tlog.length === 0) b.tl = void 0;
|
|
1542
|
+
} else {
|
|
1543
|
+
removeNumberRange(ctx._cstTriviaLog, tlogStart, tlogEnd);
|
|
1544
|
+
}
|
|
1545
|
+
removeNumberRange(ctx._triviaLog, logStart, logEnd);
|
|
1546
|
+
removeNumberRange(ctx._rootTriviaLog, rootLogStart, rootLogEnd);
|
|
1547
|
+
}
|
|
1517
1548
|
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1518
1549
|
const probeCtx = createDetachedParseContext(ctx.trackLines, ctx.state);
|
|
1519
1550
|
probeCtx._lineIndex = ctx._lineIndex;
|
|
@@ -2173,7 +2204,9 @@ function sequence(...parsers) {
|
|
|
2173
2204
|
continue;
|
|
2174
2205
|
}
|
|
2175
2206
|
if (ctx.trivia && i > 0) {
|
|
2176
|
-
const
|
|
2207
|
+
const mTlog = cstTlLen(ctx);
|
|
2208
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2209
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2177
2210
|
let scanEnd;
|
|
2178
2211
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2179
2212
|
const scan = scanTrivia(input, cur, ctx);
|
|
@@ -2182,10 +2215,13 @@ function sequence(...parsers) {
|
|
|
2182
2215
|
} else {
|
|
2183
2216
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2184
2217
|
}
|
|
2218
|
+
const scanTlog = cstTlLen(ctx);
|
|
2219
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2220
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2185
2221
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2186
2222
|
if (!result2.ok) return result2;
|
|
2187
2223
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2188
|
-
else
|
|
2224
|
+
else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2189
2225
|
if (values !== void 0) values.push(result2.value);
|
|
2190
2226
|
continue;
|
|
2191
2227
|
}
|
|
@@ -2216,7 +2252,9 @@ function sequence(...parsers) {
|
|
|
2216
2252
|
}
|
|
2217
2253
|
if (ctx.trivia && i > 0) {
|
|
2218
2254
|
let scanEnd;
|
|
2219
|
-
const
|
|
2255
|
+
const mTlog = cstTlLen(ctx);
|
|
2256
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2257
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2220
2258
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2221
2259
|
const scan = scanTrivia(input, cur, ctx);
|
|
2222
2260
|
scan.commit();
|
|
@@ -2224,10 +2262,13 @@ function sequence(...parsers) {
|
|
|
2224
2262
|
} else {
|
|
2225
2263
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2226
2264
|
}
|
|
2265
|
+
const scanTlog = cstTlLen(ctx);
|
|
2266
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2267
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2227
2268
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2228
2269
|
if (!result2.ok) return result2;
|
|
2229
2270
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2230
|
-
else
|
|
2271
|
+
else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2231
2272
|
if (values !== void 0) values.push(result2.value);
|
|
2232
2273
|
continue;
|
|
2233
2274
|
}
|
|
@@ -2255,7 +2296,9 @@ function sequence(...parsers) {
|
|
|
2255
2296
|
for (let i = 0; i < parsers.length; i++) {
|
|
2256
2297
|
if (ctx.trivia && i > 0) {
|
|
2257
2298
|
let scanEnd;
|
|
2258
|
-
|
|
2299
|
+
const mTlog = cstTlLen(ctx);
|
|
2300
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2301
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2259
2302
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2260
2303
|
const scan = scanTrivia(input, cur, ctx);
|
|
2261
2304
|
scan.commit();
|
|
@@ -2263,12 +2306,15 @@ function sequence(...parsers) {
|
|
|
2263
2306
|
} else {
|
|
2264
2307
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2265
2308
|
}
|
|
2309
|
+
const scanTlog = cstTlLen(ctx);
|
|
2310
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2311
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2266
2312
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2267
2313
|
if (!result2.ok) return result2;
|
|
2268
2314
|
if (result2.span.end > scanEnd) {
|
|
2269
2315
|
cur = result2.span.end;
|
|
2270
2316
|
} else {
|
|
2271
|
-
|
|
2317
|
+
rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2272
2318
|
}
|
|
2273
2319
|
if (values !== void 0) values.push(result2.value);
|
|
2274
2320
|
continue;
|
|
@@ -3602,6 +3648,7 @@ var OP_LIVE = 37;
|
|
|
3602
3648
|
var OP_ATTEMPT = 38;
|
|
3603
3649
|
var OP_LABEL = 39;
|
|
3604
3650
|
var OP_COV = 40;
|
|
3651
|
+
var OP_SCOPE_PLAIN = 41;
|
|
3605
3652
|
var OP_DISPATCH = 25;
|
|
3606
3653
|
var OP_ROUTED = 26;
|
|
3607
3654
|
var OP_NAMES = {
|
|
@@ -3644,515 +3691,844 @@ var OP_NAMES = {
|
|
|
3644
3691
|
[OP_LIVE]: "LIVE",
|
|
3645
3692
|
[OP_ATTEMPT]: "ATTEMPT",
|
|
3646
3693
|
[OP_LABEL]: "LABEL",
|
|
3647
|
-
[OP_COV]: "COV"
|
|
3694
|
+
[OP_COV]: "COV",
|
|
3695
|
+
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
|
|
3648
3696
|
};
|
|
3649
3697
|
|
|
3650
|
-
// src/table/
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
function classToRanges(cls) {
|
|
3654
|
-
if (cls === "\\d") return shorthandRanges("d");
|
|
3655
|
-
if (cls === "\\w") return shorthandRanges("w");
|
|
3656
|
-
if (cls === "\\s") return shorthandRanges("s");
|
|
3657
|
-
const body = cls.slice(1, -1);
|
|
3658
|
-
if (body.startsWith("^")) return null;
|
|
3659
|
-
return parseClassRanges(body);
|
|
3698
|
+
// src/table/program.ts
|
|
3699
|
+
function closureArtifact(prog) {
|
|
3700
|
+
return { ...prog, asm: [] };
|
|
3660
3701
|
}
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
const CLS = String.raw`\[\^((?:\\.|[^\]])+)\]`;
|
|
3672
|
-
const ESC = String.raw`\\\\(\.|\[\\s\\S\]|\[\\S\\s\])`;
|
|
3673
|
-
let body;
|
|
3674
|
-
let esc;
|
|
3675
|
-
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${ESC}\\)\\*$`).exec(inner);
|
|
3676
|
-
if (m) {
|
|
3677
|
-
body = m[1];
|
|
3678
|
-
esc = m[2];
|
|
3679
|
-
} else {
|
|
3680
|
-
m = new RegExp(`^\\((?:\\?:)?${ESC}\\|${CLS}\\)\\*$`).exec(inner);
|
|
3681
|
-
if (m) {
|
|
3682
|
-
esc = m[1];
|
|
3683
|
-
body = m[2];
|
|
3684
|
-
}
|
|
3702
|
+
function covKindCode(kind) {
|
|
3703
|
+
switch (kind) {
|
|
3704
|
+
case "rule":
|
|
3705
|
+
return 0;
|
|
3706
|
+
case "choice-arm":
|
|
3707
|
+
return 1;
|
|
3708
|
+
case "dispatch-arm":
|
|
3709
|
+
return 2;
|
|
3710
|
+
case "label":
|
|
3711
|
+
return 3;
|
|
3685
3712
|
}
|
|
3686
|
-
if (body === void 0 || esc === void 0) return null;
|
|
3687
|
-
const excluded = parseClassRanges(body);
|
|
3688
|
-
if (!excluded) return null;
|
|
3689
|
-
const qcp = q2.codePointAt(0);
|
|
3690
|
-
const inSet = (cp) => excluded.some(([lo, hi]) => cp >= lo && cp <= hi);
|
|
3691
|
-
if (!inSet(qcp) || !inSet(BACKSLASH)) return null;
|
|
3692
|
-
return { kind: "string", quote: qcp, excluded, escLineTerm: esc !== "." };
|
|
3693
3713
|
}
|
|
3694
|
-
function
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3714
|
+
function covKindName(code) {
|
|
3715
|
+
switch (code) {
|
|
3716
|
+
case 0:
|
|
3717
|
+
return "rule";
|
|
3718
|
+
case 1:
|
|
3719
|
+
return "choice-arm";
|
|
3720
|
+
case 2:
|
|
3721
|
+
return "dispatch-arm";
|
|
3722
|
+
case 3:
|
|
3723
|
+
return "label";
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
function covDefinitions(prog) {
|
|
3727
|
+
return (prog.cov ?? []).map(([id, kind]) => ({ id, kind: covKindName(kind) }));
|
|
3728
|
+
}
|
|
3729
|
+
function expandCompact(p) {
|
|
3730
|
+
if ("code" in p) return p;
|
|
3731
|
+
return ownTableProgram({
|
|
3732
|
+
code: p.c,
|
|
3733
|
+
k: p.k,
|
|
3734
|
+
cc: p.x,
|
|
3735
|
+
fx: p.e,
|
|
3736
|
+
disp: p.d,
|
|
3737
|
+
rules: p.r,
|
|
3738
|
+
fns: p.f,
|
|
3739
|
+
lines: p.l ?? 0,
|
|
3740
|
+
dsp: p.p ?? [],
|
|
3741
|
+
...p.lb === void 0 ? {} : { labels: p.lb },
|
|
3742
|
+
...p.rc === void 0 ? {} : { classified: p.rc },
|
|
3743
|
+
...p.h === void 0 ? {} : { hostMode: p.h },
|
|
3744
|
+
...p.tv === void 0 ? {} : { triviaSpecs: p.tv },
|
|
3745
|
+
...p.sc === void 0 ? {} : { scans: p.sc },
|
|
3746
|
+
...p.ss === void 0 ? {} : { scanSkip: p.ss },
|
|
3747
|
+
...p.so === void 0 ? {} : { scanSkipOf: p.so },
|
|
3748
|
+
...p.rv === void 0 ? {} : { rec: p.rv },
|
|
3749
|
+
...p.cv === void 0 ? {} : { cov: p.cv },
|
|
3750
|
+
...p.a === void 0 ? {} : { asm: p.a }
|
|
3751
|
+
});
|
|
3752
|
+
}
|
|
3753
|
+
function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
3754
|
+
const invalid = (arms) => {
|
|
3755
|
+
for (const arm of arms) if (!Number.isInteger(arm) || arm < 0 || arm >= arity) return true;
|
|
3756
|
+
return false;
|
|
3713
3757
|
};
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3758
|
+
if (spec === void 0 || !Number.isInteger(arity) || arity < 0 || fallbackRouted !== 0 && fallbackRouted !== 1 || spec.routed.length !== arity || spec.routed.some((value) => value !== 0 && value !== 1) || invalid(spec.byKey.values()) || invalid(spec.byFold.values()) || spec.match.some((matcher) => invalid([matcher[3]]))) {
|
|
3759
|
+
throw new TypeError("table: malformed dispatch");
|
|
3760
|
+
}
|
|
3761
|
+
}
|
|
3762
|
+
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
3763
|
+
function ownTableProgram(prog, resolved) {
|
|
3764
|
+
return { ...prog, [TABLE_RUNTIME]: { resolved } };
|
|
3765
|
+
}
|
|
3766
|
+
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
3767
|
+
var WIDE_CLASS_PREFIX_HI = 0;
|
|
3768
|
+
function validateClassRange(lo, hi) {
|
|
3769
|
+
for (const cp of [lo, hi]) {
|
|
3770
|
+
if (!Number.isInteger(cp) || cp < 0 || cp > 1114111) {
|
|
3771
|
+
throw new TypeError(`table char-class endpoint is outside Unicode: ${cp}`);
|
|
3719
3772
|
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3773
|
+
}
|
|
3774
|
+
if (lo > hi) {
|
|
3775
|
+
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
function encodeClassSpec(ranges) {
|
|
3779
|
+
let wide = false;
|
|
3780
|
+
for (const range of ranges) {
|
|
3781
|
+
validateClassRange(range.lo, range.hi);
|
|
3782
|
+
if (range.hi > 65535) wide = true;
|
|
3783
|
+
}
|
|
3784
|
+
if (!wide) {
|
|
3785
|
+
let spec2 = "";
|
|
3786
|
+
for (const range of ranges) spec2 += String.fromCharCode(range.lo, range.hi);
|
|
3787
|
+
return spec2;
|
|
3788
|
+
}
|
|
3789
|
+
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
3790
|
+
for (const range of ranges) {
|
|
3791
|
+
spec += String.fromCharCode(
|
|
3792
|
+
range.lo >>> 16,
|
|
3793
|
+
range.lo & 65535,
|
|
3794
|
+
range.hi >>> 16,
|
|
3795
|
+
range.hi & 65535
|
|
3796
|
+
);
|
|
3797
|
+
}
|
|
3798
|
+
return spec;
|
|
3799
|
+
}
|
|
3800
|
+
function decodeClassSpec(spec) {
|
|
3801
|
+
if (spec.charCodeAt(0) === WIDE_CLASS_PREFIX_LO && spec.charCodeAt(1) === WIDE_CLASS_PREFIX_HI) {
|
|
3802
|
+
if ((spec.length - 2) % 4 !== 0) throw new TypeError("table char-class spec has a truncated wide range");
|
|
3803
|
+
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
3804
|
+
const ranges2 = [];
|
|
3805
|
+
for (let i = 2; i < spec.length; i += 4) {
|
|
3806
|
+
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
3807
|
+
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
3808
|
+
validateClassRange(lo, hi);
|
|
3809
|
+
ranges2.push({ lo, hi });
|
|
3723
3810
|
}
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3811
|
+
return ranges2;
|
|
3812
|
+
}
|
|
3813
|
+
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
3814
|
+
const ranges = [];
|
|
3815
|
+
for (let i = 0; i < spec.length; i += 2) {
|
|
3816
|
+
const lo = spec.charCodeAt(i);
|
|
3817
|
+
const hi = spec.charCodeAt(i + 1);
|
|
3818
|
+
validateClassRange(lo, hi);
|
|
3819
|
+
ranges.push({ lo, hi });
|
|
3820
|
+
}
|
|
3821
|
+
return ranges;
|
|
3822
|
+
}
|
|
3823
|
+
function resolveClass(spec) {
|
|
3824
|
+
const ascii = new Uint8Array(128);
|
|
3825
|
+
const hi = [];
|
|
3826
|
+
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
3827
|
+
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
3828
|
+
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
3829
|
+
}
|
|
3830
|
+
return { ascii, hi };
|
|
3831
|
+
}
|
|
3832
|
+
function classHas(cls, code) {
|
|
3833
|
+
if (code < 0) return false;
|
|
3834
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
3835
|
+
const hi = cls.hi;
|
|
3836
|
+
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
3837
|
+
return false;
|
|
3838
|
+
}
|
|
3839
|
+
function resolveDispatch(arms, cc) {
|
|
3840
|
+
const ascii = new Uint8Array(128);
|
|
3841
|
+
const hi = [];
|
|
3842
|
+
const open = [];
|
|
3843
|
+
const armCls = [];
|
|
3844
|
+
let exclusive = true;
|
|
3845
|
+
let hiOwners = 0;
|
|
3846
|
+
for (let a = 0; a < arms.length; a++) {
|
|
3847
|
+
const ci = arms[a];
|
|
3848
|
+
if (ci < 0) {
|
|
3849
|
+
open.push(a);
|
|
3850
|
+
armCls.push(null);
|
|
3851
|
+
exclusive = false;
|
|
3852
|
+
continue;
|
|
3727
3853
|
}
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3854
|
+
const cls = cc[ci];
|
|
3855
|
+
armCls.push(cls);
|
|
3856
|
+
for (let c = 0; c < 128; c++) {
|
|
3857
|
+
if (cls.ascii[c] !== 1) continue;
|
|
3858
|
+
if (ascii[c] === 0) ascii[c] = a + 1;
|
|
3859
|
+
else exclusive = false;
|
|
3734
3860
|
}
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
}
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3861
|
+
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
3862
|
+
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
3863
|
+
}
|
|
3864
|
+
return { ascii, hi, open, armCls, exclusive };
|
|
3865
|
+
}
|
|
3866
|
+
function buildTrivia(spec) {
|
|
3867
|
+
if (spec.live !== void 0) return spec.live;
|
|
3868
|
+
if (spec.plain !== void 0) return trivia(regex(new RegExp(spec.plain[0], spec.plain[1])));
|
|
3869
|
+
if (spec.alts !== void 0) {
|
|
3870
|
+
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
3871
|
+
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
3872
|
+
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
3873
|
+
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
3874
|
+
}
|
|
3875
|
+
const arms = {};
|
|
3876
|
+
for (const [name, source, flags] of spec.arms) arms[name] = regex(new RegExp(source, flags));
|
|
3877
|
+
return classifiedTrivia(arms);
|
|
3878
|
+
}
|
|
3879
|
+
function resolveTable(prog) {
|
|
3880
|
+
const owner = prog[TABLE_RUNTIME];
|
|
3881
|
+
const hit = owner?.resolved;
|
|
3882
|
+
if (hit !== void 0) return hit;
|
|
3883
|
+
const cc = prog.cc.map(resolveClass);
|
|
3884
|
+
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
3885
|
+
const built = {
|
|
3886
|
+
prog,
|
|
3887
|
+
code: Int32Array.from(prog.code),
|
|
3888
|
+
k: prog.k,
|
|
3889
|
+
fns: prog.fns,
|
|
3890
|
+
cc,
|
|
3891
|
+
fx: prog.fx,
|
|
3892
|
+
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
3893
|
+
trivia: triviaBuilt,
|
|
3894
|
+
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
3895
|
+
triviaLabelled: triviaBuilt.map((t) => t._meta.triviaKindLabels !== void 0),
|
|
3896
|
+
dsp: prog.dsp.map((d) => ({
|
|
3897
|
+
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
3898
|
+
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
3899
|
+
match: d.match,
|
|
3900
|
+
routed: d.routed,
|
|
3901
|
+
expected: d.expected
|
|
3902
|
+
})),
|
|
3903
|
+
rules: prog.rules
|
|
3904
|
+
};
|
|
3905
|
+
if (owner !== void 0) owner.resolved = built;
|
|
3906
|
+
return built;
|
|
3907
|
+
}
|
|
3908
|
+
var FOLDED_RUNTIME = /* @__PURE__ */ Symbol("parseman.foldedRuntime");
|
|
3909
|
+
function ownFoldedProgram(base, variants) {
|
|
3910
|
+
return { base, variants, [FOLDED_RUNTIME]: { byName: /* @__PURE__ */ new Map() } };
|
|
3911
|
+
}
|
|
3912
|
+
var SHARED_FIELDS = [
|
|
3913
|
+
"k",
|
|
3914
|
+
"cc",
|
|
3915
|
+
"fx",
|
|
3916
|
+
"disp",
|
|
3917
|
+
"dsp",
|
|
3918
|
+
"rules",
|
|
3919
|
+
"labels",
|
|
3920
|
+
"classified",
|
|
3921
|
+
"scanSkip",
|
|
3922
|
+
"scanSkipOf",
|
|
3923
|
+
"scans",
|
|
3924
|
+
"triviaSpecs",
|
|
3925
|
+
"runtimeOnly",
|
|
3926
|
+
// `rec` is a property of the GRAMMAR BUILD, not of the trackLines/hostMode
|
|
3927
|
+
// axis a fold varies — every variant of one export is encoded with the same
|
|
3928
|
+
// recovery setting, and a mismatch is two tables, which is what the refusal says.
|
|
3929
|
+
"rec",
|
|
3930
|
+
// `cov` is a property of the GRAMMAR and its coverage plan, for the same reason
|
|
3931
|
+
// `rec` is a property of the build: the plan is built from the rule map, which
|
|
3932
|
+
// every variant of one export shares. It ships ONCE, and a variant that
|
|
3933
|
+
// disagrees is two tables — which is what the refusal says.
|
|
3934
|
+
"cov"
|
|
3935
|
+
];
|
|
3936
|
+
function foldPrograms(programs, baseName) {
|
|
3937
|
+
const suppliedBase = programs[baseName];
|
|
3938
|
+
if (suppliedBase === void 0) throw new TypeError(`foldPrograms: no program named ${JSON.stringify(baseName)}`);
|
|
3939
|
+
const base = closureArtifact(suppliedBase);
|
|
3940
|
+
const variants = {};
|
|
3941
|
+
for (const name of Object.keys(programs)) {
|
|
3942
|
+
const p = programs[name];
|
|
3943
|
+
if (p.asm !== void 0 && p.asm.length > 0) {
|
|
3944
|
+
throw new TypeError(
|
|
3945
|
+
`foldPrograms: program ${JSON.stringify(name)} already carries pre-compiled assemblies. An assembly is emitted from a \`code\` stream and a fold overwrites \`code\` per variant, so pre-compiling must happen AFTER the fold, per variant \u2014 not before it.`
|
|
3946
|
+
);
|
|
3762
3947
|
}
|
|
3763
|
-
if (
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
i += 2;
|
|
3768
|
-
i += runFrom(shorthandRanges(e), false, i);
|
|
3769
|
-
continue;
|
|
3770
|
-
}
|
|
3771
|
-
const uni = readUnicodeEscape(source, i);
|
|
3772
|
-
let cp2;
|
|
3773
|
-
if (uni) {
|
|
3774
|
-
cp2 = uni.cp;
|
|
3775
|
-
i = uni.next;
|
|
3776
|
-
} else if (e === void 0) return null;
|
|
3777
|
-
else if (e in CLASS_ESCAPES) {
|
|
3778
|
-
cp2 = CLASS_ESCAPES[e];
|
|
3779
|
-
i += 2;
|
|
3780
|
-
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
3781
|
-
else {
|
|
3782
|
-
cp2 = e.codePointAt(0);
|
|
3783
|
-
i += 2;
|
|
3784
|
-
}
|
|
3785
|
-
if (source[i] === "?") {
|
|
3786
|
-
flush();
|
|
3787
|
-
parts.push({ part: "lit", cps: [cp2], optional: true });
|
|
3788
|
-
i++;
|
|
3789
|
-
} else lit.push(cp2);
|
|
3790
|
-
continue;
|
|
3948
|
+
if (p.code.length !== base.code.length) {
|
|
3949
|
+
throw new TypeError(
|
|
3950
|
+
`foldPrograms: variant ${JSON.stringify(name)} has ${p.code.length} code words, base ${JSON.stringify(baseName)} has ${base.code.length}. A fold overwrites words; it cannot resize the stream. These are two different tables, not one table and its edits.`
|
|
3951
|
+
);
|
|
3791
3952
|
}
|
|
3792
|
-
|
|
3793
|
-
if (
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
const c2 = source[k];
|
|
3798
|
-
if (c2 === "\\") {
|
|
3799
|
-
k += 2;
|
|
3800
|
-
continue;
|
|
3801
|
-
}
|
|
3802
|
-
if (c2 === "[") {
|
|
3803
|
-
let j = k + 1;
|
|
3804
|
-
if (source[j] === "^") j++;
|
|
3805
|
-
while (j < source.length && source[j] !== "]") {
|
|
3806
|
-
if (source[j] === "\\") j += 2;
|
|
3807
|
-
else j++;
|
|
3808
|
-
}
|
|
3809
|
-
if (source[j] !== "]") return null;
|
|
3810
|
-
k = j + 1;
|
|
3811
|
-
continue;
|
|
3812
|
-
}
|
|
3813
|
-
if (c2 === "(") depth++;
|
|
3814
|
-
else if (c2 === ")") depth--;
|
|
3815
|
-
k++;
|
|
3816
|
-
}
|
|
3817
|
-
if (depth !== 0) return null;
|
|
3818
|
-
const body = source.slice(i + 3, k - 1);
|
|
3819
|
-
const inner = parseScanShape(body);
|
|
3820
|
-
if (!inner || !groupInnerSafe(inner)) return null;
|
|
3821
|
-
const q2 = source[k];
|
|
3822
|
-
if (q2 === "{") return null;
|
|
3823
|
-
flush();
|
|
3824
|
-
if (q2 === "+") {
|
|
3825
|
-
if (shapeCanBeEmpty(inner)) return null;
|
|
3826
|
-
parts.push({ part: "group", inner, min: 1, unbounded: true });
|
|
3827
|
-
i = k + 1;
|
|
3828
|
-
} else if (q2 === "*") {
|
|
3829
|
-
if (shapeCanBeEmpty(inner)) return null;
|
|
3830
|
-
parts.push({ part: "group", inner, min: 0, unbounded: true });
|
|
3831
|
-
i = k + 1;
|
|
3832
|
-
} else if (q2 === "?") {
|
|
3833
|
-
parts.push({ part: "group", inner, min: 0, unbounded: false });
|
|
3834
|
-
i = k + 1;
|
|
3835
|
-
} else {
|
|
3836
|
-
parts.push({ part: "group", inner, min: 1, unbounded: false });
|
|
3837
|
-
i = k;
|
|
3953
|
+
for (const f of SHARED_FIELDS) {
|
|
3954
|
+
if (JSON.stringify(p[f]) !== JSON.stringify(base[f])) {
|
|
3955
|
+
throw new TypeError(
|
|
3956
|
+
`foldPrograms: variant ${JSON.stringify(name)} differs from base ${JSON.stringify(baseName)} in ${JSON.stringify(f)}, which the fold ships ONCE. Either the variants are not encodings of one grammar, or this field has become variant-dependent and needs its own delta.`
|
|
3957
|
+
);
|
|
3838
3958
|
}
|
|
3839
|
-
continue;
|
|
3840
3959
|
}
|
|
3841
|
-
if (
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
flush();
|
|
3846
|
-
parts.push({ part: "lit", cps: [cp], optional: true });
|
|
3847
|
-
i++;
|
|
3848
|
-
} else lit.push(cp);
|
|
3849
|
-
}
|
|
3850
|
-
flush();
|
|
3851
|
-
return parts.length ? parts : null;
|
|
3852
|
-
}
|
|
3853
|
-
function seqIsUnambiguous(parts) {
|
|
3854
|
-
let hasMandatory = false;
|
|
3855
|
-
for (let k = 0; k < parts.length; k++) {
|
|
3856
|
-
const p = parts[k];
|
|
3857
|
-
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
3858
|
-
if (mandatory) hasMandatory = true;
|
|
3859
|
-
if (p.part === "group") {
|
|
3860
|
-
const exposure = groupPartExposure(p);
|
|
3861
|
-
if (exposure === "unsupported") {
|
|
3862
|
-
const trailingOnce = k === parts.length - 1 && p.min === 1 && !p.unbounded;
|
|
3863
|
-
if (!trailingOnce) return false;
|
|
3864
|
-
} else if (exposure !== null) {
|
|
3865
|
-
if (!firstSetsDisjoint(exposure, seqFirstAccept(parts.slice(k + 1)))) return false;
|
|
3866
|
-
}
|
|
3960
|
+
if (p.fns.length !== base.fns.length || p.fns.some((f, i) => f !== base.fns[i])) {
|
|
3961
|
+
throw new TypeError(
|
|
3962
|
+
`foldPrograms: variant ${JSON.stringify(name)} does not share the base's reducer pool BY IDENTITY. Equal source text is not enough \u2014 two closures can print alike and capture different scopes. Encode every variant from ONE grammar export.`
|
|
3963
|
+
);
|
|
3867
3964
|
}
|
|
3868
|
-
const
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3965
|
+
const at = [];
|
|
3966
|
+
const to = [];
|
|
3967
|
+
let prev = 0;
|
|
3968
|
+
for (let i = 0; i < p.code.length; i++) {
|
|
3969
|
+
if (p.code[i] === base.code[i]) continue;
|
|
3970
|
+
at.push(i - prev);
|
|
3971
|
+
to.push(p.code[i]);
|
|
3972
|
+
prev = i;
|
|
3872
3973
|
}
|
|
3974
|
+
variants[name] = {
|
|
3975
|
+
at,
|
|
3976
|
+
to,
|
|
3977
|
+
...p.lines === void 0 ? {} : { lines: p.lines },
|
|
3978
|
+
...p.hostMode === void 0 ? {} : { hostMode: p.hostMode }
|
|
3979
|
+
};
|
|
3873
3980
|
}
|
|
3874
|
-
return
|
|
3875
|
-
}
|
|
3876
|
-
function rangesOverlap(a, b) {
|
|
3877
|
-
return a.some(([lo, hi]) => b.some(([lo2, hi2]) => lo <= hi2 && lo2 <= hi));
|
|
3878
|
-
}
|
|
3879
|
-
function rangesSubset(sub, sup) {
|
|
3880
|
-
return sub.every(([lo, hi]) => sup.some(([lo2, hi2]) => lo >= lo2 && hi <= hi2));
|
|
3881
|
-
}
|
|
3882
|
-
function classSubset(t, u) {
|
|
3883
|
-
if (!t.negated && !u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
3884
|
-
if (!t.negated && u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
3885
|
-
if (t.negated && !u.negated) return false;
|
|
3886
|
-
return rangesSubset(u.ranges, t.ranges);
|
|
3887
|
-
}
|
|
3888
|
-
function classDisjoint(t, u) {
|
|
3889
|
-
if (!t.negated && !u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
3890
|
-
if (!t.negated && u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
3891
|
-
if (t.negated && !u.negated) return rangesSubset(u.ranges, t.ranges);
|
|
3892
|
-
return false;
|
|
3893
|
-
}
|
|
3894
|
-
function firstSetsDisjoint(a, b) {
|
|
3895
|
-
if (a === "any" || b === "any") return false;
|
|
3896
|
-
return classDisjoint(a, b);
|
|
3981
|
+
return ownFoldedProgram(base, variants);
|
|
3897
3982
|
}
|
|
3898
|
-
function
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
for (const p of shape.parts) {
|
|
3908
|
-
if (p.part === "lit") {
|
|
3909
|
-
if (p.optional) return null;
|
|
3910
|
-
for (const cp of p.cps) out.push({ ranges: [[cp, cp]], negated: false });
|
|
3911
|
-
} else if (p.part === "run" && p.max === p.min && Number.isFinite(p.max)) {
|
|
3912
|
-
for (let c = 0; c < p.max; c++) out.push({ ranges: p.ranges, negated: p.negated });
|
|
3913
|
-
} else {
|
|
3914
|
-
return null;
|
|
3915
|
-
}
|
|
3916
|
-
}
|
|
3917
|
-
return out.length ? out : null;
|
|
3918
|
-
}
|
|
3919
|
-
function altFixedMutuallyExclusive(shape) {
|
|
3920
|
-
if (shape.kind !== "alt" || shape.disjoint) return false;
|
|
3921
|
-
const lists = [];
|
|
3922
|
-
for (const arm of shape.arms) {
|
|
3923
|
-
const f = fixedClassSeq(arm);
|
|
3924
|
-
if (!f) return false;
|
|
3925
|
-
lists.push(f);
|
|
3983
|
+
function unfoldVariant(folded, name) {
|
|
3984
|
+
const byName = folded[FOLDED_RUNTIME]?.byName;
|
|
3985
|
+
const hit = byName?.get(name);
|
|
3986
|
+
if (hit !== void 0) return hit;
|
|
3987
|
+
const d = folded.variants[name];
|
|
3988
|
+
if (d === void 0) {
|
|
3989
|
+
throw new TypeError(
|
|
3990
|
+
`unfoldVariant: no variant ${JSON.stringify(name)}. This table carries: ${Object.keys(folded.variants).map((n) => JSON.stringify(n)).join(", ")}.`
|
|
3991
|
+
);
|
|
3926
3992
|
}
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
let disjointAt = false;
|
|
3934
|
-
for (let p = 0; p < a.length; p++) {
|
|
3935
|
-
if (classDisjoint(a[p], b[p])) {
|
|
3936
|
-
disjointAt = true;
|
|
3937
|
-
break;
|
|
3938
|
-
}
|
|
3939
|
-
}
|
|
3940
|
-
if (!disjointAt) return false;
|
|
3941
|
-
}
|
|
3993
|
+
const base = folded.base;
|
|
3994
|
+
const code = [...base.code];
|
|
3995
|
+
let ip = 0;
|
|
3996
|
+
for (let i = 0; i < d.at.length; i++) {
|
|
3997
|
+
ip += d.at[i];
|
|
3998
|
+
code[ip] = d.to[i];
|
|
3942
3999
|
}
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
const
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
return unioned === "any" ? "unsupported" : unioned;
|
|
4000
|
+
const raw = {
|
|
4001
|
+
...base,
|
|
4002
|
+
code,
|
|
4003
|
+
...d.lines === void 0 ? {} : { lines: d.lines },
|
|
4004
|
+
...d.hostMode === void 0 ? {} : { hostMode: d.hostMode }
|
|
4005
|
+
};
|
|
4006
|
+
const prog = ownTableProgram(raw);
|
|
4007
|
+
const owner = prog[TABLE_RUNTIME];
|
|
4008
|
+
owner.resolved = { ...resolveTable(base), prog, code: Int32Array.from(code) };
|
|
4009
|
+
byName?.set(name, prog);
|
|
4010
|
+
return prog;
|
|
3955
4011
|
}
|
|
3956
|
-
function
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
if (last.max > last.min) return { ranges: last.ranges, negated: last.negated };
|
|
3967
|
-
return null;
|
|
3968
|
-
}
|
|
3969
|
-
return groupPartExposure(last);
|
|
3970
|
-
}
|
|
3971
|
-
if (shape.kind === "alt") {
|
|
3972
|
-
if (!shape.disjoint) return altFixedMutuallyExclusive(shape) ? null : "unsupported";
|
|
3973
|
-
const classes = shape.arms.map(trailingBacktrackClass);
|
|
3974
|
-
if (classes.some((c) => c === "unsupported")) return "unsupported";
|
|
3975
|
-
const concrete = classes.filter((c) => c !== null);
|
|
3976
|
-
if (concrete.length === 0) return null;
|
|
3977
|
-
const unioned = unionCharSets(concrete);
|
|
3978
|
-
return unioned === "any" ? "unsupported" : unioned;
|
|
4012
|
+
function expandCompactFolded(f) {
|
|
4013
|
+
const variants = {};
|
|
4014
|
+
for (const name of Object.keys(f.v)) {
|
|
4015
|
+
const d = f.v[name];
|
|
4016
|
+
variants[name] = {
|
|
4017
|
+
at: d.a ?? [],
|
|
4018
|
+
to: d.t ?? [],
|
|
4019
|
+
...d.l === void 0 ? {} : { lines: d.l },
|
|
4020
|
+
...d.h === void 0 ? {} : { hostMode: d.h }
|
|
4021
|
+
};
|
|
3979
4022
|
}
|
|
3980
|
-
return
|
|
3981
|
-
}
|
|
3982
|
-
function lookaheadUnambiguous(inner, operand, negative) {
|
|
3983
|
-
const tail = trailingBacktrackClass(inner);
|
|
3984
|
-
if (tail === "unsupported") return false;
|
|
3985
|
-
if (tail === null) return true;
|
|
3986
|
-
return negative ? classSubset(tail, operand) : classDisjoint(tail, operand);
|
|
4023
|
+
return ownFoldedProgram(expandCompact(f.b), variants);
|
|
3987
4024
|
}
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
return
|
|
4025
|
+
|
|
4026
|
+
// src/table/scan-shapes.ts
|
|
4027
|
+
var BACKSLASH = 92;
|
|
4028
|
+
var META2 = new Set("()[]{}*+?|^$.".split(""));
|
|
4029
|
+
function classToRanges(cls) {
|
|
4030
|
+
if (cls === "\\d") return shorthandRanges("d");
|
|
4031
|
+
if (cls === "\\w") return shorthandRanges("w");
|
|
4032
|
+
if (cls === "\\s") return shorthandRanges("s");
|
|
4033
|
+
const body = cls.slice(1, -1);
|
|
4034
|
+
if (body.startsWith("^")) return null;
|
|
4035
|
+
return parseClassRanges(body);
|
|
3999
4036
|
}
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
continue;
|
|
4024
|
-
}
|
|
4025
|
-
if (ch2 === "(") depth++;
|
|
4026
|
-
else if (ch2 === ")") depth--;
|
|
4027
|
-
i++;
|
|
4037
|
+
var foldEq = (cVar, cp) => {
|
|
4038
|
+
if (cp >= 65 && cp <= 90) return `(${cVar} | 32) === ${cp + 32}`;
|
|
4039
|
+
if (cp >= 97 && cp <= 122) return `(${cVar} | 32) === ${cp}`;
|
|
4040
|
+
return `${cVar} === ${cp}`;
|
|
4041
|
+
};
|
|
4042
|
+
function parseStringShape(source) {
|
|
4043
|
+
const q2 = source[0];
|
|
4044
|
+
if (q2 === void 0 || q2 === "\\" || META2.has(q2)) return null;
|
|
4045
|
+
if (source.length < 3 || source[source.length - 1] !== q2) return null;
|
|
4046
|
+
const inner = source.slice(1, -1);
|
|
4047
|
+
const CLS = String.raw`\[\^((?:\\.|[^\]])+)\]`;
|
|
4048
|
+
const ESC = String.raw`\\\\(\.|\[\\s\\S\]|\[\\S\\s\])`;
|
|
4049
|
+
let body;
|
|
4050
|
+
let esc;
|
|
4051
|
+
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${ESC}\\)\\*$`).exec(inner);
|
|
4052
|
+
if (m) {
|
|
4053
|
+
body = m[1];
|
|
4054
|
+
esc = m[2];
|
|
4055
|
+
} else {
|
|
4056
|
+
m = new RegExp(`^\\((?:\\?:)?${ESC}\\|${CLS}\\)\\*$`).exec(inner);
|
|
4057
|
+
if (m) {
|
|
4058
|
+
esc = m[1];
|
|
4059
|
+
body = m[2];
|
|
4028
4060
|
}
|
|
4029
|
-
if (!ok || depth !== 0 || i !== source.length) break;
|
|
4030
|
-
source = source.slice(3, -1);
|
|
4031
4061
|
}
|
|
4032
|
-
return
|
|
4062
|
+
if (body === void 0 || esc === void 0) return null;
|
|
4063
|
+
const excluded = parseClassRanges(body);
|
|
4064
|
+
if (!excluded) return null;
|
|
4065
|
+
const qcp = q2.codePointAt(0);
|
|
4066
|
+
const inSet = (cp) => excluded.some(([lo, hi]) => cp >= lo && cp <= hi);
|
|
4067
|
+
if (!inSet(qcp) || !inSet(BACKSLASH)) return null;
|
|
4068
|
+
return { kind: "string", quote: qcp, excluded, escLineTerm: esc !== "." };
|
|
4033
4069
|
}
|
|
4034
|
-
function
|
|
4035
|
-
const body = unwrapOuterGroup(source);
|
|
4070
|
+
function parseSeqParts(source) {
|
|
4036
4071
|
const parts = [];
|
|
4037
|
-
let
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
if (ch2 === "\\") {
|
|
4043
|
-
i += 2;
|
|
4044
|
-
continue;
|
|
4072
|
+
let lit = [];
|
|
4073
|
+
const flush = () => {
|
|
4074
|
+
if (lit.length) {
|
|
4075
|
+
parts.push({ part: "lit", cps: lit, optional: false });
|
|
4076
|
+
lit = [];
|
|
4045
4077
|
}
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4078
|
+
};
|
|
4079
|
+
const braceQuant = (at) => {
|
|
4080
|
+
const close = source.indexOf("}", at);
|
|
4081
|
+
if (close === -1) return null;
|
|
4082
|
+
const body = source.slice(at + 1, close);
|
|
4083
|
+
const m = /^(\d+)(,(\d*)?)?$/.exec(body);
|
|
4084
|
+
if (!m) return null;
|
|
4085
|
+
const min = Number(m[1]);
|
|
4086
|
+
const max = m[2] === void 0 ? min : m[3] ? Number(m[3]) : Infinity;
|
|
4087
|
+
if (max < 1 || min > max) return null;
|
|
4088
|
+
return { min, max, len: close - at + 1 };
|
|
4089
|
+
};
|
|
4090
|
+
const runFrom = (ranges, negated, at) => {
|
|
4091
|
+
const q2 = source[at];
|
|
4092
|
+
if (q2 === "+") {
|
|
4093
|
+
parts.push({ part: "run", ranges, negated, min: 1, max: Infinity });
|
|
4094
|
+
return 1;
|
|
4056
4095
|
}
|
|
4057
|
-
if (
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
continue;
|
|
4096
|
+
if (q2 === "*") {
|
|
4097
|
+
parts.push({ part: "run", ranges, negated, min: 0, max: Infinity });
|
|
4098
|
+
return 1;
|
|
4061
4099
|
}
|
|
4062
|
-
if (
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4100
|
+
if (q2 === "?") {
|
|
4101
|
+
parts.push({ part: "run", ranges, negated, min: 0, max: 1 });
|
|
4102
|
+
return 1;
|
|
4103
|
+
}
|
|
4104
|
+
if (q2 === "{") {
|
|
4105
|
+
const b = braceQuant(at);
|
|
4106
|
+
if (b) {
|
|
4107
|
+
parts.push({ part: "run", ranges, negated, min: b.min, max: b.max });
|
|
4108
|
+
return b.len;
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
parts.push({ part: "run", ranges, negated, min: 1, max: 1 });
|
|
4112
|
+
return 0;
|
|
4113
|
+
};
|
|
4114
|
+
let i = 0;
|
|
4115
|
+
while (i < source.length) {
|
|
4116
|
+
const ch2 = source[i];
|
|
4117
|
+
if (ch2 === "[") {
|
|
4118
|
+
let k = i + 1;
|
|
4119
|
+
const neg = source[k] === "^";
|
|
4120
|
+
if (neg) k++;
|
|
4121
|
+
let body = "";
|
|
4122
|
+
while (k < source.length && source[k] !== "]") {
|
|
4123
|
+
if (source[k] === "\\") {
|
|
4124
|
+
body += source[k] + (source[k + 1] ?? "");
|
|
4125
|
+
k += 2;
|
|
4126
|
+
} else {
|
|
4127
|
+
body += source[k];
|
|
4128
|
+
k++;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
if (source[k] !== "]") return null;
|
|
4132
|
+
const ranges = parseClassRanges(body);
|
|
4133
|
+
if (!ranges) return null;
|
|
4134
|
+
flush();
|
|
4135
|
+
i = k + 1;
|
|
4136
|
+
i += runFrom(ranges, neg, i);
|
|
4066
4137
|
continue;
|
|
4067
4138
|
}
|
|
4068
|
-
if (ch2 === "
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4139
|
+
if (ch2 === "\\") {
|
|
4140
|
+
const e = source[i + 1];
|
|
4141
|
+
if (e === "d" || e === "w" || e === "s") {
|
|
4142
|
+
flush();
|
|
4143
|
+
i += 2;
|
|
4144
|
+
i += runFrom(shorthandRanges(e), false, i);
|
|
4145
|
+
continue;
|
|
4146
|
+
}
|
|
4147
|
+
const uni = readUnicodeEscape(source, i);
|
|
4148
|
+
let cp2;
|
|
4149
|
+
if (uni) {
|
|
4150
|
+
cp2 = uni.cp;
|
|
4151
|
+
i = uni.next;
|
|
4152
|
+
} else if (e === void 0) return null;
|
|
4153
|
+
else if (e in CLASS_ESCAPES) {
|
|
4154
|
+
cp2 = CLASS_ESCAPES[e];
|
|
4155
|
+
i += 2;
|
|
4156
|
+
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
4157
|
+
else {
|
|
4158
|
+
cp2 = e.codePointAt(0);
|
|
4159
|
+
i += 2;
|
|
4160
|
+
}
|
|
4161
|
+
if (source[i] === "?") {
|
|
4162
|
+
flush();
|
|
4163
|
+
parts.push({ part: "lit", cps: [cp2], optional: true });
|
|
4164
|
+
i++;
|
|
4165
|
+
} else lit.push(cp2);
|
|
4072
4166
|
continue;
|
|
4073
4167
|
}
|
|
4074
|
-
|
|
4168
|
+
if (ch2 === "(") {
|
|
4169
|
+
if (source[i + 1] !== "?" || source[i + 2] !== ":") return null;
|
|
4170
|
+
let k = i + 3;
|
|
4171
|
+
let depth = 1;
|
|
4172
|
+
while (k < source.length && depth > 0) {
|
|
4173
|
+
const c2 = source[k];
|
|
4174
|
+
if (c2 === "\\") {
|
|
4175
|
+
k += 2;
|
|
4176
|
+
continue;
|
|
4177
|
+
}
|
|
4178
|
+
if (c2 === "[") {
|
|
4179
|
+
let j = k + 1;
|
|
4180
|
+
if (source[j] === "^") j++;
|
|
4181
|
+
while (j < source.length && source[j] !== "]") {
|
|
4182
|
+
if (source[j] === "\\") j += 2;
|
|
4183
|
+
else j++;
|
|
4184
|
+
}
|
|
4185
|
+
if (source[j] !== "]") return null;
|
|
4186
|
+
k = j + 1;
|
|
4187
|
+
continue;
|
|
4188
|
+
}
|
|
4189
|
+
if (c2 === "(") depth++;
|
|
4190
|
+
else if (c2 === ")") depth--;
|
|
4191
|
+
k++;
|
|
4192
|
+
}
|
|
4193
|
+
if (depth !== 0) return null;
|
|
4194
|
+
const body = source.slice(i + 3, k - 1);
|
|
4195
|
+
const inner = parseScanShape(body);
|
|
4196
|
+
if (!inner || !groupInnerSafe(inner)) return null;
|
|
4197
|
+
const q2 = source[k];
|
|
4198
|
+
if (q2 === "{") return null;
|
|
4199
|
+
flush();
|
|
4200
|
+
if (q2 === "+") {
|
|
4201
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
4202
|
+
parts.push({ part: "group", inner, min: 1, unbounded: true });
|
|
4203
|
+
i = k + 1;
|
|
4204
|
+
} else if (q2 === "*") {
|
|
4205
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
4206
|
+
parts.push({ part: "group", inner, min: 0, unbounded: true });
|
|
4207
|
+
i = k + 1;
|
|
4208
|
+
} else if (q2 === "?") {
|
|
4209
|
+
parts.push({ part: "group", inner, min: 0, unbounded: false });
|
|
4210
|
+
i = k + 1;
|
|
4211
|
+
} else {
|
|
4212
|
+
parts.push({ part: "group", inner, min: 1, unbounded: false });
|
|
4213
|
+
i = k;
|
|
4214
|
+
}
|
|
4215
|
+
continue;
|
|
4216
|
+
}
|
|
4217
|
+
if (META2.has(ch2)) return null;
|
|
4218
|
+
const cp = ch2.codePointAt(0);
|
|
4219
|
+
i += ch2.length;
|
|
4220
|
+
if (source[i] === "?") {
|
|
4221
|
+
flush();
|
|
4222
|
+
parts.push({ part: "lit", cps: [cp], optional: true });
|
|
4223
|
+
i++;
|
|
4224
|
+
} else lit.push(cp);
|
|
4075
4225
|
}
|
|
4076
|
-
|
|
4077
|
-
parts.
|
|
4078
|
-
if (parts.length < 2 || parts.some((p) => p.length === 0)) return null;
|
|
4079
|
-
return parts;
|
|
4226
|
+
flush();
|
|
4227
|
+
return parts.length ? parts : null;
|
|
4080
4228
|
}
|
|
4081
|
-
function
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4229
|
+
function seqIsUnambiguous(parts) {
|
|
4230
|
+
let hasMandatory = false;
|
|
4231
|
+
for (let k = 0; k < parts.length; k++) {
|
|
4232
|
+
const p = parts[k];
|
|
4233
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
4234
|
+
if (mandatory) hasMandatory = true;
|
|
4235
|
+
if (p.part === "group") {
|
|
4236
|
+
const exposure = groupPartExposure(p);
|
|
4237
|
+
if (exposure === "unsupported") {
|
|
4238
|
+
const trailingOnce = k === parts.length - 1 && p.min === 1 && !p.unbounded;
|
|
4239
|
+
if (!trailingOnce) return false;
|
|
4240
|
+
} else if (exposure !== null) {
|
|
4241
|
+
if (!firstSetsDisjoint(exposure, seqFirstAccept(parts.slice(k + 1)))) return false;
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
const needsDisjoint = p.part === "lit" ? p.optional : p.part === "run" ? p.max > p.min : p.unbounded || p.min === 0;
|
|
4245
|
+
if (needsDisjoint) {
|
|
4246
|
+
const rest = seqFirstAccept(parts.slice(k + 1));
|
|
4247
|
+
if (!firstSetsDisjoint(partFirstAccept(p), rest)) return false;
|
|
4248
|
+
}
|
|
4249
|
+
}
|
|
4250
|
+
return hasMandatory;
|
|
4086
4251
|
}
|
|
4087
|
-
function
|
|
4088
|
-
|
|
4089
|
-
const concrete = sets;
|
|
4090
|
-
if (concrete.length === 1) return concrete[0];
|
|
4091
|
-
if (concrete.some((s) => s.negated)) return "any";
|
|
4092
|
-
return { ranges: concrete.flatMap((s) => s.ranges), negated: false };
|
|
4252
|
+
function rangesOverlap(a, b) {
|
|
4253
|
+
return a.some(([lo, hi]) => b.some(([lo2, hi2]) => lo <= hi2 && lo2 <= hi));
|
|
4093
4254
|
}
|
|
4094
|
-
function
|
|
4095
|
-
|
|
4096
|
-
if (part.part === "run") return { ranges: part.ranges, negated: part.negated };
|
|
4097
|
-
return shapeFirstAccept(part.inner);
|
|
4255
|
+
function rangesSubset(sub, sup) {
|
|
4256
|
+
return sub.every(([lo, hi]) => sup.some(([lo2, hi2]) => lo >= lo2 && hi <= hi2));
|
|
4098
4257
|
}
|
|
4099
|
-
function
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
if (mandatory) break;
|
|
4105
|
-
}
|
|
4106
|
-
return unionCharSets(sets);
|
|
4258
|
+
function classSubset(t, u) {
|
|
4259
|
+
if (!t.negated && !u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
4260
|
+
if (!t.negated && u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
4261
|
+
if (t.negated && !u.negated) return false;
|
|
4262
|
+
return rangesSubset(u.ranges, t.ranges);
|
|
4107
4263
|
}
|
|
4108
|
-
function
|
|
4109
|
-
if (
|
|
4110
|
-
if (
|
|
4111
|
-
if (
|
|
4264
|
+
function classDisjoint(t, u) {
|
|
4265
|
+
if (!t.negated && !u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
4266
|
+
if (!t.negated && u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
4267
|
+
if (t.negated && !u.negated) return rangesSubset(u.ranges, t.ranges);
|
|
4112
4268
|
return false;
|
|
4113
4269
|
}
|
|
4114
|
-
function
|
|
4115
|
-
if (
|
|
4116
|
-
|
|
4117
|
-
case "chars":
|
|
4118
|
-
return { ranges: shape.ranges, negated: false };
|
|
4119
|
-
case "ident":
|
|
4120
|
-
return { ranges: shape.head, negated: false };
|
|
4121
|
-
case "until":
|
|
4122
|
-
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4123
|
-
case "delimited":
|
|
4124
|
-
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4125
|
-
case "string":
|
|
4126
|
-
return { ranges: [[shape.quote, shape.quote]], negated: false };
|
|
4127
|
-
case "litFold": {
|
|
4128
|
-
const cp = shape.open[0];
|
|
4129
|
-
if (cp >= 65 && cp <= 90) return { ranges: [[cp, cp], [cp + 32, cp + 32]], negated: false };
|
|
4130
|
-
if (cp >= 97 && cp <= 122) return { ranges: [[cp, cp], [cp - 32, cp - 32]], negated: false };
|
|
4131
|
-
return { ranges: [[cp, cp]], negated: false };
|
|
4132
|
-
}
|
|
4133
|
-
case "seq":
|
|
4134
|
-
return seqFirstAccept(shape.parts);
|
|
4135
|
-
case "lookahead":
|
|
4136
|
-
return shapeFirstAccept(shape.inner);
|
|
4137
|
-
// zero-width — doesn't change first-char acceptance
|
|
4138
|
-
case "alt": {
|
|
4139
|
-
const sets = shape.firsts.map((f) => f === null ? "any" : f);
|
|
4140
|
-
return unionCharSets(sets);
|
|
4141
|
-
}
|
|
4142
|
-
}
|
|
4270
|
+
function firstSetsDisjoint(a, b) {
|
|
4271
|
+
if (a === "any" || b === "any") return false;
|
|
4272
|
+
return classDisjoint(a, b);
|
|
4143
4273
|
}
|
|
4144
|
-
function
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4274
|
+
function fixedClassSeq(shape) {
|
|
4275
|
+
if (shape.kind === "litFold") {
|
|
4276
|
+
return shape.open.map((cp) => {
|
|
4277
|
+
const other = cp >= 65 && cp <= 90 ? cp + 32 : cp >= 97 && cp <= 122 ? cp - 32 : cp;
|
|
4278
|
+
return other === cp ? { ranges: [[cp, cp]], negated: false } : { ranges: [[Math.min(cp, other), Math.min(cp, other)], [Math.max(cp, other), Math.max(cp, other)]], negated: false };
|
|
4279
|
+
});
|
|
4280
|
+
}
|
|
4281
|
+
if (shape.kind !== "seq") return null;
|
|
4282
|
+
const out = [];
|
|
4283
|
+
for (const p of shape.parts) {
|
|
4284
|
+
if (p.part === "lit") {
|
|
4285
|
+
if (p.optional) return null;
|
|
4286
|
+
for (const cp of p.cps) out.push({ ranges: [[cp, cp]], negated: false });
|
|
4287
|
+
} else if (p.part === "run" && p.max === p.min && Number.isFinite(p.max)) {
|
|
4288
|
+
for (let c = 0; c < p.max; c++) out.push({ ranges: p.ranges, negated: p.negated });
|
|
4289
|
+
} else {
|
|
4290
|
+
return null;
|
|
4151
4291
|
}
|
|
4152
4292
|
}
|
|
4153
|
-
return
|
|
4293
|
+
return out.length ? out : null;
|
|
4154
4294
|
}
|
|
4155
|
-
function
|
|
4295
|
+
function altFixedMutuallyExclusive(shape) {
|
|
4296
|
+
if (shape.kind !== "alt" || shape.disjoint) return false;
|
|
4297
|
+
const lists = [];
|
|
4298
|
+
for (const arm of shape.arms) {
|
|
4299
|
+
const f = fixedClassSeq(arm);
|
|
4300
|
+
if (!f) return false;
|
|
4301
|
+
lists.push(f);
|
|
4302
|
+
}
|
|
4303
|
+
for (let i = 0; i < lists.length; i++) {
|
|
4304
|
+
for (let j = 0; j < lists.length; j++) {
|
|
4305
|
+
if (i === j) continue;
|
|
4306
|
+
const a = lists[i];
|
|
4307
|
+
const b = lists[j];
|
|
4308
|
+
if (a.length > b.length) continue;
|
|
4309
|
+
let disjointAt = false;
|
|
4310
|
+
for (let p = 0; p < a.length; p++) {
|
|
4311
|
+
if (classDisjoint(a[p], b[p])) {
|
|
4312
|
+
disjointAt = true;
|
|
4313
|
+
break;
|
|
4314
|
+
}
|
|
4315
|
+
}
|
|
4316
|
+
if (!disjointAt) return false;
|
|
4317
|
+
}
|
|
4318
|
+
}
|
|
4319
|
+
return true;
|
|
4320
|
+
}
|
|
4321
|
+
function groupPartExposure(part) {
|
|
4322
|
+
const innerWiggle = trailingBacktrackClass(part.inner);
|
|
4323
|
+
if (innerWiggle === "unsupported") return "unsupported";
|
|
4324
|
+
const requiredOnce = !part.unbounded && part.min === 1;
|
|
4325
|
+
if (requiredOnce) return innerWiggle;
|
|
4326
|
+
const dropExposed = shapeFirstAccept(part.inner);
|
|
4327
|
+
if (dropExposed === "any") return "unsupported";
|
|
4328
|
+
if (innerWiggle === null) return dropExposed;
|
|
4329
|
+
const unioned = unionCharSets([innerWiggle, dropExposed]);
|
|
4330
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
4331
|
+
}
|
|
4332
|
+
function trailingBacktrackClass(shape) {
|
|
4333
|
+
if (shape.kind === "chars") return { ranges: shape.ranges, negated: false };
|
|
4334
|
+
if (shape.kind === "ident") return { ranges: shape.tail, negated: false };
|
|
4335
|
+
if (shape.kind === "litFold") return null;
|
|
4336
|
+
if (shape.kind === "seq") {
|
|
4337
|
+
const last = shape.parts[shape.parts.length - 1];
|
|
4338
|
+
if (last.part === "lit") {
|
|
4339
|
+
return last.optional ? "unsupported" : null;
|
|
4340
|
+
}
|
|
4341
|
+
if (last.part === "run") {
|
|
4342
|
+
if (last.max > last.min) return { ranges: last.ranges, negated: last.negated };
|
|
4343
|
+
return null;
|
|
4344
|
+
}
|
|
4345
|
+
return groupPartExposure(last);
|
|
4346
|
+
}
|
|
4347
|
+
if (shape.kind === "alt") {
|
|
4348
|
+
if (!shape.disjoint) return altFixedMutuallyExclusive(shape) ? null : "unsupported";
|
|
4349
|
+
const classes = shape.arms.map(trailingBacktrackClass);
|
|
4350
|
+
if (classes.some((c) => c === "unsupported")) return "unsupported";
|
|
4351
|
+
const concrete = classes.filter((c) => c !== null);
|
|
4352
|
+
if (concrete.length === 0) return null;
|
|
4353
|
+
const unioned = unionCharSets(concrete);
|
|
4354
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
4355
|
+
}
|
|
4356
|
+
return "unsupported";
|
|
4357
|
+
}
|
|
4358
|
+
function lookaheadUnambiguous(inner, operand, negative) {
|
|
4359
|
+
const tail = trailingBacktrackClass(inner);
|
|
4360
|
+
if (tail === "unsupported") return false;
|
|
4361
|
+
if (tail === null) return true;
|
|
4362
|
+
return negative ? classSubset(tail, operand) : classDisjoint(tail, operand);
|
|
4363
|
+
}
|
|
4364
|
+
function stripTrailingLookahead(source) {
|
|
4365
|
+
if (!source.endsWith(")")) return null;
|
|
4366
|
+
for (const negative of [true, false]) {
|
|
4367
|
+
const lead2 = negative ? "(?!" : "(?=";
|
|
4368
|
+
const idx = source.lastIndexOf(lead2);
|
|
4369
|
+
if (idx === -1) continue;
|
|
4370
|
+
const operand = parseClassOperand(source.slice(idx + lead2.length, -1));
|
|
4371
|
+
if (!operand) continue;
|
|
4372
|
+
return { base: source.slice(0, idx), ranges: operand.ranges, classNegated: operand.negated, negative };
|
|
4373
|
+
}
|
|
4374
|
+
return null;
|
|
4375
|
+
}
|
|
4376
|
+
function unwrapOuterGroup(source) {
|
|
4377
|
+
while (source.startsWith("(?:")) {
|
|
4378
|
+
let depth = 1;
|
|
4379
|
+
let i = 3;
|
|
4380
|
+
let ok = true;
|
|
4381
|
+
while (i < source.length && depth > 0) {
|
|
4382
|
+
const ch2 = source[i];
|
|
4383
|
+
if (ch2 === "\\") {
|
|
4384
|
+
i += 2;
|
|
4385
|
+
continue;
|
|
4386
|
+
}
|
|
4387
|
+
if (ch2 === "[") {
|
|
4388
|
+
let j = i + 1;
|
|
4389
|
+
if (source[j] === "^") j++;
|
|
4390
|
+
while (j < source.length && source[j] !== "]") {
|
|
4391
|
+
if (source[j] === "\\") j += 2;
|
|
4392
|
+
else j++;
|
|
4393
|
+
}
|
|
4394
|
+
if (source[j] !== "]") {
|
|
4395
|
+
ok = false;
|
|
4396
|
+
break;
|
|
4397
|
+
}
|
|
4398
|
+
i = j + 1;
|
|
4399
|
+
continue;
|
|
4400
|
+
}
|
|
4401
|
+
if (ch2 === "(") depth++;
|
|
4402
|
+
else if (ch2 === ")") depth--;
|
|
4403
|
+
i++;
|
|
4404
|
+
}
|
|
4405
|
+
if (!ok || depth !== 0 || i !== source.length) break;
|
|
4406
|
+
source = source.slice(3, -1);
|
|
4407
|
+
}
|
|
4408
|
+
return source;
|
|
4409
|
+
}
|
|
4410
|
+
function splitTopLevelAlternation(source) {
|
|
4411
|
+
const body = unwrapOuterGroup(source);
|
|
4412
|
+
const parts = [];
|
|
4413
|
+
let depth = 0;
|
|
4414
|
+
let last = 0;
|
|
4415
|
+
let i = 0;
|
|
4416
|
+
while (i < body.length) {
|
|
4417
|
+
const ch2 = body[i];
|
|
4418
|
+
if (ch2 === "\\") {
|
|
4419
|
+
i += 2;
|
|
4420
|
+
continue;
|
|
4421
|
+
}
|
|
4422
|
+
if (ch2 === "[") {
|
|
4423
|
+
let j = i + 1;
|
|
4424
|
+
if (body[j] === "^") j++;
|
|
4425
|
+
while (j < body.length && body[j] !== "]") {
|
|
4426
|
+
if (body[j] === "\\") j += 2;
|
|
4427
|
+
else j++;
|
|
4428
|
+
}
|
|
4429
|
+
if (body[j] !== "]") return null;
|
|
4430
|
+
i = j + 1;
|
|
4431
|
+
continue;
|
|
4432
|
+
}
|
|
4433
|
+
if (ch2 === "(") {
|
|
4434
|
+
depth++;
|
|
4435
|
+
i++;
|
|
4436
|
+
continue;
|
|
4437
|
+
}
|
|
4438
|
+
if (ch2 === ")") {
|
|
4439
|
+
depth--;
|
|
4440
|
+
if (depth < 0) return null;
|
|
4441
|
+
i++;
|
|
4442
|
+
continue;
|
|
4443
|
+
}
|
|
4444
|
+
if (ch2 === "|" && depth === 0) {
|
|
4445
|
+
parts.push(body.slice(last, i));
|
|
4446
|
+
last = i + 1;
|
|
4447
|
+
i++;
|
|
4448
|
+
continue;
|
|
4449
|
+
}
|
|
4450
|
+
i++;
|
|
4451
|
+
}
|
|
4452
|
+
if (depth !== 0) return null;
|
|
4453
|
+
parts.push(body.slice(last));
|
|
4454
|
+
if (parts.length < 2 || parts.some((p) => p.length === 0)) return null;
|
|
4455
|
+
return parts;
|
|
4456
|
+
}
|
|
4457
|
+
function shapeCanBeEmpty(shape) {
|
|
4458
|
+
if (shape.kind === "chars") return !shape.minOne;
|
|
4459
|
+
if (shape.kind === "lookahead") return shapeCanBeEmpty(shape.inner);
|
|
4460
|
+
if (shape.kind === "alt") return shape.arms.some(shapeCanBeEmpty);
|
|
4461
|
+
return false;
|
|
4462
|
+
}
|
|
4463
|
+
function unionCharSets(sets) {
|
|
4464
|
+
if (sets.some((s) => s === "any")) return "any";
|
|
4465
|
+
const concrete = sets;
|
|
4466
|
+
if (concrete.length === 1) return concrete[0];
|
|
4467
|
+
if (concrete.some((s) => s.negated)) return "any";
|
|
4468
|
+
return { ranges: concrete.flatMap((s) => s.ranges), negated: false };
|
|
4469
|
+
}
|
|
4470
|
+
function partFirstAccept(part) {
|
|
4471
|
+
if (part.part === "lit") return { ranges: [[part.cps[0], part.cps[0]]], negated: false };
|
|
4472
|
+
if (part.part === "run") return { ranges: part.ranges, negated: part.negated };
|
|
4473
|
+
return shapeFirstAccept(part.inner);
|
|
4474
|
+
}
|
|
4475
|
+
function seqFirstAccept(parts) {
|
|
4476
|
+
const sets = [];
|
|
4477
|
+
for (const p of parts) {
|
|
4478
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
4479
|
+
sets.push(partFirstAccept(p));
|
|
4480
|
+
if (mandatory) break;
|
|
4481
|
+
}
|
|
4482
|
+
return unionCharSets(sets);
|
|
4483
|
+
}
|
|
4484
|
+
function groupInnerSafe(shape) {
|
|
4485
|
+
if (shape.kind === "chars" || shape.kind === "ident" || shape.kind === "seq" || shape.kind === "litFold") return true;
|
|
4486
|
+
if (shape.kind === "lookahead") return groupInnerSafe(shape.inner);
|
|
4487
|
+
if (shape.kind === "alt") return true;
|
|
4488
|
+
return false;
|
|
4489
|
+
}
|
|
4490
|
+
function shapeFirstAccept(shape) {
|
|
4491
|
+
if (shapeCanBeEmpty(shape)) return "any";
|
|
4492
|
+
switch (shape.kind) {
|
|
4493
|
+
case "chars":
|
|
4494
|
+
return { ranges: shape.ranges, negated: false };
|
|
4495
|
+
case "ident":
|
|
4496
|
+
return { ranges: shape.head, negated: false };
|
|
4497
|
+
case "until":
|
|
4498
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4499
|
+
case "delimited":
|
|
4500
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4501
|
+
case "string":
|
|
4502
|
+
return { ranges: [[shape.quote, shape.quote]], negated: false };
|
|
4503
|
+
case "litFold": {
|
|
4504
|
+
const cp = shape.open[0];
|
|
4505
|
+
if (cp >= 65 && cp <= 90) return { ranges: [[cp, cp], [cp + 32, cp + 32]], negated: false };
|
|
4506
|
+
if (cp >= 97 && cp <= 122) return { ranges: [[cp, cp], [cp - 32, cp - 32]], negated: false };
|
|
4507
|
+
return { ranges: [[cp, cp]], negated: false };
|
|
4508
|
+
}
|
|
4509
|
+
case "seq":
|
|
4510
|
+
return seqFirstAccept(shape.parts);
|
|
4511
|
+
case "lookahead":
|
|
4512
|
+
return shapeFirstAccept(shape.inner);
|
|
4513
|
+
// zero-width — doesn't change first-char acceptance
|
|
4514
|
+
case "alt": {
|
|
4515
|
+
const sets = shape.firsts.map((f) => f === null ? "any" : f);
|
|
4516
|
+
return unionCharSets(sets);
|
|
4517
|
+
}
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
function allPairsDisjoint(sets) {
|
|
4521
|
+
for (let i = 0; i < sets.length; i++) {
|
|
4522
|
+
const a = sets[i];
|
|
4523
|
+
if (a === "any") return false;
|
|
4524
|
+
for (let j = i + 1; j < sets.length; j++) {
|
|
4525
|
+
const b = sets[j];
|
|
4526
|
+
if (b === "any" || !classDisjoint(a, b)) return false;
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
return true;
|
|
4530
|
+
}
|
|
4531
|
+
function parseAlternation(source) {
|
|
4156
4532
|
const parts = splitTopLevelAlternation(source);
|
|
4157
4533
|
if (!parts) return null;
|
|
4158
4534
|
const arms = [];
|
|
@@ -4705,6 +5081,7 @@ function childSlots(code, ip, out) {
|
|
|
4705
5081
|
case OP_GATE:
|
|
4706
5082
|
case OP_SCOPE:
|
|
4707
5083
|
case OP_SCOPE_CAP:
|
|
5084
|
+
case OP_SCOPE_PLAIN:
|
|
4708
5085
|
case OP_WITHCTX:
|
|
4709
5086
|
case OP_XFORM:
|
|
4710
5087
|
case OP_NODE:
|
|
@@ -4793,7 +5170,7 @@ function reachableSites(code, roots) {
|
|
|
4793
5170
|
}
|
|
4794
5171
|
function transfer(code, ip, at, hostCst) {
|
|
4795
5172
|
const op = code[ip];
|
|
4796
|
-
if (op === OP_SCOPE || op === OP_SCOPE_CAP) {
|
|
5173
|
+
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
4797
5174
|
const ki = code[ip + 1];
|
|
4798
5175
|
const tri = ki < 0 ? TRI_NONE : ki;
|
|
4799
5176
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
@@ -4874,6 +5251,7 @@ var EMITTED_PARAMS = [
|
|
|
4874
5251
|
"pushCstLeaf",
|
|
4875
5252
|
"pushCstChild",
|
|
4876
5253
|
"rollbackTriviaAt",
|
|
5254
|
+
"rollbackScannedTriviaAt",
|
|
4877
5255
|
"failAt",
|
|
4878
5256
|
"classHas",
|
|
4879
5257
|
"consumeTrivia",
|
|
@@ -5017,19 +5395,24 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}e
|
|
|
5017
5395
|
if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,0,undefined,${t}lg,${t}rt)`;
|
|
5018
5396
|
return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "0"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
|
|
5019
5397
|
}
|
|
5020
|
-
function emitTerm(callee, dst, t, l, skip
|
|
5398
|
+
function emitTerm(callee, dst, t, l, skip) {
|
|
5021
5399
|
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
5022
5400
|
if(${t}v===FAIL)return FAIL
|
|
5023
5401
|
${dst}=${t}v
|
|
5024
5402
|
cur=EC.e`;
|
|
5025
5403
|
if (l.tri === TRI_NONE) return fast;
|
|
5026
|
-
const scanned =
|
|
5404
|
+
const scanned = `const ${t}tl=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
5405
|
+
const ${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5406
|
+
const ${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
5027
5407
|
const ${t}s=${skip}(input,cur,ctx)
|
|
5408
|
+
const ${t}stl=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
5409
|
+
const ${t}slg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5410
|
+
const ${t}srt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
5028
5411
|
const ${t}v=${callee}(input,${t}s,ctx)
|
|
5029
5412
|
if(${t}v===FAIL)return FAIL
|
|
5030
5413
|
${dst}=${t}v
|
|
5031
5414
|
if(EC.e>${t}s)cur=EC.e
|
|
5032
|
-
else{
|
|
5415
|
+
else{rollbackScannedTriviaAt(ctx,${t}tl,${t}stl,${t}lg,${t}slg,${t}rt,${t}srt)}`;
|
|
5033
5416
|
if (l.tri !== TRI_UNKNOWN) return scanned;
|
|
5034
5417
|
return `if(ctx.trivia===undefined){
|
|
5035
5418
|
${fast}
|
|
@@ -5192,7 +5575,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5192
5575
|
const op = code[ip];
|
|
5193
5576
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
5194
5577
|
if (op === OP_RULE) return code[ip + 1];
|
|
5195
|
-
if (op === OP_SCOPE && code[ip + 3] === 0 && code[ip + 1] >= 0 && labels.at(ip).tri === code[ip + 1]) {
|
|
5578
|
+
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && labels.at(ip).tri === code[ip + 1]) {
|
|
5196
5579
|
return code[ip + 2];
|
|
5197
5580
|
}
|
|
5198
5581
|
return void 0;
|
|
@@ -5243,1048 +5626,731 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5243
5626
|
tests.push(`input.charCodeAt(${at})===${f}`);
|
|
5244
5627
|
}
|
|
5245
5628
|
}
|
|
5246
|
-
return `${head}
|
|
5247
|
-
${reads.length > 0 ? `${reads.join("\n")}
|
|
5248
|
-
` : ""}if(${tests.join("&&")}){
|
|
5249
|
-
const e=pos+${s.length}
|
|
5250
|
-
const v=input.slice(pos,e)
|
|
5251
|
-
${captureLeaf("v")}
|
|
5252
|
-
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5253
|
-
return v
|
|
5254
|
-
}
|
|
5255
|
-
ctx._fe=pos;ctx._fx=${xf}
|
|
5256
|
-
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5257
|
-
` : ""}return FAIL
|
|
5258
|
-
}`;
|
|
5259
|
-
}
|
|
5260
|
-
case OP_RX:
|
|
5261
|
-
case OP_RX_TRACK: {
|
|
5262
|
-
const xf = fxRef(code[ip + 2]);
|
|
5263
|
-
const track = op === OP_RX_TRACK;
|
|
5264
|
-
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
5265
|
-
if (scanned !== void 0) return `${head}${scanned}}`;
|
|
5266
|
-
const rxk = k[code[ip + 1]];
|
|
5267
|
-
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
5268
|
-
const re = kRef(code[ip + 1]);
|
|
5269
|
-
return `${head}
|
|
5270
|
-
${re}.lastIndex=pos
|
|
5271
|
-
if(${re}.test(input)){
|
|
5272
|
-
const e=${re}.lastIndex
|
|
5273
|
-
const v=input.slice(pos,e)
|
|
5274
|
-
${captureLeaf("v")}
|
|
5275
|
-
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5276
|
-
return v
|
|
5277
|
-
}
|
|
5278
|
-
ctx._fe=pos;ctx._fx=${xf}
|
|
5279
|
-
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5280
|
-
` : ""}return FAIL
|
|
5281
|
-
}`;
|
|
5282
|
-
}
|
|
5283
|
-
case OP_EMPTY:
|
|
5284
|
-
return `${head}EC.e=pos;return ''}`;
|
|
5285
|
-
case OP_GATE: {
|
|
5286
|
-
const child = link(code[ip + 2]);
|
|
5287
|
-
const ci = classes.push([t.cc[code[ip + 1]]]) - 1;
|
|
5288
|
-
classPlan.push([code[ip + 1]]);
|
|
5289
|
-
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
5290
|
-
const xf = fxRef(code[ip + 3]);
|
|
5291
|
-
return `${head}
|
|
5292
|
-
if(!classHas(${cls},lead(input,pos))){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5293
|
-
return ${child}(input,pos,ctx)
|
|
5294
|
-
}`;
|
|
5295
|
-
}
|
|
5296
|
-
case OP_XFORM: {
|
|
5297
|
-
const fn = fnRef(code[ip + 1]);
|
|
5298
|
-
const child = link(code[ip + 2]);
|
|
5299
|
-
return `${head}
|
|
5300
|
-
const v=${child}(input,pos,ctx)
|
|
5301
|
-
if(v===FAIL)return FAIL
|
|
5302
|
-
return ${fn}(v,{start:pos,end:EC.e})
|
|
5303
|
-
}`;
|
|
5304
|
-
}
|
|
5305
|
-
case OP_LABEL: {
|
|
5306
|
-
const child = link(code[ip + 1]);
|
|
5307
|
-
const xf = fxRef(code[ip + 2]);
|
|
5308
|
-
return `${head}
|
|
5309
|
-
const v=${child}(input,pos,ctx)
|
|
5310
|
-
if(v===FAIL)ctx._fx=${xf}
|
|
5311
|
-
return v
|
|
5312
|
-
}`;
|
|
5313
|
-
}
|
|
5314
|
-
case OP_FIELD: {
|
|
5315
|
-
const name = q(k[code[ip + 1]]);
|
|
5316
|
-
const child = link(code[ip + 2]);
|
|
5317
|
-
return `${head}
|
|
5318
|
-
const v=${child}(input,pos,ctx)
|
|
5319
|
-
if(v===FAIL)return FAIL
|
|
5320
|
-
const f=ctx._fields
|
|
5321
|
-
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
5322
|
-
return v
|
|
5323
|
-
}`;
|
|
5324
|
-
}
|
|
5325
|
-
case OP_EXPECT: {
|
|
5326
|
-
const child = link(code[ip + 1]);
|
|
5327
|
-
const xf = fxRef(code[ip + 2]);
|
|
5328
|
-
return `${head}
|
|
5329
|
-
const v=${child}(input,pos,ctx)
|
|
5330
|
-
if(v!==FAIL)return v
|
|
5331
|
-
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
5332
|
-
const es=ctx._errors
|
|
5333
|
-
if(es!==undefined)es.push(err)
|
|
5334
|
-
${REC ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
5335
|
-
EC.e=pos
|
|
5336
|
-
return err
|
|
5337
|
-
}`;
|
|
5338
|
-
}
|
|
5339
|
-
case OP_ROUTED: {
|
|
5340
|
-
const fb = code[ip + 1];
|
|
5341
|
-
const fallback = fb >= 0 ? link(fb) : void 0;
|
|
5342
|
-
const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
|
|
5343
|
-
return `${head}
|
|
5344
|
-
const it=ctx._routed
|
|
5345
|
-
if(it===undefined||pos!==it.span.start){
|
|
5346
|
-
${fallback !== void 0 ? `return ${fallback}(input,pos,ctx)` : "ctx._fe=pos;ctx._fx=ROUTED_FX;return FAIL"}
|
|
5347
|
-
}
|
|
5348
|
-
${L.buf ? push : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${push}`}
|
|
5349
|
-
EC.e=it.span.end
|
|
5350
|
-
return it.value
|
|
5351
|
-
}`;
|
|
5352
|
-
}
|
|
5353
|
-
case OP_SCAN: {
|
|
5354
|
-
const si = code[ip + 1];
|
|
5355
|
-
return `${head}
|
|
5356
|
-
const r=SCANS[${si}].parse(input,pos,ctx)
|
|
5357
|
-
if(!r.ok){ctx._fe=r.span.start;ctx._fx=r.expected??EMPTY_FX;return FAIL}
|
|
5358
|
-
EC.e=r.span.end
|
|
5359
|
-
return r.value
|
|
5360
|
-
}`;
|
|
5361
|
-
}
|
|
5362
|
-
case OP_SCOPE:
|
|
5363
|
-
case OP_SCOPE_CAP: {
|
|
5364
|
-
const ki = code[ip + 1];
|
|
5365
|
-
const cap = op === OP_SCOPE_CAP;
|
|
5366
|
-
const flags = code[ip + 3];
|
|
5367
|
-
const child = link(code[ip + 2]);
|
|
5368
|
-
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
5369
|
-
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
5370
|
-
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
5371
|
-
const strict = (flags & 2) !== 0 ? "refuseUnclassifiedRootScope(ctx._rootTriviaStrictScopes)\n" : "";
|
|
5372
|
-
const rootCap = (flags & 1) !== 0;
|
|
5373
|
-
return `${head}
|
|
5374
|
-
${strict}${rootCap ? "const sR=ctx._rootTriviaCapture\nctx._rootTriviaCapture=false\n" : ""}const sT=ctx.trivia,sL=ctx.triviaKindLabels,sS=_pfScan${cap ? ",sC=ctx.captureTrivia" : ""}
|
|
5375
|
-
_pfScan=${scanFor}
|
|
5376
|
-
ctx.trivia=${tri}
|
|
5377
|
-
ctx.triviaKindLabels=${lab}
|
|
5378
|
-
${cap ? "ctx.captureTrivia=true\n" : ""}const v=${child}(input,pos,ctx)
|
|
5379
|
-
${cap ? "ctx.captureTrivia=sC\n" : ""}ctx.trivia=sT
|
|
5380
|
-
ctx.triviaKindLabels=sL
|
|
5381
|
-
_pfScan=sS
|
|
5382
|
-
${rootCap ? "ctx._rootTriviaCapture=sR\n" : ""}return v
|
|
5383
|
-
}`;
|
|
5384
|
-
}
|
|
5385
|
-
/* ── boundaries ──────────────────────────────────────────────────────── */
|
|
5386
|
-
case OP_TOKEN:
|
|
5387
|
-
case OP_LEAF: {
|
|
5388
|
-
const isToken = op === OP_TOKEN;
|
|
5389
|
-
const fn = isToken ? void 0 : fnRef(code[ip + 1]);
|
|
5390
|
-
const child = link(isToken ? code[ip + 1] : code[ip + 2]);
|
|
5391
|
-
const wasCap = L.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)";
|
|
5392
|
-
return `${head}
|
|
5393
|
-
const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5394
|
-
const sOtl=ctx._triviaLog
|
|
5395
|
-
${isToken ? "const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan,sRtl=ctx._rootTriviaLog\n" : ""}const wasCap=${wasCap}
|
|
5396
|
-
${isToken ? `_pfScan=null
|
|
5397
|
-
ctx.trivia=undefined
|
|
5398
|
-
ctx.triviaKindLabels=undefined
|
|
5399
|
-
` : ""}ctx._cstBuf=undefined
|
|
5400
|
-
ctx._cstChildren=undefined
|
|
5401
|
-
ctx._cstLeaves=undefined
|
|
5402
|
-
ctx._cstRawChildren=undefined
|
|
5403
|
-
ctx._cstTriviaLog=undefined
|
|
5404
|
-
ctx._triviaLog=undefined
|
|
5405
|
-
${isToken ? "ctx._rootTriviaLog=undefined\n" : ""}let v
|
|
5406
|
-
try{v=${child}(input,pos,ctx)}finally{
|
|
5407
|
-
${isToken ? `_pfScan=sScan
|
|
5408
|
-
ctx.trivia=sTri
|
|
5409
|
-
ctx.triviaKindLabels=sKinds
|
|
5410
|
-
ctx._rootTriviaLog=sRtl
|
|
5411
|
-
` : ""}ctx._cstBuf=sBuf
|
|
5412
|
-
ctx._cstChildren=sCh
|
|
5413
|
-
ctx._cstLeaves=sLv
|
|
5414
|
-
ctx._cstRawChildren=sRaw
|
|
5415
|
-
ctx._cstTriviaLog=sTl
|
|
5416
|
-
ctx._triviaLog=sOtl
|
|
5417
|
-
}
|
|
5418
|
-
if(v===FAIL)return FAIL
|
|
5419
|
-
const e=EC.e
|
|
5420
|
-
const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
|
|
5421
|
-
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
|
|
5422
|
-
EC.e=e
|
|
5423
|
-
return out
|
|
5424
|
-
}`;
|
|
5425
|
-
}
|
|
5426
|
-
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
5427
|
-
case OP_ATTEMPT: {
|
|
5428
|
-
const child = link(code[ip + 1]);
|
|
5429
|
-
const p = tmp();
|
|
5430
|
-
return `${head}
|
|
5431
|
-
${emitMark(p, L.buf, sinks)}
|
|
5432
|
-
const v=${child}(input,pos,ctx)
|
|
5433
|
-
if(v!==FAIL)return v
|
|
5434
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5435
|
-
if(ctx._fc===true)return FAIL
|
|
5436
|
-
ctx._fe=pos
|
|
5437
|
-
return FAIL
|
|
5438
|
-
}`;
|
|
5439
|
-
}
|
|
5440
|
-
case OP_NOT: {
|
|
5441
|
-
const child = link(code[ip + 1]);
|
|
5442
|
-
const xf = fxRef(code[ip + 2]);
|
|
5443
|
-
const p = tmp();
|
|
5444
|
-
return `${head}
|
|
5445
|
-
${emitMark(p, L.buf, sinks)}
|
|
5446
|
-
const v=${child}(input,pos,ctx)
|
|
5447
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5448
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
5449
|
-
ctx._fe=pos
|
|
5450
|
-
ctx._fx=${xf}
|
|
5451
|
-
return FAIL
|
|
5452
|
-
}`;
|
|
5453
|
-
}
|
|
5454
|
-
case OP_PEEK: {
|
|
5455
|
-
const child = link(code[ip + 1]);
|
|
5456
|
-
const xf = fxRef(code[ip + 2]);
|
|
5457
|
-
const p = tmp();
|
|
5458
|
-
return `${head}
|
|
5459
|
-
${emitMark(p, L.buf, sinks)}
|
|
5460
|
-
const v=${child}(input,pos,ctx)
|
|
5461
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5462
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5463
|
-
EC.e=pos
|
|
5464
|
-
return null
|
|
5465
|
-
}`;
|
|
5466
|
-
}
|
|
5467
|
-
case OP_OPT: {
|
|
5468
|
-
const child = link(code[ip + 1]);
|
|
5469
|
-
const p = tmp();
|
|
5470
|
-
return `${head}
|
|
5471
|
-
${emitMark(p, L.buf, sinks)}
|
|
5472
|
-
ctx._fc=false
|
|
5473
|
-
const v=${child}(input,pos,ctx)
|
|
5474
|
-
if(v===FAIL){
|
|
5475
|
-
if(ctx._fc===true)return FAIL
|
|
5476
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5477
|
-
EC.e=pos
|
|
5478
|
-
return null
|
|
5479
|
-
}
|
|
5480
|
-
return v
|
|
5481
|
-
}`;
|
|
5482
|
-
}
|
|
5483
|
-
case OP_SEQ:
|
|
5484
|
-
case OP_SEQV:
|
|
5485
|
-
case OP_SEQX: {
|
|
5486
|
-
const fused = op === OP_SEQX;
|
|
5487
|
-
const base = fused ? ip + 3 : ip + 2;
|
|
5488
|
-
const n = code[fused ? ip + 2 : ip + 1];
|
|
5489
|
-
const wantValues = op !== OP_SEQV;
|
|
5490
|
-
for (let i = 1; i < n; i++) {
|
|
5491
|
-
if (code[code[base + i]] === OP_ADJ) {
|
|
5492
|
-
throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
|
|
5493
|
-
}
|
|
5494
|
-
}
|
|
5495
|
-
const fn = fused ? fnRef(code[ip + 1]) : void 0;
|
|
5496
|
-
const kids = [];
|
|
5497
|
-
for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
|
|
5498
|
-
const sy = REC ? `${tmp()}sy` : "";
|
|
5499
|
-
const pub = (i) => {
|
|
5500
|
-
const s = sentRef(code[base + n + i]);
|
|
5501
|
-
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
5502
|
-
};
|
|
5503
|
-
const parts = [head];
|
|
5504
|
-
if (REC) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
5505
|
-
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
5506
|
-
const close = () => REC ? `${parts.join("\n")}
|
|
5507
|
-
}finally{ctx._sync=${sy}}
|
|
5508
|
-
}` : `${parts.join("\n")}
|
|
5509
|
-
}`;
|
|
5510
|
-
if (n === 1) {
|
|
5511
|
-
parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
5512
|
-
return close();
|
|
5513
|
-
}
|
|
5514
|
-
parts.push("let cur=EC.e");
|
|
5515
|
-
const names = ["v0"];
|
|
5516
|
-
for (let i = 1; i < n; i++) {
|
|
5517
|
-
const vn = `v${i}`;
|
|
5518
|
-
parts.push(`let ${vn}`);
|
|
5519
|
-
if (REC) parts.push(pub(i));
|
|
5520
|
-
parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L), sinks));
|
|
5521
|
-
names.push(vn);
|
|
5522
|
-
}
|
|
5523
|
-
parts.push("EC.e=cur");
|
|
5524
|
-
parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
5525
|
-
return close();
|
|
5526
|
-
}
|
|
5527
|
-
case OP_CHOICE: {
|
|
5528
|
-
const table = disp[code[ip + 1]];
|
|
5529
|
-
const n = code[ip + 2];
|
|
5530
|
-
const choiceFx = fxRef(code[ip + 3]);
|
|
5531
|
-
const base = ip + 4;
|
|
5532
|
-
const arms = [];
|
|
5533
|
-
for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
|
|
5534
|
-
const axi = armExpected.push(
|
|
5535
|
-
Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
|
|
5536
|
-
) - 1;
|
|
5537
|
-
armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
|
|
5538
|
-
const afx = hoist("afx", `AFX[${axi}]`);
|
|
5539
|
-
if (table.exclusive) {
|
|
5540
|
-
const di = code[ip + 1];
|
|
5541
|
-
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
5542
|
-
const hiArr = table.hi;
|
|
5543
|
-
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
5544
|
-
return `${head}
|
|
5545
|
-
const c=lead(input,pos)
|
|
5546
|
-
let arm=-1
|
|
5547
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
5548
|
-
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
5549
|
-
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
5550
|
-
if(arm>=0){
|
|
5551
|
-
ctx._fc=false
|
|
5552
|
-
let v
|
|
5553
|
-
switch(arm){
|
|
5554
|
-
${armSwitch}
|
|
5555
|
-
}
|
|
5556
|
-
if(v!==FAIL)return v
|
|
5557
|
-
if(ctx._fc===true)return FAIL
|
|
5558
|
-
const af=ctx._fx
|
|
5559
|
-
if(af!==undefined&&af.length>0){ctx._fe=pos;return FAIL}
|
|
5560
|
-
}
|
|
5561
|
-
ctx._fe=pos;ctx._fx=${choiceFx}
|
|
5562
|
-
return FAIL
|
|
5563
|
-
}`;
|
|
5564
|
-
}
|
|
5565
|
-
const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
|
|
5566
|
-
classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
|
|
5567
|
-
const gates = classes[ci];
|
|
5568
|
-
const gRef = hoist("g", `CLS[${ci}]`);
|
|
5569
|
-
const maskable = n <= 32;
|
|
5570
|
-
let maskName = "";
|
|
5571
|
-
if (maskable) {
|
|
5572
|
-
maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
|
|
5573
|
-
maskPlan.push(ci);
|
|
5574
|
-
}
|
|
5575
|
-
const p = tmp();
|
|
5576
|
-
const maskArms = arms.map((a, i) => `
|
|
5577
|
-
if((bits&${1 << i})!==0){
|
|
5578
|
-
ctx._fc=false
|
|
5579
|
-
{const v=${a}(input,pos,ctx)
|
|
5580
|
-
if(v!==FAIL)return v}
|
|
5581
|
-
for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5582
|
-
prev=${i + 1}
|
|
5583
|
-
acc=_accSet(ctx._fx,acc)
|
|
5584
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5585
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5586
|
-
}`).join("");
|
|
5587
|
-
const generalArms = arms.map((a, i) => `
|
|
5588
|
-
if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
|
|
5589
|
-
ctx._fc=false
|
|
5590
|
-
{const v=${a}(input,pos,ctx)
|
|
5591
|
-
if(v!==FAIL)return v}
|
|
5592
|
-
acc=_accSet(ctx._fx,acc)
|
|
5593
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5594
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5595
|
-
}else acc=_accSet(${afx}[${i}],acc)`).join("");
|
|
5596
|
-
return `${head}
|
|
5597
|
-
const c=lead(input,pos)
|
|
5598
|
-
${emitMark(p, L.buf, sinks)}
|
|
5599
|
-
let acc
|
|
5600
|
-
${maskable ? `if(c<128){
|
|
5601
|
-
const bits=${maskName}[c<0?128:c]
|
|
5602
|
-
let prev=0
|
|
5603
|
-
${maskArms}
|
|
5604
|
-
for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5605
|
-
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5606
|
-
return FAIL
|
|
5629
|
+
return `${head}
|
|
5630
|
+
${reads.length > 0 ? `${reads.join("\n")}
|
|
5631
|
+
` : ""}if(${tests.join("&&")}){
|
|
5632
|
+
const e=pos+${s.length}
|
|
5633
|
+
const v=input.slice(pos,e)
|
|
5634
|
+
${captureLeaf("v")}
|
|
5635
|
+
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5636
|
+
return v
|
|
5607
5637
|
}
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
return FAIL
|
|
5638
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
5639
|
+
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5640
|
+
` : ""}return FAIL
|
|
5611
5641
|
}`;
|
|
5612
5642
|
}
|
|
5613
|
-
case
|
|
5614
|
-
|
|
5615
|
-
const
|
|
5616
|
-
const
|
|
5617
|
-
const
|
|
5618
|
-
|
|
5619
|
-
const
|
|
5620
|
-
|
|
5621
|
-
const
|
|
5622
|
-
const arms = [];
|
|
5623
|
-
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
5624
|
-
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
5625
|
-
const rt = hoist("rt", `DSP[${di}].routed`);
|
|
5626
|
-
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
5627
|
-
const claims = (m) => {
|
|
5628
|
-
switch (m[0]) {
|
|
5629
|
-
case 0:
|
|
5630
|
-
return `key.startsWith(${q(m[1])})`;
|
|
5631
|
-
case 1:
|
|
5632
|
-
return `key.endsWith(${q(m[1])})`;
|
|
5633
|
-
case 3:
|
|
5634
|
-
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
5635
|
-
case 4:
|
|
5636
|
-
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
5637
|
-
default:
|
|
5638
|
-
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
5639
|
-
}
|
|
5640
|
-
};
|
|
5641
|
-
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
5642
|
-
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
|
|
5643
|
-
}
|
|
5644
|
-
`;
|
|
5645
|
-
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
5646
|
-
` : "";
|
|
5647
|
-
const m1 = tmp();
|
|
5648
|
-
const m2 = tmp();
|
|
5643
|
+
case OP_RX:
|
|
5644
|
+
case OP_RX_TRACK: {
|
|
5645
|
+
const xf = fxRef(code[ip + 2]);
|
|
5646
|
+
const track = op === OP_RX_TRACK;
|
|
5647
|
+
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
5648
|
+
if (scanned !== void 0) return `${head}${scanned}}`;
|
|
5649
|
+
const rxk = k[code[ip + 1]];
|
|
5650
|
+
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
5651
|
+
const re = kRef(code[ip + 1]);
|
|
5649
5652
|
return `${head}
|
|
5650
|
-
${
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
const
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
if(arm===undefined){
|
|
5658
|
-
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : `ur=${String(otherRouted)}`}
|
|
5659
|
-
}else ur=${rt}[arm]===1
|
|
5660
|
-
const savedRouted=ctx._routed
|
|
5661
|
-
${emitMark(m2, L.buf, sinks)}
|
|
5662
|
-
if(ur){
|
|
5663
|
-
${emitRollback(m1, L.buf, sinks)}
|
|
5664
|
-
${emitMark(m2, L.buf, sinks, false)}
|
|
5665
|
-
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
5666
|
-
}
|
|
5667
|
-
const at=ur?pos:selEnd
|
|
5668
|
-
let v
|
|
5669
|
-
switch(arm){
|
|
5670
|
-
${arms.map((a, i) => `case ${i}:v=${a}(input,at,ctx);break`).join("\n")}
|
|
5671
|
-
${other === void 0 ? "" : `default:v=${other}(input,at,ctx)`}
|
|
5672
|
-
}
|
|
5673
|
-
if(ur)ctx._routed=savedRouted
|
|
5674
|
-
if(v===FAIL){
|
|
5675
|
-
${emitRollback(m2, L.buf, sinks)}
|
|
5676
|
-
ctx._fc=true
|
|
5677
|
-
return FAIL
|
|
5653
|
+
${re}.lastIndex=pos
|
|
5654
|
+
if(${re}.test(input)){
|
|
5655
|
+
const e=${re}.lastIndex
|
|
5656
|
+
const v=input.slice(pos,e)
|
|
5657
|
+
${captureLeaf("v")}
|
|
5658
|
+
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5659
|
+
return v
|
|
5678
5660
|
}
|
|
5679
|
-
|
|
5661
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
5662
|
+
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5663
|
+
` : ""}return FAIL
|
|
5680
5664
|
}`;
|
|
5681
5665
|
}
|
|
5682
|
-
case
|
|
5683
|
-
|
|
5666
|
+
case OP_EMPTY:
|
|
5667
|
+
return `${head}EC.e=pos;return ''}`;
|
|
5668
|
+
case OP_GATE: {
|
|
5669
|
+
const child = link(code[ip + 2]);
|
|
5670
|
+
const ci = classes.push([t.cc[code[ip + 1]]]) - 1;
|
|
5671
|
+
classPlan.push([code[ip + 1]]);
|
|
5672
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
5673
|
+
const xf = fxRef(code[ip + 3]);
|
|
5674
|
+
return `${head}
|
|
5675
|
+
if(!classHas(${cls},lead(input,pos))){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5676
|
+
return ${child}(input,pos,ctx)
|
|
5677
|
+
}`;
|
|
5678
|
+
}
|
|
5679
|
+
case OP_XFORM: {
|
|
5680
|
+
const fn = fnRef(code[ip + 1]);
|
|
5681
|
+
const child = link(code[ip + 2]);
|
|
5682
|
+
return `${head}
|
|
5683
|
+
const v=${child}(input,pos,ctx)
|
|
5684
|
+
if(v===FAIL)return FAIL
|
|
5685
|
+
return ${fn}(v,{start:pos,end:EC.e})
|
|
5686
|
+
}`;
|
|
5687
|
+
}
|
|
5688
|
+
case OP_LABEL: {
|
|
5684
5689
|
const child = link(code[ip + 1]);
|
|
5685
|
-
const
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
const keepSeparators = (flags & 2) !== 0;
|
|
5691
|
-
const trailingAllowed = (flags & 1) !== 0;
|
|
5692
|
-
const reportItem = (flags & 4) !== 0;
|
|
5693
|
-
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
5694
|
-
const collect = op === OP_REP;
|
|
5695
|
-
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
5696
|
-
const p = tmp();
|
|
5697
|
-
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
5698
|
-
const leadTrivia = skipBeforeFirst ? "true" : "count>0";
|
|
5699
|
-
const skip = skipFor(L);
|
|
5700
|
-
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
5701
|
-
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
5702
|
-
const needMark = L.buf ? "true" : "needMark";
|
|
5703
|
-
const pfd = sinks.fd ? `${p}fd` : "0";
|
|
5704
|
-
const per = sinks.er ? `${p}er` : "undefined";
|
|
5705
|
-
const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
5706
|
-
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
5707
|
-
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)`;
|
|
5708
|
-
const markSinks = `${sinks.fd ? `
|
|
5709
|
-
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
5710
|
-
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
5711
|
-
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
5712
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
5713
|
-
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
5714
|
-
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
5715
|
-
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5716
|
-
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
5717
|
-
const b=ctx._cstBuf
|
|
5718
|
-
if(b!==undefined){
|
|
5719
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
5720
|
-
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
5721
|
-
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
5722
|
-
}else{
|
|
5723
|
-
${p}raw=ctx._cstRawChildren!==undefined?ctx._cstRawChildren.length:0
|
|
5724
|
-
${p}tl=ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0
|
|
5725
|
-
${p}lv=ctx._cstLeaves!==undefined?ctx._cstLeaves.length:0
|
|
5726
|
-
}
|
|
5727
|
-
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5728
|
-
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
5690
|
+
const xf = fxRef(code[ip + 2]);
|
|
5691
|
+
return `${head}
|
|
5692
|
+
const v=${child}(input,pos,ctx)
|
|
5693
|
+
if(v===FAIL)ctx._fx=${xf}
|
|
5694
|
+
return v
|
|
5729
5695
|
}`;
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
const
|
|
5733
|
-
const
|
|
5734
|
-
const recGate = sep !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
5735
|
-
const recBranch = !REC ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
5736
|
-
${sep === void 0 ? `${rb}
|
|
5737
|
-
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
5738
|
-
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
5739
|
-
count++
|
|
5740
|
-
cur=rr.end
|
|
5741
|
-
continue
|
|
5742
|
-
}
|
|
5743
|
-
`;
|
|
5696
|
+
}
|
|
5697
|
+
case OP_FIELD: {
|
|
5698
|
+
const name = q(k[code[ip + 1]]);
|
|
5699
|
+
const child = link(code[ip + 2]);
|
|
5744
5700
|
return `${head}
|
|
5745
|
-
const
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
${
|
|
5774
|
-
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
5775
|
-
}
|
|
5776
|
-
ctx._fc=false
|
|
5777
|
-
const v=${child}(input,itemStart,ctx)
|
|
5778
|
-
if(v===FAIL){
|
|
5779
|
-
${REC ? `if(ctx._fc===true){
|
|
5780
|
-
${rb}
|
|
5781
|
-
return FAIL
|
|
5782
|
-
}
|
|
5783
|
-
${recBranch}${rb}` : `${rb}
|
|
5784
|
-
if(ctx._fc===true)return FAIL`}
|
|
5785
|
-
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
5786
|
-
}
|
|
5787
|
-
if(EC.e===itemStart&&${via}){
|
|
5788
|
-
${rb}
|
|
5789
|
-
break
|
|
5790
|
-
}
|
|
5791
|
-
${collect ? "out.push(v)\n" : ""}cur=EC.e
|
|
5792
|
-
count++
|
|
5793
|
-
}
|
|
5794
|
-
${min > 0 ? `if(count<${min}){
|
|
5795
|
-
${reportItem ? `ctx._fe=cur;ctx._fx=${itemFx}
|
|
5796
|
-
` : ""}return FAIL
|
|
5701
|
+
const v=${child}(input,pos,ctx)
|
|
5702
|
+
if(v===FAIL)return FAIL
|
|
5703
|
+
const f=ctx._fields
|
|
5704
|
+
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
5705
|
+
return v
|
|
5706
|
+
}`;
|
|
5707
|
+
}
|
|
5708
|
+
case OP_EXPECT: {
|
|
5709
|
+
const child = link(code[ip + 1]);
|
|
5710
|
+
const xf = fxRef(code[ip + 2]);
|
|
5711
|
+
return `${head}
|
|
5712
|
+
const v=${child}(input,pos,ctx)
|
|
5713
|
+
if(v!==FAIL)return v
|
|
5714
|
+
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
5715
|
+
const es=ctx._errors
|
|
5716
|
+
if(es!==undefined)es.push(err)
|
|
5717
|
+
${REC ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
5718
|
+
EC.e=pos
|
|
5719
|
+
return err
|
|
5720
|
+
}`;
|
|
5721
|
+
}
|
|
5722
|
+
case OP_ROUTED: {
|
|
5723
|
+
const fb = code[ip + 1];
|
|
5724
|
+
const fallback = fb >= 0 ? link(fb) : void 0;
|
|
5725
|
+
const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
|
|
5726
|
+
return `${head}
|
|
5727
|
+
const it=ctx._routed
|
|
5728
|
+
if(it===undefined||pos!==it.span.start){
|
|
5729
|
+
${fallback !== void 0 ? `return ${fallback}(input,pos,ctx)` : "ctx._fe=pos;ctx._fx=ROUTED_FX;return FAIL"}
|
|
5797
5730
|
}
|
|
5798
|
-
|
|
5799
|
-
|
|
5731
|
+
${L.buf ? push : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${push}`}
|
|
5732
|
+
EC.e=it.span.end
|
|
5733
|
+
return it.value
|
|
5800
5734
|
}`;
|
|
5801
5735
|
}
|
|
5802
|
-
case
|
|
5803
|
-
|
|
5804
|
-
|
|
5736
|
+
case OP_SCAN: {
|
|
5737
|
+
const si = code[ip + 1];
|
|
5738
|
+
return `${head}
|
|
5739
|
+
const r=SCANS[${si}].parse(input,pos,ctx)
|
|
5740
|
+
if(!r.ok){ctx._fe=r.span.start;ctx._fx=r.expected??EMPTY_FX;return FAIL}
|
|
5741
|
+
EC.e=r.span.end
|
|
5742
|
+
return r.value
|
|
5743
|
+
}`;
|
|
5744
|
+
}
|
|
5745
|
+
case OP_SCOPE:
|
|
5746
|
+
case OP_SCOPE_CAP:
|
|
5747
|
+
case OP_SCOPE_PLAIN: {
|
|
5748
|
+
const ki = code[ip + 1];
|
|
5749
|
+
const cap = op === OP_SCOPE_CAP;
|
|
5750
|
+
const flags = op === OP_SCOPE_PLAIN ? 0 : code[ip + 3];
|
|
5805
5751
|
const child = link(code[ip + 2]);
|
|
5806
|
-
const
|
|
5807
|
-
const
|
|
5808
|
-
const
|
|
5809
|
-
const
|
|
5810
|
-
const
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
const
|
|
5827
|
-
const
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
const openCapture = keepChildren ? `const buf={}
|
|
5839
|
-
ctx._cstBuf=buf
|
|
5840
|
-
ctx._cstChildren=undefined
|
|
5841
|
-
ctx._cstLeaves=undefined
|
|
5842
|
-
ctx._cstRawChildren=undefined
|
|
5843
|
-
ctx._cstTriviaLog=undefined` : `const buf={rawOnly:true}
|
|
5844
|
-
ctx._cstBuf=buf
|
|
5752
|
+
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
5753
|
+
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
5754
|
+
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
5755
|
+
const strict = (flags & 2) !== 0 ? "refuseUnclassifiedRootScope(ctx._rootTriviaStrictScopes)\n" : "";
|
|
5756
|
+
const rootCap = (flags & 1) !== 0;
|
|
5757
|
+
return `${head}
|
|
5758
|
+
${strict}${rootCap ? "const sR=ctx._rootTriviaCapture\nctx._rootTriviaCapture=false\n" : ""}const sT=ctx.trivia,sL=ctx.triviaKindLabels,sS=_pfScan${cap ? ",sC=ctx.captureTrivia" : ""}
|
|
5759
|
+
_pfScan=${scanFor}
|
|
5760
|
+
ctx.trivia=${tri}
|
|
5761
|
+
ctx.triviaKindLabels=${lab}
|
|
5762
|
+
${cap ? "ctx.captureTrivia=true\n" : ""}const v=${child}(input,pos,ctx)
|
|
5763
|
+
${cap ? "ctx.captureTrivia=sC\n" : ""}ctx.trivia=sT
|
|
5764
|
+
ctx.triviaKindLabels=sL
|
|
5765
|
+
_pfScan=sS
|
|
5766
|
+
${rootCap ? "ctx._rootTriviaCapture=sR\n" : ""}return v
|
|
5767
|
+
}`;
|
|
5768
|
+
}
|
|
5769
|
+
/* ── boundaries ──────────────────────────────────────────────────────── */
|
|
5770
|
+
case OP_TOKEN:
|
|
5771
|
+
case OP_LEAF: {
|
|
5772
|
+
const isToken = op === OP_TOKEN;
|
|
5773
|
+
const fn = isToken ? void 0 : fnRef(code[ip + 1]);
|
|
5774
|
+
const child = link(isToken ? code[ip + 1] : code[ip + 2]);
|
|
5775
|
+
const wasCap = L.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)";
|
|
5776
|
+
return `${head}
|
|
5777
|
+
const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5778
|
+
const sOtl=ctx._triviaLog
|
|
5779
|
+
${isToken ? "const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan,sRtl=ctx._rootTriviaLog\n" : ""}const wasCap=${wasCap}
|
|
5780
|
+
${isToken ? `_pfScan=null
|
|
5781
|
+
ctx.trivia=undefined
|
|
5782
|
+
ctx.triviaKindLabels=undefined
|
|
5783
|
+
` : ""}ctx._cstBuf=undefined
|
|
5845
5784
|
ctx._cstChildren=undefined
|
|
5846
5785
|
ctx._cstLeaves=undefined
|
|
5847
5786
|
ctx._cstRawChildren=undefined
|
|
5848
|
-
ctx._cstTriviaLog=undefined
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5858
|
-
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
5859
|
-
${openCapture}
|
|
5860
|
-
ctx.captureTrivia=${captureWide}
|
|
5861
|
-
const savedFields=ctx._fields
|
|
5862
|
-
ctx._fields=${wantFields ? "[]" : "undefined"}
|
|
5863
|
-
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
5864
|
-
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
5865
|
-
` : ""}const v=${child}(input,pos,ctx)
|
|
5866
|
-
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
5867
|
-
` : ""}const fieldMap=${wantFields ? "buildFieldMap(ctx._fields)" : "undefined"}
|
|
5868
|
-
ctx._fields=savedFields
|
|
5869
|
-
${structural ? "ctx._triviaCaptureMask=savedMask\n" : ""}${finishCapture}
|
|
5870
|
-
ctx._cstBuf=sBuf
|
|
5787
|
+
ctx._cstTriviaLog=undefined
|
|
5788
|
+
ctx._triviaLog=undefined
|
|
5789
|
+
${isToken ? "ctx._rootTriviaLog=undefined\n" : ""}let v
|
|
5790
|
+
try{v=${child}(input,pos,ctx)}finally{
|
|
5791
|
+
${isToken ? `_pfScan=sScan
|
|
5792
|
+
ctx.trivia=sTri
|
|
5793
|
+
ctx.triviaKindLabels=sKinds
|
|
5794
|
+
ctx._rootTriviaLog=sRtl
|
|
5795
|
+
` : ""}ctx._cstBuf=sBuf
|
|
5871
5796
|
ctx._cstChildren=sCh
|
|
5872
5797
|
ctx._cstLeaves=sLv
|
|
5873
5798
|
ctx._cstRawChildren=sRaw
|
|
5874
5799
|
ctx._cstTriviaLog=sTl
|
|
5875
|
-
ctx.
|
|
5800
|
+
ctx._triviaLog=sOtl
|
|
5801
|
+
}
|
|
5876
5802
|
if(v===FAIL)return FAIL
|
|
5877
|
-
const
|
|
5878
|
-
const
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
else ` : ""}{${value}}
|
|
5883
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
5884
|
-
EC.e=end
|
|
5885
|
-
return nd
|
|
5803
|
+
const e=EC.e
|
|
5804
|
+
const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
|
|
5805
|
+
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
|
|
5806
|
+
EC.e=e
|
|
5807
|
+
return out
|
|
5886
5808
|
}`;
|
|
5887
5809
|
}
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5810
|
+
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
5811
|
+
case OP_ATTEMPT: {
|
|
5812
|
+
const child = link(code[ip + 1]);
|
|
5813
|
+
const p = tmp();
|
|
5814
|
+
return `${head}
|
|
5815
|
+
${emitMark(p, L.buf, sinks)}
|
|
5816
|
+
const v=${child}(input,pos,ctx)
|
|
5817
|
+
if(v!==FAIL)return v
|
|
5818
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5819
|
+
if(ctx._fc===true)return FAIL
|
|
5820
|
+
ctx._fe=pos
|
|
5821
|
+
return FAIL
|
|
5822
|
+
}`;
|
|
5823
|
+
}
|
|
5824
|
+
case OP_NOT: {
|
|
5825
|
+
const child = link(code[ip + 1]);
|
|
5826
|
+
const xf = fxRef(code[ip + 2]);
|
|
5827
|
+
const p = tmp();
|
|
5828
|
+
return `${head}
|
|
5829
|
+
${emitMark(p, L.buf, sinks)}
|
|
5830
|
+
const v=${child}(input,pos,ctx)
|
|
5831
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5832
|
+
if(v===FAIL){EC.e=pos;return null}
|
|
5833
|
+
ctx._fe=pos
|
|
5834
|
+
ctx._fx=${xf}
|
|
5835
|
+
return FAIL
|
|
5836
|
+
}`;
|
|
5837
|
+
}
|
|
5838
|
+
case OP_PEEK: {
|
|
5839
|
+
const child = link(code[ip + 1]);
|
|
5840
|
+
const xf = fxRef(code[ip + 2]);
|
|
5841
|
+
const p = tmp();
|
|
5842
|
+
return `${head}
|
|
5843
|
+
${emitMark(p, L.buf, sinks)}
|
|
5844
|
+
const v=${child}(input,pos,ctx)
|
|
5845
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5846
|
+
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5847
|
+
EC.e=pos
|
|
5848
|
+
return null
|
|
5849
|
+
}`;
|
|
5850
|
+
}
|
|
5851
|
+
case OP_OPT: {
|
|
5852
|
+
const child = link(code[ip + 1]);
|
|
5853
|
+
const p = tmp();
|
|
5854
|
+
return `${head}
|
|
5855
|
+
${emitMark(p, L.buf, sinks)}
|
|
5856
|
+
ctx._fc=false
|
|
5857
|
+
const v=${child}(input,pos,ctx)
|
|
5858
|
+
if(v===FAIL){
|
|
5859
|
+
if(ctx._fc===true)return FAIL
|
|
5860
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5861
|
+
EC.e=pos
|
|
5862
|
+
return null
|
|
5920
5863
|
}
|
|
5921
|
-
return
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5864
|
+
return v
|
|
5865
|
+
}`;
|
|
5866
|
+
}
|
|
5867
|
+
case OP_SEQ:
|
|
5868
|
+
case OP_SEQV:
|
|
5869
|
+
case OP_SEQX: {
|
|
5870
|
+
const fused = op === OP_SEQX;
|
|
5871
|
+
const base = fused ? ip + 3 : ip + 2;
|
|
5872
|
+
const n = code[fused ? ip + 2 : ip + 1];
|
|
5873
|
+
const wantValues = op !== OP_SEQV;
|
|
5874
|
+
for (let i = 1; i < n; i++) {
|
|
5875
|
+
if (code[code[base + i]] === OP_ADJ) {
|
|
5876
|
+
throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
|
|
5877
|
+
}
|
|
5878
|
+
}
|
|
5879
|
+
const fn = fused ? fnRef(code[ip + 1]) : void 0;
|
|
5880
|
+
const kids = [];
|
|
5881
|
+
for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
|
|
5882
|
+
const sy = REC ? `${tmp()}sy` : "";
|
|
5883
|
+
const pub = (i) => {
|
|
5884
|
+
const s = sentRef(code[base + n + i]);
|
|
5885
|
+
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
5886
|
+
};
|
|
5887
|
+
const parts = [head];
|
|
5888
|
+
if (REC) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
5889
|
+
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
5890
|
+
const close = () => REC ? `${parts.join("\n")}
|
|
5891
|
+
}finally{ctx._sync=${sy}}
|
|
5892
|
+
}` : `${parts.join("\n")}
|
|
5927
5893
|
}`;
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5894
|
+
if (n === 1) {
|
|
5895
|
+
parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
5896
|
+
return close();
|
|
5897
|
+
}
|
|
5898
|
+
parts.push("let cur=EC.e");
|
|
5899
|
+
const names = ["v0"];
|
|
5900
|
+
for (let i = 1; i < n; i++) {
|
|
5901
|
+
const vn = `v${i}`;
|
|
5902
|
+
parts.push(`let ${vn}`);
|
|
5903
|
+
if (REC) parts.push(pub(i));
|
|
5904
|
+
parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
|
|
5905
|
+
names.push(vn);
|
|
5906
|
+
}
|
|
5907
|
+
parts.push("EC.e=cur");
|
|
5908
|
+
parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
5909
|
+
return close();
|
|
5910
|
+
}
|
|
5911
|
+
case OP_CHOICE: {
|
|
5912
|
+
const table = disp[code[ip + 1]];
|
|
5913
|
+
const n = code[ip + 2];
|
|
5914
|
+
const choiceFx = fxRef(code[ip + 3]);
|
|
5915
|
+
const base = ip + 4;
|
|
5916
|
+
const arms = [];
|
|
5917
|
+
for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
|
|
5918
|
+
const axi = armExpected.push(
|
|
5919
|
+
Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
|
|
5920
|
+
) - 1;
|
|
5921
|
+
armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
|
|
5922
|
+
const afx = hoist("afx", `AFX[${axi}]`);
|
|
5923
|
+
if (table.exclusive) {
|
|
5924
|
+
const di = code[ip + 1];
|
|
5925
|
+
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
5926
|
+
const hiArr = table.hi;
|
|
5927
|
+
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
5928
|
+
return `${head}
|
|
5929
|
+
const c=lead(input,pos)
|
|
5930
|
+
let arm=-1
|
|
5931
|
+
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
5932
|
+
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
5933
|
+
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
5934
|
+
if(arm>=0){
|
|
5935
|
+
ctx._fc=false
|
|
5936
|
+
let v
|
|
5937
|
+
switch(arm){
|
|
5938
|
+
${armSwitch}
|
|
5936
5939
|
}
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
let lo = 0, hi = starts.length - 1;
|
|
5942
|
-
while (lo < hi) {
|
|
5943
|
-
const mid = lo + hi + 1 >> 1;
|
|
5944
|
-
if (starts[mid] <= offset) lo = mid;
|
|
5945
|
-
else hi = mid - 1;
|
|
5946
|
-
}
|
|
5947
|
-
return [lo + 1, offset - starts[lo] + 1];
|
|
5940
|
+
if(v!==FAIL)return v
|
|
5941
|
+
if(ctx._fc===true)return FAIL
|
|
5942
|
+
const af=ctx._fx
|
|
5943
|
+
if(af!==undefined&&af.length>0){ctx._fe=pos;return FAIL}
|
|
5948
5944
|
}
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5945
|
+
ctx._fe=pos;ctx._fx=${choiceFx}
|
|
5946
|
+
return FAIL
|
|
5947
|
+
}`;
|
|
5948
|
+
}
|
|
5949
|
+
const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
|
|
5950
|
+
classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
|
|
5951
|
+
const gates = classes[ci];
|
|
5952
|
+
const gRef = hoist("g", `CLS[${ci}]`);
|
|
5953
|
+
const maskable = n <= 32;
|
|
5954
|
+
let maskName = "";
|
|
5955
|
+
if (maskable) {
|
|
5956
|
+
maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
|
|
5957
|
+
maskPlan.push(ci);
|
|
5958
|
+
}
|
|
5959
|
+
const p = tmp();
|
|
5960
|
+
const maskArms = arms.map((a, i) => `
|
|
5961
|
+
if((bits&${1 << i})!==0){
|
|
5962
|
+
ctx._fc=false
|
|
5963
|
+
{const v=${a}(input,pos,ctx)
|
|
5964
|
+
if(v!==FAIL)return v}
|
|
5965
|
+
for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5966
|
+
prev=${i + 1}
|
|
5967
|
+
acc=_accSet(ctx._fx,acc)
|
|
5968
|
+
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5969
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5970
|
+
}`).join("");
|
|
5971
|
+
const generalArms = arms.map((a, i) => `
|
|
5972
|
+
if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
|
|
5973
|
+
ctx._fc=false
|
|
5974
|
+
{const v=${a}(input,pos,ctx)
|
|
5975
|
+
if(v!==FAIL)return v}
|
|
5976
|
+
acc=_accSet(ctx._fx,acc)
|
|
5977
|
+
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5978
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5979
|
+
}else acc=_accSet(${afx}[${i}],acc)`).join("");
|
|
5980
|
+
return `${head}
|
|
5981
|
+
const c=lead(input,pos)
|
|
5982
|
+
${emitMark(p, L.buf, sinks)}
|
|
5983
|
+
let acc
|
|
5984
|
+
${maskable ? `if(c<128){
|
|
5985
|
+
const bits=${maskName}[c<0?128:c]
|
|
5986
|
+
let prev=0
|
|
5987
|
+
${maskArms}
|
|
5988
|
+
for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5989
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5990
|
+
return FAIL
|
|
5952
5991
|
}
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
|
|
5957
|
-
|
|
5958
|
-
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5992
|
+
` : ""}${generalArms}
|
|
5993
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5994
|
+
return FAIL
|
|
5995
|
+
}`;
|
|
5996
|
+
}
|
|
5997
|
+
case OP_DISPATCH: {
|
|
5998
|
+
const di = code[ip + 2];
|
|
5999
|
+
const spec = dsp[di];
|
|
6000
|
+
const selector = link(code[ip + 1]);
|
|
6001
|
+
const otherIp = code[ip + 3];
|
|
6002
|
+
const other = otherIp >= 0 ? link(otherIp) : void 0;
|
|
6003
|
+
const otherRouted = code[ip + 4] === 1;
|
|
6004
|
+
const n = code[ip + 5];
|
|
6005
|
+
validateDispatchSpec(spec, n, code[ip + 4]);
|
|
6006
|
+
const armBase = ip + 6;
|
|
6007
|
+
const arms = [];
|
|
6008
|
+
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
6009
|
+
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
6010
|
+
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
6011
|
+
const claims = (m) => {
|
|
6012
|
+
switch (m[0]) {
|
|
6013
|
+
case 0:
|
|
6014
|
+
return `key.startsWith(${q(m[1])})`;
|
|
6015
|
+
case 1:
|
|
6016
|
+
return `key.endsWith(${q(m[1])})`;
|
|
6017
|
+
case 3:
|
|
6018
|
+
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
6019
|
+
case 4:
|
|
6020
|
+
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
6021
|
+
default:
|
|
6022
|
+
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
6023
|
+
}
|
|
6024
|
+
};
|
|
6025
|
+
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
6026
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
|
|
5963
6027
|
}
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
6028
|
+
`;
|
|
6029
|
+
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
6030
|
+
` : "";
|
|
6031
|
+
const m1 = tmp();
|
|
6032
|
+
const m2 = tmp();
|
|
6033
|
+
const routedCall = (target) => `{const savedRouted=ctx._routed
|
|
6034
|
+
${emitRollback(m1, L.buf, sinks)}
|
|
6035
|
+
${emitMark(m2, L.buf, sinks, false)}
|
|
6036
|
+
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
6037
|
+
try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
|
|
6038
|
+
break}`;
|
|
6039
|
+
const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
|
|
6040
|
+
const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
|
|
6041
|
+
const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
|
|
6042
|
+
return `${head}
|
|
6043
|
+
${emitMark(m1, L.buf, sinks)}
|
|
6044
|
+
const sv=${selector}(input,pos,ctx)
|
|
6045
|
+
if(sv===FAIL)return FAIL
|
|
6046
|
+
const selEnd=EC.e
|
|
6047
|
+
const key=sv
|
|
6048
|
+
let arm=${bk}.get(key)
|
|
6049
|
+
${fold}${chain}
|
|
6050
|
+
if(arm===undefined){
|
|
6051
|
+
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
|
|
5969
6052
|
}
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
6053
|
+
${emitMark(m2, L.buf, sinks)}
|
|
6054
|
+
let v
|
|
6055
|
+
switch(arm){
|
|
6056
|
+
${armCases}
|
|
6057
|
+
${fallbackCase}
|
|
5974
6058
|
}
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
case "choice-arm":
|
|
5980
|
-
return 1;
|
|
5981
|
-
case "dispatch-arm":
|
|
5982
|
-
return 2;
|
|
5983
|
-
case "label":
|
|
5984
|
-
return 3;
|
|
5985
|
-
}
|
|
6059
|
+
if(v===FAIL){
|
|
6060
|
+
${emitRollback(m2, L.buf, sinks)}
|
|
6061
|
+
ctx._fc=true
|
|
6062
|
+
return FAIL
|
|
5986
6063
|
}
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
6064
|
+
return [key,v]
|
|
6065
|
+
}`;
|
|
6066
|
+
}
|
|
6067
|
+
case OP_REP:
|
|
6068
|
+
case OP_REPV: {
|
|
6069
|
+
const child = link(code[ip + 1]);
|
|
6070
|
+
const min = code[ip + 2];
|
|
6071
|
+
const max = code[ip + 3];
|
|
6072
|
+
const sepIp = code[ip + 4];
|
|
6073
|
+
const sep = sepIp >= 0 ? link(sepIp) : void 0;
|
|
6074
|
+
const flags = code[ip + 5];
|
|
6075
|
+
const keepSeparators = (flags & 2) !== 0;
|
|
6076
|
+
const trailingAllowed = (flags & 1) !== 0;
|
|
6077
|
+
const reportItem = (flags & 4) !== 0;
|
|
6078
|
+
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
6079
|
+
const collect = op === OP_REP;
|
|
6080
|
+
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
6081
|
+
const p = tmp();
|
|
6082
|
+
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
6083
|
+
const leadTrivia = skipBeforeFirst ? "true" : "count>0";
|
|
6084
|
+
const skip = skipFor(L);
|
|
6085
|
+
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
6086
|
+
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
6087
|
+
const needMark = L.buf ? "true" : "needMark";
|
|
6088
|
+
const pfd = sinks.fd ? `${p}fd` : "0";
|
|
6089
|
+
const per = sinks.er ? `${p}er` : "undefined";
|
|
6090
|
+
const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
6091
|
+
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
6092
|
+
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)`;
|
|
6093
|
+
const markSinks = `${sinks.fd ? `
|
|
6094
|
+
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
6095
|
+
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
6096
|
+
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
6097
|
+
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
6098
|
+
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6099
|
+
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6100
|
+
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
6101
|
+
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
6102
|
+
const b=ctx._cstBuf
|
|
6103
|
+
if(b!==undefined){
|
|
6104
|
+
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
6105
|
+
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6106
|
+
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6107
|
+
}else{
|
|
6108
|
+
${p}raw=ctx._cstRawChildren!==undefined?ctx._cstRawChildren.length:0
|
|
6109
|
+
${p}tl=ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0
|
|
6110
|
+
${p}lv=ctx._cstLeaves!==undefined?ctx._cstLeaves.length:0
|
|
5998
6111
|
}
|
|
5999
|
-
|
|
6000
|
-
|
|
6112
|
+
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
6113
|
+
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
6114
|
+
}`;
|
|
6115
|
+
const my = `${p}my`;
|
|
6116
|
+
const recFx = REC ? fxRef(code[ip + 6]) : "";
|
|
6117
|
+
const sepSent = REC ? sentRef(code[ip + 7]) : "undefined";
|
|
6118
|
+
const recSent = sep === void 0 ? my : sepSent === "undefined" ? `orSentinel(${my},undefined)` : `orSentinel(${sepSent}??${my},${sepSent}===undefined?undefined:${my})`;
|
|
6119
|
+
const recGate = sep !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
6120
|
+
const recBranch = !REC ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
6121
|
+
${sep === void 0 ? `${rb}
|
|
6122
|
+
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
6123
|
+
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
6124
|
+
count++
|
|
6125
|
+
cur=rr.end
|
|
6126
|
+
continue
|
|
6001
6127
|
}
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6128
|
+
`;
|
|
6129
|
+
return `${head}
|
|
6130
|
+
const out=${collect ? "[]" : "undefined"}
|
|
6131
|
+
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC ? `const ${my}=ctx._sync
|
|
6132
|
+
` : ""}let cur=pos
|
|
6133
|
+
let count=0
|
|
6134
|
+
for(;;){
|
|
6135
|
+
${max >= 0 ? `if(count>=${max})break
|
|
6136
|
+
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
6137
|
+
` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
|
|
6138
|
+
${markBody}
|
|
6139
|
+
let itemStart=cur
|
|
6140
|
+
let sepEnd=-1
|
|
6141
|
+
${sep !== void 0 ? `if(count>0){
|
|
6142
|
+
const lb=cstLeavesLen(ctx)
|
|
6143
|
+
let sp=cur
|
|
6144
|
+
${hasTrivia === "false" ? "" : hasTrivia === "true" ? `sp=${skip}(input,sp,ctx)
|
|
6145
|
+
` : `if(hasTrivia)sp=${skip}(input,sp,ctx)
|
|
6146
|
+
`}ctx._fc=false
|
|
6147
|
+
const sv=${sep}(input,sp,ctx)
|
|
6148
|
+
if(sv===FAIL){
|
|
6149
|
+
${rb}
|
|
6150
|
+
if(ctx._fc===true)return FAIL
|
|
6151
|
+
break
|
|
6025
6152
|
}
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6153
|
+
${keepSeparators ? "" : "demoteCapturedToRaw(ctx,lb)\n"}sepEnd=EC.e
|
|
6154
|
+
itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(input,EC.e,ctx)` : `hasTrivia?${skip}(input,EC.e,ctx):EC.e`}
|
|
6155
|
+
}else ${leadSkip(hasTrivia, leadTrivia, skip)}
|
|
6156
|
+
` : `${leadSkip(hasTrivia, leadTrivia, skip)}
|
|
6157
|
+
`}if(itemStart>=input.length&&${via}){
|
|
6158
|
+
${rb}
|
|
6159
|
+
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
6029
6160
|
}
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
}
|
|
6037
|
-
}
|
|
6038
|
-
if (lo > hi) {
|
|
6039
|
-
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
6040
|
-
}
|
|
6161
|
+
ctx._fc=false
|
|
6162
|
+
const v=${child}(input,itemStart,ctx)
|
|
6163
|
+
if(v===FAIL){
|
|
6164
|
+
${REC ? `if(ctx._fc===true){
|
|
6165
|
+
${rb}
|
|
6166
|
+
return FAIL
|
|
6041
6167
|
}
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
validateClassRange(range.lo, range.hi);
|
|
6046
|
-
if (range.hi > 65535) wide = true;
|
|
6047
|
-
}
|
|
6048
|
-
if (!wide) {
|
|
6049
|
-
let spec2 = "";
|
|
6050
|
-
for (const range of ranges) spec2 += String.fromCharCode(range.lo, range.hi);
|
|
6051
|
-
return spec2;
|
|
6052
|
-
}
|
|
6053
|
-
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
6054
|
-
for (const range of ranges) {
|
|
6055
|
-
spec += String.fromCharCode(
|
|
6056
|
-
range.lo >>> 16,
|
|
6057
|
-
range.lo & 65535,
|
|
6058
|
-
range.hi >>> 16,
|
|
6059
|
-
range.hi & 65535
|
|
6060
|
-
);
|
|
6061
|
-
}
|
|
6062
|
-
return spec;
|
|
6168
|
+
${recBranch}${rb}` : `${rb}
|
|
6169
|
+
if(ctx._fc===true)return FAIL`}
|
|
6170
|
+
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
6063
6171
|
}
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
6068
|
-
const ranges2 = [];
|
|
6069
|
-
for (let i = 2; i < spec.length; i += 4) {
|
|
6070
|
-
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
6071
|
-
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
6072
|
-
validateClassRange(lo, hi);
|
|
6073
|
-
ranges2.push({ lo, hi });
|
|
6074
|
-
}
|
|
6075
|
-
return ranges2;
|
|
6076
|
-
}
|
|
6077
|
-
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
6078
|
-
const ranges = [];
|
|
6079
|
-
for (let i = 0; i < spec.length; i += 2) {
|
|
6080
|
-
const lo = spec.charCodeAt(i);
|
|
6081
|
-
const hi = spec.charCodeAt(i + 1);
|
|
6082
|
-
validateClassRange(lo, hi);
|
|
6083
|
-
ranges.push({ lo, hi });
|
|
6084
|
-
}
|
|
6085
|
-
return ranges;
|
|
6172
|
+
if(EC.e===itemStart&&${via}){
|
|
6173
|
+
${rb}
|
|
6174
|
+
break
|
|
6086
6175
|
}
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
const hi = [];
|
|
6090
|
-
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
6091
|
-
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
6092
|
-
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
6093
|
-
}
|
|
6094
|
-
return { ascii, hi };
|
|
6176
|
+
${collect ? "out.push(v)\n" : ""}cur=EC.e
|
|
6177
|
+
count++
|
|
6095
6178
|
}
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
const hi = cls.hi;
|
|
6100
|
-
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
6101
|
-
return false;
|
|
6179
|
+
${min > 0 ? `if(count<${min}){
|
|
6180
|
+
${reportItem ? `ctx._fe=cur;ctx._fx=${itemFx}
|
|
6181
|
+
` : ""}return FAIL
|
|
6102
6182
|
}
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6183
|
+
` : ""}EC.e=cur
|
|
6184
|
+
return out
|
|
6185
|
+
}`;
|
|
6186
|
+
}
|
|
6187
|
+
case OP_NODE:
|
|
6188
|
+
case OP_NODE_TRACK: {
|
|
6189
|
+
const flags = code[ip + 3];
|
|
6190
|
+
const child = link(code[ip + 2]);
|
|
6191
|
+
const proj = code[ip + 4];
|
|
6192
|
+
const buildIdx = code[ip + 1];
|
|
6193
|
+
const type = k[code[ip + 5]];
|
|
6194
|
+
const tagIdx = code[ip + 6];
|
|
6195
|
+
const tags = tagIdx < 0 ? "undefined" : kRef(tagIdx);
|
|
6196
|
+
const tracked = op === OP_NODE_TRACK;
|
|
6197
|
+
const readsTrivia = (flags & 4) !== 0;
|
|
6198
|
+
const readsState = (flags & 8) !== 0;
|
|
6199
|
+
const hasFields = (flags & 16) !== 0;
|
|
6200
|
+
const collapse = (flags & 32) !== 0;
|
|
6201
|
+
const unwrap = (flags & 64) !== 0;
|
|
6202
|
+
const trailingTrivia = (flags & 128) !== 0;
|
|
6203
|
+
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
6204
|
+
const structural = build === void 0 && proj < 0;
|
|
6205
|
+
const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
|
|
6206
|
+
const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
|
|
6207
|
+
const wantFields = hasFields || hostCst;
|
|
6208
|
+
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
6209
|
+
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
6210
|
+
const ty = q(type);
|
|
6211
|
+
const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
|
|
6212
|
+
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
6213
|
+
let value;
|
|
6214
|
+
if (proj >= 0) {
|
|
6215
|
+
value = hostCst ? `nd=_pfHost!==undefined?${hostCall}:projectChild(kids,${proj},${ty})` : `nd=projectChild(kids,${proj},${ty})`;
|
|
6216
|
+
} else if (build !== void 0) {
|
|
6217
|
+
const direct = `${build}(kids,fieldMap,span,rawKids,${captureWide ? "tlog" : "EMPTY_TL"},st)`;
|
|
6218
|
+
value = hostCst ? `nd=_pfHost!==undefined?${hostCall}:${direct}` : `nd=${direct}`;
|
|
6219
|
+
} else {
|
|
6220
|
+
value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
|
|
6221
|
+
}
|
|
6222
|
+
const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
|
|
6223
|
+
const openCapture = keepChildren ? `const buf={}
|
|
6224
|
+
ctx._cstBuf=buf
|
|
6225
|
+
ctx._cstChildren=undefined
|
|
6226
|
+
ctx._cstLeaves=undefined
|
|
6227
|
+
ctx._cstRawChildren=undefined
|
|
6228
|
+
ctx._cstTriviaLog=undefined` : `const buf={rawOnly:true}
|
|
6229
|
+
ctx._cstBuf=buf
|
|
6230
|
+
ctx._cstChildren=undefined
|
|
6231
|
+
ctx._cstLeaves=undefined
|
|
6232
|
+
ctx._cstRawChildren=undefined
|
|
6233
|
+
ctx._cstTriviaLog=undefined`;
|
|
6234
|
+
const finishCapture = keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
6235
|
+
const hostKids=kids
|
|
6236
|
+
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
6237
|
+
const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
6238
|
+
const hostKids=kids
|
|
6239
|
+
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
6240
|
+
const tlog=buf.tl??EMPTY_TLOG`;
|
|
6241
|
+
return `${head}
|
|
6242
|
+
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
6243
|
+
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
6244
|
+
${openCapture}
|
|
6245
|
+
ctx.captureTrivia=${captureWide}
|
|
6246
|
+
const savedFields=ctx._fields
|
|
6247
|
+
ctx._fields=${wantFields ? "[]" : "undefined"}
|
|
6248
|
+
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
6249
|
+
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
6250
|
+
` : ""}const v=${child}(input,pos,ctx)
|
|
6251
|
+
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
6252
|
+
` : ""}const fieldMap=${wantFields ? "buildFieldMap(ctx._fields)" : "undefined"}
|
|
6253
|
+
ctx._fields=savedFields
|
|
6254
|
+
${structural ? "ctx._triviaCaptureMask=savedMask\n" : ""}${finishCapture}
|
|
6255
|
+
ctx._cstBuf=sBuf
|
|
6256
|
+
ctx._cstChildren=sCh
|
|
6257
|
+
ctx._cstLeaves=sLv
|
|
6258
|
+
ctx._cstRawChildren=sRaw
|
|
6259
|
+
ctx._cstTriviaLog=sTl
|
|
6260
|
+
ctx.captureTrivia=sCap
|
|
6261
|
+
if(v===FAIL)return FAIL
|
|
6262
|
+
const end=EC.e
|
|
6263
|
+
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
6264
|
+
const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)" : "undefined"}
|
|
6265
|
+
let nd
|
|
6266
|
+
${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]
|
|
6267
|
+
else ` : ""}{${value}}
|
|
6268
|
+
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
6269
|
+
EC.e=end
|
|
6270
|
+
return nd
|
|
6271
|
+
}`;
|
|
6272
|
+
}
|
|
6273
|
+
default:
|
|
6274
|
+
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
6124
6275
|
}
|
|
6125
|
-
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
6126
|
-
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
6127
6276
|
}
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
6135
|
-
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
6136
|
-
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
6137
|
-
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
6277
|
+
const ruleEntries = [];
|
|
6278
|
+
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
6279
|
+
const target = link(entryIp);
|
|
6280
|
+
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
6281
|
+
bodies.push(`const ${rn}=${target}`);
|
|
6282
|
+
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
6138
6283
|
}
|
|
6139
|
-
const
|
|
6140
|
-
for (const
|
|
6141
|
-
|
|
6284
|
+
const extra = [];
|
|
6285
|
+
for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
|
|
6286
|
+
const source = `${RUNTIME_PRELUDE}
|
|
6287
|
+
${prelude.join("\n")}
|
|
6288
|
+
${skipDefs.join("\n")}
|
|
6289
|
+
${bodies.join("\n")}
|
|
6290
|
+
function _begin(ctx){
|
|
6291
|
+
const host=ctx.build
|
|
6292
|
+
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
6293
|
+
_pfDepth++
|
|
6294
|
+
_pfScan=null
|
|
6295
|
+
_pfHost=host
|
|
6142
6296
|
}
|
|
6143
|
-
function
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
code: Int32Array.from(prog.code),
|
|
6152
|
-
k: prog.k,
|
|
6153
|
-
fns: prog.fns,
|
|
6154
|
-
cc,
|
|
6155
|
-
fx: prog.fx,
|
|
6156
|
-
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
6157
|
-
trivia: triviaBuilt,
|
|
6158
|
-
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
6159
|
-
triviaLabelled: triviaBuilt.map((t) => t._meta.triviaKindLabels !== void 0),
|
|
6160
|
-
dsp: prog.dsp.map((d) => ({
|
|
6161
|
-
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
6162
|
-
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
6163
|
-
match: d.match,
|
|
6164
|
-
routed: d.routed,
|
|
6165
|
-
expected: d.expected
|
|
6166
|
-
})),
|
|
6167
|
-
rules: prog.rules
|
|
6168
|
-
};
|
|
6169
|
-
if (owner !== void 0) owner.resolved = built;
|
|
6170
|
-
return built;
|
|
6297
|
+
function _finish(){
|
|
6298
|
+
if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
|
|
6299
|
+
_pfDepth--
|
|
6300
|
+
if(_pfDepth===0)return
|
|
6301
|
+
const prior=_pfFrames.pop()
|
|
6302
|
+
_pfScan=prior[0]
|
|
6303
|
+
_pfHost=prior[1]
|
|
6304
|
+
EC.e=prior[2]
|
|
6171
6305
|
}
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6306
|
+
return{
|
|
6307
|
+
pieces:{${ruleEntries.join(",")}},
|
|
6308
|
+
byIp:{${extra.join(",")}},
|
|
6309
|
+
end:function(){return EC.e},
|
|
6310
|
+
begin:_begin,
|
|
6311
|
+
finish:_finish
|
|
6312
|
+
}`;
|
|
6313
|
+
return {
|
|
6314
|
+
source,
|
|
6315
|
+
reached,
|
|
6316
|
+
masks,
|
|
6317
|
+
classes,
|
|
6318
|
+
armExpected,
|
|
6319
|
+
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
6320
|
+
};
|
|
6175
6321
|
}
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
"scanSkip",
|
|
6186
|
-
"scanSkipOf",
|
|
6187
|
-
"scans",
|
|
6188
|
-
"triviaSpecs",
|
|
6189
|
-
"runtimeOnly",
|
|
6190
|
-
// `rec` is a property of the GRAMMAR BUILD, not of the trackLines/hostMode
|
|
6191
|
-
// axis a fold varies — every variant of one export is encoded with the same
|
|
6192
|
-
// recovery setting, and a mismatch is two tables, which is what the refusal says.
|
|
6193
|
-
"rec",
|
|
6194
|
-
// `cov` is a property of the GRAMMAR and its coverage plan, for the same reason
|
|
6195
|
-
// `rec` is a property of the build: the plan is built from the rule map, which
|
|
6196
|
-
// every variant of one export shares. It ships ONCE, and a variant that
|
|
6197
|
-
// disagrees is two tables — which is what the refusal says.
|
|
6198
|
-
"cov"
|
|
6199
|
-
];
|
|
6200
|
-
function foldPrograms(programs, baseName) {
|
|
6201
|
-
const suppliedBase = programs[baseName];
|
|
6202
|
-
if (suppliedBase === void 0) throw new TypeError(`foldPrograms: no program named ${JSON.stringify(baseName)}`);
|
|
6203
|
-
const base = closureArtifact(suppliedBase);
|
|
6204
|
-
const variants = {};
|
|
6205
|
-
for (const name of Object.keys(programs)) {
|
|
6206
|
-
const p = programs[name];
|
|
6207
|
-
if (p.asm !== void 0 && p.asm.length > 0) {
|
|
6208
|
-
throw new TypeError(
|
|
6209
|
-
`foldPrograms: program ${JSON.stringify(name)} already carries pre-compiled assemblies. An assembly is emitted from a \`code\` stream and a fold overwrites \`code\` per variant, so pre-compiling must happen AFTER the fold, per variant \u2014 not before it.`
|
|
6210
|
-
);
|
|
6211
|
-
}
|
|
6212
|
-
if (p.code.length !== base.code.length) {
|
|
6213
|
-
throw new TypeError(
|
|
6214
|
-
`foldPrograms: variant ${JSON.stringify(name)} has ${p.code.length} code words, base ${JSON.stringify(baseName)} has ${base.code.length}. A fold overwrites words; it cannot resize the stream. These are two different tables, not one table and its edits.`
|
|
6215
|
-
);
|
|
6216
|
-
}
|
|
6217
|
-
for (const f of SHARED_FIELDS) {
|
|
6218
|
-
if (JSON.stringify(p[f]) !== JSON.stringify(base[f])) {
|
|
6219
|
-
throw new TypeError(
|
|
6220
|
-
`foldPrograms: variant ${JSON.stringify(name)} differs from base ${JSON.stringify(baseName)} in ${JSON.stringify(f)}, which the fold ships ONCE. Either the variants are not encodings of one grammar, or this field has become variant-dependent and needs its own delta.`
|
|
6221
|
-
);
|
|
6222
|
-
}
|
|
6223
|
-
}
|
|
6224
|
-
if (p.fns.length !== base.fns.length || p.fns.some((f, i) => f !== base.fns[i])) {
|
|
6225
|
-
throw new TypeError(
|
|
6226
|
-
`foldPrograms: variant ${JSON.stringify(name)} does not share the base's reducer pool BY IDENTITY. Equal source text is not enough \u2014 two closures can print alike and capture different scopes. Encode every variant from ONE grammar export.`
|
|
6227
|
-
);
|
|
6228
|
-
}
|
|
6229
|
-
const at = [];
|
|
6230
|
-
const to = [];
|
|
6231
|
-
let prev = 0;
|
|
6232
|
-
for (let i = 0; i < p.code.length; i++) {
|
|
6233
|
-
if (p.code[i] === base.code[i]) continue;
|
|
6234
|
-
at.push(i - prev);
|
|
6235
|
-
to.push(p.code[i]);
|
|
6236
|
-
prev = i;
|
|
6237
|
-
}
|
|
6238
|
-
variants[name] = {
|
|
6239
|
-
at,
|
|
6240
|
-
to,
|
|
6241
|
-
...p.lines === void 0 ? {} : { lines: p.lines },
|
|
6242
|
-
...p.hostMode === void 0 ? {} : { hostMode: p.hostMode }
|
|
6243
|
-
};
|
|
6322
|
+
|
|
6323
|
+
// src/table/run-support.ts
|
|
6324
|
+
function lineCol(ctx, offset) {
|
|
6325
|
+
const starts = ctx._lineStarts ?? [0];
|
|
6326
|
+
let lo = 0, hi = starts.length - 1;
|
|
6327
|
+
while (lo < hi) {
|
|
6328
|
+
const mid = lo + hi + 1 >> 1;
|
|
6329
|
+
if (starts[mid] <= offset) lo = mid;
|
|
6330
|
+
else hi = mid - 1;
|
|
6244
6331
|
}
|
|
6245
|
-
return
|
|
6332
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
6246
6333
|
}
|
|
6247
|
-
function
|
|
6248
|
-
const
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
if (
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
);
|
|
6256
|
-
}
|
|
6257
|
-
const base = folded.base;
|
|
6258
|
-
const code = [...base.code];
|
|
6259
|
-
let ip = 0;
|
|
6260
|
-
for (let i = 0; i < d.at.length; i++) {
|
|
6261
|
-
ip += d.at[i];
|
|
6262
|
-
code[ip] = d.to[i];
|
|
6334
|
+
function spanLines(ctx, start, end) {
|
|
6335
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
6336
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
6337
|
+
}
|
|
6338
|
+
function rawEntry(v, input, s, e) {
|
|
6339
|
+
if (typeof v === "object" && v !== null) {
|
|
6340
|
+
const tg = v._tag;
|
|
6341
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
6263
6342
|
}
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
...d.hostMode === void 0 ? {} : { hostMode: d.hostMode }
|
|
6343
|
+
return {
|
|
6344
|
+
_tag: "leaf",
|
|
6345
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
6346
|
+
span: { start: s, end: e }
|
|
6269
6347
|
};
|
|
6270
|
-
const prog = ownTableProgram(raw);
|
|
6271
|
-
const owner = prog[TABLE_RUNTIME];
|
|
6272
|
-
owner.resolved = { ...resolveTable(base), prog, code: Int32Array.from(code) };
|
|
6273
|
-
byName?.set(name, prog);
|
|
6274
|
-
return prog;
|
|
6275
6348
|
}
|
|
6276
|
-
function
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
at: d.a ?? [],
|
|
6282
|
-
to: d.t ?? [],
|
|
6283
|
-
...d.l === void 0 ? {} : { lines: d.l },
|
|
6284
|
-
...d.h === void 0 ? {} : { hostMode: d.h }
|
|
6285
|
-
};
|
|
6286
|
-
}
|
|
6287
|
-
return ownFoldedProgram(expandCompact(f.b), variants);
|
|
6349
|
+
function lead(input, pos) {
|
|
6350
|
+
if (pos >= input.length) return -1;
|
|
6351
|
+
const c = input.charCodeAt(pos);
|
|
6352
|
+
if (c < 55296 || c > 56319) return c;
|
|
6353
|
+
return input.codePointAt(pos) ?? c;
|
|
6288
6354
|
}
|
|
6289
6355
|
|
|
6290
6356
|
// src/cst/host-mode.ts
|
|
@@ -6332,7 +6398,7 @@ function committed(c) {
|
|
|
6332
6398
|
}
|
|
6333
6399
|
function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(prog)) {
|
|
6334
6400
|
const triviaOfRule = (ip) => {
|
|
6335
|
-
if (prog.code[ip] !== OP_SCOPE) return void 0;
|
|
6401
|
+
if (prog.code[ip] !== OP_SCOPE_PLAIN && prog.code[ip] !== OP_SCOPE) return void 0;
|
|
6336
6402
|
const slot = prog.code[ip + 1];
|
|
6337
6403
|
return slot < 0 ? void 0 : resolved.trivia[slot];
|
|
6338
6404
|
};
|
|
@@ -6552,20 +6618,19 @@ function assemble(t, prog, cfg) {
|
|
|
6552
6618
|
TERMV = v2;
|
|
6553
6619
|
return EC.e > scanEnd2 ? EC.e : cur;
|
|
6554
6620
|
}
|
|
6555
|
-
const need =
|
|
6556
|
-
const
|
|
6557
|
-
const mTl = MTL;
|
|
6558
|
-
const mLv = MLV;
|
|
6559
|
-
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
6560
|
-
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
6621
|
+
const need = rollbackNeeded(ctx);
|
|
6622
|
+
const mTl = need ? cstTlLen(ctx) : 0;
|
|
6561
6623
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
6562
6624
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
6563
6625
|
const scanEnd = skipTrivia(input, cur, ctx);
|
|
6626
|
+
const scanTl = need ? cstTlLen(ctx) : 0;
|
|
6627
|
+
const scanLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
6628
|
+
const scanRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
6564
6629
|
const v = child(input, scanEnd, ctx);
|
|
6565
6630
|
if (v === FAIL) return -1;
|
|
6566
6631
|
TERMV = v;
|
|
6567
6632
|
if (EC.e > scanEnd) return EC.e;
|
|
6568
|
-
if (need)
|
|
6633
|
+
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
6569
6634
|
return cur;
|
|
6570
6635
|
}
|
|
6571
6636
|
function committed2(c) {
|
|
@@ -6979,7 +7044,8 @@ function assemble(t, prog, cfg) {
|
|
|
6979
7044
|
};
|
|
6980
7045
|
}
|
|
6981
7046
|
case OP_SCOPE:
|
|
6982
|
-
case OP_SCOPE_CAP:
|
|
7047
|
+
case OP_SCOPE_CAP:
|
|
7048
|
+
case OP_SCOPE_PLAIN: {
|
|
6983
7049
|
const ki = code[ip + 1];
|
|
6984
7050
|
const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
|
|
6985
7051
|
const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
|
|
@@ -7013,7 +7079,7 @@ function assemble(t, prog, cfg) {
|
|
|
7013
7079
|
SCAN = savedScan;
|
|
7014
7080
|
return v;
|
|
7015
7081
|
};
|
|
7016
|
-
return scopeRootPolicy(scopePiece, code[ip + 3]);
|
|
7082
|
+
return scopeRootPolicy(scopePiece, code[ip] === OP_SCOPE_PLAIN ? 0 : code[ip + 3]);
|
|
7017
7083
|
}
|
|
7018
7084
|
case OP_ROUTED: {
|
|
7019
7085
|
const fb = code[ip + 1];
|
|
@@ -7929,15 +7995,21 @@ function assemble(t, prog, cfg) {
|
|
|
7929
7995
|
target = arms[arm];
|
|
7930
7996
|
usesRouted = routed[arm] === 1;
|
|
7931
7997
|
}
|
|
7932
|
-
const savedRouted = ctx._routed;
|
|
7933
7998
|
let mark = saveTriviaMark(ctx);
|
|
7999
|
+
let v;
|
|
7934
8000
|
if (usesRouted) {
|
|
8001
|
+
const savedRouted = ctx._routed;
|
|
7935
8002
|
rollbackTrivia(ctx, selectorMark);
|
|
7936
8003
|
mark = saveTriviaMark(ctx);
|
|
7937
8004
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
8005
|
+
try {
|
|
8006
|
+
v = target(input, pos, ctx);
|
|
8007
|
+
} finally {
|
|
8008
|
+
ctx._routed = savedRouted;
|
|
8009
|
+
}
|
|
8010
|
+
} else {
|
|
8011
|
+
v = target(input, selEnd, ctx);
|
|
7938
8012
|
}
|
|
7939
|
-
const v = target(input, usesRouted ? pos : selEnd, ctx);
|
|
7940
|
-
if (usesRouted) ctx._routed = savedRouted;
|
|
7941
8013
|
if (v === FAIL) {
|
|
7942
8014
|
rollbackTrivia(ctx, mark);
|
|
7943
8015
|
ctx._fc = true;
|
|
@@ -8083,6 +8155,11 @@ function assemble(t, prog, cfg) {
|
|
|
8083
8155
|
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
8084
8156
|
}
|
|
8085
8157
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
8158
|
+
const validationRoots = [...Object.values(prog.rules), ...extraIps];
|
|
8159
|
+
for (const ip of reachableSites(code, validationRoots)) {
|
|
8160
|
+
if (code[ip] !== OP_DISPATCH) continue;
|
|
8161
|
+
validateDispatchSpec(dsp[code[ip + 2]], code[ip + 5], code[ip + 4]);
|
|
8162
|
+
}
|
|
8086
8163
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
8087
8164
|
if (pre !== void 0) {
|
|
8088
8165
|
const pools = rebuildPools(t.cc, t.fx, pre.plan);
|
|
@@ -8109,6 +8186,7 @@ function assemble(t, prog, cfg) {
|
|
|
8109
8186
|
pushCstLeaf,
|
|
8110
8187
|
pushCstChild,
|
|
8111
8188
|
rollbackTriviaAt,
|
|
8189
|
+
rollbackScannedTriviaAt,
|
|
8112
8190
|
failAt,
|
|
8113
8191
|
classHas,
|
|
8114
8192
|
consumeTrivia,
|
|
@@ -8179,6 +8257,7 @@ function assemble(t, prog, cfg) {
|
|
|
8179
8257
|
pushCstLeaf,
|
|
8180
8258
|
pushCstChild,
|
|
8181
8259
|
rollbackTriviaAt,
|
|
8260
|
+
rollbackScannedTriviaAt,
|
|
8182
8261
|
failAt,
|
|
8183
8262
|
classHas,
|
|
8184
8263
|
consumeTrivia,
|
|
@@ -8868,7 +8947,7 @@ var Encoder = class {
|
|
|
8868
8947
|
this.carryTriviaMeta(amb);
|
|
8869
8948
|
this.carryTriviaMeta(p);
|
|
8870
8949
|
if (p._def.tag === "grammar") this.carryTriviaMeta(p._def.triviaParser);
|
|
8871
|
-
this.rules[name] = amb === void 0 ? body : this.emit(
|
|
8950
|
+
this.rules[name] = amb === void 0 ? body : this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), body);
|
|
8872
8951
|
}
|
|
8873
8952
|
/**
|
|
8874
8953
|
* The row a cross-rule `g.X` reference jumps to — the target's body, RE-WRAPPED
|
|
@@ -8911,7 +8990,7 @@ var Encoder = class {
|
|
|
8911
8990
|
const amb = p._meta.grammarTrivia ?? target._meta.grammarTrivia;
|
|
8912
8991
|
if (amb === void 0 || this.activeTrivia !== void 0) return ip;
|
|
8913
8992
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
8914
|
-
return this.emit(
|
|
8993
|
+
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
8915
8994
|
}
|
|
8916
8995
|
node(p) {
|
|
8917
8996
|
const lazyRef = p._def.tag === "lazy";
|
|
@@ -9316,6 +9395,7 @@ var Encoder = class {
|
|
|
9316
9395
|
return [ip + 1];
|
|
9317
9396
|
case OP_SCOPE:
|
|
9318
9397
|
case OP_SCOPE_CAP:
|
|
9398
|
+
case OP_SCOPE_PLAIN:
|
|
9319
9399
|
case OP_WITHCTX:
|
|
9320
9400
|
case OP_XFORM:
|
|
9321
9401
|
case OP_LEAF:
|
|
@@ -9455,6 +9535,14 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
9455
9535
|
function jsString(s) {
|
|
9456
9536
|
return JSON.stringify(s);
|
|
9457
9537
|
}
|
|
9538
|
+
function emitClassPool(classes) {
|
|
9539
|
+
const array = `[${classes.map(jsString).join(",")}]`;
|
|
9540
|
+
if (classes.length < 2) return array;
|
|
9541
|
+
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
9542
|
+
if (delimiter === void 0) return array;
|
|
9543
|
+
const split = `${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
9544
|
+
return split.length < array.length ? split : array;
|
|
9545
|
+
}
|
|
9458
9546
|
function emitConst(v) {
|
|
9459
9547
|
if (v instanceof RegExp) return `/${v.source}/${v.flags}`;
|
|
9460
9548
|
if (typeof v === "string") return jsString(v);
|
|
@@ -9533,7 +9621,7 @@ function programFields(prog, fns, opts = {}) {
|
|
|
9533
9621
|
...emitAssemblies(prog, opts.assemblies ?? []),
|
|
9534
9622
|
`c:[${prog.code.join(",")}],`,
|
|
9535
9623
|
`k:[${prog.k.map(emitConst).join(",")}],`,
|
|
9536
|
-
`x
|
|
9624
|
+
`x:${emitClassPool(prog.cc)},`,
|
|
9537
9625
|
`e:[${prog.fx.map((f) => `[${f.map(jsString).join(",")}]`).join(",")}],`,
|
|
9538
9626
|
`d:[${prog.disp.map((a) => `[${a.join(",")}]`).join(",")}],`,
|
|
9539
9627
|
`r:${JSON.stringify(prog.rules)},`,
|