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.js
CHANGED
|
@@ -44,6 +44,13 @@ function empty() {
|
|
|
44
44
|
function matchesEmpty(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
45
45
|
if (seen.has(p)) return true;
|
|
46
46
|
seen.add(p);
|
|
47
|
+
try {
|
|
48
|
+
return matchesEmptyBody(p, seen, resolve);
|
|
49
|
+
} finally {
|
|
50
|
+
seen.delete(p);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function matchesEmptyBody(p, seen, resolve) {
|
|
47
54
|
const me = (c) => matchesEmpty(c, seen, resolve);
|
|
48
55
|
const d = p._def;
|
|
49
56
|
switch (d.tag) {
|
|
@@ -145,6 +152,13 @@ function sequenceFirstSet(parsers) {
|
|
|
145
152
|
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
146
153
|
if (seen.has(p)) return any();
|
|
147
154
|
seen.add(p);
|
|
155
|
+
try {
|
|
156
|
+
return firstSetBody(p, seen, resolve);
|
|
157
|
+
} finally {
|
|
158
|
+
seen.delete(p);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function firstSetBody(p, seen, resolve) {
|
|
148
162
|
const fs = (c) => firstSetOf(c, seen, resolve);
|
|
149
163
|
const empties = (c) => matchesEmpty(c, /* @__PURE__ */ new Set(), resolve);
|
|
150
164
|
const d = p._def;
|
|
@@ -1471,6 +1485,23 @@ function rollbackTrivia(ctx, mark) {
|
|
|
1471
1485
|
if (ctx._triviaLog && ctx._triviaLog.length !== mark.log) ctx._triviaLog.length = mark.log;
|
|
1472
1486
|
if (ctx._rootTriviaLog && ctx._rootTriviaLog.length !== mark.rootLog) ctx._rootTriviaLog.length = mark.rootLog;
|
|
1473
1487
|
}
|
|
1488
|
+
function removeNumberRange(values, start, end) {
|
|
1489
|
+
if (values === void 0 || end <= start) return;
|
|
1490
|
+
if (values.length > end) values.copyWithin(start, end);
|
|
1491
|
+
values.length -= end - start;
|
|
1492
|
+
}
|
|
1493
|
+
function rollbackScannedTriviaAt(ctx, tlogStart, tlogEnd, logStart, logEnd, rootLogStart, rootLogEnd) {
|
|
1494
|
+
const b = ctx._cstBuf;
|
|
1495
|
+
if (b !== void 0) {
|
|
1496
|
+
const tlog = b.tl;
|
|
1497
|
+
removeNumberRange(tlog, tlogStart, tlogEnd);
|
|
1498
|
+
if (tlog !== void 0 && tlog.length === 0) b.tl = void 0;
|
|
1499
|
+
} else {
|
|
1500
|
+
removeNumberRange(ctx._cstTriviaLog, tlogStart, tlogEnd);
|
|
1501
|
+
}
|
|
1502
|
+
removeNumberRange(ctx._triviaLog, logStart, logEnd);
|
|
1503
|
+
removeNumberRange(ctx._rootTriviaLog, rootLogStart, rootLogEnd);
|
|
1504
|
+
}
|
|
1474
1505
|
function parseTriviaNoCapture(triviaP, input, cur, ctx) {
|
|
1475
1506
|
const probeCtx = createDetachedParseContext(ctx.trackLines, ctx.state);
|
|
1476
1507
|
probeCtx._lineIndex = ctx._lineIndex;
|
|
@@ -2130,7 +2161,9 @@ function sequence(...parsers) {
|
|
|
2130
2161
|
continue;
|
|
2131
2162
|
}
|
|
2132
2163
|
if (ctx.trivia && i > 0) {
|
|
2133
|
-
const
|
|
2164
|
+
const mTlog = cstTlLen(ctx);
|
|
2165
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2166
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2134
2167
|
let scanEnd;
|
|
2135
2168
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2136
2169
|
const scan = scanTrivia(input, cur, ctx);
|
|
@@ -2139,10 +2172,13 @@ function sequence(...parsers) {
|
|
|
2139
2172
|
} else {
|
|
2140
2173
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2141
2174
|
}
|
|
2175
|
+
const scanTlog = cstTlLen(ctx);
|
|
2176
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2177
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2142
2178
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2143
2179
|
if (!result2.ok) return result2;
|
|
2144
2180
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2145
|
-
else
|
|
2181
|
+
else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2146
2182
|
if (values !== void 0) values.push(result2.value);
|
|
2147
2183
|
continue;
|
|
2148
2184
|
}
|
|
@@ -2173,7 +2209,9 @@ function sequence(...parsers) {
|
|
|
2173
2209
|
}
|
|
2174
2210
|
if (ctx.trivia && i > 0) {
|
|
2175
2211
|
let scanEnd;
|
|
2176
|
-
const
|
|
2212
|
+
const mTlog = cstTlLen(ctx);
|
|
2213
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2214
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2177
2215
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2178
2216
|
const scan = scanTrivia(input, cur, ctx);
|
|
2179
2217
|
scan.commit();
|
|
@@ -2181,10 +2219,13 @@ function sequence(...parsers) {
|
|
|
2181
2219
|
} else {
|
|
2182
2220
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2183
2221
|
}
|
|
2222
|
+
const scanTlog = cstTlLen(ctx);
|
|
2223
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2224
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2184
2225
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2185
2226
|
if (!result2.ok) return result2;
|
|
2186
2227
|
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2187
|
-
else
|
|
2228
|
+
else rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2188
2229
|
if (values !== void 0) values.push(result2.value);
|
|
2189
2230
|
continue;
|
|
2190
2231
|
}
|
|
@@ -2212,7 +2253,9 @@ function sequence(...parsers) {
|
|
|
2212
2253
|
for (let i = 0; i < parsers.length; i++) {
|
|
2213
2254
|
if (ctx.trivia && i > 0) {
|
|
2214
2255
|
let scanEnd;
|
|
2215
|
-
|
|
2256
|
+
const mTlog = cstTlLen(ctx);
|
|
2257
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2258
|
+
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2216
2259
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
2217
2260
|
const scan = scanTrivia(input, cur, ctx);
|
|
2218
2261
|
scan.commit();
|
|
@@ -2220,12 +2263,15 @@ function sequence(...parsers) {
|
|
|
2220
2263
|
} else {
|
|
2221
2264
|
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2222
2265
|
}
|
|
2266
|
+
const scanTlog = cstTlLen(ctx);
|
|
2267
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2268
|
+
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2223
2269
|
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2224
2270
|
if (!result2.ok) return result2;
|
|
2225
2271
|
if (result2.span.end > scanEnd) {
|
|
2226
2272
|
cur = result2.span.end;
|
|
2227
2273
|
} else {
|
|
2228
|
-
|
|
2274
|
+
rollbackScannedTriviaAt(ctx, mTlog, scanTlog, mLog, scanLog, mRootLog, scanRootLog);
|
|
2229
2275
|
}
|
|
2230
2276
|
if (values !== void 0) values.push(result2.value);
|
|
2231
2277
|
continue;
|
|
@@ -3559,6 +3605,7 @@ var OP_LIVE = 37;
|
|
|
3559
3605
|
var OP_ATTEMPT = 38;
|
|
3560
3606
|
var OP_LABEL = 39;
|
|
3561
3607
|
var OP_COV = 40;
|
|
3608
|
+
var OP_SCOPE_PLAIN = 41;
|
|
3562
3609
|
var OP_DISPATCH = 25;
|
|
3563
3610
|
var OP_ROUTED = 26;
|
|
3564
3611
|
var OP_NAMES = {
|
|
@@ -3601,515 +3648,844 @@ var OP_NAMES = {
|
|
|
3601
3648
|
[OP_LIVE]: "LIVE",
|
|
3602
3649
|
[OP_ATTEMPT]: "ATTEMPT",
|
|
3603
3650
|
[OP_LABEL]: "LABEL",
|
|
3604
|
-
[OP_COV]: "COV"
|
|
3651
|
+
[OP_COV]: "COV",
|
|
3652
|
+
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
|
|
3605
3653
|
};
|
|
3606
3654
|
|
|
3607
|
-
// src/table/
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
function classToRanges(cls) {
|
|
3611
|
-
if (cls === "\\d") return shorthandRanges("d");
|
|
3612
|
-
if (cls === "\\w") return shorthandRanges("w");
|
|
3613
|
-
if (cls === "\\s") return shorthandRanges("s");
|
|
3614
|
-
const body = cls.slice(1, -1);
|
|
3615
|
-
if (body.startsWith("^")) return null;
|
|
3616
|
-
return parseClassRanges(body);
|
|
3655
|
+
// src/table/program.ts
|
|
3656
|
+
function closureArtifact(prog) {
|
|
3657
|
+
return { ...prog, asm: [] };
|
|
3617
3658
|
}
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
const CLS = String.raw`\[\^((?:\\.|[^\]])+)\]`;
|
|
3629
|
-
const ESC = String.raw`\\\\(\.|\[\\s\\S\]|\[\\S\\s\])`;
|
|
3630
|
-
let body;
|
|
3631
|
-
let esc;
|
|
3632
|
-
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${ESC}\\)\\*$`).exec(inner);
|
|
3633
|
-
if (m) {
|
|
3634
|
-
body = m[1];
|
|
3635
|
-
esc = m[2];
|
|
3636
|
-
} else {
|
|
3637
|
-
m = new RegExp(`^\\((?:\\?:)?${ESC}\\|${CLS}\\)\\*$`).exec(inner);
|
|
3638
|
-
if (m) {
|
|
3639
|
-
esc = m[1];
|
|
3640
|
-
body = m[2];
|
|
3641
|
-
}
|
|
3659
|
+
function covKindCode(kind) {
|
|
3660
|
+
switch (kind) {
|
|
3661
|
+
case "rule":
|
|
3662
|
+
return 0;
|
|
3663
|
+
case "choice-arm":
|
|
3664
|
+
return 1;
|
|
3665
|
+
case "dispatch-arm":
|
|
3666
|
+
return 2;
|
|
3667
|
+
case "label":
|
|
3668
|
+
return 3;
|
|
3642
3669
|
}
|
|
3643
|
-
if (body === void 0 || esc === void 0) return null;
|
|
3644
|
-
const excluded = parseClassRanges(body);
|
|
3645
|
-
if (!excluded) return null;
|
|
3646
|
-
const qcp = q2.codePointAt(0);
|
|
3647
|
-
const inSet = (cp) => excluded.some(([lo, hi]) => cp >= lo && cp <= hi);
|
|
3648
|
-
if (!inSet(qcp) || !inSet(BACKSLASH)) return null;
|
|
3649
|
-
return { kind: "string", quote: qcp, excluded, escLineTerm: esc !== "." };
|
|
3650
3670
|
}
|
|
3651
|
-
function
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3671
|
+
function covKindName(code) {
|
|
3672
|
+
switch (code) {
|
|
3673
|
+
case 0:
|
|
3674
|
+
return "rule";
|
|
3675
|
+
case 1:
|
|
3676
|
+
return "choice-arm";
|
|
3677
|
+
case 2:
|
|
3678
|
+
return "dispatch-arm";
|
|
3679
|
+
case 3:
|
|
3680
|
+
return "label";
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
function covDefinitions(prog) {
|
|
3684
|
+
return (prog.cov ?? []).map(([id, kind]) => ({ id, kind: covKindName(kind) }));
|
|
3685
|
+
}
|
|
3686
|
+
function expandCompact(p) {
|
|
3687
|
+
if ("code" in p) return p;
|
|
3688
|
+
return ownTableProgram({
|
|
3689
|
+
code: p.c,
|
|
3690
|
+
k: p.k,
|
|
3691
|
+
cc: p.x,
|
|
3692
|
+
fx: p.e,
|
|
3693
|
+
disp: p.d,
|
|
3694
|
+
rules: p.r,
|
|
3695
|
+
fns: p.f,
|
|
3696
|
+
lines: p.l ?? 0,
|
|
3697
|
+
dsp: p.p ?? [],
|
|
3698
|
+
...p.lb === void 0 ? {} : { labels: p.lb },
|
|
3699
|
+
...p.rc === void 0 ? {} : { classified: p.rc },
|
|
3700
|
+
...p.h === void 0 ? {} : { hostMode: p.h },
|
|
3701
|
+
...p.tv === void 0 ? {} : { triviaSpecs: p.tv },
|
|
3702
|
+
...p.sc === void 0 ? {} : { scans: p.sc },
|
|
3703
|
+
...p.ss === void 0 ? {} : { scanSkip: p.ss },
|
|
3704
|
+
...p.so === void 0 ? {} : { scanSkipOf: p.so },
|
|
3705
|
+
...p.rv === void 0 ? {} : { rec: p.rv },
|
|
3706
|
+
...p.cv === void 0 ? {} : { cov: p.cv },
|
|
3707
|
+
...p.a === void 0 ? {} : { asm: p.a }
|
|
3708
|
+
});
|
|
3709
|
+
}
|
|
3710
|
+
function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
3711
|
+
const invalid = (arms) => {
|
|
3712
|
+
for (const arm of arms) if (!Number.isInteger(arm) || arm < 0 || arm >= arity) return true;
|
|
3713
|
+
return false;
|
|
3670
3714
|
};
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
|
|
3675
|
-
|
|
3715
|
+
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]]))) {
|
|
3716
|
+
throw new TypeError("table: malformed dispatch");
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
3720
|
+
function ownTableProgram(prog, resolved) {
|
|
3721
|
+
return { ...prog, [TABLE_RUNTIME]: { resolved } };
|
|
3722
|
+
}
|
|
3723
|
+
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
3724
|
+
var WIDE_CLASS_PREFIX_HI = 0;
|
|
3725
|
+
function validateClassRange(lo, hi) {
|
|
3726
|
+
for (const cp of [lo, hi]) {
|
|
3727
|
+
if (!Number.isInteger(cp) || cp < 0 || cp > 1114111) {
|
|
3728
|
+
throw new TypeError(`table char-class endpoint is outside Unicode: ${cp}`);
|
|
3676
3729
|
}
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3730
|
+
}
|
|
3731
|
+
if (lo > hi) {
|
|
3732
|
+
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
3733
|
+
}
|
|
3734
|
+
}
|
|
3735
|
+
function encodeClassSpec(ranges) {
|
|
3736
|
+
let wide = false;
|
|
3737
|
+
for (const range of ranges) {
|
|
3738
|
+
validateClassRange(range.lo, range.hi);
|
|
3739
|
+
if (range.hi > 65535) wide = true;
|
|
3740
|
+
}
|
|
3741
|
+
if (!wide) {
|
|
3742
|
+
let spec2 = "";
|
|
3743
|
+
for (const range of ranges) spec2 += String.fromCharCode(range.lo, range.hi);
|
|
3744
|
+
return spec2;
|
|
3745
|
+
}
|
|
3746
|
+
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
3747
|
+
for (const range of ranges) {
|
|
3748
|
+
spec += String.fromCharCode(
|
|
3749
|
+
range.lo >>> 16,
|
|
3750
|
+
range.lo & 65535,
|
|
3751
|
+
range.hi >>> 16,
|
|
3752
|
+
range.hi & 65535
|
|
3753
|
+
);
|
|
3754
|
+
}
|
|
3755
|
+
return spec;
|
|
3756
|
+
}
|
|
3757
|
+
function decodeClassSpec(spec) {
|
|
3758
|
+
if (spec.charCodeAt(0) === WIDE_CLASS_PREFIX_LO && spec.charCodeAt(1) === WIDE_CLASS_PREFIX_HI) {
|
|
3759
|
+
if ((spec.length - 2) % 4 !== 0) throw new TypeError("table char-class spec has a truncated wide range");
|
|
3760
|
+
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
3761
|
+
const ranges2 = [];
|
|
3762
|
+
for (let i = 2; i < spec.length; i += 4) {
|
|
3763
|
+
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
3764
|
+
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
3765
|
+
validateClassRange(lo, hi);
|
|
3766
|
+
ranges2.push({ lo, hi });
|
|
3680
3767
|
}
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3768
|
+
return ranges2;
|
|
3769
|
+
}
|
|
3770
|
+
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
3771
|
+
const ranges = [];
|
|
3772
|
+
for (let i = 0; i < spec.length; i += 2) {
|
|
3773
|
+
const lo = spec.charCodeAt(i);
|
|
3774
|
+
const hi = spec.charCodeAt(i + 1);
|
|
3775
|
+
validateClassRange(lo, hi);
|
|
3776
|
+
ranges.push({ lo, hi });
|
|
3777
|
+
}
|
|
3778
|
+
return ranges;
|
|
3779
|
+
}
|
|
3780
|
+
function resolveClass(spec) {
|
|
3781
|
+
const ascii = new Uint8Array(128);
|
|
3782
|
+
const hi = [];
|
|
3783
|
+
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
3784
|
+
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
3785
|
+
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
3786
|
+
}
|
|
3787
|
+
return { ascii, hi };
|
|
3788
|
+
}
|
|
3789
|
+
function classHas(cls, code) {
|
|
3790
|
+
if (code < 0) return false;
|
|
3791
|
+
if (code < 128) return cls.ascii[code] === 1;
|
|
3792
|
+
const hi = cls.hi;
|
|
3793
|
+
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
3794
|
+
return false;
|
|
3795
|
+
}
|
|
3796
|
+
function resolveDispatch(arms, cc) {
|
|
3797
|
+
const ascii = new Uint8Array(128);
|
|
3798
|
+
const hi = [];
|
|
3799
|
+
const open = [];
|
|
3800
|
+
const armCls = [];
|
|
3801
|
+
let exclusive = true;
|
|
3802
|
+
let hiOwners = 0;
|
|
3803
|
+
for (let a = 0; a < arms.length; a++) {
|
|
3804
|
+
const ci = arms[a];
|
|
3805
|
+
if (ci < 0) {
|
|
3806
|
+
open.push(a);
|
|
3807
|
+
armCls.push(null);
|
|
3808
|
+
exclusive = false;
|
|
3809
|
+
continue;
|
|
3684
3810
|
}
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3811
|
+
const cls = cc[ci];
|
|
3812
|
+
armCls.push(cls);
|
|
3813
|
+
for (let c = 0; c < 128; c++) {
|
|
3814
|
+
if (cls.ascii[c] !== 1) continue;
|
|
3815
|
+
if (ascii[c] === 0) ascii[c] = a + 1;
|
|
3816
|
+
else exclusive = false;
|
|
3691
3817
|
}
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
}
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
3818
|
+
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
3819
|
+
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
3820
|
+
}
|
|
3821
|
+
return { ascii, hi, open, armCls, exclusive };
|
|
3822
|
+
}
|
|
3823
|
+
function buildTrivia(spec) {
|
|
3824
|
+
if (spec.live !== void 0) return spec.live;
|
|
3825
|
+
if (spec.plain !== void 0) return trivia(regex(new RegExp(spec.plain[0], spec.plain[1])));
|
|
3826
|
+
if (spec.alts !== void 0) {
|
|
3827
|
+
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
3828
|
+
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
3829
|
+
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
3830
|
+
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
3831
|
+
}
|
|
3832
|
+
const arms = {};
|
|
3833
|
+
for (const [name, source, flags] of spec.arms) arms[name] = regex(new RegExp(source, flags));
|
|
3834
|
+
return classifiedTrivia(arms);
|
|
3835
|
+
}
|
|
3836
|
+
function resolveTable(prog) {
|
|
3837
|
+
const owner = prog[TABLE_RUNTIME];
|
|
3838
|
+
const hit = owner?.resolved;
|
|
3839
|
+
if (hit !== void 0) return hit;
|
|
3840
|
+
const cc = prog.cc.map(resolveClass);
|
|
3841
|
+
const triviaBuilt = (prog.triviaSpecs ?? []).map(buildTrivia);
|
|
3842
|
+
const built = {
|
|
3843
|
+
prog,
|
|
3844
|
+
code: Int32Array.from(prog.code),
|
|
3845
|
+
k: prog.k,
|
|
3846
|
+
fns: prog.fns,
|
|
3847
|
+
cc,
|
|
3848
|
+
fx: prog.fx,
|
|
3849
|
+
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
3850
|
+
trivia: triviaBuilt,
|
|
3851
|
+
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
3852
|
+
triviaLabelled: triviaBuilt.map((t) => t._meta.triviaKindLabels !== void 0),
|
|
3853
|
+
dsp: prog.dsp.map((d) => ({
|
|
3854
|
+
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
3855
|
+
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
3856
|
+
match: d.match,
|
|
3857
|
+
routed: d.routed,
|
|
3858
|
+
expected: d.expected
|
|
3859
|
+
})),
|
|
3860
|
+
rules: prog.rules
|
|
3861
|
+
};
|
|
3862
|
+
if (owner !== void 0) owner.resolved = built;
|
|
3863
|
+
return built;
|
|
3864
|
+
}
|
|
3865
|
+
var FOLDED_RUNTIME = /* @__PURE__ */ Symbol("parseman.foldedRuntime");
|
|
3866
|
+
function ownFoldedProgram(base, variants) {
|
|
3867
|
+
return { base, variants, [FOLDED_RUNTIME]: { byName: /* @__PURE__ */ new Map() } };
|
|
3868
|
+
}
|
|
3869
|
+
var SHARED_FIELDS = [
|
|
3870
|
+
"k",
|
|
3871
|
+
"cc",
|
|
3872
|
+
"fx",
|
|
3873
|
+
"disp",
|
|
3874
|
+
"dsp",
|
|
3875
|
+
"rules",
|
|
3876
|
+
"labels",
|
|
3877
|
+
"classified",
|
|
3878
|
+
"scanSkip",
|
|
3879
|
+
"scanSkipOf",
|
|
3880
|
+
"scans",
|
|
3881
|
+
"triviaSpecs",
|
|
3882
|
+
"runtimeOnly",
|
|
3883
|
+
// `rec` is a property of the GRAMMAR BUILD, not of the trackLines/hostMode
|
|
3884
|
+
// axis a fold varies — every variant of one export is encoded with the same
|
|
3885
|
+
// recovery setting, and a mismatch is two tables, which is what the refusal says.
|
|
3886
|
+
"rec",
|
|
3887
|
+
// `cov` is a property of the GRAMMAR and its coverage plan, for the same reason
|
|
3888
|
+
// `rec` is a property of the build: the plan is built from the rule map, which
|
|
3889
|
+
// every variant of one export shares. It ships ONCE, and a variant that
|
|
3890
|
+
// disagrees is two tables — which is what the refusal says.
|
|
3891
|
+
"cov"
|
|
3892
|
+
];
|
|
3893
|
+
function foldPrograms(programs, baseName) {
|
|
3894
|
+
const suppliedBase = programs[baseName];
|
|
3895
|
+
if (suppliedBase === void 0) throw new TypeError(`foldPrograms: no program named ${JSON.stringify(baseName)}`);
|
|
3896
|
+
const base = closureArtifact(suppliedBase);
|
|
3897
|
+
const variants = {};
|
|
3898
|
+
for (const name of Object.keys(programs)) {
|
|
3899
|
+
const p = programs[name];
|
|
3900
|
+
if (p.asm !== void 0 && p.asm.length > 0) {
|
|
3901
|
+
throw new TypeError(
|
|
3902
|
+
`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.`
|
|
3903
|
+
);
|
|
3719
3904
|
}
|
|
3720
|
-
if (
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
i += 2;
|
|
3725
|
-
i += runFrom(shorthandRanges(e), false, i);
|
|
3726
|
-
continue;
|
|
3727
|
-
}
|
|
3728
|
-
const uni = readUnicodeEscape(source, i);
|
|
3729
|
-
let cp2;
|
|
3730
|
-
if (uni) {
|
|
3731
|
-
cp2 = uni.cp;
|
|
3732
|
-
i = uni.next;
|
|
3733
|
-
} else if (e === void 0) return null;
|
|
3734
|
-
else if (e in CLASS_ESCAPES) {
|
|
3735
|
-
cp2 = CLASS_ESCAPES[e];
|
|
3736
|
-
i += 2;
|
|
3737
|
-
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
3738
|
-
else {
|
|
3739
|
-
cp2 = e.codePointAt(0);
|
|
3740
|
-
i += 2;
|
|
3741
|
-
}
|
|
3742
|
-
if (source[i] === "?") {
|
|
3743
|
-
flush();
|
|
3744
|
-
parts.push({ part: "lit", cps: [cp2], optional: true });
|
|
3745
|
-
i++;
|
|
3746
|
-
} else lit.push(cp2);
|
|
3747
|
-
continue;
|
|
3905
|
+
if (p.code.length !== base.code.length) {
|
|
3906
|
+
throw new TypeError(
|
|
3907
|
+
`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.`
|
|
3908
|
+
);
|
|
3748
3909
|
}
|
|
3749
|
-
|
|
3750
|
-
if (
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
const c2 = source[k];
|
|
3755
|
-
if (c2 === "\\") {
|
|
3756
|
-
k += 2;
|
|
3757
|
-
continue;
|
|
3758
|
-
}
|
|
3759
|
-
if (c2 === "[") {
|
|
3760
|
-
let j = k + 1;
|
|
3761
|
-
if (source[j] === "^") j++;
|
|
3762
|
-
while (j < source.length && source[j] !== "]") {
|
|
3763
|
-
if (source[j] === "\\") j += 2;
|
|
3764
|
-
else j++;
|
|
3765
|
-
}
|
|
3766
|
-
if (source[j] !== "]") return null;
|
|
3767
|
-
k = j + 1;
|
|
3768
|
-
continue;
|
|
3769
|
-
}
|
|
3770
|
-
if (c2 === "(") depth++;
|
|
3771
|
-
else if (c2 === ")") depth--;
|
|
3772
|
-
k++;
|
|
3773
|
-
}
|
|
3774
|
-
if (depth !== 0) return null;
|
|
3775
|
-
const body = source.slice(i + 3, k - 1);
|
|
3776
|
-
const inner = parseScanShape(body);
|
|
3777
|
-
if (!inner || !groupInnerSafe(inner)) return null;
|
|
3778
|
-
const q2 = source[k];
|
|
3779
|
-
if (q2 === "{") return null;
|
|
3780
|
-
flush();
|
|
3781
|
-
if (q2 === "+") {
|
|
3782
|
-
if (shapeCanBeEmpty(inner)) return null;
|
|
3783
|
-
parts.push({ part: "group", inner, min: 1, unbounded: true });
|
|
3784
|
-
i = k + 1;
|
|
3785
|
-
} else if (q2 === "*") {
|
|
3786
|
-
if (shapeCanBeEmpty(inner)) return null;
|
|
3787
|
-
parts.push({ part: "group", inner, min: 0, unbounded: true });
|
|
3788
|
-
i = k + 1;
|
|
3789
|
-
} else if (q2 === "?") {
|
|
3790
|
-
parts.push({ part: "group", inner, min: 0, unbounded: false });
|
|
3791
|
-
i = k + 1;
|
|
3792
|
-
} else {
|
|
3793
|
-
parts.push({ part: "group", inner, min: 1, unbounded: false });
|
|
3794
|
-
i = k;
|
|
3910
|
+
for (const f of SHARED_FIELDS) {
|
|
3911
|
+
if (JSON.stringify(p[f]) !== JSON.stringify(base[f])) {
|
|
3912
|
+
throw new TypeError(
|
|
3913
|
+
`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.`
|
|
3914
|
+
);
|
|
3795
3915
|
}
|
|
3796
|
-
continue;
|
|
3797
3916
|
}
|
|
3798
|
-
if (
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
flush();
|
|
3803
|
-
parts.push({ part: "lit", cps: [cp], optional: true });
|
|
3804
|
-
i++;
|
|
3805
|
-
} else lit.push(cp);
|
|
3806
|
-
}
|
|
3807
|
-
flush();
|
|
3808
|
-
return parts.length ? parts : null;
|
|
3809
|
-
}
|
|
3810
|
-
function seqIsUnambiguous(parts) {
|
|
3811
|
-
let hasMandatory = false;
|
|
3812
|
-
for (let k = 0; k < parts.length; k++) {
|
|
3813
|
-
const p = parts[k];
|
|
3814
|
-
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
3815
|
-
if (mandatory) hasMandatory = true;
|
|
3816
|
-
if (p.part === "group") {
|
|
3817
|
-
const exposure = groupPartExposure(p);
|
|
3818
|
-
if (exposure === "unsupported") {
|
|
3819
|
-
const trailingOnce = k === parts.length - 1 && p.min === 1 && !p.unbounded;
|
|
3820
|
-
if (!trailingOnce) return false;
|
|
3821
|
-
} else if (exposure !== null) {
|
|
3822
|
-
if (!firstSetsDisjoint(exposure, seqFirstAccept(parts.slice(k + 1)))) return false;
|
|
3823
|
-
}
|
|
3917
|
+
if (p.fns.length !== base.fns.length || p.fns.some((f, i) => f !== base.fns[i])) {
|
|
3918
|
+
throw new TypeError(
|
|
3919
|
+
`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.`
|
|
3920
|
+
);
|
|
3824
3921
|
}
|
|
3825
|
-
const
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3922
|
+
const at = [];
|
|
3923
|
+
const to = [];
|
|
3924
|
+
let prev = 0;
|
|
3925
|
+
for (let i = 0; i < p.code.length; i++) {
|
|
3926
|
+
if (p.code[i] === base.code[i]) continue;
|
|
3927
|
+
at.push(i - prev);
|
|
3928
|
+
to.push(p.code[i]);
|
|
3929
|
+
prev = i;
|
|
3829
3930
|
}
|
|
3931
|
+
variants[name] = {
|
|
3932
|
+
at,
|
|
3933
|
+
to,
|
|
3934
|
+
...p.lines === void 0 ? {} : { lines: p.lines },
|
|
3935
|
+
...p.hostMode === void 0 ? {} : { hostMode: p.hostMode }
|
|
3936
|
+
};
|
|
3830
3937
|
}
|
|
3831
|
-
return
|
|
3832
|
-
}
|
|
3833
|
-
function rangesOverlap(a, b) {
|
|
3834
|
-
return a.some(([lo, hi]) => b.some(([lo2, hi2]) => lo <= hi2 && lo2 <= hi));
|
|
3835
|
-
}
|
|
3836
|
-
function rangesSubset(sub, sup) {
|
|
3837
|
-
return sub.every(([lo, hi]) => sup.some(([lo2, hi2]) => lo >= lo2 && hi <= hi2));
|
|
3838
|
-
}
|
|
3839
|
-
function classSubset(t, u) {
|
|
3840
|
-
if (!t.negated && !u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
3841
|
-
if (!t.negated && u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
3842
|
-
if (t.negated && !u.negated) return false;
|
|
3843
|
-
return rangesSubset(u.ranges, t.ranges);
|
|
3844
|
-
}
|
|
3845
|
-
function classDisjoint(t, u) {
|
|
3846
|
-
if (!t.negated && !u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
3847
|
-
if (!t.negated && u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
3848
|
-
if (t.negated && !u.negated) return rangesSubset(u.ranges, t.ranges);
|
|
3849
|
-
return false;
|
|
3850
|
-
}
|
|
3851
|
-
function firstSetsDisjoint(a, b) {
|
|
3852
|
-
if (a === "any" || b === "any") return false;
|
|
3853
|
-
return classDisjoint(a, b);
|
|
3938
|
+
return ownFoldedProgram(base, variants);
|
|
3854
3939
|
}
|
|
3855
|
-
function
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
for (const p of shape.parts) {
|
|
3865
|
-
if (p.part === "lit") {
|
|
3866
|
-
if (p.optional) return null;
|
|
3867
|
-
for (const cp of p.cps) out.push({ ranges: [[cp, cp]], negated: false });
|
|
3868
|
-
} else if (p.part === "run" && p.max === p.min && Number.isFinite(p.max)) {
|
|
3869
|
-
for (let c = 0; c < p.max; c++) out.push({ ranges: p.ranges, negated: p.negated });
|
|
3870
|
-
} else {
|
|
3871
|
-
return null;
|
|
3872
|
-
}
|
|
3873
|
-
}
|
|
3874
|
-
return out.length ? out : null;
|
|
3875
|
-
}
|
|
3876
|
-
function altFixedMutuallyExclusive(shape) {
|
|
3877
|
-
if (shape.kind !== "alt" || shape.disjoint) return false;
|
|
3878
|
-
const lists = [];
|
|
3879
|
-
for (const arm of shape.arms) {
|
|
3880
|
-
const f = fixedClassSeq(arm);
|
|
3881
|
-
if (!f) return false;
|
|
3882
|
-
lists.push(f);
|
|
3940
|
+
function unfoldVariant(folded, name) {
|
|
3941
|
+
const byName = folded[FOLDED_RUNTIME]?.byName;
|
|
3942
|
+
const hit = byName?.get(name);
|
|
3943
|
+
if (hit !== void 0) return hit;
|
|
3944
|
+
const d = folded.variants[name];
|
|
3945
|
+
if (d === void 0) {
|
|
3946
|
+
throw new TypeError(
|
|
3947
|
+
`unfoldVariant: no variant ${JSON.stringify(name)}. This table carries: ${Object.keys(folded.variants).map((n) => JSON.stringify(n)).join(", ")}.`
|
|
3948
|
+
);
|
|
3883
3949
|
}
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
let disjointAt = false;
|
|
3891
|
-
for (let p = 0; p < a.length; p++) {
|
|
3892
|
-
if (classDisjoint(a[p], b[p])) {
|
|
3893
|
-
disjointAt = true;
|
|
3894
|
-
break;
|
|
3895
|
-
}
|
|
3896
|
-
}
|
|
3897
|
-
if (!disjointAt) return false;
|
|
3898
|
-
}
|
|
3950
|
+
const base = folded.base;
|
|
3951
|
+
const code = [...base.code];
|
|
3952
|
+
let ip = 0;
|
|
3953
|
+
for (let i = 0; i < d.at.length; i++) {
|
|
3954
|
+
ip += d.at[i];
|
|
3955
|
+
code[ip] = d.to[i];
|
|
3899
3956
|
}
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
const
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
return unioned === "any" ? "unsupported" : unioned;
|
|
3957
|
+
const raw = {
|
|
3958
|
+
...base,
|
|
3959
|
+
code,
|
|
3960
|
+
...d.lines === void 0 ? {} : { lines: d.lines },
|
|
3961
|
+
...d.hostMode === void 0 ? {} : { hostMode: d.hostMode }
|
|
3962
|
+
};
|
|
3963
|
+
const prog = ownTableProgram(raw);
|
|
3964
|
+
const owner = prog[TABLE_RUNTIME];
|
|
3965
|
+
owner.resolved = { ...resolveTable(base), prog, code: Int32Array.from(code) };
|
|
3966
|
+
byName?.set(name, prog);
|
|
3967
|
+
return prog;
|
|
3912
3968
|
}
|
|
3913
|
-
function
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
if (last.max > last.min) return { ranges: last.ranges, negated: last.negated };
|
|
3924
|
-
return null;
|
|
3925
|
-
}
|
|
3926
|
-
return groupPartExposure(last);
|
|
3927
|
-
}
|
|
3928
|
-
if (shape.kind === "alt") {
|
|
3929
|
-
if (!shape.disjoint) return altFixedMutuallyExclusive(shape) ? null : "unsupported";
|
|
3930
|
-
const classes = shape.arms.map(trailingBacktrackClass);
|
|
3931
|
-
if (classes.some((c) => c === "unsupported")) return "unsupported";
|
|
3932
|
-
const concrete = classes.filter((c) => c !== null);
|
|
3933
|
-
if (concrete.length === 0) return null;
|
|
3934
|
-
const unioned = unionCharSets(concrete);
|
|
3935
|
-
return unioned === "any" ? "unsupported" : unioned;
|
|
3969
|
+
function expandCompactFolded(f) {
|
|
3970
|
+
const variants = {};
|
|
3971
|
+
for (const name of Object.keys(f.v)) {
|
|
3972
|
+
const d = f.v[name];
|
|
3973
|
+
variants[name] = {
|
|
3974
|
+
at: d.a ?? [],
|
|
3975
|
+
to: d.t ?? [],
|
|
3976
|
+
...d.l === void 0 ? {} : { lines: d.l },
|
|
3977
|
+
...d.h === void 0 ? {} : { hostMode: d.h }
|
|
3978
|
+
};
|
|
3936
3979
|
}
|
|
3937
|
-
return
|
|
3938
|
-
}
|
|
3939
|
-
function lookaheadUnambiguous(inner, operand, negative) {
|
|
3940
|
-
const tail = trailingBacktrackClass(inner);
|
|
3941
|
-
if (tail === "unsupported") return false;
|
|
3942
|
-
if (tail === null) return true;
|
|
3943
|
-
return negative ? classSubset(tail, operand) : classDisjoint(tail, operand);
|
|
3980
|
+
return ownFoldedProgram(expandCompact(f.b), variants);
|
|
3944
3981
|
}
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
return
|
|
3982
|
+
|
|
3983
|
+
// src/table/scan-shapes.ts
|
|
3984
|
+
var BACKSLASH = 92;
|
|
3985
|
+
var META2 = new Set("()[]{}*+?|^$.".split(""));
|
|
3986
|
+
function classToRanges(cls) {
|
|
3987
|
+
if (cls === "\\d") return shorthandRanges("d");
|
|
3988
|
+
if (cls === "\\w") return shorthandRanges("w");
|
|
3989
|
+
if (cls === "\\s") return shorthandRanges("s");
|
|
3990
|
+
const body = cls.slice(1, -1);
|
|
3991
|
+
if (body.startsWith("^")) return null;
|
|
3992
|
+
return parseClassRanges(body);
|
|
3956
3993
|
}
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
continue;
|
|
3981
|
-
}
|
|
3982
|
-
if (ch2 === "(") depth++;
|
|
3983
|
-
else if (ch2 === ")") depth--;
|
|
3984
|
-
i++;
|
|
3994
|
+
var foldEq = (cVar, cp) => {
|
|
3995
|
+
if (cp >= 65 && cp <= 90) return `(${cVar} | 32) === ${cp + 32}`;
|
|
3996
|
+
if (cp >= 97 && cp <= 122) return `(${cVar} | 32) === ${cp}`;
|
|
3997
|
+
return `${cVar} === ${cp}`;
|
|
3998
|
+
};
|
|
3999
|
+
function parseStringShape(source) {
|
|
4000
|
+
const q2 = source[0];
|
|
4001
|
+
if (q2 === void 0 || q2 === "\\" || META2.has(q2)) return null;
|
|
4002
|
+
if (source.length < 3 || source[source.length - 1] !== q2) return null;
|
|
4003
|
+
const inner = source.slice(1, -1);
|
|
4004
|
+
const CLS = String.raw`\[\^((?:\\.|[^\]])+)\]`;
|
|
4005
|
+
const ESC = String.raw`\\\\(\.|\[\\s\\S\]|\[\\S\\s\])`;
|
|
4006
|
+
let body;
|
|
4007
|
+
let esc;
|
|
4008
|
+
let m = new RegExp(`^\\((?:\\?:)?${CLS}\\|${ESC}\\)\\*$`).exec(inner);
|
|
4009
|
+
if (m) {
|
|
4010
|
+
body = m[1];
|
|
4011
|
+
esc = m[2];
|
|
4012
|
+
} else {
|
|
4013
|
+
m = new RegExp(`^\\((?:\\?:)?${ESC}\\|${CLS}\\)\\*$`).exec(inner);
|
|
4014
|
+
if (m) {
|
|
4015
|
+
esc = m[1];
|
|
4016
|
+
body = m[2];
|
|
3985
4017
|
}
|
|
3986
|
-
if (!ok || depth !== 0 || i !== source.length) break;
|
|
3987
|
-
source = source.slice(3, -1);
|
|
3988
4018
|
}
|
|
3989
|
-
return
|
|
4019
|
+
if (body === void 0 || esc === void 0) return null;
|
|
4020
|
+
const excluded = parseClassRanges(body);
|
|
4021
|
+
if (!excluded) return null;
|
|
4022
|
+
const qcp = q2.codePointAt(0);
|
|
4023
|
+
const inSet = (cp) => excluded.some(([lo, hi]) => cp >= lo && cp <= hi);
|
|
4024
|
+
if (!inSet(qcp) || !inSet(BACKSLASH)) return null;
|
|
4025
|
+
return { kind: "string", quote: qcp, excluded, escLineTerm: esc !== "." };
|
|
3990
4026
|
}
|
|
3991
|
-
function
|
|
3992
|
-
const body = unwrapOuterGroup(source);
|
|
4027
|
+
function parseSeqParts(source) {
|
|
3993
4028
|
const parts = [];
|
|
3994
|
-
let
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
if (ch2 === "\\") {
|
|
4000
|
-
i += 2;
|
|
4001
|
-
continue;
|
|
4029
|
+
let lit = [];
|
|
4030
|
+
const flush = () => {
|
|
4031
|
+
if (lit.length) {
|
|
4032
|
+
parts.push({ part: "lit", cps: lit, optional: false });
|
|
4033
|
+
lit = [];
|
|
4002
4034
|
}
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4035
|
+
};
|
|
4036
|
+
const braceQuant = (at) => {
|
|
4037
|
+
const close = source.indexOf("}", at);
|
|
4038
|
+
if (close === -1) return null;
|
|
4039
|
+
const body = source.slice(at + 1, close);
|
|
4040
|
+
const m = /^(\d+)(,(\d*)?)?$/.exec(body);
|
|
4041
|
+
if (!m) return null;
|
|
4042
|
+
const min = Number(m[1]);
|
|
4043
|
+
const max = m[2] === void 0 ? min : m[3] ? Number(m[3]) : Infinity;
|
|
4044
|
+
if (max < 1 || min > max) return null;
|
|
4045
|
+
return { min, max, len: close - at + 1 };
|
|
4046
|
+
};
|
|
4047
|
+
const runFrom = (ranges, negated, at) => {
|
|
4048
|
+
const q2 = source[at];
|
|
4049
|
+
if (q2 === "+") {
|
|
4050
|
+
parts.push({ part: "run", ranges, negated, min: 1, max: Infinity });
|
|
4051
|
+
return 1;
|
|
4013
4052
|
}
|
|
4014
|
-
if (
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
continue;
|
|
4053
|
+
if (q2 === "*") {
|
|
4054
|
+
parts.push({ part: "run", ranges, negated, min: 0, max: Infinity });
|
|
4055
|
+
return 1;
|
|
4018
4056
|
}
|
|
4019
|
-
if (
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4057
|
+
if (q2 === "?") {
|
|
4058
|
+
parts.push({ part: "run", ranges, negated, min: 0, max: 1 });
|
|
4059
|
+
return 1;
|
|
4060
|
+
}
|
|
4061
|
+
if (q2 === "{") {
|
|
4062
|
+
const b = braceQuant(at);
|
|
4063
|
+
if (b) {
|
|
4064
|
+
parts.push({ part: "run", ranges, negated, min: b.min, max: b.max });
|
|
4065
|
+
return b.len;
|
|
4066
|
+
}
|
|
4067
|
+
}
|
|
4068
|
+
parts.push({ part: "run", ranges, negated, min: 1, max: 1 });
|
|
4069
|
+
return 0;
|
|
4070
|
+
};
|
|
4071
|
+
let i = 0;
|
|
4072
|
+
while (i < source.length) {
|
|
4073
|
+
const ch2 = source[i];
|
|
4074
|
+
if (ch2 === "[") {
|
|
4075
|
+
let k = i + 1;
|
|
4076
|
+
const neg = source[k] === "^";
|
|
4077
|
+
if (neg) k++;
|
|
4078
|
+
let body = "";
|
|
4079
|
+
while (k < source.length && source[k] !== "]") {
|
|
4080
|
+
if (source[k] === "\\") {
|
|
4081
|
+
body += source[k] + (source[k + 1] ?? "");
|
|
4082
|
+
k += 2;
|
|
4083
|
+
} else {
|
|
4084
|
+
body += source[k];
|
|
4085
|
+
k++;
|
|
4086
|
+
}
|
|
4087
|
+
}
|
|
4088
|
+
if (source[k] !== "]") return null;
|
|
4089
|
+
const ranges = parseClassRanges(body);
|
|
4090
|
+
if (!ranges) return null;
|
|
4091
|
+
flush();
|
|
4092
|
+
i = k + 1;
|
|
4093
|
+
i += runFrom(ranges, neg, i);
|
|
4023
4094
|
continue;
|
|
4024
4095
|
}
|
|
4025
|
-
if (ch2 === "
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4096
|
+
if (ch2 === "\\") {
|
|
4097
|
+
const e = source[i + 1];
|
|
4098
|
+
if (e === "d" || e === "w" || e === "s") {
|
|
4099
|
+
flush();
|
|
4100
|
+
i += 2;
|
|
4101
|
+
i += runFrom(shorthandRanges(e), false, i);
|
|
4102
|
+
continue;
|
|
4103
|
+
}
|
|
4104
|
+
const uni = readUnicodeEscape(source, i);
|
|
4105
|
+
let cp2;
|
|
4106
|
+
if (uni) {
|
|
4107
|
+
cp2 = uni.cp;
|
|
4108
|
+
i = uni.next;
|
|
4109
|
+
} else if (e === void 0) return null;
|
|
4110
|
+
else if (e in CLASS_ESCAPES) {
|
|
4111
|
+
cp2 = CLASS_ESCAPES[e];
|
|
4112
|
+
i += 2;
|
|
4113
|
+
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
4114
|
+
else {
|
|
4115
|
+
cp2 = e.codePointAt(0);
|
|
4116
|
+
i += 2;
|
|
4117
|
+
}
|
|
4118
|
+
if (source[i] === "?") {
|
|
4119
|
+
flush();
|
|
4120
|
+
parts.push({ part: "lit", cps: [cp2], optional: true });
|
|
4121
|
+
i++;
|
|
4122
|
+
} else lit.push(cp2);
|
|
4029
4123
|
continue;
|
|
4030
4124
|
}
|
|
4031
|
-
|
|
4125
|
+
if (ch2 === "(") {
|
|
4126
|
+
if (source[i + 1] !== "?" || source[i + 2] !== ":") return null;
|
|
4127
|
+
let k = i + 3;
|
|
4128
|
+
let depth = 1;
|
|
4129
|
+
while (k < source.length && depth > 0) {
|
|
4130
|
+
const c2 = source[k];
|
|
4131
|
+
if (c2 === "\\") {
|
|
4132
|
+
k += 2;
|
|
4133
|
+
continue;
|
|
4134
|
+
}
|
|
4135
|
+
if (c2 === "[") {
|
|
4136
|
+
let j = k + 1;
|
|
4137
|
+
if (source[j] === "^") j++;
|
|
4138
|
+
while (j < source.length && source[j] !== "]") {
|
|
4139
|
+
if (source[j] === "\\") j += 2;
|
|
4140
|
+
else j++;
|
|
4141
|
+
}
|
|
4142
|
+
if (source[j] !== "]") return null;
|
|
4143
|
+
k = j + 1;
|
|
4144
|
+
continue;
|
|
4145
|
+
}
|
|
4146
|
+
if (c2 === "(") depth++;
|
|
4147
|
+
else if (c2 === ")") depth--;
|
|
4148
|
+
k++;
|
|
4149
|
+
}
|
|
4150
|
+
if (depth !== 0) return null;
|
|
4151
|
+
const body = source.slice(i + 3, k - 1);
|
|
4152
|
+
const inner = parseScanShape(body);
|
|
4153
|
+
if (!inner || !groupInnerSafe(inner)) return null;
|
|
4154
|
+
const q2 = source[k];
|
|
4155
|
+
if (q2 === "{") return null;
|
|
4156
|
+
flush();
|
|
4157
|
+
if (q2 === "+") {
|
|
4158
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
4159
|
+
parts.push({ part: "group", inner, min: 1, unbounded: true });
|
|
4160
|
+
i = k + 1;
|
|
4161
|
+
} else if (q2 === "*") {
|
|
4162
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
4163
|
+
parts.push({ part: "group", inner, min: 0, unbounded: true });
|
|
4164
|
+
i = k + 1;
|
|
4165
|
+
} else if (q2 === "?") {
|
|
4166
|
+
parts.push({ part: "group", inner, min: 0, unbounded: false });
|
|
4167
|
+
i = k + 1;
|
|
4168
|
+
} else {
|
|
4169
|
+
parts.push({ part: "group", inner, min: 1, unbounded: false });
|
|
4170
|
+
i = k;
|
|
4171
|
+
}
|
|
4172
|
+
continue;
|
|
4173
|
+
}
|
|
4174
|
+
if (META2.has(ch2)) return null;
|
|
4175
|
+
const cp = ch2.codePointAt(0);
|
|
4176
|
+
i += ch2.length;
|
|
4177
|
+
if (source[i] === "?") {
|
|
4178
|
+
flush();
|
|
4179
|
+
parts.push({ part: "lit", cps: [cp], optional: true });
|
|
4180
|
+
i++;
|
|
4181
|
+
} else lit.push(cp);
|
|
4032
4182
|
}
|
|
4033
|
-
|
|
4034
|
-
parts.
|
|
4035
|
-
if (parts.length < 2 || parts.some((p) => p.length === 0)) return null;
|
|
4036
|
-
return parts;
|
|
4183
|
+
flush();
|
|
4184
|
+
return parts.length ? parts : null;
|
|
4037
4185
|
}
|
|
4038
|
-
function
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4186
|
+
function seqIsUnambiguous(parts) {
|
|
4187
|
+
let hasMandatory = false;
|
|
4188
|
+
for (let k = 0; k < parts.length; k++) {
|
|
4189
|
+
const p = parts[k];
|
|
4190
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
4191
|
+
if (mandatory) hasMandatory = true;
|
|
4192
|
+
if (p.part === "group") {
|
|
4193
|
+
const exposure = groupPartExposure(p);
|
|
4194
|
+
if (exposure === "unsupported") {
|
|
4195
|
+
const trailingOnce = k === parts.length - 1 && p.min === 1 && !p.unbounded;
|
|
4196
|
+
if (!trailingOnce) return false;
|
|
4197
|
+
} else if (exposure !== null) {
|
|
4198
|
+
if (!firstSetsDisjoint(exposure, seqFirstAccept(parts.slice(k + 1)))) return false;
|
|
4199
|
+
}
|
|
4200
|
+
}
|
|
4201
|
+
const needsDisjoint = p.part === "lit" ? p.optional : p.part === "run" ? p.max > p.min : p.unbounded || p.min === 0;
|
|
4202
|
+
if (needsDisjoint) {
|
|
4203
|
+
const rest = seqFirstAccept(parts.slice(k + 1));
|
|
4204
|
+
if (!firstSetsDisjoint(partFirstAccept(p), rest)) return false;
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
return hasMandatory;
|
|
4043
4208
|
}
|
|
4044
|
-
function
|
|
4045
|
-
|
|
4046
|
-
const concrete = sets;
|
|
4047
|
-
if (concrete.length === 1) return concrete[0];
|
|
4048
|
-
if (concrete.some((s) => s.negated)) return "any";
|
|
4049
|
-
return { ranges: concrete.flatMap((s) => s.ranges), negated: false };
|
|
4209
|
+
function rangesOverlap(a, b) {
|
|
4210
|
+
return a.some(([lo, hi]) => b.some(([lo2, hi2]) => lo <= hi2 && lo2 <= hi));
|
|
4050
4211
|
}
|
|
4051
|
-
function
|
|
4052
|
-
|
|
4053
|
-
if (part.part === "run") return { ranges: part.ranges, negated: part.negated };
|
|
4054
|
-
return shapeFirstAccept(part.inner);
|
|
4212
|
+
function rangesSubset(sub, sup) {
|
|
4213
|
+
return sub.every(([lo, hi]) => sup.some(([lo2, hi2]) => lo >= lo2 && hi <= hi2));
|
|
4055
4214
|
}
|
|
4056
|
-
function
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
if (mandatory) break;
|
|
4062
|
-
}
|
|
4063
|
-
return unionCharSets(sets);
|
|
4215
|
+
function classSubset(t, u) {
|
|
4216
|
+
if (!t.negated && !u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
4217
|
+
if (!t.negated && u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
4218
|
+
if (t.negated && !u.negated) return false;
|
|
4219
|
+
return rangesSubset(u.ranges, t.ranges);
|
|
4064
4220
|
}
|
|
4065
|
-
function
|
|
4066
|
-
if (
|
|
4067
|
-
if (
|
|
4068
|
-
if (
|
|
4221
|
+
function classDisjoint(t, u) {
|
|
4222
|
+
if (!t.negated && !u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
4223
|
+
if (!t.negated && u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
4224
|
+
if (t.negated && !u.negated) return rangesSubset(u.ranges, t.ranges);
|
|
4069
4225
|
return false;
|
|
4070
4226
|
}
|
|
4071
|
-
function
|
|
4072
|
-
if (
|
|
4073
|
-
|
|
4074
|
-
case "chars":
|
|
4075
|
-
return { ranges: shape.ranges, negated: false };
|
|
4076
|
-
case "ident":
|
|
4077
|
-
return { ranges: shape.head, negated: false };
|
|
4078
|
-
case "until":
|
|
4079
|
-
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4080
|
-
case "delimited":
|
|
4081
|
-
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4082
|
-
case "string":
|
|
4083
|
-
return { ranges: [[shape.quote, shape.quote]], negated: false };
|
|
4084
|
-
case "litFold": {
|
|
4085
|
-
const cp = shape.open[0];
|
|
4086
|
-
if (cp >= 65 && cp <= 90) return { ranges: [[cp, cp], [cp + 32, cp + 32]], negated: false };
|
|
4087
|
-
if (cp >= 97 && cp <= 122) return { ranges: [[cp, cp], [cp - 32, cp - 32]], negated: false };
|
|
4088
|
-
return { ranges: [[cp, cp]], negated: false };
|
|
4089
|
-
}
|
|
4090
|
-
case "seq":
|
|
4091
|
-
return seqFirstAccept(shape.parts);
|
|
4092
|
-
case "lookahead":
|
|
4093
|
-
return shapeFirstAccept(shape.inner);
|
|
4094
|
-
// zero-width — doesn't change first-char acceptance
|
|
4095
|
-
case "alt": {
|
|
4096
|
-
const sets = shape.firsts.map((f) => f === null ? "any" : f);
|
|
4097
|
-
return unionCharSets(sets);
|
|
4098
|
-
}
|
|
4099
|
-
}
|
|
4227
|
+
function firstSetsDisjoint(a, b) {
|
|
4228
|
+
if (a === "any" || b === "any") return false;
|
|
4229
|
+
return classDisjoint(a, b);
|
|
4100
4230
|
}
|
|
4101
|
-
function
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4231
|
+
function fixedClassSeq(shape) {
|
|
4232
|
+
if (shape.kind === "litFold") {
|
|
4233
|
+
return shape.open.map((cp) => {
|
|
4234
|
+
const other = cp >= 65 && cp <= 90 ? cp + 32 : cp >= 97 && cp <= 122 ? cp - 32 : cp;
|
|
4235
|
+
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 };
|
|
4236
|
+
});
|
|
4237
|
+
}
|
|
4238
|
+
if (shape.kind !== "seq") return null;
|
|
4239
|
+
const out = [];
|
|
4240
|
+
for (const p of shape.parts) {
|
|
4241
|
+
if (p.part === "lit") {
|
|
4242
|
+
if (p.optional) return null;
|
|
4243
|
+
for (const cp of p.cps) out.push({ ranges: [[cp, cp]], negated: false });
|
|
4244
|
+
} else if (p.part === "run" && p.max === p.min && Number.isFinite(p.max)) {
|
|
4245
|
+
for (let c = 0; c < p.max; c++) out.push({ ranges: p.ranges, negated: p.negated });
|
|
4246
|
+
} else {
|
|
4247
|
+
return null;
|
|
4108
4248
|
}
|
|
4109
4249
|
}
|
|
4110
|
-
return
|
|
4250
|
+
return out.length ? out : null;
|
|
4111
4251
|
}
|
|
4112
|
-
function
|
|
4252
|
+
function altFixedMutuallyExclusive(shape) {
|
|
4253
|
+
if (shape.kind !== "alt" || shape.disjoint) return false;
|
|
4254
|
+
const lists = [];
|
|
4255
|
+
for (const arm of shape.arms) {
|
|
4256
|
+
const f = fixedClassSeq(arm);
|
|
4257
|
+
if (!f) return false;
|
|
4258
|
+
lists.push(f);
|
|
4259
|
+
}
|
|
4260
|
+
for (let i = 0; i < lists.length; i++) {
|
|
4261
|
+
for (let j = 0; j < lists.length; j++) {
|
|
4262
|
+
if (i === j) continue;
|
|
4263
|
+
const a = lists[i];
|
|
4264
|
+
const b = lists[j];
|
|
4265
|
+
if (a.length > b.length) continue;
|
|
4266
|
+
let disjointAt = false;
|
|
4267
|
+
for (let p = 0; p < a.length; p++) {
|
|
4268
|
+
if (classDisjoint(a[p], b[p])) {
|
|
4269
|
+
disjointAt = true;
|
|
4270
|
+
break;
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
if (!disjointAt) return false;
|
|
4274
|
+
}
|
|
4275
|
+
}
|
|
4276
|
+
return true;
|
|
4277
|
+
}
|
|
4278
|
+
function groupPartExposure(part) {
|
|
4279
|
+
const innerWiggle = trailingBacktrackClass(part.inner);
|
|
4280
|
+
if (innerWiggle === "unsupported") return "unsupported";
|
|
4281
|
+
const requiredOnce = !part.unbounded && part.min === 1;
|
|
4282
|
+
if (requiredOnce) return innerWiggle;
|
|
4283
|
+
const dropExposed = shapeFirstAccept(part.inner);
|
|
4284
|
+
if (dropExposed === "any") return "unsupported";
|
|
4285
|
+
if (innerWiggle === null) return dropExposed;
|
|
4286
|
+
const unioned = unionCharSets([innerWiggle, dropExposed]);
|
|
4287
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
4288
|
+
}
|
|
4289
|
+
function trailingBacktrackClass(shape) {
|
|
4290
|
+
if (shape.kind === "chars") return { ranges: shape.ranges, negated: false };
|
|
4291
|
+
if (shape.kind === "ident") return { ranges: shape.tail, negated: false };
|
|
4292
|
+
if (shape.kind === "litFold") return null;
|
|
4293
|
+
if (shape.kind === "seq") {
|
|
4294
|
+
const last = shape.parts[shape.parts.length - 1];
|
|
4295
|
+
if (last.part === "lit") {
|
|
4296
|
+
return last.optional ? "unsupported" : null;
|
|
4297
|
+
}
|
|
4298
|
+
if (last.part === "run") {
|
|
4299
|
+
if (last.max > last.min) return { ranges: last.ranges, negated: last.negated };
|
|
4300
|
+
return null;
|
|
4301
|
+
}
|
|
4302
|
+
return groupPartExposure(last);
|
|
4303
|
+
}
|
|
4304
|
+
if (shape.kind === "alt") {
|
|
4305
|
+
if (!shape.disjoint) return altFixedMutuallyExclusive(shape) ? null : "unsupported";
|
|
4306
|
+
const classes = shape.arms.map(trailingBacktrackClass);
|
|
4307
|
+
if (classes.some((c) => c === "unsupported")) return "unsupported";
|
|
4308
|
+
const concrete = classes.filter((c) => c !== null);
|
|
4309
|
+
if (concrete.length === 0) return null;
|
|
4310
|
+
const unioned = unionCharSets(concrete);
|
|
4311
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
4312
|
+
}
|
|
4313
|
+
return "unsupported";
|
|
4314
|
+
}
|
|
4315
|
+
function lookaheadUnambiguous(inner, operand, negative) {
|
|
4316
|
+
const tail = trailingBacktrackClass(inner);
|
|
4317
|
+
if (tail === "unsupported") return false;
|
|
4318
|
+
if (tail === null) return true;
|
|
4319
|
+
return negative ? classSubset(tail, operand) : classDisjoint(tail, operand);
|
|
4320
|
+
}
|
|
4321
|
+
function stripTrailingLookahead(source) {
|
|
4322
|
+
if (!source.endsWith(")")) return null;
|
|
4323
|
+
for (const negative of [true, false]) {
|
|
4324
|
+
const lead2 = negative ? "(?!" : "(?=";
|
|
4325
|
+
const idx = source.lastIndexOf(lead2);
|
|
4326
|
+
if (idx === -1) continue;
|
|
4327
|
+
const operand = parseClassOperand(source.slice(idx + lead2.length, -1));
|
|
4328
|
+
if (!operand) continue;
|
|
4329
|
+
return { base: source.slice(0, idx), ranges: operand.ranges, classNegated: operand.negated, negative };
|
|
4330
|
+
}
|
|
4331
|
+
return null;
|
|
4332
|
+
}
|
|
4333
|
+
function unwrapOuterGroup(source) {
|
|
4334
|
+
while (source.startsWith("(?:")) {
|
|
4335
|
+
let depth = 1;
|
|
4336
|
+
let i = 3;
|
|
4337
|
+
let ok = true;
|
|
4338
|
+
while (i < source.length && depth > 0) {
|
|
4339
|
+
const ch2 = source[i];
|
|
4340
|
+
if (ch2 === "\\") {
|
|
4341
|
+
i += 2;
|
|
4342
|
+
continue;
|
|
4343
|
+
}
|
|
4344
|
+
if (ch2 === "[") {
|
|
4345
|
+
let j = i + 1;
|
|
4346
|
+
if (source[j] === "^") j++;
|
|
4347
|
+
while (j < source.length && source[j] !== "]") {
|
|
4348
|
+
if (source[j] === "\\") j += 2;
|
|
4349
|
+
else j++;
|
|
4350
|
+
}
|
|
4351
|
+
if (source[j] !== "]") {
|
|
4352
|
+
ok = false;
|
|
4353
|
+
break;
|
|
4354
|
+
}
|
|
4355
|
+
i = j + 1;
|
|
4356
|
+
continue;
|
|
4357
|
+
}
|
|
4358
|
+
if (ch2 === "(") depth++;
|
|
4359
|
+
else if (ch2 === ")") depth--;
|
|
4360
|
+
i++;
|
|
4361
|
+
}
|
|
4362
|
+
if (!ok || depth !== 0 || i !== source.length) break;
|
|
4363
|
+
source = source.slice(3, -1);
|
|
4364
|
+
}
|
|
4365
|
+
return source;
|
|
4366
|
+
}
|
|
4367
|
+
function splitTopLevelAlternation(source) {
|
|
4368
|
+
const body = unwrapOuterGroup(source);
|
|
4369
|
+
const parts = [];
|
|
4370
|
+
let depth = 0;
|
|
4371
|
+
let last = 0;
|
|
4372
|
+
let i = 0;
|
|
4373
|
+
while (i < body.length) {
|
|
4374
|
+
const ch2 = body[i];
|
|
4375
|
+
if (ch2 === "\\") {
|
|
4376
|
+
i += 2;
|
|
4377
|
+
continue;
|
|
4378
|
+
}
|
|
4379
|
+
if (ch2 === "[") {
|
|
4380
|
+
let j = i + 1;
|
|
4381
|
+
if (body[j] === "^") j++;
|
|
4382
|
+
while (j < body.length && body[j] !== "]") {
|
|
4383
|
+
if (body[j] === "\\") j += 2;
|
|
4384
|
+
else j++;
|
|
4385
|
+
}
|
|
4386
|
+
if (body[j] !== "]") return null;
|
|
4387
|
+
i = j + 1;
|
|
4388
|
+
continue;
|
|
4389
|
+
}
|
|
4390
|
+
if (ch2 === "(") {
|
|
4391
|
+
depth++;
|
|
4392
|
+
i++;
|
|
4393
|
+
continue;
|
|
4394
|
+
}
|
|
4395
|
+
if (ch2 === ")") {
|
|
4396
|
+
depth--;
|
|
4397
|
+
if (depth < 0) return null;
|
|
4398
|
+
i++;
|
|
4399
|
+
continue;
|
|
4400
|
+
}
|
|
4401
|
+
if (ch2 === "|" && depth === 0) {
|
|
4402
|
+
parts.push(body.slice(last, i));
|
|
4403
|
+
last = i + 1;
|
|
4404
|
+
i++;
|
|
4405
|
+
continue;
|
|
4406
|
+
}
|
|
4407
|
+
i++;
|
|
4408
|
+
}
|
|
4409
|
+
if (depth !== 0) return null;
|
|
4410
|
+
parts.push(body.slice(last));
|
|
4411
|
+
if (parts.length < 2 || parts.some((p) => p.length === 0)) return null;
|
|
4412
|
+
return parts;
|
|
4413
|
+
}
|
|
4414
|
+
function shapeCanBeEmpty(shape) {
|
|
4415
|
+
if (shape.kind === "chars") return !shape.minOne;
|
|
4416
|
+
if (shape.kind === "lookahead") return shapeCanBeEmpty(shape.inner);
|
|
4417
|
+
if (shape.kind === "alt") return shape.arms.some(shapeCanBeEmpty);
|
|
4418
|
+
return false;
|
|
4419
|
+
}
|
|
4420
|
+
function unionCharSets(sets) {
|
|
4421
|
+
if (sets.some((s) => s === "any")) return "any";
|
|
4422
|
+
const concrete = sets;
|
|
4423
|
+
if (concrete.length === 1) return concrete[0];
|
|
4424
|
+
if (concrete.some((s) => s.negated)) return "any";
|
|
4425
|
+
return { ranges: concrete.flatMap((s) => s.ranges), negated: false };
|
|
4426
|
+
}
|
|
4427
|
+
function partFirstAccept(part) {
|
|
4428
|
+
if (part.part === "lit") return { ranges: [[part.cps[0], part.cps[0]]], negated: false };
|
|
4429
|
+
if (part.part === "run") return { ranges: part.ranges, negated: part.negated };
|
|
4430
|
+
return shapeFirstAccept(part.inner);
|
|
4431
|
+
}
|
|
4432
|
+
function seqFirstAccept(parts) {
|
|
4433
|
+
const sets = [];
|
|
4434
|
+
for (const p of parts) {
|
|
4435
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min >= 1;
|
|
4436
|
+
sets.push(partFirstAccept(p));
|
|
4437
|
+
if (mandatory) break;
|
|
4438
|
+
}
|
|
4439
|
+
return unionCharSets(sets);
|
|
4440
|
+
}
|
|
4441
|
+
function groupInnerSafe(shape) {
|
|
4442
|
+
if (shape.kind === "chars" || shape.kind === "ident" || shape.kind === "seq" || shape.kind === "litFold") return true;
|
|
4443
|
+
if (shape.kind === "lookahead") return groupInnerSafe(shape.inner);
|
|
4444
|
+
if (shape.kind === "alt") return true;
|
|
4445
|
+
return false;
|
|
4446
|
+
}
|
|
4447
|
+
function shapeFirstAccept(shape) {
|
|
4448
|
+
if (shapeCanBeEmpty(shape)) return "any";
|
|
4449
|
+
switch (shape.kind) {
|
|
4450
|
+
case "chars":
|
|
4451
|
+
return { ranges: shape.ranges, negated: false };
|
|
4452
|
+
case "ident":
|
|
4453
|
+
return { ranges: shape.head, negated: false };
|
|
4454
|
+
case "until":
|
|
4455
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4456
|
+
case "delimited":
|
|
4457
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
4458
|
+
case "string":
|
|
4459
|
+
return { ranges: [[shape.quote, shape.quote]], negated: false };
|
|
4460
|
+
case "litFold": {
|
|
4461
|
+
const cp = shape.open[0];
|
|
4462
|
+
if (cp >= 65 && cp <= 90) return { ranges: [[cp, cp], [cp + 32, cp + 32]], negated: false };
|
|
4463
|
+
if (cp >= 97 && cp <= 122) return { ranges: [[cp, cp], [cp - 32, cp - 32]], negated: false };
|
|
4464
|
+
return { ranges: [[cp, cp]], negated: false };
|
|
4465
|
+
}
|
|
4466
|
+
case "seq":
|
|
4467
|
+
return seqFirstAccept(shape.parts);
|
|
4468
|
+
case "lookahead":
|
|
4469
|
+
return shapeFirstAccept(shape.inner);
|
|
4470
|
+
// zero-width — doesn't change first-char acceptance
|
|
4471
|
+
case "alt": {
|
|
4472
|
+
const sets = shape.firsts.map((f) => f === null ? "any" : f);
|
|
4473
|
+
return unionCharSets(sets);
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
function allPairsDisjoint(sets) {
|
|
4478
|
+
for (let i = 0; i < sets.length; i++) {
|
|
4479
|
+
const a = sets[i];
|
|
4480
|
+
if (a === "any") return false;
|
|
4481
|
+
for (let j = i + 1; j < sets.length; j++) {
|
|
4482
|
+
const b = sets[j];
|
|
4483
|
+
if (b === "any" || !classDisjoint(a, b)) return false;
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
return true;
|
|
4487
|
+
}
|
|
4488
|
+
function parseAlternation(source) {
|
|
4113
4489
|
const parts = splitTopLevelAlternation(source);
|
|
4114
4490
|
if (!parts) return null;
|
|
4115
4491
|
const arms = [];
|
|
@@ -4662,6 +5038,7 @@ function childSlots(code, ip, out) {
|
|
|
4662
5038
|
case OP_GATE:
|
|
4663
5039
|
case OP_SCOPE:
|
|
4664
5040
|
case OP_SCOPE_CAP:
|
|
5041
|
+
case OP_SCOPE_PLAIN:
|
|
4665
5042
|
case OP_WITHCTX:
|
|
4666
5043
|
case OP_XFORM:
|
|
4667
5044
|
case OP_NODE:
|
|
@@ -4750,7 +5127,7 @@ function reachableSites(code, roots) {
|
|
|
4750
5127
|
}
|
|
4751
5128
|
function transfer(code, ip, at, hostCst) {
|
|
4752
5129
|
const op = code[ip];
|
|
4753
|
-
if (op === OP_SCOPE || op === OP_SCOPE_CAP) {
|
|
5130
|
+
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
4754
5131
|
const ki = code[ip + 1];
|
|
4755
5132
|
const tri = ki < 0 ? TRI_NONE : ki;
|
|
4756
5133
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
@@ -4831,6 +5208,7 @@ var EMITTED_PARAMS = [
|
|
|
4831
5208
|
"pushCstLeaf",
|
|
4832
5209
|
"pushCstChild",
|
|
4833
5210
|
"rollbackTriviaAt",
|
|
5211
|
+
"rollbackScannedTriviaAt",
|
|
4834
5212
|
"failAt",
|
|
4835
5213
|
"classHas",
|
|
4836
5214
|
"consumeTrivia",
|
|
@@ -4974,19 +5352,24 @@ if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}e
|
|
|
4974
5352
|
if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,0,undefined,${t}lg,${t}rt)`;
|
|
4975
5353
|
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)}`;
|
|
4976
5354
|
}
|
|
4977
|
-
function emitTerm(callee, dst, t, l, skip
|
|
5355
|
+
function emitTerm(callee, dst, t, l, skip) {
|
|
4978
5356
|
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
4979
5357
|
if(${t}v===FAIL)return FAIL
|
|
4980
5358
|
${dst}=${t}v
|
|
4981
5359
|
cur=EC.e`;
|
|
4982
5360
|
if (l.tri === TRI_NONE) return fast;
|
|
4983
|
-
const scanned =
|
|
5361
|
+
const scanned = `const ${t}tl=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
5362
|
+
const ${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5363
|
+
const ${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
4984
5364
|
const ${t}s=${skip}(input,cur,ctx)
|
|
5365
|
+
const ${t}stl=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
5366
|
+
const ${t}slg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5367
|
+
const ${t}srt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
4985
5368
|
const ${t}v=${callee}(input,${t}s,ctx)
|
|
4986
5369
|
if(${t}v===FAIL)return FAIL
|
|
4987
5370
|
${dst}=${t}v
|
|
4988
5371
|
if(EC.e>${t}s)cur=EC.e
|
|
4989
|
-
else{
|
|
5372
|
+
else{rollbackScannedTriviaAt(ctx,${t}tl,${t}stl,${t}lg,${t}slg,${t}rt,${t}srt)}`;
|
|
4990
5373
|
if (l.tri !== TRI_UNKNOWN) return scanned;
|
|
4991
5374
|
return `if(ctx.trivia===undefined){
|
|
4992
5375
|
${fast}
|
|
@@ -5149,7 +5532,7 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5149
5532
|
const op = code[ip];
|
|
5150
5533
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2];
|
|
5151
5534
|
if (op === OP_RULE) return code[ip + 1];
|
|
5152
|
-
if (op === OP_SCOPE && code[ip + 3] === 0 && code[ip + 1] >= 0 && labels.at(ip).tri === code[ip + 1]) {
|
|
5535
|
+
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && labels.at(ip).tri === code[ip + 1]) {
|
|
5153
5536
|
return code[ip + 2];
|
|
5154
5537
|
}
|
|
5155
5538
|
return void 0;
|
|
@@ -5200,1048 +5583,731 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
5200
5583
|
tests.push(`input.charCodeAt(${at})===${f}`);
|
|
5201
5584
|
}
|
|
5202
5585
|
}
|
|
5203
|
-
return `${head}
|
|
5204
|
-
${reads.length > 0 ? `${reads.join("\n")}
|
|
5205
|
-
` : ""}if(${tests.join("&&")}){
|
|
5206
|
-
const e=pos+${s.length}
|
|
5207
|
-
const v=input.slice(pos,e)
|
|
5208
|
-
${captureLeaf("v")}
|
|
5209
|
-
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5210
|
-
return v
|
|
5211
|
-
}
|
|
5212
|
-
ctx._fe=pos;ctx._fx=${xf}
|
|
5213
|
-
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5214
|
-
` : ""}return FAIL
|
|
5215
|
-
}`;
|
|
5216
|
-
}
|
|
5217
|
-
case OP_RX:
|
|
5218
|
-
case OP_RX_TRACK: {
|
|
5219
|
-
const xf = fxRef(code[ip + 2]);
|
|
5220
|
-
const track = op === OP_RX_TRACK;
|
|
5221
|
-
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
5222
|
-
if (scanned !== void 0) return `${head}${scanned}}`;
|
|
5223
|
-
const rxk = k[code[ip + 1]];
|
|
5224
|
-
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
5225
|
-
const re = kRef(code[ip + 1]);
|
|
5226
|
-
return `${head}
|
|
5227
|
-
${re}.lastIndex=pos
|
|
5228
|
-
if(${re}.test(input)){
|
|
5229
|
-
const e=${re}.lastIndex
|
|
5230
|
-
const v=input.slice(pos,e)
|
|
5231
|
-
${captureLeaf("v")}
|
|
5232
|
-
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5233
|
-
return v
|
|
5234
|
-
}
|
|
5235
|
-
ctx._fe=pos;ctx._fx=${xf}
|
|
5236
|
-
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5237
|
-
` : ""}return FAIL
|
|
5238
|
-
}`;
|
|
5239
|
-
}
|
|
5240
|
-
case OP_EMPTY:
|
|
5241
|
-
return `${head}EC.e=pos;return ''}`;
|
|
5242
|
-
case OP_GATE: {
|
|
5243
|
-
const child = link(code[ip + 2]);
|
|
5244
|
-
const ci = classes.push([t.cc[code[ip + 1]]]) - 1;
|
|
5245
|
-
classPlan.push([code[ip + 1]]);
|
|
5246
|
-
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
5247
|
-
const xf = fxRef(code[ip + 3]);
|
|
5248
|
-
return `${head}
|
|
5249
|
-
if(!classHas(${cls},lead(input,pos))){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5250
|
-
return ${child}(input,pos,ctx)
|
|
5251
|
-
}`;
|
|
5252
|
-
}
|
|
5253
|
-
case OP_XFORM: {
|
|
5254
|
-
const fn = fnRef(code[ip + 1]);
|
|
5255
|
-
const child = link(code[ip + 2]);
|
|
5256
|
-
return `${head}
|
|
5257
|
-
const v=${child}(input,pos,ctx)
|
|
5258
|
-
if(v===FAIL)return FAIL
|
|
5259
|
-
return ${fn}(v,{start:pos,end:EC.e})
|
|
5260
|
-
}`;
|
|
5261
|
-
}
|
|
5262
|
-
case OP_LABEL: {
|
|
5263
|
-
const child = link(code[ip + 1]);
|
|
5264
|
-
const xf = fxRef(code[ip + 2]);
|
|
5265
|
-
return `${head}
|
|
5266
|
-
const v=${child}(input,pos,ctx)
|
|
5267
|
-
if(v===FAIL)ctx._fx=${xf}
|
|
5268
|
-
return v
|
|
5269
|
-
}`;
|
|
5270
|
-
}
|
|
5271
|
-
case OP_FIELD: {
|
|
5272
|
-
const name = q(k[code[ip + 1]]);
|
|
5273
|
-
const child = link(code[ip + 2]);
|
|
5274
|
-
return `${head}
|
|
5275
|
-
const v=${child}(input,pos,ctx)
|
|
5276
|
-
if(v===FAIL)return FAIL
|
|
5277
|
-
const f=ctx._fields
|
|
5278
|
-
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
5279
|
-
return v
|
|
5280
|
-
}`;
|
|
5281
|
-
}
|
|
5282
|
-
case OP_EXPECT: {
|
|
5283
|
-
const child = link(code[ip + 1]);
|
|
5284
|
-
const xf = fxRef(code[ip + 2]);
|
|
5285
|
-
return `${head}
|
|
5286
|
-
const v=${child}(input,pos,ctx)
|
|
5287
|
-
if(v!==FAIL)return v
|
|
5288
|
-
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
5289
|
-
const es=ctx._errors
|
|
5290
|
-
if(es!==undefined)es.push(err)
|
|
5291
|
-
${REC ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
5292
|
-
EC.e=pos
|
|
5293
|
-
return err
|
|
5294
|
-
}`;
|
|
5295
|
-
}
|
|
5296
|
-
case OP_ROUTED: {
|
|
5297
|
-
const fb = code[ip + 1];
|
|
5298
|
-
const fallback = fb >= 0 ? link(fb) : void 0;
|
|
5299
|
-
const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
|
|
5300
|
-
return `${head}
|
|
5301
|
-
const it=ctx._routed
|
|
5302
|
-
if(it===undefined||pos!==it.span.start){
|
|
5303
|
-
${fallback !== void 0 ? `return ${fallback}(input,pos,ctx)` : "ctx._fe=pos;ctx._fx=ROUTED_FX;return FAIL"}
|
|
5304
|
-
}
|
|
5305
|
-
${L.buf ? push : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${push}`}
|
|
5306
|
-
EC.e=it.span.end
|
|
5307
|
-
return it.value
|
|
5308
|
-
}`;
|
|
5309
|
-
}
|
|
5310
|
-
case OP_SCAN: {
|
|
5311
|
-
const si = code[ip + 1];
|
|
5312
|
-
return `${head}
|
|
5313
|
-
const r=SCANS[${si}].parse(input,pos,ctx)
|
|
5314
|
-
if(!r.ok){ctx._fe=r.span.start;ctx._fx=r.expected??EMPTY_FX;return FAIL}
|
|
5315
|
-
EC.e=r.span.end
|
|
5316
|
-
return r.value
|
|
5317
|
-
}`;
|
|
5318
|
-
}
|
|
5319
|
-
case OP_SCOPE:
|
|
5320
|
-
case OP_SCOPE_CAP: {
|
|
5321
|
-
const ki = code[ip + 1];
|
|
5322
|
-
const cap = op === OP_SCOPE_CAP;
|
|
5323
|
-
const flags = code[ip + 3];
|
|
5324
|
-
const child = link(code[ip + 2]);
|
|
5325
|
-
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
5326
|
-
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
5327
|
-
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
5328
|
-
const strict = (flags & 2) !== 0 ? "refuseUnclassifiedRootScope(ctx._rootTriviaStrictScopes)\n" : "";
|
|
5329
|
-
const rootCap = (flags & 1) !== 0;
|
|
5330
|
-
return `${head}
|
|
5331
|
-
${strict}${rootCap ? "const sR=ctx._rootTriviaCapture\nctx._rootTriviaCapture=false\n" : ""}const sT=ctx.trivia,sL=ctx.triviaKindLabels,sS=_pfScan${cap ? ",sC=ctx.captureTrivia" : ""}
|
|
5332
|
-
_pfScan=${scanFor}
|
|
5333
|
-
ctx.trivia=${tri}
|
|
5334
|
-
ctx.triviaKindLabels=${lab}
|
|
5335
|
-
${cap ? "ctx.captureTrivia=true\n" : ""}const v=${child}(input,pos,ctx)
|
|
5336
|
-
${cap ? "ctx.captureTrivia=sC\n" : ""}ctx.trivia=sT
|
|
5337
|
-
ctx.triviaKindLabels=sL
|
|
5338
|
-
_pfScan=sS
|
|
5339
|
-
${rootCap ? "ctx._rootTriviaCapture=sR\n" : ""}return v
|
|
5340
|
-
}`;
|
|
5341
|
-
}
|
|
5342
|
-
/* ── boundaries ──────────────────────────────────────────────────────── */
|
|
5343
|
-
case OP_TOKEN:
|
|
5344
|
-
case OP_LEAF: {
|
|
5345
|
-
const isToken = op === OP_TOKEN;
|
|
5346
|
-
const fn = isToken ? void 0 : fnRef(code[ip + 1]);
|
|
5347
|
-
const child = link(isToken ? code[ip + 1] : code[ip + 2]);
|
|
5348
|
-
const wasCap = L.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)";
|
|
5349
|
-
return `${head}
|
|
5350
|
-
const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5351
|
-
const sOtl=ctx._triviaLog
|
|
5352
|
-
${isToken ? "const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan,sRtl=ctx._rootTriviaLog\n" : ""}const wasCap=${wasCap}
|
|
5353
|
-
${isToken ? `_pfScan=null
|
|
5354
|
-
ctx.trivia=undefined
|
|
5355
|
-
ctx.triviaKindLabels=undefined
|
|
5356
|
-
` : ""}ctx._cstBuf=undefined
|
|
5357
|
-
ctx._cstChildren=undefined
|
|
5358
|
-
ctx._cstLeaves=undefined
|
|
5359
|
-
ctx._cstRawChildren=undefined
|
|
5360
|
-
ctx._cstTriviaLog=undefined
|
|
5361
|
-
ctx._triviaLog=undefined
|
|
5362
|
-
${isToken ? "ctx._rootTriviaLog=undefined\n" : ""}let v
|
|
5363
|
-
try{v=${child}(input,pos,ctx)}finally{
|
|
5364
|
-
${isToken ? `_pfScan=sScan
|
|
5365
|
-
ctx.trivia=sTri
|
|
5366
|
-
ctx.triviaKindLabels=sKinds
|
|
5367
|
-
ctx._rootTriviaLog=sRtl
|
|
5368
|
-
` : ""}ctx._cstBuf=sBuf
|
|
5369
|
-
ctx._cstChildren=sCh
|
|
5370
|
-
ctx._cstLeaves=sLv
|
|
5371
|
-
ctx._cstRawChildren=sRaw
|
|
5372
|
-
ctx._cstTriviaLog=sTl
|
|
5373
|
-
ctx._triviaLog=sOtl
|
|
5374
|
-
}
|
|
5375
|
-
if(v===FAIL)return FAIL
|
|
5376
|
-
const e=EC.e
|
|
5377
|
-
const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
|
|
5378
|
-
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
|
|
5379
|
-
EC.e=e
|
|
5380
|
-
return out
|
|
5381
|
-
}`;
|
|
5382
|
-
}
|
|
5383
|
-
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
5384
|
-
case OP_ATTEMPT: {
|
|
5385
|
-
const child = link(code[ip + 1]);
|
|
5386
|
-
const p = tmp();
|
|
5387
|
-
return `${head}
|
|
5388
|
-
${emitMark(p, L.buf, sinks)}
|
|
5389
|
-
const v=${child}(input,pos,ctx)
|
|
5390
|
-
if(v!==FAIL)return v
|
|
5391
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5392
|
-
if(ctx._fc===true)return FAIL
|
|
5393
|
-
ctx._fe=pos
|
|
5394
|
-
return FAIL
|
|
5395
|
-
}`;
|
|
5396
|
-
}
|
|
5397
|
-
case OP_NOT: {
|
|
5398
|
-
const child = link(code[ip + 1]);
|
|
5399
|
-
const xf = fxRef(code[ip + 2]);
|
|
5400
|
-
const p = tmp();
|
|
5401
|
-
return `${head}
|
|
5402
|
-
${emitMark(p, L.buf, sinks)}
|
|
5403
|
-
const v=${child}(input,pos,ctx)
|
|
5404
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5405
|
-
if(v===FAIL){EC.e=pos;return null}
|
|
5406
|
-
ctx._fe=pos
|
|
5407
|
-
ctx._fx=${xf}
|
|
5408
|
-
return FAIL
|
|
5409
|
-
}`;
|
|
5410
|
-
}
|
|
5411
|
-
case OP_PEEK: {
|
|
5412
|
-
const child = link(code[ip + 1]);
|
|
5413
|
-
const xf = fxRef(code[ip + 2]);
|
|
5414
|
-
const p = tmp();
|
|
5415
|
-
return `${head}
|
|
5416
|
-
${emitMark(p, L.buf, sinks)}
|
|
5417
|
-
const v=${child}(input,pos,ctx)
|
|
5418
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5419
|
-
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5420
|
-
EC.e=pos
|
|
5421
|
-
return null
|
|
5422
|
-
}`;
|
|
5423
|
-
}
|
|
5424
|
-
case OP_OPT: {
|
|
5425
|
-
const child = link(code[ip + 1]);
|
|
5426
|
-
const p = tmp();
|
|
5427
|
-
return `${head}
|
|
5428
|
-
${emitMark(p, L.buf, sinks)}
|
|
5429
|
-
ctx._fc=false
|
|
5430
|
-
const v=${child}(input,pos,ctx)
|
|
5431
|
-
if(v===FAIL){
|
|
5432
|
-
if(ctx._fc===true)return FAIL
|
|
5433
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5434
|
-
EC.e=pos
|
|
5435
|
-
return null
|
|
5436
|
-
}
|
|
5437
|
-
return v
|
|
5438
|
-
}`;
|
|
5439
|
-
}
|
|
5440
|
-
case OP_SEQ:
|
|
5441
|
-
case OP_SEQV:
|
|
5442
|
-
case OP_SEQX: {
|
|
5443
|
-
const fused = op === OP_SEQX;
|
|
5444
|
-
const base = fused ? ip + 3 : ip + 2;
|
|
5445
|
-
const n = code[fused ? ip + 2 : ip + 1];
|
|
5446
|
-
const wantValues = op !== OP_SEQV;
|
|
5447
|
-
for (let i = 1; i < n; i++) {
|
|
5448
|
-
if (code[code[base + i]] === OP_ADJ) {
|
|
5449
|
-
throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
|
|
5450
|
-
}
|
|
5451
|
-
}
|
|
5452
|
-
const fn = fused ? fnRef(code[ip + 1]) : void 0;
|
|
5453
|
-
const kids = [];
|
|
5454
|
-
for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
|
|
5455
|
-
const sy = REC ? `${tmp()}sy` : "";
|
|
5456
|
-
const pub = (i) => {
|
|
5457
|
-
const s = sentRef(code[base + n + i]);
|
|
5458
|
-
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
5459
|
-
};
|
|
5460
|
-
const parts = [head];
|
|
5461
|
-
if (REC) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
5462
|
-
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
5463
|
-
const close = () => REC ? `${parts.join("\n")}
|
|
5464
|
-
}finally{ctx._sync=${sy}}
|
|
5465
|
-
}` : `${parts.join("\n")}
|
|
5466
|
-
}`;
|
|
5467
|
-
if (n === 1) {
|
|
5468
|
-
parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
5469
|
-
return close();
|
|
5470
|
-
}
|
|
5471
|
-
parts.push("let cur=EC.e");
|
|
5472
|
-
const names = ["v0"];
|
|
5473
|
-
for (let i = 1; i < n; i++) {
|
|
5474
|
-
const vn = `v${i}`;
|
|
5475
|
-
parts.push(`let ${vn}`);
|
|
5476
|
-
if (REC) parts.push(pub(i));
|
|
5477
|
-
parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L), sinks));
|
|
5478
|
-
names.push(vn);
|
|
5479
|
-
}
|
|
5480
|
-
parts.push("EC.e=cur");
|
|
5481
|
-
parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
5482
|
-
return close();
|
|
5483
|
-
}
|
|
5484
|
-
case OP_CHOICE: {
|
|
5485
|
-
const table = disp[code[ip + 1]];
|
|
5486
|
-
const n = code[ip + 2];
|
|
5487
|
-
const choiceFx = fxRef(code[ip + 3]);
|
|
5488
|
-
const base = ip + 4;
|
|
5489
|
-
const arms = [];
|
|
5490
|
-
for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
|
|
5491
|
-
const axi = armExpected.push(
|
|
5492
|
-
Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
|
|
5493
|
-
) - 1;
|
|
5494
|
-
armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
|
|
5495
|
-
const afx = hoist("afx", `AFX[${axi}]`);
|
|
5496
|
-
if (table.exclusive) {
|
|
5497
|
-
const di = code[ip + 1];
|
|
5498
|
-
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
5499
|
-
const hiArr = table.hi;
|
|
5500
|
-
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
5501
|
-
return `${head}
|
|
5502
|
-
const c=lead(input,pos)
|
|
5503
|
-
let arm=-1
|
|
5504
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
5505
|
-
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
5506
|
-
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
5507
|
-
if(arm>=0){
|
|
5508
|
-
ctx._fc=false
|
|
5509
|
-
let v
|
|
5510
|
-
switch(arm){
|
|
5511
|
-
${armSwitch}
|
|
5512
|
-
}
|
|
5513
|
-
if(v!==FAIL)return v
|
|
5514
|
-
if(ctx._fc===true)return FAIL
|
|
5515
|
-
const af=ctx._fx
|
|
5516
|
-
if(af!==undefined&&af.length>0){ctx._fe=pos;return FAIL}
|
|
5517
|
-
}
|
|
5518
|
-
ctx._fe=pos;ctx._fx=${choiceFx}
|
|
5519
|
-
return FAIL
|
|
5520
|
-
}`;
|
|
5521
|
-
}
|
|
5522
|
-
const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
|
|
5523
|
-
classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
|
|
5524
|
-
const gates = classes[ci];
|
|
5525
|
-
const gRef = hoist("g", `CLS[${ci}]`);
|
|
5526
|
-
const maskable = n <= 32;
|
|
5527
|
-
let maskName = "";
|
|
5528
|
-
if (maskable) {
|
|
5529
|
-
maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
|
|
5530
|
-
maskPlan.push(ci);
|
|
5531
|
-
}
|
|
5532
|
-
const p = tmp();
|
|
5533
|
-
const maskArms = arms.map((a, i) => `
|
|
5534
|
-
if((bits&${1 << i})!==0){
|
|
5535
|
-
ctx._fc=false
|
|
5536
|
-
{const v=${a}(input,pos,ctx)
|
|
5537
|
-
if(v!==FAIL)return v}
|
|
5538
|
-
for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5539
|
-
prev=${i + 1}
|
|
5540
|
-
acc=_accSet(ctx._fx,acc)
|
|
5541
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5542
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5543
|
-
}`).join("");
|
|
5544
|
-
const generalArms = arms.map((a, i) => `
|
|
5545
|
-
if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
|
|
5546
|
-
ctx._fc=false
|
|
5547
|
-
{const v=${a}(input,pos,ctx)
|
|
5548
|
-
if(v!==FAIL)return v}
|
|
5549
|
-
acc=_accSet(ctx._fx,acc)
|
|
5550
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5551
|
-
${emitRollback(p, L.buf, sinks)}
|
|
5552
|
-
}else acc=_accSet(${afx}[${i}],acc)`).join("");
|
|
5553
|
-
return `${head}
|
|
5554
|
-
const c=lead(input,pos)
|
|
5555
|
-
${emitMark(p, L.buf, sinks)}
|
|
5556
|
-
let acc
|
|
5557
|
-
${maskable ? `if(c<128){
|
|
5558
|
-
const bits=${maskName}[c<0?128:c]
|
|
5559
|
-
let prev=0
|
|
5560
|
-
${maskArms}
|
|
5561
|
-
for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5562
|
-
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5563
|
-
return FAIL
|
|
5586
|
+
return `${head}
|
|
5587
|
+
${reads.length > 0 ? `${reads.join("\n")}
|
|
5588
|
+
` : ""}if(${tests.join("&&")}){
|
|
5589
|
+
const e=pos+${s.length}
|
|
5590
|
+
const v=input.slice(pos,e)
|
|
5591
|
+
${captureLeaf("v")}
|
|
5592
|
+
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5593
|
+
return v
|
|
5564
5594
|
}
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
return FAIL
|
|
5595
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
5596
|
+
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5597
|
+
` : ""}return FAIL
|
|
5568
5598
|
}`;
|
|
5569
5599
|
}
|
|
5570
|
-
case
|
|
5571
|
-
|
|
5572
|
-
const
|
|
5573
|
-
const
|
|
5574
|
-
const
|
|
5575
|
-
|
|
5576
|
-
const
|
|
5577
|
-
|
|
5578
|
-
const
|
|
5579
|
-
const arms = [];
|
|
5580
|
-
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
5581
|
-
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
5582
|
-
const rt = hoist("rt", `DSP[${di}].routed`);
|
|
5583
|
-
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
5584
|
-
const claims = (m) => {
|
|
5585
|
-
switch (m[0]) {
|
|
5586
|
-
case 0:
|
|
5587
|
-
return `key.startsWith(${q(m[1])})`;
|
|
5588
|
-
case 1:
|
|
5589
|
-
return `key.endsWith(${q(m[1])})`;
|
|
5590
|
-
case 3:
|
|
5591
|
-
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
5592
|
-
case 4:
|
|
5593
|
-
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
5594
|
-
default:
|
|
5595
|
-
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
5596
|
-
}
|
|
5597
|
-
};
|
|
5598
|
-
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
5599
|
-
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
|
|
5600
|
-
}
|
|
5601
|
-
`;
|
|
5602
|
-
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
5603
|
-
` : "";
|
|
5604
|
-
const m1 = tmp();
|
|
5605
|
-
const m2 = tmp();
|
|
5600
|
+
case OP_RX:
|
|
5601
|
+
case OP_RX_TRACK: {
|
|
5602
|
+
const xf = fxRef(code[ip + 2]);
|
|
5603
|
+
const track = op === OP_RX_TRACK;
|
|
5604
|
+
const scanned = emitScan(code[ip + 1], xf, track, captureLeaf);
|
|
5605
|
+
if (scanned !== void 0) return `${head}${scanned}}`;
|
|
5606
|
+
const rxk = k[code[ip + 1]];
|
|
5607
|
+
if (!(rxk instanceof RegExp) || !rxk.sticky) throw new Unemittable("a non-sticky regex row");
|
|
5608
|
+
const re = kRef(code[ip + 1]);
|
|
5606
5609
|
return `${head}
|
|
5607
|
-
${
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
const
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
if(arm===undefined){
|
|
5615
|
-
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : `ur=${String(otherRouted)}`}
|
|
5616
|
-
}else ur=${rt}[arm]===1
|
|
5617
|
-
const savedRouted=ctx._routed
|
|
5618
|
-
${emitMark(m2, L.buf, sinks)}
|
|
5619
|
-
if(ur){
|
|
5620
|
-
${emitRollback(m1, L.buf, sinks)}
|
|
5621
|
-
${emitMark(m2, L.buf, sinks, false)}
|
|
5622
|
-
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
5623
|
-
}
|
|
5624
|
-
const at=ur?pos:selEnd
|
|
5625
|
-
let v
|
|
5626
|
-
switch(arm){
|
|
5627
|
-
${arms.map((a, i) => `case ${i}:v=${a}(input,at,ctx);break`).join("\n")}
|
|
5628
|
-
${other === void 0 ? "" : `default:v=${other}(input,at,ctx)`}
|
|
5629
|
-
}
|
|
5630
|
-
if(ur)ctx._routed=savedRouted
|
|
5631
|
-
if(v===FAIL){
|
|
5632
|
-
${emitRollback(m2, L.buf, sinks)}
|
|
5633
|
-
ctx._fc=true
|
|
5634
|
-
return FAIL
|
|
5610
|
+
${re}.lastIndex=pos
|
|
5611
|
+
if(${re}.test(input)){
|
|
5612
|
+
const e=${re}.lastIndex
|
|
5613
|
+
const v=input.slice(pos,e)
|
|
5614
|
+
${captureLeaf("v")}
|
|
5615
|
+
${track ? "_trackLines(ctx,input,e)\n" : ""}EC.e=e
|
|
5616
|
+
return v
|
|
5635
5617
|
}
|
|
5636
|
-
|
|
5618
|
+
ctx._fe=pos;ctx._fx=${xf}
|
|
5619
|
+
${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
5620
|
+
` : ""}return FAIL
|
|
5637
5621
|
}`;
|
|
5638
5622
|
}
|
|
5639
|
-
case
|
|
5640
|
-
|
|
5623
|
+
case OP_EMPTY:
|
|
5624
|
+
return `${head}EC.e=pos;return ''}`;
|
|
5625
|
+
case OP_GATE: {
|
|
5626
|
+
const child = link(code[ip + 2]);
|
|
5627
|
+
const ci = classes.push([t.cc[code[ip + 1]]]) - 1;
|
|
5628
|
+
classPlan.push([code[ip + 1]]);
|
|
5629
|
+
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
5630
|
+
const xf = fxRef(code[ip + 3]);
|
|
5631
|
+
return `${head}
|
|
5632
|
+
if(!classHas(${cls},lead(input,pos))){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5633
|
+
return ${child}(input,pos,ctx)
|
|
5634
|
+
}`;
|
|
5635
|
+
}
|
|
5636
|
+
case OP_XFORM: {
|
|
5637
|
+
const fn = fnRef(code[ip + 1]);
|
|
5638
|
+
const child = link(code[ip + 2]);
|
|
5639
|
+
return `${head}
|
|
5640
|
+
const v=${child}(input,pos,ctx)
|
|
5641
|
+
if(v===FAIL)return FAIL
|
|
5642
|
+
return ${fn}(v,{start:pos,end:EC.e})
|
|
5643
|
+
}`;
|
|
5644
|
+
}
|
|
5645
|
+
case OP_LABEL: {
|
|
5641
5646
|
const child = link(code[ip + 1]);
|
|
5642
|
-
const
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
const keepSeparators = (flags & 2) !== 0;
|
|
5648
|
-
const trailingAllowed = (flags & 1) !== 0;
|
|
5649
|
-
const reportItem = (flags & 4) !== 0;
|
|
5650
|
-
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
5651
|
-
const collect = op === OP_REP;
|
|
5652
|
-
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
5653
|
-
const p = tmp();
|
|
5654
|
-
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
5655
|
-
const leadTrivia = skipBeforeFirst ? "true" : "count>0";
|
|
5656
|
-
const skip = skipFor(L);
|
|
5657
|
-
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
5658
|
-
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
5659
|
-
const needMark = L.buf ? "true" : "needMark";
|
|
5660
|
-
const pfd = sinks.fd ? `${p}fd` : "0";
|
|
5661
|
-
const per = sinks.er ? `${p}er` : "undefined";
|
|
5662
|
-
const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
5663
|
-
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
5664
|
-
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)`;
|
|
5665
|
-
const markSinks = `${sinks.fd ? `
|
|
5666
|
-
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
5667
|
-
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
5668
|
-
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
5669
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
5670
|
-
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
5671
|
-
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
5672
|
-
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5673
|
-
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
5674
|
-
const b=ctx._cstBuf
|
|
5675
|
-
if(b!==undefined){
|
|
5676
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
5677
|
-
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
5678
|
-
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
5679
|
-
}else{
|
|
5680
|
-
${p}raw=ctx._cstRawChildren!==undefined?ctx._cstRawChildren.length:0
|
|
5681
|
-
${p}tl=ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0
|
|
5682
|
-
${p}lv=ctx._cstLeaves!==undefined?ctx._cstLeaves.length:0
|
|
5683
|
-
}
|
|
5684
|
-
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
5685
|
-
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
5647
|
+
const xf = fxRef(code[ip + 2]);
|
|
5648
|
+
return `${head}
|
|
5649
|
+
const v=${child}(input,pos,ctx)
|
|
5650
|
+
if(v===FAIL)ctx._fx=${xf}
|
|
5651
|
+
return v
|
|
5686
5652
|
}`;
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
const
|
|
5690
|
-
const
|
|
5691
|
-
const recGate = sep !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
5692
|
-
const recBranch = !REC ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
5693
|
-
${sep === void 0 ? `${rb}
|
|
5694
|
-
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
5695
|
-
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
5696
|
-
count++
|
|
5697
|
-
cur=rr.end
|
|
5698
|
-
continue
|
|
5699
|
-
}
|
|
5700
|
-
`;
|
|
5653
|
+
}
|
|
5654
|
+
case OP_FIELD: {
|
|
5655
|
+
const name = q(k[code[ip + 1]]);
|
|
5656
|
+
const child = link(code[ip + 2]);
|
|
5701
5657
|
return `${head}
|
|
5702
|
-
const
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
${
|
|
5731
|
-
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
5732
|
-
}
|
|
5733
|
-
ctx._fc=false
|
|
5734
|
-
const v=${child}(input,itemStart,ctx)
|
|
5735
|
-
if(v===FAIL){
|
|
5736
|
-
${REC ? `if(ctx._fc===true){
|
|
5737
|
-
${rb}
|
|
5738
|
-
return FAIL
|
|
5739
|
-
}
|
|
5740
|
-
${recBranch}${rb}` : `${rb}
|
|
5741
|
-
if(ctx._fc===true)return FAIL`}
|
|
5742
|
-
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
5743
|
-
}
|
|
5744
|
-
if(EC.e===itemStart&&${via}){
|
|
5745
|
-
${rb}
|
|
5746
|
-
break
|
|
5747
|
-
}
|
|
5748
|
-
${collect ? "out.push(v)\n" : ""}cur=EC.e
|
|
5749
|
-
count++
|
|
5750
|
-
}
|
|
5751
|
-
${min > 0 ? `if(count<${min}){
|
|
5752
|
-
${reportItem ? `ctx._fe=cur;ctx._fx=${itemFx}
|
|
5753
|
-
` : ""}return FAIL
|
|
5658
|
+
const v=${child}(input,pos,ctx)
|
|
5659
|
+
if(v===FAIL)return FAIL
|
|
5660
|
+
const f=ctx._fields
|
|
5661
|
+
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
5662
|
+
return v
|
|
5663
|
+
}`;
|
|
5664
|
+
}
|
|
5665
|
+
case OP_EXPECT: {
|
|
5666
|
+
const child = link(code[ip + 1]);
|
|
5667
|
+
const xf = fxRef(code[ip + 2]);
|
|
5668
|
+
return `${head}
|
|
5669
|
+
const v=${child}(input,pos,ctx)
|
|
5670
|
+
if(v!==FAIL)return v
|
|
5671
|
+
const err={_tag:'parseError',span:${prog.lines === 1 ? "spanLines(ctx,pos,pos)" : "{start:pos,end:pos}"},expected:${xf}}
|
|
5672
|
+
const es=ctx._errors
|
|
5673
|
+
if(es!==undefined)es.push(err)
|
|
5674
|
+
${REC ? "if(ctx._tolerant===true)captureError(ctx,err)\n" : ""}ctx._fc=false
|
|
5675
|
+
EC.e=pos
|
|
5676
|
+
return err
|
|
5677
|
+
}`;
|
|
5678
|
+
}
|
|
5679
|
+
case OP_ROUTED: {
|
|
5680
|
+
const fb = code[ip + 1];
|
|
5681
|
+
const fallback = fb >= 0 ? link(fb) : void 0;
|
|
5682
|
+
const push = `pushCstLeaf(ctx,{_tag:'leaf',value:it.value,span:it.span})`;
|
|
5683
|
+
return `${head}
|
|
5684
|
+
const it=ctx._routed
|
|
5685
|
+
if(it===undefined||pos!==it.span.start){
|
|
5686
|
+
${fallback !== void 0 ? `return ${fallback}(input,pos,ctx)` : "ctx._fe=pos;ctx._fx=ROUTED_FX;return FAIL"}
|
|
5754
5687
|
}
|
|
5755
|
-
|
|
5756
|
-
|
|
5688
|
+
${L.buf ? push : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${push}`}
|
|
5689
|
+
EC.e=it.span.end
|
|
5690
|
+
return it.value
|
|
5757
5691
|
}`;
|
|
5758
5692
|
}
|
|
5759
|
-
case
|
|
5760
|
-
|
|
5761
|
-
|
|
5693
|
+
case OP_SCAN: {
|
|
5694
|
+
const si = code[ip + 1];
|
|
5695
|
+
return `${head}
|
|
5696
|
+
const r=SCANS[${si}].parse(input,pos,ctx)
|
|
5697
|
+
if(!r.ok){ctx._fe=r.span.start;ctx._fx=r.expected??EMPTY_FX;return FAIL}
|
|
5698
|
+
EC.e=r.span.end
|
|
5699
|
+
return r.value
|
|
5700
|
+
}`;
|
|
5701
|
+
}
|
|
5702
|
+
case OP_SCOPE:
|
|
5703
|
+
case OP_SCOPE_CAP:
|
|
5704
|
+
case OP_SCOPE_PLAIN: {
|
|
5705
|
+
const ki = code[ip + 1];
|
|
5706
|
+
const cap = op === OP_SCOPE_CAP;
|
|
5707
|
+
const flags = op === OP_SCOPE_PLAIN ? 0 : code[ip + 3];
|
|
5762
5708
|
const child = link(code[ip + 2]);
|
|
5763
|
-
const
|
|
5764
|
-
const
|
|
5765
|
-
const
|
|
5766
|
-
const
|
|
5767
|
-
const
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
const
|
|
5784
|
-
const
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
const openCapture = keepChildren ? `const buf={}
|
|
5796
|
-
ctx._cstBuf=buf
|
|
5797
|
-
ctx._cstChildren=undefined
|
|
5798
|
-
ctx._cstLeaves=undefined
|
|
5799
|
-
ctx._cstRawChildren=undefined
|
|
5800
|
-
ctx._cstTriviaLog=undefined` : `const buf={rawOnly:true}
|
|
5801
|
-
ctx._cstBuf=buf
|
|
5709
|
+
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
5710
|
+
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
5711
|
+
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
5712
|
+
const strict = (flags & 2) !== 0 ? "refuseUnclassifiedRootScope(ctx._rootTriviaStrictScopes)\n" : "";
|
|
5713
|
+
const rootCap = (flags & 1) !== 0;
|
|
5714
|
+
return `${head}
|
|
5715
|
+
${strict}${rootCap ? "const sR=ctx._rootTriviaCapture\nctx._rootTriviaCapture=false\n" : ""}const sT=ctx.trivia,sL=ctx.triviaKindLabels,sS=_pfScan${cap ? ",sC=ctx.captureTrivia" : ""}
|
|
5716
|
+
_pfScan=${scanFor}
|
|
5717
|
+
ctx.trivia=${tri}
|
|
5718
|
+
ctx.triviaKindLabels=${lab}
|
|
5719
|
+
${cap ? "ctx.captureTrivia=true\n" : ""}const v=${child}(input,pos,ctx)
|
|
5720
|
+
${cap ? "ctx.captureTrivia=sC\n" : ""}ctx.trivia=sT
|
|
5721
|
+
ctx.triviaKindLabels=sL
|
|
5722
|
+
_pfScan=sS
|
|
5723
|
+
${rootCap ? "ctx._rootTriviaCapture=sR\n" : ""}return v
|
|
5724
|
+
}`;
|
|
5725
|
+
}
|
|
5726
|
+
/* ── boundaries ──────────────────────────────────────────────────────── */
|
|
5727
|
+
case OP_TOKEN:
|
|
5728
|
+
case OP_LEAF: {
|
|
5729
|
+
const isToken = op === OP_TOKEN;
|
|
5730
|
+
const fn = isToken ? void 0 : fnRef(code[ip + 1]);
|
|
5731
|
+
const child = link(isToken ? code[ip + 1] : code[ip + 2]);
|
|
5732
|
+
const wasCap = L.buf ? "true" : "(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)";
|
|
5733
|
+
return `${head}
|
|
5734
|
+
const sBuf=ctx._cstBuf,sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5735
|
+
const sOtl=ctx._triviaLog
|
|
5736
|
+
${isToken ? "const sTri=ctx.trivia,sKinds=ctx.triviaKindLabels,sScan=_pfScan,sRtl=ctx._rootTriviaLog\n" : ""}const wasCap=${wasCap}
|
|
5737
|
+
${isToken ? `_pfScan=null
|
|
5738
|
+
ctx.trivia=undefined
|
|
5739
|
+
ctx.triviaKindLabels=undefined
|
|
5740
|
+
` : ""}ctx._cstBuf=undefined
|
|
5802
5741
|
ctx._cstChildren=undefined
|
|
5803
5742
|
ctx._cstLeaves=undefined
|
|
5804
5743
|
ctx._cstRawChildren=undefined
|
|
5805
|
-
ctx._cstTriviaLog=undefined
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
5815
|
-
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
5816
|
-
${openCapture}
|
|
5817
|
-
ctx.captureTrivia=${captureWide}
|
|
5818
|
-
const savedFields=ctx._fields
|
|
5819
|
-
ctx._fields=${wantFields ? "[]" : "undefined"}
|
|
5820
|
-
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
5821
|
-
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
5822
|
-
` : ""}const v=${child}(input,pos,ctx)
|
|
5823
|
-
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
5824
|
-
` : ""}const fieldMap=${wantFields ? "buildFieldMap(ctx._fields)" : "undefined"}
|
|
5825
|
-
ctx._fields=savedFields
|
|
5826
|
-
${structural ? "ctx._triviaCaptureMask=savedMask\n" : ""}${finishCapture}
|
|
5827
|
-
ctx._cstBuf=sBuf
|
|
5744
|
+
ctx._cstTriviaLog=undefined
|
|
5745
|
+
ctx._triviaLog=undefined
|
|
5746
|
+
${isToken ? "ctx._rootTriviaLog=undefined\n" : ""}let v
|
|
5747
|
+
try{v=${child}(input,pos,ctx)}finally{
|
|
5748
|
+
${isToken ? `_pfScan=sScan
|
|
5749
|
+
ctx.trivia=sTri
|
|
5750
|
+
ctx.triviaKindLabels=sKinds
|
|
5751
|
+
ctx._rootTriviaLog=sRtl
|
|
5752
|
+
` : ""}ctx._cstBuf=sBuf
|
|
5828
5753
|
ctx._cstChildren=sCh
|
|
5829
5754
|
ctx._cstLeaves=sLv
|
|
5830
5755
|
ctx._cstRawChildren=sRaw
|
|
5831
5756
|
ctx._cstTriviaLog=sTl
|
|
5832
|
-
ctx.
|
|
5757
|
+
ctx._triviaLog=sOtl
|
|
5758
|
+
}
|
|
5833
5759
|
if(v===FAIL)return FAIL
|
|
5834
|
-
const
|
|
5835
|
-
const
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
|
-
|
|
5839
|
-
else ` : ""}{${value}}
|
|
5840
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
5841
|
-
EC.e=end
|
|
5842
|
-
return nd
|
|
5760
|
+
const e=EC.e
|
|
5761
|
+
const out=${isToken ? "input.slice(pos,e)" : `${fn}(v,{start:pos,end:e})`}
|
|
5762
|
+
if(wasCap)pushCstLeaf(ctx,{_tag:'leaf',value:out,span:{start:pos,end:e}})
|
|
5763
|
+
EC.e=e
|
|
5764
|
+
return out
|
|
5843
5765
|
}`;
|
|
5844
5766
|
}
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5767
|
+
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
5768
|
+
case OP_ATTEMPT: {
|
|
5769
|
+
const child = link(code[ip + 1]);
|
|
5770
|
+
const p = tmp();
|
|
5771
|
+
return `${head}
|
|
5772
|
+
${emitMark(p, L.buf, sinks)}
|
|
5773
|
+
const v=${child}(input,pos,ctx)
|
|
5774
|
+
if(v!==FAIL)return v
|
|
5775
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5776
|
+
if(ctx._fc===true)return FAIL
|
|
5777
|
+
ctx._fe=pos
|
|
5778
|
+
return FAIL
|
|
5779
|
+
}`;
|
|
5780
|
+
}
|
|
5781
|
+
case OP_NOT: {
|
|
5782
|
+
const child = link(code[ip + 1]);
|
|
5783
|
+
const xf = fxRef(code[ip + 2]);
|
|
5784
|
+
const p = tmp();
|
|
5785
|
+
return `${head}
|
|
5786
|
+
${emitMark(p, L.buf, sinks)}
|
|
5787
|
+
const v=${child}(input,pos,ctx)
|
|
5788
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5789
|
+
if(v===FAIL){EC.e=pos;return null}
|
|
5790
|
+
ctx._fe=pos
|
|
5791
|
+
ctx._fx=${xf}
|
|
5792
|
+
return FAIL
|
|
5793
|
+
}`;
|
|
5794
|
+
}
|
|
5795
|
+
case OP_PEEK: {
|
|
5796
|
+
const child = link(code[ip + 1]);
|
|
5797
|
+
const xf = fxRef(code[ip + 2]);
|
|
5798
|
+
const p = tmp();
|
|
5799
|
+
return `${head}
|
|
5800
|
+
${emitMark(p, L.buf, sinks)}
|
|
5801
|
+
const v=${child}(input,pos,ctx)
|
|
5802
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5803
|
+
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
5804
|
+
EC.e=pos
|
|
5805
|
+
return null
|
|
5806
|
+
}`;
|
|
5807
|
+
}
|
|
5808
|
+
case OP_OPT: {
|
|
5809
|
+
const child = link(code[ip + 1]);
|
|
5810
|
+
const p = tmp();
|
|
5811
|
+
return `${head}
|
|
5812
|
+
${emitMark(p, L.buf, sinks)}
|
|
5813
|
+
ctx._fc=false
|
|
5814
|
+
const v=${child}(input,pos,ctx)
|
|
5815
|
+
if(v===FAIL){
|
|
5816
|
+
if(ctx._fc===true)return FAIL
|
|
5817
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5818
|
+
EC.e=pos
|
|
5819
|
+
return null
|
|
5877
5820
|
}
|
|
5878
|
-
return
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5821
|
+
return v
|
|
5822
|
+
}`;
|
|
5823
|
+
}
|
|
5824
|
+
case OP_SEQ:
|
|
5825
|
+
case OP_SEQV:
|
|
5826
|
+
case OP_SEQX: {
|
|
5827
|
+
const fused = op === OP_SEQX;
|
|
5828
|
+
const base = fused ? ip + 3 : ip + 2;
|
|
5829
|
+
const n = code[fused ? ip + 2 : ip + 1];
|
|
5830
|
+
const wantValues = op !== OP_SEQV;
|
|
5831
|
+
for (let i = 1; i < n; i++) {
|
|
5832
|
+
if (code[code[base + i]] === OP_ADJ) {
|
|
5833
|
+
throw new Unemittable("a sequence carrying an adjacency assertion (OP_ADJ)");
|
|
5834
|
+
}
|
|
5835
|
+
}
|
|
5836
|
+
const fn = fused ? fnRef(code[ip + 1]) : void 0;
|
|
5837
|
+
const kids = [];
|
|
5838
|
+
for (let i = 0; i < n; i++) kids.push(link(code[base + i]));
|
|
5839
|
+
const sy = REC ? `${tmp()}sy` : "";
|
|
5840
|
+
const pub = (i) => {
|
|
5841
|
+
const s = sentRef(code[base + n + i]);
|
|
5842
|
+
return s === "undefined" ? `ctx._sync=${sy}` : `ctx._sync=${s}??${sy}`;
|
|
5843
|
+
};
|
|
5844
|
+
const parts = [head];
|
|
5845
|
+
if (REC) parts.push(`const ${sy}=ctx._sync`, "try{", pub(0));
|
|
5846
|
+
parts.push(`const v0=${kids[0]}(input,pos,ctx)`, "if(v0===FAIL)return FAIL");
|
|
5847
|
+
const close = () => REC ? `${parts.join("\n")}
|
|
5848
|
+
}finally{ctx._sync=${sy}}
|
|
5849
|
+
}` : `${parts.join("\n")}
|
|
5884
5850
|
}`;
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5851
|
+
if (n === 1) {
|
|
5852
|
+
parts.push(fused ? `return ${fn}([v0],{start:pos,end:EC.e})` : wantValues ? "return [v0]" : "return undefined");
|
|
5853
|
+
return close();
|
|
5854
|
+
}
|
|
5855
|
+
parts.push("let cur=EC.e");
|
|
5856
|
+
const names = ["v0"];
|
|
5857
|
+
for (let i = 1; i < n; i++) {
|
|
5858
|
+
const vn = `v${i}`;
|
|
5859
|
+
parts.push(`let ${vn}`);
|
|
5860
|
+
if (REC) parts.push(pub(i));
|
|
5861
|
+
parts.push(emitTerm(kids[i], vn, tmp(), L, skipFor(L)));
|
|
5862
|
+
names.push(vn);
|
|
5863
|
+
}
|
|
5864
|
+
parts.push("EC.e=cur");
|
|
5865
|
+
parts.push(fused ? `return ${fn}([${names.join(",")}],{start:pos,end:cur})` : wantValues ? `return [${names.join(",")}]` : "return undefined");
|
|
5866
|
+
return close();
|
|
5867
|
+
}
|
|
5868
|
+
case OP_CHOICE: {
|
|
5869
|
+
const table = disp[code[ip + 1]];
|
|
5870
|
+
const n = code[ip + 2];
|
|
5871
|
+
const choiceFx = fxRef(code[ip + 3]);
|
|
5872
|
+
const base = ip + 4;
|
|
5873
|
+
const arms = [];
|
|
5874
|
+
for (let i = 0; i < n; i++) arms.push(link(code[base + i]));
|
|
5875
|
+
const axi = armExpected.push(
|
|
5876
|
+
Array.from({ length: n }, (_, i) => t.fx[code[base + n + i]])
|
|
5877
|
+
) - 1;
|
|
5878
|
+
armExpectedPlan.push(Array.from({ length: n }, (_, i) => code[base + n + i]));
|
|
5879
|
+
const afx = hoist("afx", `AFX[${axi}]`);
|
|
5880
|
+
if (table.exclusive) {
|
|
5881
|
+
const di = code[ip + 1];
|
|
5882
|
+
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
5883
|
+
const hiArr = table.hi;
|
|
5884
|
+
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
5885
|
+
return `${head}
|
|
5886
|
+
const c=lead(input,pos)
|
|
5887
|
+
let arm=-1
|
|
5888
|
+
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
5889
|
+
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
5890
|
+
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
5891
|
+
if(arm>=0){
|
|
5892
|
+
ctx._fc=false
|
|
5893
|
+
let v
|
|
5894
|
+
switch(arm){
|
|
5895
|
+
${armSwitch}
|
|
5893
5896
|
}
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
let lo = 0, hi = starts.length - 1;
|
|
5899
|
-
while (lo < hi) {
|
|
5900
|
-
const mid = lo + hi + 1 >> 1;
|
|
5901
|
-
if (starts[mid] <= offset) lo = mid;
|
|
5902
|
-
else hi = mid - 1;
|
|
5903
|
-
}
|
|
5904
|
-
return [lo + 1, offset - starts[lo] + 1];
|
|
5897
|
+
if(v!==FAIL)return v
|
|
5898
|
+
if(ctx._fc===true)return FAIL
|
|
5899
|
+
const af=ctx._fx
|
|
5900
|
+
if(af!==undefined&&af.length>0){ctx._fe=pos;return FAIL}
|
|
5905
5901
|
}
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5902
|
+
ctx._fe=pos;ctx._fx=${choiceFx}
|
|
5903
|
+
return FAIL
|
|
5904
|
+
}`;
|
|
5905
|
+
}
|
|
5906
|
+
const ci = classes.push(Array.from({ length: n }, (_, i) => table.armCls[i] ?? null)) - 1;
|
|
5907
|
+
classPlan.push(Array.from({ length: n }, (_, i) => prog.disp[code[ip + 1]][i] ?? -1));
|
|
5908
|
+
const gates = classes[ci];
|
|
5909
|
+
const gRef = hoist("g", `CLS[${ci}]`);
|
|
5910
|
+
const maskable = n <= 32;
|
|
5911
|
+
let maskName = "";
|
|
5912
|
+
if (maskable) {
|
|
5913
|
+
maskName = hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`);
|
|
5914
|
+
maskPlan.push(ci);
|
|
5915
|
+
}
|
|
5916
|
+
const p = tmp();
|
|
5917
|
+
const maskArms = arms.map((a, i) => `
|
|
5918
|
+
if((bits&${1 << i})!==0){
|
|
5919
|
+
ctx._fc=false
|
|
5920
|
+
{const v=${a}(input,pos,ctx)
|
|
5921
|
+
if(v!==FAIL)return v}
|
|
5922
|
+
for(let j=prev;j<${i};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5923
|
+
prev=${i + 1}
|
|
5924
|
+
acc=_accSet(ctx._fx,acc)
|
|
5925
|
+
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5926
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5927
|
+
}`).join("");
|
|
5928
|
+
const generalArms = arms.map((a, i) => `
|
|
5929
|
+
if(${gRef}[${i}]===null||classHas(${gRef}[${i}],c)){
|
|
5930
|
+
ctx._fc=false
|
|
5931
|
+
{const v=${a}(input,pos,ctx)
|
|
5932
|
+
if(v!==FAIL)return v}
|
|
5933
|
+
acc=_accSet(ctx._fx,acc)
|
|
5934
|
+
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
5935
|
+
${emitRollback(p, L.buf, sinks)}
|
|
5936
|
+
}else acc=_accSet(${afx}[${i}],acc)`).join("");
|
|
5937
|
+
return `${head}
|
|
5938
|
+
const c=lead(input,pos)
|
|
5939
|
+
${emitMark(p, L.buf, sinks)}
|
|
5940
|
+
let acc
|
|
5941
|
+
${maskable ? `if(c<128){
|
|
5942
|
+
const bits=${maskName}[c<0?128:c]
|
|
5943
|
+
let prev=0
|
|
5944
|
+
${maskArms}
|
|
5945
|
+
for(let j=prev;j<${n};j++)if((bits&(1<<j))===0)acc=_accSet(${afx}[j],acc)
|
|
5946
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5947
|
+
return FAIL
|
|
5909
5948
|
}
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5949
|
+
` : ""}${generalArms}
|
|
5950
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
5951
|
+
return FAIL
|
|
5952
|
+
}`;
|
|
5953
|
+
}
|
|
5954
|
+
case OP_DISPATCH: {
|
|
5955
|
+
const di = code[ip + 2];
|
|
5956
|
+
const spec = dsp[di];
|
|
5957
|
+
const selector = link(code[ip + 1]);
|
|
5958
|
+
const otherIp = code[ip + 3];
|
|
5959
|
+
const other = otherIp >= 0 ? link(otherIp) : void 0;
|
|
5960
|
+
const otherRouted = code[ip + 4] === 1;
|
|
5961
|
+
const n = code[ip + 5];
|
|
5962
|
+
validateDispatchSpec(spec, n, code[ip + 4]);
|
|
5963
|
+
const armBase = ip + 6;
|
|
5964
|
+
const arms = [];
|
|
5965
|
+
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
5966
|
+
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
5967
|
+
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
5968
|
+
const claims = (m) => {
|
|
5969
|
+
switch (m[0]) {
|
|
5970
|
+
case 0:
|
|
5971
|
+
return `key.startsWith(${q(m[1])})`;
|
|
5972
|
+
case 1:
|
|
5973
|
+
return `key.endsWith(${q(m[1])})`;
|
|
5974
|
+
case 3:
|
|
5975
|
+
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
5976
|
+
case 4:
|
|
5977
|
+
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
5978
|
+
default:
|
|
5979
|
+
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
5980
|
+
}
|
|
5981
|
+
};
|
|
5982
|
+
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
5983
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}`).join("\n")}
|
|
5920
5984
|
}
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5985
|
+
`;
|
|
5986
|
+
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
5987
|
+
` : "";
|
|
5988
|
+
const m1 = tmp();
|
|
5989
|
+
const m2 = tmp();
|
|
5990
|
+
const routedCall = (target) => `{const savedRouted=ctx._routed
|
|
5991
|
+
${emitRollback(m1, L.buf, sinks)}
|
|
5992
|
+
${emitMark(m2, L.buf, sinks, false)}
|
|
5993
|
+
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
5994
|
+
try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
|
|
5995
|
+
break}`;
|
|
5996
|
+
const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
|
|
5997
|
+
const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
|
|
5998
|
+
const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
|
|
5999
|
+
return `${head}
|
|
6000
|
+
${emitMark(m1, L.buf, sinks)}
|
|
6001
|
+
const sv=${selector}(input,pos,ctx)
|
|
6002
|
+
if(sv===FAIL)return FAIL
|
|
6003
|
+
const selEnd=EC.e
|
|
6004
|
+
const key=sv
|
|
6005
|
+
let arm=${bk}.get(key)
|
|
6006
|
+
${fold}${chain}
|
|
6007
|
+
if(arm===undefined){
|
|
6008
|
+
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
|
|
5926
6009
|
}
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
6010
|
+
${emitMark(m2, L.buf, sinks)}
|
|
6011
|
+
let v
|
|
6012
|
+
switch(arm){
|
|
6013
|
+
${armCases}
|
|
6014
|
+
${fallbackCase}
|
|
5931
6015
|
}
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
case "choice-arm":
|
|
5937
|
-
return 1;
|
|
5938
|
-
case "dispatch-arm":
|
|
5939
|
-
return 2;
|
|
5940
|
-
case "label":
|
|
5941
|
-
return 3;
|
|
5942
|
-
}
|
|
6016
|
+
if(v===FAIL){
|
|
6017
|
+
${emitRollback(m2, L.buf, sinks)}
|
|
6018
|
+
ctx._fc=true
|
|
6019
|
+
return FAIL
|
|
5943
6020
|
}
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
5953
|
-
|
|
5954
|
-
|
|
6021
|
+
return [key,v]
|
|
6022
|
+
}`;
|
|
6023
|
+
}
|
|
6024
|
+
case OP_REP:
|
|
6025
|
+
case OP_REPV: {
|
|
6026
|
+
const child = link(code[ip + 1]);
|
|
6027
|
+
const min = code[ip + 2];
|
|
6028
|
+
const max = code[ip + 3];
|
|
6029
|
+
const sepIp = code[ip + 4];
|
|
6030
|
+
const sep = sepIp >= 0 ? link(sepIp) : void 0;
|
|
6031
|
+
const flags = code[ip + 5];
|
|
6032
|
+
const keepSeparators = (flags & 2) !== 0;
|
|
6033
|
+
const trailingAllowed = (flags & 1) !== 0;
|
|
6034
|
+
const reportItem = (flags & 4) !== 0;
|
|
6035
|
+
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
6036
|
+
const collect = op === OP_REP;
|
|
6037
|
+
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
6038
|
+
const p = tmp();
|
|
6039
|
+
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
6040
|
+
const leadTrivia = skipBeforeFirst ? "true" : "count>0";
|
|
6041
|
+
const skip = skipFor(L);
|
|
6042
|
+
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
6043
|
+
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
6044
|
+
const needMark = L.buf ? "true" : "needMark";
|
|
6045
|
+
const pfd = sinks.fd ? `${p}fd` : "0";
|
|
6046
|
+
const per = sinks.er ? `${p}er` : "undefined";
|
|
6047
|
+
const rb = L.buf ? `_rbBuf(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
6048
|
+
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
6049
|
+
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)`;
|
|
6050
|
+
const markSinks = `${sinks.fd ? `
|
|
6051
|
+
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
6052
|
+
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
6053
|
+
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
6054
|
+
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
6055
|
+
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6056
|
+
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6057
|
+
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
6058
|
+
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
6059
|
+
const b=ctx._cstBuf
|
|
6060
|
+
if(b!==undefined){
|
|
6061
|
+
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
6062
|
+
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6063
|
+
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6064
|
+
}else{
|
|
6065
|
+
${p}raw=ctx._cstRawChildren!==undefined?ctx._cstRawChildren.length:0
|
|
6066
|
+
${p}tl=ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0
|
|
6067
|
+
${p}lv=ctx._cstLeaves!==undefined?ctx._cstLeaves.length:0
|
|
5955
6068
|
}
|
|
5956
|
-
|
|
5957
|
-
|
|
6069
|
+
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
6070
|
+
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}
|
|
6071
|
+
}`;
|
|
6072
|
+
const my = `${p}my`;
|
|
6073
|
+
const recFx = REC ? fxRef(code[ip + 6]) : "";
|
|
6074
|
+
const sepSent = REC ? sentRef(code[ip + 7]) : "undefined";
|
|
6075
|
+
const recSent = sep === void 0 ? my : sepSent === "undefined" ? `orSentinel(${my},undefined)` : `orSentinel(${sepSent}??${my},${sepSent}===undefined?undefined:${my})`;
|
|
6076
|
+
const recGate = sep !== void 0 || min === 0 ? "" : `count>=${min}&&`;
|
|
6077
|
+
const recBranch = !REC ? "" : `if(ctx._tolerant===true&&${my}!==undefined&&${recGate}!matchesAt(${my},input,itemStart,ctx)){
|
|
6078
|
+
${sep === void 0 ? `${rb}
|
|
6079
|
+
` : ""}const rr=recoverScan(input,itemStart,ctx,${recSent},${recFx})
|
|
6080
|
+
${collect ? "out.push(rr.error)\n" : ""}captureError(ctx,rr.error)
|
|
6081
|
+
count++
|
|
6082
|
+
cur=rr.end
|
|
6083
|
+
continue
|
|
5958
6084
|
}
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
6085
|
+
`;
|
|
6086
|
+
return `${head}
|
|
6087
|
+
const out=${collect ? "[]" : "undefined"}
|
|
6088
|
+
${knownTrivia === void 0 ? "const hasTrivia=ctx.trivia!==undefined\n" : ""}${L.buf ? "" : "const needMark=_rollbackNeeded(ctx)\n"}${REC ? `const ${my}=ctx._sync
|
|
6089
|
+
` : ""}let cur=pos
|
|
6090
|
+
let count=0
|
|
6091
|
+
for(;;){
|
|
6092
|
+
${max >= 0 ? `if(count>=${max})break
|
|
6093
|
+
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
6094
|
+
` : ""}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` : ""}
|
|
6095
|
+
${markBody}
|
|
6096
|
+
let itemStart=cur
|
|
6097
|
+
let sepEnd=-1
|
|
6098
|
+
${sep !== void 0 ? `if(count>0){
|
|
6099
|
+
const lb=cstLeavesLen(ctx)
|
|
6100
|
+
let sp=cur
|
|
6101
|
+
${hasTrivia === "false" ? "" : hasTrivia === "true" ? `sp=${skip}(input,sp,ctx)
|
|
6102
|
+
` : `if(hasTrivia)sp=${skip}(input,sp,ctx)
|
|
6103
|
+
`}ctx._fc=false
|
|
6104
|
+
const sv=${sep}(input,sp,ctx)
|
|
6105
|
+
if(sv===FAIL){
|
|
6106
|
+
${rb}
|
|
6107
|
+
if(ctx._fc===true)return FAIL
|
|
6108
|
+
break
|
|
5982
6109
|
}
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
6110
|
+
${keepSeparators ? "" : "demoteCapturedToRaw(ctx,lb)\n"}sepEnd=EC.e
|
|
6111
|
+
itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(input,EC.e,ctx)` : `hasTrivia?${skip}(input,EC.e,ctx):EC.e`}
|
|
6112
|
+
}else ${leadSkip(hasTrivia, leadTrivia, skip)}
|
|
6113
|
+
` : `${leadSkip(hasTrivia, leadTrivia, skip)}
|
|
6114
|
+
`}if(itemStart>=input.length&&${via}){
|
|
6115
|
+
${rb}
|
|
6116
|
+
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
5986
6117
|
}
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
}
|
|
5994
|
-
}
|
|
5995
|
-
if (lo > hi) {
|
|
5996
|
-
throw new TypeError(`table char-class range is descending: ${lo} > ${hi}`);
|
|
5997
|
-
}
|
|
6118
|
+
ctx._fc=false
|
|
6119
|
+
const v=${child}(input,itemStart,ctx)
|
|
6120
|
+
if(v===FAIL){
|
|
6121
|
+
${REC ? `if(ctx._fc===true){
|
|
6122
|
+
${rb}
|
|
6123
|
+
return FAIL
|
|
5998
6124
|
}
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
validateClassRange(range.lo, range.hi);
|
|
6003
|
-
if (range.hi > 65535) wide = true;
|
|
6004
|
-
}
|
|
6005
|
-
if (!wide) {
|
|
6006
|
-
let spec2 = "";
|
|
6007
|
-
for (const range of ranges) spec2 += String.fromCharCode(range.lo, range.hi);
|
|
6008
|
-
return spec2;
|
|
6009
|
-
}
|
|
6010
|
-
let spec = String.fromCharCode(WIDE_CLASS_PREFIX_LO, WIDE_CLASS_PREFIX_HI);
|
|
6011
|
-
for (const range of ranges) {
|
|
6012
|
-
spec += String.fromCharCode(
|
|
6013
|
-
range.lo >>> 16,
|
|
6014
|
-
range.lo & 65535,
|
|
6015
|
-
range.hi >>> 16,
|
|
6016
|
-
range.hi & 65535
|
|
6017
|
-
);
|
|
6018
|
-
}
|
|
6019
|
-
return spec;
|
|
6125
|
+
${recBranch}${rb}` : `${rb}
|
|
6126
|
+
if(ctx._fc===true)return FAIL`}
|
|
6127
|
+
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
6020
6128
|
}
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
if (spec.length === 2) throw new TypeError("table char-class spec has a wide prefix but no ranges");
|
|
6025
|
-
const ranges2 = [];
|
|
6026
|
-
for (let i = 2; i < spec.length; i += 4) {
|
|
6027
|
-
const lo = spec.charCodeAt(i) * 65536 + spec.charCodeAt(i + 1);
|
|
6028
|
-
const hi = spec.charCodeAt(i + 2) * 65536 + spec.charCodeAt(i + 3);
|
|
6029
|
-
validateClassRange(lo, hi);
|
|
6030
|
-
ranges2.push({ lo, hi });
|
|
6031
|
-
}
|
|
6032
|
-
return ranges2;
|
|
6033
|
-
}
|
|
6034
|
-
if (spec.length % 2 !== 0) throw new TypeError("table char-class spec has an unmatched range endpoint");
|
|
6035
|
-
const ranges = [];
|
|
6036
|
-
for (let i = 0; i < spec.length; i += 2) {
|
|
6037
|
-
const lo = spec.charCodeAt(i);
|
|
6038
|
-
const hi = spec.charCodeAt(i + 1);
|
|
6039
|
-
validateClassRange(lo, hi);
|
|
6040
|
-
ranges.push({ lo, hi });
|
|
6041
|
-
}
|
|
6042
|
-
return ranges;
|
|
6129
|
+
if(EC.e===itemStart&&${via}){
|
|
6130
|
+
${rb}
|
|
6131
|
+
break
|
|
6043
6132
|
}
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
const hi = [];
|
|
6047
|
-
for (const { lo, hi: up } of decodeClassSpec(spec)) {
|
|
6048
|
-
if (lo < 128) for (let c = lo; c <= Math.min(up, 127); c++) ascii[c] = 1;
|
|
6049
|
-
if (up >= 128) hi.push(Math.max(lo, 128), up);
|
|
6050
|
-
}
|
|
6051
|
-
return { ascii, hi };
|
|
6133
|
+
${collect ? "out.push(v)\n" : ""}cur=EC.e
|
|
6134
|
+
count++
|
|
6052
6135
|
}
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
const hi = cls.hi;
|
|
6057
|
-
for (let i = 0; i < hi.length; i += 2) if (code >= hi[i] && code <= hi[i + 1]) return true;
|
|
6058
|
-
return false;
|
|
6136
|
+
${min > 0 ? `if(count<${min}){
|
|
6137
|
+
${reportItem ? `ctx._fe=cur;ctx._fx=${itemFx}
|
|
6138
|
+
` : ""}return FAIL
|
|
6059
6139
|
}
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6080
|
-
|
|
6140
|
+
` : ""}EC.e=cur
|
|
6141
|
+
return out
|
|
6142
|
+
}`;
|
|
6143
|
+
}
|
|
6144
|
+
case OP_NODE:
|
|
6145
|
+
case OP_NODE_TRACK: {
|
|
6146
|
+
const flags = code[ip + 3];
|
|
6147
|
+
const child = link(code[ip + 2]);
|
|
6148
|
+
const proj = code[ip + 4];
|
|
6149
|
+
const buildIdx = code[ip + 1];
|
|
6150
|
+
const type = k[code[ip + 5]];
|
|
6151
|
+
const tagIdx = code[ip + 6];
|
|
6152
|
+
const tags = tagIdx < 0 ? "undefined" : kRef(tagIdx);
|
|
6153
|
+
const tracked = op === OP_NODE_TRACK;
|
|
6154
|
+
const readsTrivia = (flags & 4) !== 0;
|
|
6155
|
+
const readsState = (flags & 8) !== 0;
|
|
6156
|
+
const hasFields = (flags & 16) !== 0;
|
|
6157
|
+
const collapse = (flags & 32) !== 0;
|
|
6158
|
+
const unwrap = (flags & 64) !== 0;
|
|
6159
|
+
const trailingTrivia = (flags & 128) !== 0;
|
|
6160
|
+
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
6161
|
+
const structural = build === void 0 && proj < 0;
|
|
6162
|
+
const grammarCapture = (flags & 1) !== 0 || trailingTrivia;
|
|
6163
|
+
const hostCapturesThisType = structural && cfg.hostCaptureTrivia !== void 0 ? cfg.hostCaptureTrivia(type) : void 0;
|
|
6164
|
+
const wantFields = hasFields || hostCst;
|
|
6165
|
+
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
6166
|
+
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
6167
|
+
const ty = q(type);
|
|
6168
|
+
const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
|
|
6169
|
+
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
6170
|
+
let value;
|
|
6171
|
+
if (proj >= 0) {
|
|
6172
|
+
value = hostCst ? `nd=_pfHost!==undefined?${hostCall}:projectChild(kids,${proj},${ty})` : `nd=projectChild(kids,${proj},${ty})`;
|
|
6173
|
+
} else if (build !== void 0) {
|
|
6174
|
+
const direct = `${build}(kids,fieldMap,span,rawKids,${captureWide ? "tlog" : "EMPTY_TL"},st)`;
|
|
6175
|
+
value = hostCst ? `nd=_pfHost!==undefined?${hostCall}:${direct}` : `nd=${direct}`;
|
|
6176
|
+
} else {
|
|
6177
|
+
value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
|
|
6178
|
+
}
|
|
6179
|
+
const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
|
|
6180
|
+
const openCapture = keepChildren ? `const buf={}
|
|
6181
|
+
ctx._cstBuf=buf
|
|
6182
|
+
ctx._cstChildren=undefined
|
|
6183
|
+
ctx._cstLeaves=undefined
|
|
6184
|
+
ctx._cstRawChildren=undefined
|
|
6185
|
+
ctx._cstTriviaLog=undefined` : `const buf={rawOnly:true}
|
|
6186
|
+
ctx._cstBuf=buf
|
|
6187
|
+
ctx._cstChildren=undefined
|
|
6188
|
+
ctx._cstLeaves=undefined
|
|
6189
|
+
ctx._cstRawChildren=undefined
|
|
6190
|
+
ctx._cstTriviaLog=undefined`;
|
|
6191
|
+
const finishCapture = keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
6192
|
+
const hostKids=kids
|
|
6193
|
+
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
6194
|
+
const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
6195
|
+
const hostKids=kids
|
|
6196
|
+
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
6197
|
+
const tlog=buf.tl??EMPTY_TLOG`;
|
|
6198
|
+
return `${head}
|
|
6199
|
+
const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
6200
|
+
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
6201
|
+
${openCapture}
|
|
6202
|
+
ctx.captureTrivia=${captureWide}
|
|
6203
|
+
const savedFields=ctx._fields
|
|
6204
|
+
ctx._fields=${wantFields ? "[]" : "undefined"}
|
|
6205
|
+
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
6206
|
+
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
6207
|
+
` : ""}const v=${child}(input,pos,ctx)
|
|
6208
|
+
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
6209
|
+
` : ""}const fieldMap=${wantFields ? "buildFieldMap(ctx._fields)" : "undefined"}
|
|
6210
|
+
ctx._fields=savedFields
|
|
6211
|
+
${structural ? "ctx._triviaCaptureMask=savedMask\n" : ""}${finishCapture}
|
|
6212
|
+
ctx._cstBuf=sBuf
|
|
6213
|
+
ctx._cstChildren=sCh
|
|
6214
|
+
ctx._cstLeaves=sLv
|
|
6215
|
+
ctx._cstRawChildren=sRaw
|
|
6216
|
+
ctx._cstTriviaLog=sTl
|
|
6217
|
+
ctx.captureTrivia=sCap
|
|
6218
|
+
if(v===FAIL)return FAIL
|
|
6219
|
+
const end=EC.e
|
|
6220
|
+
const span=${tracked ? "spanLines(ctx,pos,end)" : "{start:pos,end}"}
|
|
6221
|
+
const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)" : "undefined"}
|
|
6222
|
+
let nd
|
|
6223
|
+
${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]
|
|
6224
|
+
else ` : ""}{${value}}
|
|
6225
|
+
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
6226
|
+
EC.e=end
|
|
6227
|
+
return nd
|
|
6228
|
+
}`;
|
|
6229
|
+
}
|
|
6230
|
+
default:
|
|
6231
|
+
throw new Unemittable(`OP_${OP_NAMES[op] ?? String(op)}`);
|
|
6081
6232
|
}
|
|
6082
|
-
if (cls.hi.length > 0 && ++hiOwners > 1) exclusive = false;
|
|
6083
|
-
for (let i = 0; i < cls.hi.length; i += 2) hi.push(cls.hi[i], cls.hi[i + 1], a);
|
|
6084
6233
|
}
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
const [head, ...rest] = spec.alts.map(([source, flags]) => regex(new RegExp(source, flags)));
|
|
6092
|
-
if (head === void 0) throw new TypeError("trivia spec has an EMPTY alternation, which matches nothing");
|
|
6093
|
-
const body = rest.length === 0 ? head : choice(head, ...rest);
|
|
6094
|
-
return trivia(many(body, { min: spec.min ?? 1 }));
|
|
6234
|
+
const ruleEntries = [];
|
|
6235
|
+
for (const [rname, entryIp] of Object.entries(prog.rules)) {
|
|
6236
|
+
const target = link(entryIp);
|
|
6237
|
+
const rn = `_r_${rname.replace(/[^A-Za-z0-9_$]/g, "_")}`;
|
|
6238
|
+
bodies.push(`const ${rn}=${target}`);
|
|
6239
|
+
ruleEntries.push(`${q(rname)}:${rn}`);
|
|
6095
6240
|
}
|
|
6096
|
-
const
|
|
6097
|
-
for (const
|
|
6098
|
-
|
|
6241
|
+
const extra = [];
|
|
6242
|
+
for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
|
|
6243
|
+
const source = `${RUNTIME_PRELUDE}
|
|
6244
|
+
${prelude.join("\n")}
|
|
6245
|
+
${skipDefs.join("\n")}
|
|
6246
|
+
${bodies.join("\n")}
|
|
6247
|
+
function _begin(ctx){
|
|
6248
|
+
const host=ctx.build
|
|
6249
|
+
if(_pfDepth>0)_pfFrames.push([_pfScan,_pfHost,EC.e])
|
|
6250
|
+
_pfDepth++
|
|
6251
|
+
_pfScan=null
|
|
6252
|
+
_pfHost=host
|
|
6099
6253
|
}
|
|
6100
|
-
function
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
code: Int32Array.from(prog.code),
|
|
6109
|
-
k: prog.k,
|
|
6110
|
-
fns: prog.fns,
|
|
6111
|
-
cc,
|
|
6112
|
-
fx: prog.fx,
|
|
6113
|
-
disp: prog.disp.map((d) => resolveDispatch(d, cc)),
|
|
6114
|
-
trivia: triviaBuilt,
|
|
6115
|
-
triviaScan: triviaBuilt.map(fastTriviaScanner),
|
|
6116
|
-
triviaLabelled: triviaBuilt.map((t) => t._meta.triviaKindLabels !== void 0),
|
|
6117
|
-
dsp: prog.dsp.map((d) => ({
|
|
6118
|
-
byKey: new Map(d.key.map((x, i) => [x, d.keyArm[i]])),
|
|
6119
|
-
byFold: new Map(d.fold.map((x, i) => [x, d.foldArm[i]])),
|
|
6120
|
-
match: d.match,
|
|
6121
|
-
routed: d.routed,
|
|
6122
|
-
expected: d.expected
|
|
6123
|
-
})),
|
|
6124
|
-
rules: prog.rules
|
|
6125
|
-
};
|
|
6126
|
-
if (owner !== void 0) owner.resolved = built;
|
|
6127
|
-
return built;
|
|
6254
|
+
function _finish(){
|
|
6255
|
+
if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
|
|
6256
|
+
_pfDepth--
|
|
6257
|
+
if(_pfDepth===0)return
|
|
6258
|
+
const prior=_pfFrames.pop()
|
|
6259
|
+
_pfScan=prior[0]
|
|
6260
|
+
_pfHost=prior[1]
|
|
6261
|
+
EC.e=prior[2]
|
|
6128
6262
|
}
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6263
|
+
return{
|
|
6264
|
+
pieces:{${ruleEntries.join(",")}},
|
|
6265
|
+
byIp:{${extra.join(",")}},
|
|
6266
|
+
end:function(){return EC.e},
|
|
6267
|
+
begin:_begin,
|
|
6268
|
+
finish:_finish
|
|
6269
|
+
}`;
|
|
6270
|
+
return {
|
|
6271
|
+
source,
|
|
6272
|
+
reached,
|
|
6273
|
+
masks,
|
|
6274
|
+
classes,
|
|
6275
|
+
armExpected,
|
|
6276
|
+
plan: { classes: classPlan, armExpected: armExpectedPlan, masks: maskPlan }
|
|
6277
|
+
};
|
|
6132
6278
|
}
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
"scanSkip",
|
|
6143
|
-
"scanSkipOf",
|
|
6144
|
-
"scans",
|
|
6145
|
-
"triviaSpecs",
|
|
6146
|
-
"runtimeOnly",
|
|
6147
|
-
// `rec` is a property of the GRAMMAR BUILD, not of the trackLines/hostMode
|
|
6148
|
-
// axis a fold varies — every variant of one export is encoded with the same
|
|
6149
|
-
// recovery setting, and a mismatch is two tables, which is what the refusal says.
|
|
6150
|
-
"rec",
|
|
6151
|
-
// `cov` is a property of the GRAMMAR and its coverage plan, for the same reason
|
|
6152
|
-
// `rec` is a property of the build: the plan is built from the rule map, which
|
|
6153
|
-
// every variant of one export shares. It ships ONCE, and a variant that
|
|
6154
|
-
// disagrees is two tables — which is what the refusal says.
|
|
6155
|
-
"cov"
|
|
6156
|
-
];
|
|
6157
|
-
function foldPrograms(programs, baseName) {
|
|
6158
|
-
const suppliedBase = programs[baseName];
|
|
6159
|
-
if (suppliedBase === void 0) throw new TypeError(`foldPrograms: no program named ${JSON.stringify(baseName)}`);
|
|
6160
|
-
const base = closureArtifact(suppliedBase);
|
|
6161
|
-
const variants = {};
|
|
6162
|
-
for (const name of Object.keys(programs)) {
|
|
6163
|
-
const p = programs[name];
|
|
6164
|
-
if (p.asm !== void 0 && p.asm.length > 0) {
|
|
6165
|
-
throw new TypeError(
|
|
6166
|
-
`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.`
|
|
6167
|
-
);
|
|
6168
|
-
}
|
|
6169
|
-
if (p.code.length !== base.code.length) {
|
|
6170
|
-
throw new TypeError(
|
|
6171
|
-
`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.`
|
|
6172
|
-
);
|
|
6173
|
-
}
|
|
6174
|
-
for (const f of SHARED_FIELDS) {
|
|
6175
|
-
if (JSON.stringify(p[f]) !== JSON.stringify(base[f])) {
|
|
6176
|
-
throw new TypeError(
|
|
6177
|
-
`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.`
|
|
6178
|
-
);
|
|
6179
|
-
}
|
|
6180
|
-
}
|
|
6181
|
-
if (p.fns.length !== base.fns.length || p.fns.some((f, i) => f !== base.fns[i])) {
|
|
6182
|
-
throw new TypeError(
|
|
6183
|
-
`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.`
|
|
6184
|
-
);
|
|
6185
|
-
}
|
|
6186
|
-
const at = [];
|
|
6187
|
-
const to = [];
|
|
6188
|
-
let prev = 0;
|
|
6189
|
-
for (let i = 0; i < p.code.length; i++) {
|
|
6190
|
-
if (p.code[i] === base.code[i]) continue;
|
|
6191
|
-
at.push(i - prev);
|
|
6192
|
-
to.push(p.code[i]);
|
|
6193
|
-
prev = i;
|
|
6194
|
-
}
|
|
6195
|
-
variants[name] = {
|
|
6196
|
-
at,
|
|
6197
|
-
to,
|
|
6198
|
-
...p.lines === void 0 ? {} : { lines: p.lines },
|
|
6199
|
-
...p.hostMode === void 0 ? {} : { hostMode: p.hostMode }
|
|
6200
|
-
};
|
|
6279
|
+
|
|
6280
|
+
// src/table/run-support.ts
|
|
6281
|
+
function lineCol(ctx, offset) {
|
|
6282
|
+
const starts = ctx._lineStarts ?? [0];
|
|
6283
|
+
let lo = 0, hi = starts.length - 1;
|
|
6284
|
+
while (lo < hi) {
|
|
6285
|
+
const mid = lo + hi + 1 >> 1;
|
|
6286
|
+
if (starts[mid] <= offset) lo = mid;
|
|
6287
|
+
else hi = mid - 1;
|
|
6201
6288
|
}
|
|
6202
|
-
return
|
|
6289
|
+
return [lo + 1, offset - starts[lo] + 1];
|
|
6203
6290
|
}
|
|
6204
|
-
function
|
|
6205
|
-
const
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
if (
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
);
|
|
6213
|
-
}
|
|
6214
|
-
const base = folded.base;
|
|
6215
|
-
const code = [...base.code];
|
|
6216
|
-
let ip = 0;
|
|
6217
|
-
for (let i = 0; i < d.at.length; i++) {
|
|
6218
|
-
ip += d.at[i];
|
|
6219
|
-
code[ip] = d.to[i];
|
|
6291
|
+
function spanLines(ctx, start, end) {
|
|
6292
|
+
const s = lineCol(ctx, start), e = lineCol(ctx, end);
|
|
6293
|
+
return { start, end, startLine: s[0], startColumn: s[1], endLine: e[0], endColumn: e[1] };
|
|
6294
|
+
}
|
|
6295
|
+
function rawEntry(v, input, s, e) {
|
|
6296
|
+
if (typeof v === "object" && v !== null) {
|
|
6297
|
+
const tg = v._tag;
|
|
6298
|
+
if (tg === "node" || tg === "leaf" || tg === "parseError") return v;
|
|
6220
6299
|
}
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
...d.hostMode === void 0 ? {} : { hostMode: d.hostMode }
|
|
6300
|
+
return {
|
|
6301
|
+
_tag: "leaf",
|
|
6302
|
+
value: typeof v === "string" ? v : typeof v === "object" && v !== null ? input.slice(s, e) : "",
|
|
6303
|
+
span: { start: s, end: e }
|
|
6226
6304
|
};
|
|
6227
|
-
const prog = ownTableProgram(raw);
|
|
6228
|
-
const owner = prog[TABLE_RUNTIME];
|
|
6229
|
-
owner.resolved = { ...resolveTable(base), prog, code: Int32Array.from(code) };
|
|
6230
|
-
byName?.set(name, prog);
|
|
6231
|
-
return prog;
|
|
6232
6305
|
}
|
|
6233
|
-
function
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
at: d.a ?? [],
|
|
6239
|
-
to: d.t ?? [],
|
|
6240
|
-
...d.l === void 0 ? {} : { lines: d.l },
|
|
6241
|
-
...d.h === void 0 ? {} : { hostMode: d.h }
|
|
6242
|
-
};
|
|
6243
|
-
}
|
|
6244
|
-
return ownFoldedProgram(expandCompact(f.b), variants);
|
|
6306
|
+
function lead(input, pos) {
|
|
6307
|
+
if (pos >= input.length) return -1;
|
|
6308
|
+
const c = input.charCodeAt(pos);
|
|
6309
|
+
if (c < 55296 || c > 56319) return c;
|
|
6310
|
+
return input.codePointAt(pos) ?? c;
|
|
6245
6311
|
}
|
|
6246
6312
|
|
|
6247
6313
|
// src/cst/host-mode.ts
|
|
@@ -6289,7 +6355,7 @@ function committed(c) {
|
|
|
6289
6355
|
}
|
|
6290
6356
|
function stampRuleMap(prog, d, artifactMetadata = {}, resolved = resolveTable(prog)) {
|
|
6291
6357
|
const triviaOfRule = (ip) => {
|
|
6292
|
-
if (prog.code[ip] !== OP_SCOPE) return void 0;
|
|
6358
|
+
if (prog.code[ip] !== OP_SCOPE_PLAIN && prog.code[ip] !== OP_SCOPE) return void 0;
|
|
6293
6359
|
const slot = prog.code[ip + 1];
|
|
6294
6360
|
return slot < 0 ? void 0 : resolved.trivia[slot];
|
|
6295
6361
|
};
|
|
@@ -6509,20 +6575,19 @@ function assemble(t, prog, cfg) {
|
|
|
6509
6575
|
TERMV = v2;
|
|
6510
6576
|
return EC.e > scanEnd2 ? EC.e : cur;
|
|
6511
6577
|
}
|
|
6512
|
-
const need =
|
|
6513
|
-
const
|
|
6514
|
-
const mTl = MTL;
|
|
6515
|
-
const mLv = MLV;
|
|
6516
|
-
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
6517
|
-
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
6578
|
+
const need = rollbackNeeded(ctx);
|
|
6579
|
+
const mTl = need ? cstTlLen(ctx) : 0;
|
|
6518
6580
|
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
6519
6581
|
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
6520
6582
|
const scanEnd = skipTrivia(input, cur, ctx);
|
|
6583
|
+
const scanTl = need ? cstTlLen(ctx) : 0;
|
|
6584
|
+
const scanLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
6585
|
+
const scanRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
6521
6586
|
const v = child(input, scanEnd, ctx);
|
|
6522
6587
|
if (v === FAIL) return -1;
|
|
6523
6588
|
TERMV = v;
|
|
6524
6589
|
if (EC.e > scanEnd) return EC.e;
|
|
6525
|
-
if (need)
|
|
6590
|
+
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
6526
6591
|
return cur;
|
|
6527
6592
|
}
|
|
6528
6593
|
function committed2(c) {
|
|
@@ -6936,7 +7001,8 @@ function assemble(t, prog, cfg) {
|
|
|
6936
7001
|
};
|
|
6937
7002
|
}
|
|
6938
7003
|
case OP_SCOPE:
|
|
6939
|
-
case OP_SCOPE_CAP:
|
|
7004
|
+
case OP_SCOPE_CAP:
|
|
7005
|
+
case OP_SCOPE_PLAIN: {
|
|
6940
7006
|
const ki = code[ip + 1];
|
|
6941
7007
|
const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
|
|
6942
7008
|
const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
|
|
@@ -6970,7 +7036,7 @@ function assemble(t, prog, cfg) {
|
|
|
6970
7036
|
SCAN = savedScan;
|
|
6971
7037
|
return v;
|
|
6972
7038
|
};
|
|
6973
|
-
return scopeRootPolicy(scopePiece, code[ip + 3]);
|
|
7039
|
+
return scopeRootPolicy(scopePiece, code[ip] === OP_SCOPE_PLAIN ? 0 : code[ip + 3]);
|
|
6974
7040
|
}
|
|
6975
7041
|
case OP_ROUTED: {
|
|
6976
7042
|
const fb = code[ip + 1];
|
|
@@ -7886,15 +7952,21 @@ function assemble(t, prog, cfg) {
|
|
|
7886
7952
|
target = arms[arm];
|
|
7887
7953
|
usesRouted = routed[arm] === 1;
|
|
7888
7954
|
}
|
|
7889
|
-
const savedRouted = ctx._routed;
|
|
7890
7955
|
let mark = saveTriviaMark(ctx);
|
|
7956
|
+
let v;
|
|
7891
7957
|
if (usesRouted) {
|
|
7958
|
+
const savedRouted = ctx._routed;
|
|
7892
7959
|
rollbackTrivia(ctx, selectorMark);
|
|
7893
7960
|
mark = saveTriviaMark(ctx);
|
|
7894
7961
|
ctx._routed = { value: key, span: { start: pos, end: selEnd } };
|
|
7962
|
+
try {
|
|
7963
|
+
v = target(input, pos, ctx);
|
|
7964
|
+
} finally {
|
|
7965
|
+
ctx._routed = savedRouted;
|
|
7966
|
+
}
|
|
7967
|
+
} else {
|
|
7968
|
+
v = target(input, selEnd, ctx);
|
|
7895
7969
|
}
|
|
7896
|
-
const v = target(input, usesRouted ? pos : selEnd, ctx);
|
|
7897
|
-
if (usesRouted) ctx._routed = savedRouted;
|
|
7898
7970
|
if (v === FAIL) {
|
|
7899
7971
|
rollbackTrivia(ctx, mark);
|
|
7900
7972
|
ctx._fc = true;
|
|
@@ -8040,6 +8112,11 @@ function assemble(t, prog, cfg) {
|
|
|
8040
8112
|
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
8041
8113
|
}
|
|
8042
8114
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
8115
|
+
const validationRoots = [...Object.values(prog.rules), ...extraIps];
|
|
8116
|
+
for (const ip of reachableSites(code, validationRoots)) {
|
|
8117
|
+
if (code[ip] !== OP_DISPATCH) continue;
|
|
8118
|
+
validateDispatchSpec(dsp[code[ip + 2]], code[ip + 5], code[ip + 4]);
|
|
8119
|
+
}
|
|
8043
8120
|
const pre = cfg.hostCaptureTrivia === void 0 ? prog.asm?.find((a) => a.key === cfgKey(cfg)) : void 0;
|
|
8044
8121
|
if (pre !== void 0) {
|
|
8045
8122
|
const pools = rebuildPools(t.cc, t.fx, pre.plan);
|
|
@@ -8066,6 +8143,7 @@ function assemble(t, prog, cfg) {
|
|
|
8066
8143
|
pushCstLeaf,
|
|
8067
8144
|
pushCstChild,
|
|
8068
8145
|
rollbackTriviaAt,
|
|
8146
|
+
rollbackScannedTriviaAt,
|
|
8069
8147
|
failAt,
|
|
8070
8148
|
classHas,
|
|
8071
8149
|
consumeTrivia,
|
|
@@ -8136,6 +8214,7 @@ function assemble(t, prog, cfg) {
|
|
|
8136
8214
|
pushCstLeaf,
|
|
8137
8215
|
pushCstChild,
|
|
8138
8216
|
rollbackTriviaAt,
|
|
8217
|
+
rollbackScannedTriviaAt,
|
|
8139
8218
|
failAt,
|
|
8140
8219
|
classHas,
|
|
8141
8220
|
consumeTrivia,
|
|
@@ -8825,7 +8904,7 @@ var Encoder = class {
|
|
|
8825
8904
|
this.carryTriviaMeta(amb);
|
|
8826
8905
|
this.carryTriviaMeta(p);
|
|
8827
8906
|
if (p._def.tag === "grammar") this.carryTriviaMeta(p._def.triviaParser);
|
|
8828
|
-
this.rules[name] = amb === void 0 ? body : this.emit(
|
|
8907
|
+
this.rules[name] = amb === void 0 ? body : this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), body);
|
|
8829
8908
|
}
|
|
8830
8909
|
/**
|
|
8831
8910
|
* The row a cross-rule `g.X` reference jumps to — the target's body, RE-WRAPPED
|
|
@@ -8868,7 +8947,7 @@ var Encoder = class {
|
|
|
8868
8947
|
const amb = p._meta.grammarTrivia ?? target._meta.grammarTrivia;
|
|
8869
8948
|
if (amb === void 0 || this.activeTrivia !== void 0) return ip;
|
|
8870
8949
|
if (!hasOwnTriviaBoundary(target)) return ip;
|
|
8871
|
-
return this.emit(
|
|
8950
|
+
return this.emit(OP_SCOPE_PLAIN, this.triviaSlot(amb), ip);
|
|
8872
8951
|
}
|
|
8873
8952
|
node(p) {
|
|
8874
8953
|
const lazyRef = p._def.tag === "lazy";
|
|
@@ -9273,6 +9352,7 @@ var Encoder = class {
|
|
|
9273
9352
|
return [ip + 1];
|
|
9274
9353
|
case OP_SCOPE:
|
|
9275
9354
|
case OP_SCOPE_CAP:
|
|
9355
|
+
case OP_SCOPE_PLAIN:
|
|
9276
9356
|
case OP_WITHCTX:
|
|
9277
9357
|
case OP_XFORM:
|
|
9278
9358
|
case OP_LEAF:
|
|
@@ -9412,6 +9492,14 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
9412
9492
|
function jsString(s) {
|
|
9413
9493
|
return JSON.stringify(s);
|
|
9414
9494
|
}
|
|
9495
|
+
function emitClassPool(classes) {
|
|
9496
|
+
const array = `[${classes.map(jsString).join(",")}]`;
|
|
9497
|
+
if (classes.length < 2) return array;
|
|
9498
|
+
const delimiter = "|/~?^`".split("").find((ch2) => classes.every((spec) => !spec.includes(ch2)));
|
|
9499
|
+
if (delimiter === void 0) return array;
|
|
9500
|
+
const split = `${jsString(classes.join(delimiter))}.split(${jsString(delimiter)})`;
|
|
9501
|
+
return split.length < array.length ? split : array;
|
|
9502
|
+
}
|
|
9415
9503
|
function emitConst(v) {
|
|
9416
9504
|
if (v instanceof RegExp) return `/${v.source}/${v.flags}`;
|
|
9417
9505
|
if (typeof v === "string") return jsString(v);
|
|
@@ -9490,7 +9578,7 @@ function programFields(prog, fns, opts = {}) {
|
|
|
9490
9578
|
...emitAssemblies(prog, opts.assemblies ?? []),
|
|
9491
9579
|
`c:[${prog.code.join(",")}],`,
|
|
9492
9580
|
`k:[${prog.k.map(emitConst).join(",")}],`,
|
|
9493
|
-
`x
|
|
9581
|
+
`x:${emitClassPool(prog.cc)},`,
|
|
9494
9582
|
`e:[${prog.fx.map((f) => `[${f.map(jsString).join(",")}]`).join(",")}],`,
|
|
9495
9583
|
`d:[${prog.disp.map((a) => `[${a.join(",")}]`).join(",")}],`,
|
|
9496
9584
|
`r:${JSON.stringify(prog.rules)},`,
|