parseman 0.18.2 → 0.19.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/README.md +4 -1
- package/dist/combinators/map.d.ts +5 -0
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +14 -13
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +1 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +3 -3
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts +16 -0
- package/dist/compiler/fields.d.ts.map +1 -0
- package/dist/compiler/inline-build.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +17 -3
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts +1 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.cjs +255 -45
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +255 -45
- package/dist/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +255 -53
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +255 -53
- package/dist/plugin/index.js.map +3 -3
- package/dist/types.d.ts +31 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -252,7 +252,8 @@ function saveCstMark(ctx) {
|
|
|
252
252
|
return {
|
|
253
253
|
raw: cstRawLen(ctx),
|
|
254
254
|
tlog: cstTlLen(ctx),
|
|
255
|
-
leaves: cstLeavesLen(ctx)
|
|
255
|
+
leaves: cstLeavesLen(ctx),
|
|
256
|
+
fields: ctx._fields?.length ?? 0
|
|
256
257
|
};
|
|
257
258
|
}
|
|
258
259
|
function rollbackBufList(b, keyMulti, keySingle, len) {
|
|
@@ -276,11 +277,13 @@ function rollbackCstCapture(ctx, mark) {
|
|
|
276
277
|
if (mark.tlog === 0) b.tl = void 0;
|
|
277
278
|
else b.tl.length = mark.tlog;
|
|
278
279
|
}
|
|
280
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
279
281
|
return;
|
|
280
282
|
}
|
|
281
283
|
if (ctx._cstRawChildren) ctx._cstRawChildren.length = mark.raw;
|
|
282
284
|
if (ctx._cstTriviaLog) ctx._cstTriviaLog.length = mark.tlog;
|
|
283
285
|
if (ctx._cstLeaves) ctx._cstLeaves.length = mark.leaves;
|
|
286
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
284
287
|
}
|
|
285
288
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
286
289
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -1020,10 +1023,10 @@ function needsDeferredTriviaCommit(ctx) {
|
|
|
1020
1023
|
}
|
|
1021
1024
|
function saveTriviaMark(ctx) {
|
|
1022
1025
|
const m = saveCstMark(ctx);
|
|
1023
|
-
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1026
|
+
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1024
1027
|
}
|
|
1025
1028
|
function rollbackTrivia(ctx, mark) {
|
|
1026
|
-
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves });
|
|
1029
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields });
|
|
1027
1030
|
if (ctx._triviaLog) ctx._triviaLog.length = mark.log;
|
|
1028
1031
|
}
|
|
1029
1032
|
function scanWithLabels(input, cur, ctx) {
|
|
@@ -1397,6 +1400,13 @@ function ref() {
|
|
|
1397
1400
|
define(p) {
|
|
1398
1401
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
1399
1402
|
resolved = p;
|
|
1403
|
+
meta.firstSet = p._meta.firstSet;
|
|
1404
|
+
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
1405
|
+
meta.isTrivia = p._meta.isTrivia;
|
|
1406
|
+
if (p._meta.triviaKindLabels !== void 0) meta.triviaKindLabels = p._meta.triviaKindLabels;
|
|
1407
|
+
else delete meta.triviaKindLabels;
|
|
1408
|
+
if (p._meta.disjoint !== void 0) meta.disjoint = p._meta.disjoint;
|
|
1409
|
+
else delete meta.disjoint;
|
|
1400
1410
|
}
|
|
1401
1411
|
};
|
|
1402
1412
|
return slot;
|
|
@@ -1437,6 +1447,9 @@ function markUnusedValues(root) {
|
|
|
1437
1447
|
case "transform":
|
|
1438
1448
|
visit(def.parser, true);
|
|
1439
1449
|
return;
|
|
1450
|
+
case "field":
|
|
1451
|
+
visit(def.parser, true);
|
|
1452
|
+
return;
|
|
1440
1453
|
case "skip":
|
|
1441
1454
|
visit(def.main, consumed);
|
|
1442
1455
|
visit(def.skipped, false);
|
|
@@ -1488,6 +1501,11 @@ function markUnusedValues(root) {
|
|
|
1488
1501
|
}
|
|
1489
1502
|
|
|
1490
1503
|
// src/combinators/parser.ts
|
|
1504
|
+
function tagRule(r, key) {
|
|
1505
|
+
;
|
|
1506
|
+
r._ruleName = key;
|
|
1507
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1508
|
+
}
|
|
1491
1509
|
function rules(factory) {
|
|
1492
1510
|
const cache = {};
|
|
1493
1511
|
const proxy = new Proxy(cache, {
|
|
@@ -1496,7 +1514,7 @@ function rules(factory) {
|
|
|
1496
1514
|
const record = target;
|
|
1497
1515
|
if (!(key in record)) {
|
|
1498
1516
|
const r = ref();
|
|
1499
|
-
r
|
|
1517
|
+
tagRule(r, key);
|
|
1500
1518
|
record[key] = r;
|
|
1501
1519
|
}
|
|
1502
1520
|
return record[key];
|
|
@@ -1507,12 +1525,12 @@ function rules(factory) {
|
|
|
1507
1525
|
const placeholder = cache[key];
|
|
1508
1526
|
const parser2 = definitions[key];
|
|
1509
1527
|
if (placeholder !== void 0 && typeof placeholder.define === "function") {
|
|
1510
|
-
;
|
|
1528
|
+
tagRule(parser2, key);
|
|
1511
1529
|
placeholder.define(parser2);
|
|
1512
1530
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1513
1531
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1514
1532
|
} else {
|
|
1515
|
-
;
|
|
1533
|
+
tagRule(parser2, key);
|
|
1516
1534
|
cache[key] = parser2;
|
|
1517
1535
|
}
|
|
1518
1536
|
}
|
|
@@ -1569,44 +1587,130 @@ function buildReadsTrivia(def) {
|
|
|
1569
1587
|
const src = def.buildSrc ?? def.build.toString();
|
|
1570
1588
|
const arity = confirmedBuildArity(src);
|
|
1571
1589
|
if (arity === null) return true;
|
|
1572
|
-
return arity >=
|
|
1590
|
+
return arity >= 5;
|
|
1573
1591
|
}
|
|
1574
1592
|
function buildReadsState(def) {
|
|
1575
1593
|
if (!def.build) return true;
|
|
1576
1594
|
const src = def.buildSrc ?? def.build.toString();
|
|
1577
1595
|
const arity = confirmedBuildArity(src);
|
|
1578
1596
|
if (arity === null) return true;
|
|
1579
|
-
return arity >=
|
|
1597
|
+
return arity >= 6;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
// src/compiler/fields.ts
|
|
1601
|
+
function buildReadsFields(def) {
|
|
1602
|
+
if (!def.build) return true;
|
|
1603
|
+
const src = def.buildSrc ?? def.build.toString();
|
|
1604
|
+
const arity = confirmedBuildArity(src);
|
|
1605
|
+
if (arity === null) return true;
|
|
1606
|
+
return arity >= 2;
|
|
1607
|
+
}
|
|
1608
|
+
function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
1609
|
+
if (seen.has(p)) return false;
|
|
1610
|
+
seen.add(p);
|
|
1611
|
+
const d = p._def;
|
|
1612
|
+
switch (d.tag) {
|
|
1613
|
+
case "field":
|
|
1614
|
+
return true;
|
|
1615
|
+
case "node":
|
|
1616
|
+
return false;
|
|
1617
|
+
case "lazy": {
|
|
1618
|
+
try {
|
|
1619
|
+
return parserHasOwnFields(d.thunk(), seen);
|
|
1620
|
+
} catch {
|
|
1621
|
+
return false;
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
case "sequence":
|
|
1625
|
+
case "choice":
|
|
1626
|
+
return d.parsers.some((x) => parserHasOwnFields(x, seen));
|
|
1627
|
+
case "sepBy":
|
|
1628
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.separator, seen);
|
|
1629
|
+
case "skip":
|
|
1630
|
+
return parserHasOwnFields(d.main, seen) || parserHasOwnFields(d.skipped, seen);
|
|
1631
|
+
case "grammar":
|
|
1632
|
+
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
1633
|
+
case "scanTo":
|
|
1634
|
+
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
|
|
1635
|
+
case "recover":
|
|
1636
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
1637
|
+
case "many":
|
|
1638
|
+
case "oneOrMore":
|
|
1639
|
+
case "optional":
|
|
1640
|
+
case "transform":
|
|
1641
|
+
case "trivia":
|
|
1642
|
+
case "token":
|
|
1643
|
+
case "label":
|
|
1644
|
+
case "expect":
|
|
1645
|
+
case "withCtx":
|
|
1646
|
+
case "not":
|
|
1647
|
+
return parserHasOwnFields(d.parser, seen);
|
|
1648
|
+
default:
|
|
1649
|
+
return false;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
function buildFieldMap(captures) {
|
|
1653
|
+
if (!captures?.length) return void 0;
|
|
1654
|
+
const out = {};
|
|
1655
|
+
for (const cap of captures) {
|
|
1656
|
+
const entry = { value: cap.value, span: cap.span };
|
|
1657
|
+
const current = out[cap.name];
|
|
1658
|
+
if (current === void 0) out[cap.name] = entry;
|
|
1659
|
+
else if (Array.isArray(current)) current.push(entry);
|
|
1660
|
+
else out[cap.name] = [current, entry];
|
|
1661
|
+
}
|
|
1662
|
+
return out;
|
|
1580
1663
|
}
|
|
1581
1664
|
|
|
1582
1665
|
// src/combinators/node.ts
|
|
1583
|
-
function
|
|
1666
|
+
function unwrapChild(child) {
|
|
1584
1667
|
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
1585
1668
|
}
|
|
1586
|
-
function
|
|
1669
|
+
function isCstChild(value) {
|
|
1670
|
+
return typeof value === "object" && value !== null && (value._tag === "node" || value._tag === "leaf" || value._tag === "error");
|
|
1671
|
+
}
|
|
1672
|
+
function missingInferredType() {
|
|
1673
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
1674
|
+
}
|
|
1675
|
+
function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
1676
|
+
const hasExplicitType = typeof typeOrCombinator === "string";
|
|
1677
|
+
const type = hasExplicitType ? typeOrCombinator : void 0;
|
|
1678
|
+
const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
|
|
1679
|
+
const build = hasExplicitType ? buildOrOpts : combinatorOrBuild;
|
|
1680
|
+
const opts = hasExplicitType ? maybeOpts : buildOrOpts;
|
|
1681
|
+
const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
|
|
1587
1682
|
const meta = {
|
|
1588
1683
|
firstSet: combinator._meta.firstSet,
|
|
1589
1684
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1590
1685
|
isTrivia: false
|
|
1591
1686
|
};
|
|
1687
|
+
const unwrap = opts?.unwrap === true;
|
|
1592
1688
|
const collapse = opts?.collapse === true;
|
|
1593
|
-
|
|
1689
|
+
if (unwrap && collapse) {
|
|
1690
|
+
throw new Error("node() options cannot set both unwrap and collapse");
|
|
1691
|
+
}
|
|
1692
|
+
const def = unwrap || collapse ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {} } : baseDef;
|
|
1594
1693
|
const capturesTrivia = build ? buildReadsTrivia(def) : true;
|
|
1595
1694
|
const clonesState = build ? buildReadsState(def) : true;
|
|
1695
|
+
const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
|
|
1596
1696
|
return {
|
|
1597
1697
|
_tag: "node",
|
|
1598
1698
|
_meta: meta,
|
|
1599
1699
|
_def: def,
|
|
1600
1700
|
parse(input, pos, ctx) {
|
|
1601
1701
|
const saved = beginCstNodeCapture(ctx);
|
|
1702
|
+
const savedFields = ctx._fields;
|
|
1703
|
+
ctx._fields = capturesFields ? [] : void 0;
|
|
1602
1704
|
if (!capturesTrivia) ctx.captureTrivia = false;
|
|
1603
1705
|
const r = combinator.parse(input, pos, ctx);
|
|
1706
|
+
const fields = capturesFields ? buildFieldMap(ctx._fields) : void 0;
|
|
1707
|
+
ctx._fields = savedFields;
|
|
1604
1708
|
const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
1605
1709
|
if (!r.ok) return r;
|
|
1606
1710
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
1607
|
-
const
|
|
1608
|
-
const
|
|
1609
|
-
const rawEntry =
|
|
1711
|
+
const nodeType = def.type ?? missingInferredType();
|
|
1712
|
+
const built = unwrap && children.length === 1 ? unwrapChild(children[0]) : collapse && children.length === 1 ? children[0] : !build && ctx.build?._parsemanCstCollapse && children.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children[0], children, rawChildren) ? children[0] : build ? build(children, fields, r.span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children, fields, r.span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: { start: r.span.start, end: r.span.end }, state: st ?? null, children };
|
|
1713
|
+
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
|
|
1610
1714
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
1611
1715
|
pushCstChild(ctx, built, rawEntry);
|
|
1612
1716
|
}
|
|
@@ -1667,6 +1771,19 @@ function label(name, combinator) {
|
|
|
1667
1771
|
}
|
|
1668
1772
|
};
|
|
1669
1773
|
}
|
|
1774
|
+
function field(name, combinator) {
|
|
1775
|
+
return {
|
|
1776
|
+
_tag: combinator._tag,
|
|
1777
|
+
_meta: combinator._meta,
|
|
1778
|
+
_def: { tag: "field", name, parser: combinator },
|
|
1779
|
+
parse(input, pos, ctx) {
|
|
1780
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1781
|
+
if (!result.ok) return result;
|
|
1782
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
1783
|
+
return result;
|
|
1784
|
+
}
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1670
1787
|
|
|
1671
1788
|
// src/compiler/line-index.ts
|
|
1672
1789
|
function buildLineIndex(input) {
|
|
@@ -3149,21 +3266,22 @@ function emitScannableTerminal(shape, c) {
|
|
|
3149
3266
|
}
|
|
3150
3267
|
|
|
3151
3268
|
// src/compiler/inline-build.ts
|
|
3152
|
-
var MK_BUILD_RE = /^\(\s*(
|
|
3269
|
+
var MK_BUILD_RE = /^\(\s*(\w+)\s*,\s*\w+\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)\s*=>\s*mk\s*\(\s*(['"])([^'"]+)\5\s*,\s*\1\s*,\s*\3\s*,\s*\2\s*,\s*\4\s*\)\s*$/;
|
|
3153
3270
|
function escapeRegExp(s) {
|
|
3154
3271
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3155
3272
|
}
|
|
3156
3273
|
function looseMkBuildRe(type) {
|
|
3157
3274
|
return new RegExp(
|
|
3158
|
-
String.raw`^\(\s*(
|
|
3275
|
+
String.raw`^\(\s*(\w+)\s*,\s*\w+\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)\s*=>\s*.+\(\s*(['"])${escapeRegExp(type)}\5\s*,\s*\1\s*,\s*\3\s*,\s*\2\s*,\s*\4\s*\)\s*$`
|
|
3159
3276
|
);
|
|
3160
3277
|
}
|
|
3161
3278
|
function analyzeMkInlineBuild(def) {
|
|
3162
3279
|
if (!def.build) return null;
|
|
3280
|
+
if (def.type === void 0) return null;
|
|
3163
3281
|
const src = (def.buildSrc ?? def.build.toString()).trim();
|
|
3164
3282
|
const strict = src.match(MK_BUILD_RE);
|
|
3165
3283
|
if (strict) {
|
|
3166
|
-
const mkType = strict[
|
|
3284
|
+
const mkType = strict[6];
|
|
3167
3285
|
return mkType === def.type ? def.type : null;
|
|
3168
3286
|
}
|
|
3169
3287
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
@@ -3490,8 +3608,9 @@ function planDisjointDispatch(parsers) {
|
|
|
3490
3608
|
}
|
|
3491
3609
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
3492
3610
|
}
|
|
3493
|
-
function captureRestoreBody(mL, mR, mTl, mLg) {
|
|
3494
|
-
const
|
|
3611
|
+
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
3612
|
+
const fieldRestore = mF ? `; if (_ctx._fields) _ctx._fields.length = ${mF}` : "";
|
|
3613
|
+
const base = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
|
|
3495
3614
|
return mLg ? `${base}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg}` : base;
|
|
3496
3615
|
}
|
|
3497
3616
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -3539,6 +3658,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3539
3658
|
// Delegating wrappers: defer to the wrapped parser.
|
|
3540
3659
|
case "transform":
|
|
3541
3660
|
case "label":
|
|
3661
|
+
case "field":
|
|
3542
3662
|
case "expect":
|
|
3543
3663
|
case "withCtx":
|
|
3544
3664
|
case "grammar":
|
|
@@ -3585,6 +3705,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3585
3705
|
case "optional":
|
|
3586
3706
|
case "transform":
|
|
3587
3707
|
case "label":
|
|
3708
|
+
case "field":
|
|
3588
3709
|
case "expect":
|
|
3589
3710
|
case "withCtx":
|
|
3590
3711
|
case "grammar":
|
|
@@ -3622,22 +3743,25 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
3622
3743
|
ctx.recordFail = savedRecord;
|
|
3623
3744
|
const ind0 = ind(ctx);
|
|
3624
3745
|
const needsRollback = ctx.capturing && mayLeavePartialCapture(inner);
|
|
3746
|
+
const needsFieldRollback = needsRollback && parserHasOwnFields(inner);
|
|
3625
3747
|
const mL = needsRollback ? v(ctx, "_fcl") : null;
|
|
3626
3748
|
const mR = needsRollback ? v(ctx, "_fcr") : null;
|
|
3627
3749
|
const mTl = needsRollback ? v(ctx, "_fctl") : null;
|
|
3750
|
+
const mF = needsFieldRollback ? v(ctx, "_fcf") : null;
|
|
3628
3751
|
const stmts = [
|
|
3629
3752
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
3630
3753
|
...mL ? [
|
|
3631
3754
|
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
3632
3755
|
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
3633
|
-
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0
|
|
3756
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
3757
|
+
...mF ? [`${ind0}const ${mF} = _ctx._fields?.length ?? 0`] : []
|
|
3634
3758
|
] : [],
|
|
3635
3759
|
`${ind0}${lbl}: {`,
|
|
3636
3760
|
...r.stmts,
|
|
3637
3761
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
3638
3762
|
`${ind0}}`,
|
|
3639
3763
|
...mL ? [
|
|
3640
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null)} }`
|
|
3764
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
3641
3765
|
] : []
|
|
3642
3766
|
];
|
|
3643
3767
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
@@ -3864,6 +3988,7 @@ function failsAtStart(p) {
|
|
|
3864
3988
|
return true;
|
|
3865
3989
|
case "transform":
|
|
3866
3990
|
case "label":
|
|
3991
|
+
case "field":
|
|
3867
3992
|
return failsAtStart(d.parser);
|
|
3868
3993
|
default:
|
|
3869
3994
|
return false;
|
|
@@ -3883,6 +4008,7 @@ function canMatchEmptyAtStart(p) {
|
|
|
3883
4008
|
return true;
|
|
3884
4009
|
case "transform":
|
|
3885
4010
|
case "label":
|
|
4011
|
+
case "field":
|
|
3886
4012
|
return canMatchEmptyAtStart(d.parser);
|
|
3887
4013
|
case "literal":
|
|
3888
4014
|
return d.value.length === 0;
|
|
@@ -4065,11 +4191,13 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4065
4191
|
const skipCond = gateCond ? `!${resOkV} && ${gateCond}` : `!${resOkV}`;
|
|
4066
4192
|
const armHasAutoNot = !!(autoNot && autoNot.length > 0);
|
|
4067
4193
|
const armNeedsRollback = ctx.capturing && (mayLeavePartialCapture(p) || armHasAutoNot && capturesLeaf(p));
|
|
4194
|
+
const armNeedsFieldRollback = armNeedsRollback && parserHasOwnFields(p);
|
|
4068
4195
|
const markLeaves = armNeedsRollback ? v(ctx, "_cml") : null;
|
|
4069
4196
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
4070
4197
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
4071
4198
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
4072
|
-
const
|
|
4199
|
+
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
4200
|
+
const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
4073
4201
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
4074
4202
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
4075
4203
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -4079,7 +4207,8 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4079
4207
|
`${ind(ctx)}const ${markLeaves} = _ctx._cstLeaves?.length ?? 0`,
|
|
4080
4208
|
`${ind(ctx)}const ${markRaw} = _ctx._cstRawChildren?.length ?? 0`,
|
|
4081
4209
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
4082
|
-
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0
|
|
4210
|
+
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`,
|
|
4211
|
+
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
4083
4212
|
);
|
|
4084
4213
|
}
|
|
4085
4214
|
const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos, atStart);
|
|
@@ -4472,6 +4601,9 @@ function emitToken(def, ctx, pos) {
|
|
|
4472
4601
|
};
|
|
4473
4602
|
}
|
|
4474
4603
|
function emitNode(def, ctx, pos) {
|
|
4604
|
+
if (def.type === void 0) {
|
|
4605
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
4606
|
+
}
|
|
4475
4607
|
const structural = def.build === void 0;
|
|
4476
4608
|
const mkType = structural ? null : analyzeMkInlineBuild(def);
|
|
4477
4609
|
let buildIdx = null;
|
|
@@ -4483,25 +4615,36 @@ function emitNode(def, ctx, pos) {
|
|
|
4483
4615
|
const i = ind(ctx);
|
|
4484
4616
|
const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
|
|
4485
4617
|
const clonesState = !structural && buildReadsState(def);
|
|
4618
|
+
const hasFields = parserHasOwnFields(def.parser);
|
|
4619
|
+
const capturesFields = hasFields && !structural && buildReadsFields(def);
|
|
4486
4620
|
const chV = v(ctx, "_ch");
|
|
4487
4621
|
const rawV = v(ctx, "_raw");
|
|
4488
4622
|
const capTLv = structural ? v(ctx, "_ctl") : null;
|
|
4489
4623
|
const capSTv = structural ? v(ctx, "_cst") : null;
|
|
4624
|
+
const capFv = structural && hasFields ? v(ctx, "_cf") : null;
|
|
4490
4625
|
const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
|
|
4491
4626
|
if (!capturesTrivia) ctx.needsEmptyTl = true;
|
|
4492
4627
|
const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
|
|
4493
4628
|
if (structural) ctx.needsHostReads = true;
|
|
4494
|
-
const
|
|
4629
|
+
const hostTriviaGate = `_ctx.build !== undefined && (_ctx.build._parsemanCaptureTrivia !== undefined ? _ctx.build._parsemanCaptureTrivia(${JSON.stringify(def.type)}) : (_ctx._pmCapTL ??= _hostReads(_ctx.build, 5)))`;
|
|
4630
|
+
const allocStmt = structural ? `${i}const ${capTLv} = ${hostTriviaGate}, ${capSTv} = _ctx._pmCapST ??= (_ctx.build === undefined || _hostReads(_ctx.build, 6))${capFv ? `, ${capFv} = _ctx.build !== undefined && _hostReads(_ctx.build, 2)` : ""}
|
|
4495
4631
|
${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
|
|
4496
4632
|
const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
|
|
4633
|
+
const fieldsOn = structural ? capFv ?? "false" : capturesFields ? "true" : "false";
|
|
4634
|
+
const sf = hasFields ? v(ctx, "_sf") : null;
|
|
4635
|
+
const fArr = hasFields ? v(ctx, "_fa") : null;
|
|
4636
|
+
const fObj = hasFields ? v(ctx, "_fields") : "undefined";
|
|
4497
4637
|
const stmts = [
|
|
4498
4638
|
allocStmt,
|
|
4499
|
-
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
|
|
4500
|
-
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
|
|
4639
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${sf ? `, ${sf} = _ctx._fields` : ""}`,
|
|
4640
|
+
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
|
|
4501
4641
|
];
|
|
4502
4642
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
4503
4643
|
stmts.push(...innerStmts);
|
|
4504
|
-
|
|
4644
|
+
if (sf && fArr) {
|
|
4645
|
+
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
4646
|
+
}
|
|
4647
|
+
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${sf ? `; _ctx._fields = ${sf}` : ""}`);
|
|
4505
4648
|
stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
|
|
4506
4649
|
let stV = "undefined";
|
|
4507
4650
|
if (structural) {
|
|
@@ -4511,14 +4654,33 @@ ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capt
|
|
|
4511
4654
|
stV = v(ctx, "_nst");
|
|
4512
4655
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
4513
4656
|
}
|
|
4657
|
+
if (sf && fArr) {
|
|
4658
|
+
const fe = v(ctx, "_fe");
|
|
4659
|
+
const cur = v(ctx, "_fc");
|
|
4660
|
+
stmts.push(
|
|
4661
|
+
`${i}let ${fObj} = undefined`,
|
|
4662
|
+
`${i}if (${fArr} && ${fArr}.length) {`,
|
|
4663
|
+
`${i} ${fObj} = {}`,
|
|
4664
|
+
`${i} for (const ${fe} of ${fArr}) {`,
|
|
4665
|
+
`${i} const ${cur} = ${fObj}[${fe}.name], _entry = { value: ${fe}.value, span: ${fe}.span }`,
|
|
4666
|
+
`${i} if (${cur} === undefined) ${fObj}[${fe}.name] = _entry`,
|
|
4667
|
+
`${i} else if (Array.isArray(${cur})) ${cur}.push(_entry)`,
|
|
4668
|
+
`${i} else ${fObj}[${fe}.name] = [${cur}, _entry]`,
|
|
4669
|
+
`${i} }`,
|
|
4670
|
+
`${i}}`
|
|
4671
|
+
);
|
|
4672
|
+
}
|
|
4514
4673
|
const ndV = v(ctx, "_nd");
|
|
4515
|
-
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: { start: ${pos}, end: ${endVar} }, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${
|
|
4516
|
-
const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${
|
|
4517
|
-
const
|
|
4674
|
+
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: { start: ${pos}, end: ${endVar} }, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV})`;
|
|
4675
|
+
const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${fObj}, { start: ${pos}, end: ${endVar} }, ${rawV}, ${tlV}, ${stV}) : (${buildExpr})` : buildExpr;
|
|
4676
|
+
const hostCollapseExpr = ctx.ns || structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
4677
|
+
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
4678
|
+
const collapseExpr = `${chV}.length === 1 ? ${chV}[0] : (${ndExpr})`;
|
|
4679
|
+
const finalExpr = def.unwrap ? unwrapExpr : def.collapse ? collapseExpr : hostCollapseExpr;
|
|
4518
4680
|
stmts.push(
|
|
4519
4681
|
`${i}const ${ndV} = ${finalExpr}`,
|
|
4520
4682
|
`${i}if (${sc}) ${sc}.push(${ndV})`,
|
|
4521
|
-
`${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && ${ndV}._tag === 'node') ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
|
|
4683
|
+
`${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && (${ndV}._tag === 'node' || ${ndV}._tag === 'leaf' || ${ndV}._tag === 'error')) ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
|
|
4522
4684
|
);
|
|
4523
4685
|
return { stmts, valueVar: ndV, endVar };
|
|
4524
4686
|
}
|
|
@@ -4733,6 +4895,17 @@ function emitDispatch(p, ctx, pos) {
|
|
|
4733
4895
|
endVar: inner.endVar
|
|
4734
4896
|
};
|
|
4735
4897
|
}
|
|
4898
|
+
case "field": {
|
|
4899
|
+
const inner = emit(def.parser, ctx, pos);
|
|
4900
|
+
return {
|
|
4901
|
+
stmts: [
|
|
4902
|
+
...inner.stmts,
|
|
4903
|
+
`${ind(ctx)}if (_ctx._fields) _ctx._fields.push({ name: ${JSON.stringify(def.name)}, value: ${inner.valueVar}, span: { start: ${pos}, end: ${inner.endVar} } })`
|
|
4904
|
+
],
|
|
4905
|
+
valueVar: inner.valueVar,
|
|
4906
|
+
endVar: inner.endVar
|
|
4907
|
+
};
|
|
4908
|
+
}
|
|
4736
4909
|
case "grammar": {
|
|
4737
4910
|
const savedTrivia = ctx.activeTrivia;
|
|
4738
4911
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
@@ -4834,6 +5007,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4834
5007
|
case "trivia":
|
|
4835
5008
|
case "token":
|
|
4836
5009
|
case "label":
|
|
5010
|
+
case "field":
|
|
4837
5011
|
case "optional":
|
|
4838
5012
|
case "many":
|
|
4839
5013
|
case "oneOrMore":
|
|
@@ -4870,6 +5044,7 @@ function childrenOf(def) {
|
|
|
4870
5044
|
case "trivia":
|
|
4871
5045
|
case "token":
|
|
4872
5046
|
case "label":
|
|
5047
|
+
case "field":
|
|
4873
5048
|
case "grammar":
|
|
4874
5049
|
case "not":
|
|
4875
5050
|
case "node":
|
|
@@ -5111,6 +5286,11 @@ function assertRuleName(name) {
|
|
|
5111
5286
|
);
|
|
5112
5287
|
}
|
|
5113
5288
|
}
|
|
5289
|
+
function publicRuleWrapperSource(rule, fnSource) {
|
|
5290
|
+
const labels = rule._meta.triviaKindLabels;
|
|
5291
|
+
if (labels === void 0) return fnSource;
|
|
5292
|
+
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5293
|
+
}
|
|
5114
5294
|
function compileLinkable(ruleMapArg, ns) {
|
|
5115
5295
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5116
5296
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
@@ -5213,7 +5393,7 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5213
5393
|
ctx.recordFail = savedRec;
|
|
5214
5394
|
pushNamedFnDecl(ctx, fn, body.stmts, body.valueVar, body.endVar);
|
|
5215
5395
|
}
|
|
5216
|
-
perEntry.push({ key, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5396
|
+
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5217
5397
|
}
|
|
5218
5398
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
5219
5399
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
@@ -5236,14 +5416,14 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5236
5416
|
...privateFns
|
|
5237
5417
|
].filter(Boolean);
|
|
5238
5418
|
const wrappers = /* @__PURE__ */ new Map();
|
|
5239
|
-
for (const { key, r } of perEntry) {
|
|
5240
|
-
wrappers.set(key, [
|
|
5419
|
+
for (const { key, rule, r } of perEntry) {
|
|
5420
|
+
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
5241
5421
|
`function(input, _pos, _ctx) {`,
|
|
5242
5422
|
` let pos = _pos`,
|
|
5243
5423
|
...r.stmts,
|
|
5244
5424
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
5245
5425
|
`}`
|
|
5246
|
-
].join("\n"));
|
|
5426
|
+
].join("\n")));
|
|
5247
5427
|
}
|
|
5248
5428
|
const firstSets = /* @__PURE__ */ new Map();
|
|
5249
5429
|
for (const [key, rule] of ruleMap) {
|
|
@@ -5446,6 +5626,7 @@ function evalRuleMapIR(ir) {
|
|
|
5446
5626
|
"skip",
|
|
5447
5627
|
"trivia",
|
|
5448
5628
|
"label",
|
|
5629
|
+
"field",
|
|
5449
5630
|
"expect",
|
|
5450
5631
|
"_tf",
|
|
5451
5632
|
"_nd",
|
|
@@ -5472,6 +5653,7 @@ function evalRuleMapIR(ir) {
|
|
|
5472
5653
|
skip,
|
|
5473
5654
|
trivia,
|
|
5474
5655
|
label,
|
|
5656
|
+
field,
|
|
5475
5657
|
expect,
|
|
5476
5658
|
_tf,
|
|
5477
5659
|
_nd
|
|
@@ -5486,9 +5668,26 @@ function linkable(rulesMap, ns) {
|
|
|
5486
5668
|
if (!pieces) throw new Error("linkable(): this grammar cannot be compiled to a linkable artifact (contains a runtime-only parser fallback)");
|
|
5487
5669
|
return pieces;
|
|
5488
5670
|
}
|
|
5489
|
-
function
|
|
5671
|
+
function normalizeCstCollapse(collapse) {
|
|
5672
|
+
if (collapse === true) return () => true;
|
|
5673
|
+
if (Array.isArray(collapse)) {
|
|
5674
|
+
const types = new Set(collapse);
|
|
5675
|
+
return (type) => types.has(type);
|
|
5676
|
+
}
|
|
5677
|
+
return typeof collapse === "function" ? collapse : void 0;
|
|
5678
|
+
}
|
|
5679
|
+
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state) {
|
|
5490
5680
|
return { _tag: "node", type, span: { start: span.start, end: span.end }, state: state ?? null, children: [...children] };
|
|
5491
5681
|
}
|
|
5682
|
+
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state) {
|
|
5683
|
+
if (typeof typeOrOptions === "string") {
|
|
5684
|
+
return buildCstNode(typeOrOptions, children ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
5685
|
+
}
|
|
5686
|
+
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
5687
|
+
const host = (type, children2, fields, span2, rawChildren2, triviaLog2, state2) => buildCstNode(type, children2, fields, span2, rawChildren2, triviaLog2, state2);
|
|
5688
|
+
if (collapse) host._parsemanCstCollapse = collapse;
|
|
5689
|
+
return host;
|
|
5690
|
+
}
|
|
5492
5691
|
function pick(grammar, names) {
|
|
5493
5692
|
const p = grammar.ruleFns instanceof Map ? grammar : linkable(grammar);
|
|
5494
5693
|
const keep = /* @__PURE__ */ new Set();
|
|
@@ -5520,8 +5719,9 @@ function fusedBody(pieces) {
|
|
|
5520
5719
|
}
|
|
5521
5720
|
}
|
|
5522
5721
|
const contributing = new Set(winner.values());
|
|
5523
|
-
const
|
|
5524
|
-
const
|
|
5722
|
+
const contributingPieces = [...contributing];
|
|
5723
|
+
const needsEmptyTl = contributingPieces.some((p) => p.needsEmptyTl);
|
|
5724
|
+
const needsHostReads = contributingPieces.some((p) => p.needsHostReads);
|
|
5525
5725
|
const lines = [
|
|
5526
5726
|
// Shared sentinel protocol (must match NAMED_FN_FAIL / NAMED_FN_END in codegen).
|
|
5527
5727
|
"const _pfFail = {}",
|
|
@@ -5529,7 +5729,7 @@ function fusedBody(pieces) {
|
|
|
5529
5729
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5530
5730
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5531
5731
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5532
|
-
...[...
|
|
5732
|
+
...[...new Set(contributingPieces.flatMap((p) => p.prelude))],
|
|
5533
5733
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5534
5734
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5535
5735
|
];
|
|
@@ -5552,7 +5752,7 @@ function fusedBody(pieces) {
|
|
|
5552
5752
|
}
|
|
5553
5753
|
);
|
|
5554
5754
|
const env = {};
|
|
5555
|
-
for (const p of
|
|
5755
|
+
for (const p of contributingPieces) {
|
|
5556
5756
|
if (p.mfFns.length) env[`${p.ns}mf`] = p.mfFns;
|
|
5557
5757
|
if (p.buildFns.length) env[`${p.ns}build`] = p.buildFns;
|
|
5558
5758
|
}
|
|
@@ -5572,14 +5772,23 @@ function materializePiece(p) {
|
|
|
5572
5772
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
5573
5773
|
return pieces;
|
|
5574
5774
|
}
|
|
5575
|
-
function
|
|
5775
|
+
function nextComposeNs(used) {
|
|
5776
|
+
let ns;
|
|
5777
|
+
do {
|
|
5778
|
+
ns = `_lk${_nsCounter++}_`;
|
|
5779
|
+
} while (used.has(ns));
|
|
5780
|
+
used.add(ns);
|
|
5781
|
+
return ns;
|
|
5782
|
+
}
|
|
5783
|
+
function itemPieces(item, used) {
|
|
5576
5784
|
const carried = item[COMPOSED_PIECES];
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
return
|
|
5785
|
+
const pieces = Array.isArray(carried) ? carried.map(materializePiece) : item.ruleFns instanceof Map ? [item] : [linkable(item, nextComposeNs(used))];
|
|
5786
|
+
for (const p of pieces) used.add(p.ns);
|
|
5787
|
+
return pieces;
|
|
5580
5788
|
}
|
|
5581
5789
|
function compose(items) {
|
|
5582
|
-
const
|
|
5790
|
+
const used = /* @__PURE__ */ new Set();
|
|
5791
|
+
const pieces = items.flatMap((item) => itemPieces(item, used));
|
|
5583
5792
|
const map = fuseRules(pieces);
|
|
5584
5793
|
Object.defineProperty(map, COMPOSED_PIECES, { value: pieces, enumerable: false });
|
|
5585
5794
|
return map;
|
|
@@ -6305,6 +6514,7 @@ export {
|
|
|
6305
6514
|
createVisitor,
|
|
6306
6515
|
cstBuildHost,
|
|
6307
6516
|
expect,
|
|
6517
|
+
field,
|
|
6308
6518
|
gapIsSignificant,
|
|
6309
6519
|
gapText,
|
|
6310
6520
|
guard,
|