parseman 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +16 -2
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +2 -0
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/index.cjs +150 -49
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +150 -49
- package/dist/index.js.map +2 -2
- package/dist/plugin/index.cjs +169 -56
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts +9 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +169 -56
- package/dist/plugin/index.js.map +3 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -261,12 +261,16 @@ function pushTriviaLogEntry(ctx, start, end, kindIndex) {
|
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
// src/combinators/literal.ts
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
264
|
+
function asciiFoldEq(a, b) {
|
|
265
|
+
if (a.length !== b.length) return false;
|
|
266
|
+
for (let i = 0; i < a.length; i++) {
|
|
267
|
+
let ca = a.charCodeAt(i);
|
|
268
|
+
let cb = b.charCodeAt(i);
|
|
269
|
+
if (ca >= 65 && ca <= 90) ca += 32;
|
|
270
|
+
if (cb >= 65 && cb <= 90) cb += 32;
|
|
271
|
+
if (ca !== cb) return false;
|
|
268
272
|
}
|
|
269
|
-
return
|
|
273
|
+
return true;
|
|
270
274
|
}
|
|
271
275
|
function literal(value, opts = {}) {
|
|
272
276
|
const caseInsensitive = opts.caseInsensitive ?? false;
|
|
@@ -281,8 +285,9 @@ function literal(value, opts = {}) {
|
|
|
281
285
|
const lower = value.toLowerCase();
|
|
282
286
|
const firstUpper = upper.codePointAt(0);
|
|
283
287
|
const firstLower = lower.codePointAt(0);
|
|
284
|
-
meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? { kind: "ranges", ranges: [
|
|
285
|
-
{ lo:
|
|
288
|
+
meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? firstLower === firstUpper ? { kind: "ranges", ranges: [{ lo: firstLower, hi: firstLower }] } : { kind: "ranges", ranges: [
|
|
289
|
+
{ lo: firstLower, hi: firstLower },
|
|
290
|
+
{ lo: firstUpper, hi: firstUpper }
|
|
286
291
|
] } : firstSet;
|
|
287
292
|
}
|
|
288
293
|
return {
|
|
@@ -295,7 +300,7 @@ function literal(value, opts = {}) {
|
|
|
295
300
|
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
296
301
|
}
|
|
297
302
|
const slice = input.slice(pos, end);
|
|
298
|
-
const matched = caseInsensitive ?
|
|
303
|
+
const matched = caseInsensitive ? asciiFoldEq(slice, value) : slice === value;
|
|
299
304
|
if (matched) {
|
|
300
305
|
const span = { start: pos, end };
|
|
301
306
|
const leaf = { _tag: "leaf", value: slice, span };
|
|
@@ -1629,8 +1634,8 @@ function classToRanges(cls) {
|
|
|
1629
1634
|
return parseClassRanges(body);
|
|
1630
1635
|
}
|
|
1631
1636
|
var foldEq = (cVar, cp) => {
|
|
1632
|
-
if (cp >= 65 && cp <= 90) return `(${cVar}
|
|
1633
|
-
if (cp >= 97 && cp <= 122) return `(${cVar}
|
|
1637
|
+
if (cp >= 65 && cp <= 90) return `(${cVar} | 32) === ${cp + 32}`;
|
|
1638
|
+
if (cp >= 97 && cp <= 122) return `(${cVar} | 32) === ${cp}`;
|
|
1634
1639
|
return `${cVar} === ${cp}`;
|
|
1635
1640
|
};
|
|
1636
1641
|
function literalCodePoints(frag) {
|
|
@@ -1881,6 +1886,12 @@ function firstSetsDisjoint(a, b) {
|
|
|
1881
1886
|
return classDisjoint(a, b);
|
|
1882
1887
|
}
|
|
1883
1888
|
function fixedClassSeq(shape) {
|
|
1889
|
+
if (shape.kind === "litFold") {
|
|
1890
|
+
return shape.open.map((cp) => {
|
|
1891
|
+
const other = cp >= 65 && cp <= 90 ? cp + 32 : cp >= 97 && cp <= 122 ? cp - 32 : cp;
|
|
1892
|
+
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 };
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1884
1895
|
if (shape.kind !== "seq") return null;
|
|
1885
1896
|
const out = [];
|
|
1886
1897
|
for (const p of shape.parts) {
|
|
@@ -2302,12 +2313,34 @@ function parseScanShapeCore(source) {
|
|
|
2302
2313
|
}
|
|
2303
2314
|
function scanShapeFromRegex(source, flags) {
|
|
2304
2315
|
if (/[msu]/.test(flags)) return null;
|
|
2305
|
-
if (/i/.test(flags))
|
|
2306
|
-
const open = literalCodePoints(source);
|
|
2307
|
-
return open ? { kind: "litFold", open } : null;
|
|
2308
|
-
}
|
|
2316
|
+
if (/i/.test(flags)) return caseFoldShape(source);
|
|
2309
2317
|
return parseScanShape(source);
|
|
2310
2318
|
}
|
|
2319
|
+
function caseFoldShape(source) {
|
|
2320
|
+
const la = stripTrailingLookahead(source);
|
|
2321
|
+
if (la) {
|
|
2322
|
+
const inner = caseFoldLiteralOrAlt(la.base);
|
|
2323
|
+
if (!inner) return null;
|
|
2324
|
+
const operand = { ranges: la.ranges, negated: la.classNegated };
|
|
2325
|
+
if (!lookaheadUnambiguous(inner, operand, la.negative)) return null;
|
|
2326
|
+
return { kind: "lookahead", inner, ranges: la.ranges, classNegated: la.classNegated, negative: la.negative };
|
|
2327
|
+
}
|
|
2328
|
+
return caseFoldLiteralOrAlt(source);
|
|
2329
|
+
}
|
|
2330
|
+
function caseFoldLiteralOrAlt(source) {
|
|
2331
|
+
const asciiOnly = (cps) => cps.every((cp) => cp <= 127);
|
|
2332
|
+
const open = literalCodePoints(source);
|
|
2333
|
+
if (open) return asciiOnly(open) ? { kind: "litFold", open } : null;
|
|
2334
|
+
const arms = splitTopLevelAlternation(source);
|
|
2335
|
+
if (!arms || arms.length < 2) return null;
|
|
2336
|
+
const litArms = [];
|
|
2337
|
+
for (const arm of arms) {
|
|
2338
|
+
const cp = literalCodePoints(arm);
|
|
2339
|
+
if (!cp || !asciiOnly(cp)) return null;
|
|
2340
|
+
litArms.push({ kind: "litFold", open: cp });
|
|
2341
|
+
}
|
|
2342
|
+
return { kind: "alt", arms: litArms, disjoint: false, firsts: litArms.map(() => null) };
|
|
2343
|
+
}
|
|
2311
2344
|
var classCond = (cVar, ranges) => ranges.map(([lo, hi]) => lo === hi ? `${cVar} === ${lo}` : `(${cVar} >= ${lo} && ${cVar} <= ${hi})`).join(" || ");
|
|
2312
2345
|
var litCond = (base, cps, firstVar) => cps.map(
|
|
2313
2346
|
(cp, k) => k === 0 && firstVar ? `${firstVar} === ${cp}` : `input.charCodeAt(${base}${k ? ` + ${k}` : ""}) === ${cp}`
|
|
@@ -2319,6 +2352,25 @@ function stringHardStop(shape) {
|
|
|
2319
2352
|
);
|
|
2320
2353
|
}
|
|
2321
2354
|
var codeAt = (start, firstChar) => firstChar ?? `input.charCodeAt(${start})`;
|
|
2355
|
+
var ALT_SWITCH_RANGE_LIMIT = 4;
|
|
2356
|
+
var ALT_SWITCH_MAX_CASES = 48;
|
|
2357
|
+
var ALT_SWITCH_MIN_CASES = 3;
|
|
2358
|
+
function planAltSwitch(firsts) {
|
|
2359
|
+
const cases = [];
|
|
2360
|
+
let total = 0;
|
|
2361
|
+
for (const fs of firsts) {
|
|
2362
|
+
if (!fs || fs.negated) return { kind: "if" };
|
|
2363
|
+
const pts = [];
|
|
2364
|
+
for (const [lo, hi] of fs.ranges) {
|
|
2365
|
+
if (hi - lo + 1 > ALT_SWITCH_RANGE_LIMIT) return { kind: "if" };
|
|
2366
|
+
for (let cp = lo; cp <= hi; cp++) pts.push(cp);
|
|
2367
|
+
}
|
|
2368
|
+
total += pts.length;
|
|
2369
|
+
if (total > ALT_SWITCH_MAX_CASES) return { kind: "if" };
|
|
2370
|
+
cases.push(pts);
|
|
2371
|
+
}
|
|
2372
|
+
return total >= ALT_SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
2373
|
+
}
|
|
2322
2374
|
function emitShapeMatch(shape, start, mint, ind2, firstChar) {
|
|
2323
2375
|
if (shape.kind === "lookahead") {
|
|
2324
2376
|
const inner = emitShapeMatch(shape.inner, start, mint, ind2, firstChar);
|
|
@@ -2343,18 +2395,57 @@ function emitShapeMatch(shape, start, mint, ind2, firstChar) {
|
|
|
2343
2395
|
const okV = mint("_ok");
|
|
2344
2396
|
const endV2 = mint("_end");
|
|
2345
2397
|
const lines = [`${ind2}let ${okV} = false`, `${ind2}let ${endV2} = ${start}`];
|
|
2398
|
+
if (shape.arms.length >= 2 && shape.arms.every((a) => a.kind === "litFold" && a.open.length >= 1)) {
|
|
2399
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2400
|
+
for (const a of shape.arms) {
|
|
2401
|
+
const open = a.open;
|
|
2402
|
+
const f = open[0];
|
|
2403
|
+
const lower = f >= 65 && f <= 90 ? f + 32 : f;
|
|
2404
|
+
(groups.get(lower) ?? groups.set(lower, []).get(lower)).push(open);
|
|
2405
|
+
}
|
|
2406
|
+
lines.push(`${ind2}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
2407
|
+
for (const [lower, arms] of groups) {
|
|
2408
|
+
const labels = lower >= 97 && lower <= 122 ? `case ${lower}: case ${lower - 32}:` : `case ${lower}:`;
|
|
2409
|
+
lines.push(`${ind2} ${labels} {`);
|
|
2410
|
+
for (const open of arms) {
|
|
2411
|
+
const tail = open.slice(1).map((cp, i) => foldEq(`input.charCodeAt(${start} + ${i + 1})`, cp));
|
|
2412
|
+
const cond = tail.length ? ` && ${tail.join(" && ")}` : "";
|
|
2413
|
+
lines.push(`${ind2} if (${start} + ${open.length} <= input.length${cond}) { ${okV} = true; ${endV2} = ${start} + ${open.length}; break }`);
|
|
2414
|
+
}
|
|
2415
|
+
lines.push(`${ind2} break`);
|
|
2416
|
+
lines.push(`${ind2} }`);
|
|
2417
|
+
}
|
|
2418
|
+
lines.push(`${ind2}}`);
|
|
2419
|
+
return { setup: lines, ok: okV, end: endV2 };
|
|
2420
|
+
}
|
|
2346
2421
|
if (shape.disjoint) {
|
|
2347
|
-
const
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2422
|
+
const plan = planAltSwitch(shape.firsts);
|
|
2423
|
+
if (plan.kind === "switch") {
|
|
2424
|
+
lines.push(`${ind2}if (${start} < input.length) switch (${codeAt(start, firstChar)}) {`);
|
|
2425
|
+
shape.arms.forEach((arm, k) => {
|
|
2426
|
+
const labels = plan.cases[k].map((cp) => `case ${cp}:`).join(" ");
|
|
2427
|
+
const m = emitShapeMatch(arm, start, mint, `${ind2} `, firstChar);
|
|
2428
|
+
lines.push(`${ind2} ${labels} {`);
|
|
2429
|
+
lines.push(...m.setup);
|
|
2430
|
+
lines.push(`${ind2} ${okV} = ${m.ok}`);
|
|
2431
|
+
lines.push(`${ind2} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
2432
|
+
lines.push(`${ind2} break`);
|
|
2433
|
+
lines.push(`${ind2} }`);
|
|
2434
|
+
});
|
|
2356
2435
|
lines.push(`${ind2}}`);
|
|
2357
|
-
}
|
|
2436
|
+
} else {
|
|
2437
|
+
const c0 = codeAt(start, firstChar);
|
|
2438
|
+
shape.arms.forEach((arm, k) => {
|
|
2439
|
+
const fs = shape.firsts[k];
|
|
2440
|
+
const cond = fs.negated ? `!(${classCond(c0, fs.ranges)})` : `(${classCond(c0, fs.ranges)})`;
|
|
2441
|
+
const m = emitShapeMatch(arm, start, mint, `${ind2} `, firstChar);
|
|
2442
|
+
lines.push(`${ind2}${k === 0 ? "if" : "else if"} (${start} < input.length && ${cond}) {`);
|
|
2443
|
+
lines.push(...m.setup);
|
|
2444
|
+
lines.push(`${ind2} ${okV} = ${m.ok}`);
|
|
2445
|
+
lines.push(`${ind2} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
2446
|
+
lines.push(`${ind2}}`);
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2358
2449
|
} else {
|
|
2359
2450
|
const lbl = mint("_alt");
|
|
2360
2451
|
lines.push(`${ind2}${lbl}: {`);
|
|
@@ -2842,6 +2933,8 @@ function tryInlineDestructureTransform(src, valueVars) {
|
|
|
2842
2933
|
}
|
|
2843
2934
|
|
|
2844
2935
|
// src/compiler/codegen.ts
|
|
2936
|
+
var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) return false; let s; try { s = Function.prototype.toString.call(b) } catch (e) { return true } if (/\\barguments\\b/.test(s)) return true; const m = /^[^(]*\\(([\\s\\S]*?)\\)/.exec(s); if (m && /\\.\\.\\.|=/.test(m[1])) return true; return b.length > n }";
|
|
2937
|
+
var _loweringSink = null;
|
|
2845
2938
|
function v(ctx, prefix = "_v") {
|
|
2846
2939
|
return `${prefix}${ctx.vars++}`;
|
|
2847
2940
|
}
|
|
@@ -3240,13 +3333,14 @@ function emitLit(def, ctx, pos) {
|
|
|
3240
3333
|
const vv = v(ctx);
|
|
3241
3334
|
const expectedStr = JSON.stringify(JSON.stringify(value));
|
|
3242
3335
|
const stmts = [];
|
|
3243
|
-
if (caseInsensitive) {
|
|
3244
|
-
|
|
3336
|
+
if (caseInsensitive && len > 0) {
|
|
3337
|
+
const match = Array.from(
|
|
3338
|
+
{ length: len },
|
|
3339
|
+
(_, i) => `(${foldEq(`input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""})`, value.charCodeAt(i))})`
|
|
3340
|
+
).join(" && ");
|
|
3245
3341
|
stmts.push(
|
|
3246
|
-
...emitIfFail(ctx, `${pos} + ${len} > input.length`, failBody(ctx, expectedStr, pos)),
|
|
3247
|
-
`${ind(ctx)}const ${vv}
|
|
3248
|
-
...emitIfFail(ctx, `_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0`, failBody(ctx, expectedStr, pos)),
|
|
3249
|
-
`${ind(ctx)}const ${vv} = ${vv}_s`
|
|
3342
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length || !(${match})`, failBody(ctx, expectedStr, pos)),
|
|
3343
|
+
`${ind(ctx)}const ${vv} = input.slice(${pos}, ${pos} + ${len})`
|
|
3250
3344
|
);
|
|
3251
3345
|
} else if (len === 0) {
|
|
3252
3346
|
stmts.push(`${ind(ctx)}const ${vv} = ''`);
|
|
@@ -3367,6 +3461,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
3367
3461
|
return { stmts: stmts2, valueVar: vv2, endVar: scanned.endVar };
|
|
3368
3462
|
}
|
|
3369
3463
|
}
|
|
3464
|
+
_loweringSink?.add(`/${def.source}/${def.flags}`);
|
|
3370
3465
|
const flags = "y" + def.flags.replace(/[gy]/g, "");
|
|
3371
3466
|
const key = `${def.source}/${flags}`;
|
|
3372
3467
|
let rName = ctx.regexMap.get(key);
|
|
@@ -3947,15 +4042,19 @@ function emitNode(def, ctx, pos) {
|
|
|
3947
4042
|
ctx.buildSrcs.push(def.buildSrc ?? null);
|
|
3948
4043
|
}
|
|
3949
4044
|
const i = ind(ctx);
|
|
3950
|
-
const capturesTrivia = mkType !== null || structural
|
|
3951
|
-
const clonesState = structural
|
|
4045
|
+
const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
|
|
4046
|
+
const clonesState = !structural && buildReadsState(def);
|
|
3952
4047
|
const chV = v(ctx, "_ch");
|
|
3953
4048
|
const rawV = v(ctx, "_raw");
|
|
3954
|
-
const
|
|
4049
|
+
const capTLv = structural ? v(ctx, "_ctl") : null;
|
|
4050
|
+
const capSTv = structural ? v(ctx, "_cst") : null;
|
|
4051
|
+
const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
|
|
3955
4052
|
if (!capturesTrivia) ctx.needsEmptyTl = true;
|
|
3956
4053
|
const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
|
|
3957
|
-
|
|
3958
|
-
const
|
|
4054
|
+
if (structural) ctx.needsHostReads = true;
|
|
4055
|
+
const allocStmt = structural ? `${i}const ${capTLv} = _ctx._pmCapTL ??= _hostReads(_ctx.build, 4), ${capSTv} = _ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 5))
|
|
4056
|
+
${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
|
|
4057
|
+
const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
|
|
3959
4058
|
const stmts = [
|
|
3960
4059
|
allocStmt,
|
|
3961
4060
|
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
|
|
@@ -3966,7 +4065,10 @@ function emitNode(def, ctx, pos) {
|
|
|
3966
4065
|
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
|
|
3967
4066
|
stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
|
|
3968
4067
|
let stV = "undefined";
|
|
3969
|
-
if (
|
|
4068
|
+
if (structural) {
|
|
4069
|
+
stV = v(ctx, "_nst");
|
|
4070
|
+
stmts.push(`${i}const ${stV} = ${capSTv} && _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
4071
|
+
} else if (clonesState) {
|
|
3970
4072
|
stV = v(ctx, "_nst");
|
|
3971
4073
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
3972
4074
|
}
|
|
@@ -4402,7 +4504,6 @@ function compile(combinator, mapFnSources) {
|
|
|
4402
4504
|
buildFns: [],
|
|
4403
4505
|
buildSrcs: [],
|
|
4404
4506
|
runtimeParsers: [],
|
|
4405
|
-
needsCollator: false,
|
|
4406
4507
|
namedParsers: /* @__PURE__ */ new Map(),
|
|
4407
4508
|
triviaCaptureNames: /* @__PURE__ */ new Map(),
|
|
4408
4509
|
triviaFnNames: /* @__PURE__ */ new Map(),
|
|
@@ -4411,18 +4512,18 @@ function compile(combinator, mapFnSources) {
|
|
|
4411
4512
|
lazyUsage: analyzeLazyUsage(combinator)
|
|
4412
4513
|
};
|
|
4413
4514
|
const r = emit(combinator, ctx, "_pos");
|
|
4414
|
-
const collatorDecl = ctx.needsCollator ? `const _collator = new Intl.Collator(undefined, { sensitivity: 'accent' })
|
|
4415
|
-
` : "";
|
|
4416
4515
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
4417
4516
|
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
4517
|
+
const hostReadsDecls = ctx.needsHostReads ? [HOST_READS_DECL] : [];
|
|
4418
4518
|
const source = [
|
|
4419
4519
|
...emptyTlDecls,
|
|
4520
|
+
...hostReadsDecls,
|
|
4420
4521
|
...ctx.regexDecls,
|
|
4421
4522
|
...ctx.expectedDecls,
|
|
4422
4523
|
"",
|
|
4423
4524
|
...namedPrelude,
|
|
4424
4525
|
ctx.namedFnDecls.join("\n\n"),
|
|
4425
|
-
|
|
4526
|
+
`function _parse(input, _pos, _rp, _mf, _build, _ctx) {`,
|
|
4426
4527
|
` let pos = _pos`,
|
|
4427
4528
|
...r.stmts,
|
|
4428
4529
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
@@ -4430,9 +4531,9 @@ function compile(combinator, mapFnSources) {
|
|
|
4430
4531
|
].join("\n");
|
|
4431
4532
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
4432
4533
|
...emptyTlDecls,
|
|
4534
|
+
...hostReadsDecls,
|
|
4433
4535
|
...ctx.regexDecls,
|
|
4434
4536
|
...ctx.expectedDecls,
|
|
4435
|
-
collatorDecl,
|
|
4436
4537
|
...namedPrelude,
|
|
4437
4538
|
...ctx.namedFnDecls.flatMap((decl, i) => i > 0 ? ["", decl] : [decl]),
|
|
4438
4539
|
`let pos = _pos`,
|
|
@@ -4449,7 +4550,7 @@ function compile(combinator, mapFnSources) {
|
|
|
4449
4550
|
const buildSources = ctx.buildFns.length === 0 ? void 0 : ctx.buildSrcs;
|
|
4450
4551
|
const mfCovered = ctx.mapFns.length === 0 || effectiveSources !== void 0 && effectiveSources.length === ctx.mapFns.length;
|
|
4451
4552
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
4452
|
-
const inlineExpression = canInline ? buildInlineExpression(ctx, r,
|
|
4553
|
+
const inlineExpression = canInline ? buildInlineExpression(ctx, r, effectiveSources, buildSources) : null;
|
|
4453
4554
|
return {
|
|
4454
4555
|
source,
|
|
4455
4556
|
inlineExpression,
|
|
@@ -4505,7 +4606,6 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
4505
4606
|
buildFns: [],
|
|
4506
4607
|
buildSrcs: [],
|
|
4507
4608
|
runtimeParsers: [],
|
|
4508
|
-
needsCollator: false,
|
|
4509
4609
|
namedParsers: /* @__PURE__ */ new Map(),
|
|
4510
4610
|
triviaCaptureNames: /* @__PURE__ */ new Map(),
|
|
4511
4611
|
triviaFnNames: /* @__PURE__ */ new Map(),
|
|
@@ -4636,12 +4736,12 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
4636
4736
|
firstSets,
|
|
4637
4737
|
deps: ruleDependencies(ruleMap),
|
|
4638
4738
|
needsEmptyTl: !!ctx.needsEmptyTl,
|
|
4639
|
-
|
|
4739
|
+
needsHostReads: !!ctx.needsHostReads,
|
|
4640
4740
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
4641
4741
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
4642
4742
|
};
|
|
4643
4743
|
}
|
|
4644
|
-
function buildInlineExpression(ctx, r,
|
|
4744
|
+
function buildInlineExpression(ctx, r, mapFnSources, buildSources) {
|
|
4645
4745
|
const bodyLines = [
|
|
4646
4746
|
` let pos = _pos`,
|
|
4647
4747
|
...r.stmts,
|
|
@@ -4655,14 +4755,15 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
|
|
|
4655
4755
|
const mfDecl = mapFnSources?.length ? ` const _mf = [${mapFnSources.join(", ")}]` : "";
|
|
4656
4756
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
4657
4757
|
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
4658
|
-
const
|
|
4758
|
+
const hostReadsDecl = ctx.needsHostReads ? ` ${HOST_READS_DECL}` : "";
|
|
4759
|
+
const needsWrapper = ctx.regexDecls.length > 0 || ctx.expectedDecls.length > 0 || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl || !!hostReadsDecl;
|
|
4659
4760
|
if (!needsWrapper) return innerFn;
|
|
4660
4761
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
4661
4762
|
const hoistedDecls = [
|
|
4662
4763
|
emptyTlDecl,
|
|
4764
|
+
hostReadsDecl,
|
|
4663
4765
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
4664
4766
|
...ctx.expectedDecls.map((d) => ` ${d}`),
|
|
4665
|
-
collatorDecl ? ` ${collatorDecl.trim()}` : "",
|
|
4666
4767
|
mfDecl,
|
|
4667
4768
|
buildDecl,
|
|
4668
4769
|
...namedPrelude.map((l) => ` ${l}`),
|
|
@@ -4721,13 +4822,13 @@ function fusedBody(pieces) {
|
|
|
4721
4822
|
}
|
|
4722
4823
|
const contributing = new Set(winner.values());
|
|
4723
4824
|
const needsEmptyTl = [...contributing].some((p) => p.needsEmptyTl);
|
|
4724
|
-
const
|
|
4825
|
+
const needsHostReads = [...contributing].some((p) => p.needsHostReads);
|
|
4725
4826
|
const lines = [
|
|
4726
4827
|
// Shared sentinel protocol (must match NAMED_FN_FAIL / NAMED_FN_END in codegen).
|
|
4727
4828
|
"const _pfFail = {}",
|
|
4728
4829
|
"let _pfEnd",
|
|
4729
4830
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
4730
|
-
...
|
|
4831
|
+
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
4731
4832
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
4732
4833
|
...[...contributing].flatMap((p) => p.prelude),
|
|
4733
4834
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|