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/plugin/index.cjs
CHANGED
|
@@ -217,6 +217,13 @@ function ref() {
|
|
|
217
217
|
define(p) {
|
|
218
218
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
219
219
|
resolved = p;
|
|
220
|
+
meta.firstSet = p._meta.firstSet;
|
|
221
|
+
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
222
|
+
meta.isTrivia = p._meta.isTrivia;
|
|
223
|
+
if (p._meta.triviaKindLabels !== void 0) meta.triviaKindLabels = p._meta.triviaKindLabels;
|
|
224
|
+
else delete meta.triviaKindLabels;
|
|
225
|
+
if (p._meta.disjoint !== void 0) meta.disjoint = p._meta.disjoint;
|
|
226
|
+
else delete meta.disjoint;
|
|
220
227
|
}
|
|
221
228
|
};
|
|
222
229
|
return slot;
|
|
@@ -324,7 +331,8 @@ function saveCstMark(ctx) {
|
|
|
324
331
|
return {
|
|
325
332
|
raw: cstRawLen(ctx),
|
|
326
333
|
tlog: cstTlLen(ctx),
|
|
327
|
-
leaves: cstLeavesLen(ctx)
|
|
334
|
+
leaves: cstLeavesLen(ctx),
|
|
335
|
+
fields: ctx._fields?.length ?? 0
|
|
328
336
|
};
|
|
329
337
|
}
|
|
330
338
|
function rollbackBufList(b, keyMulti, keySingle, len) {
|
|
@@ -348,11 +356,13 @@ function rollbackCstCapture(ctx, mark) {
|
|
|
348
356
|
if (mark.tlog === 0) b.tl = void 0;
|
|
349
357
|
else b.tl.length = mark.tlog;
|
|
350
358
|
}
|
|
359
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
351
360
|
return;
|
|
352
361
|
}
|
|
353
362
|
if (ctx._cstRawChildren) ctx._cstRawChildren.length = mark.raw;
|
|
354
363
|
if (ctx._cstTriviaLog) ctx._cstTriviaLog.length = mark.tlog;
|
|
355
364
|
if (ctx._cstLeaves) ctx._cstLeaves.length = mark.leaves;
|
|
365
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
356
366
|
}
|
|
357
367
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
358
368
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -1089,10 +1099,10 @@ function needsDeferredTriviaCommit(ctx) {
|
|
|
1089
1099
|
}
|
|
1090
1100
|
function saveTriviaMark(ctx) {
|
|
1091
1101
|
const m = saveCstMark(ctx);
|
|
1092
|
-
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1102
|
+
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1093
1103
|
}
|
|
1094
1104
|
function rollbackTrivia(ctx, mark) {
|
|
1095
|
-
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves });
|
|
1105
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields });
|
|
1096
1106
|
if (ctx._triviaLog) ctx._triviaLog.length = mark.log;
|
|
1097
1107
|
}
|
|
1098
1108
|
function scanWithLabels(input, cur, ctx) {
|
|
@@ -1476,6 +1486,9 @@ function markUnusedValues(root) {
|
|
|
1476
1486
|
case "transform":
|
|
1477
1487
|
visit(def.parser, true);
|
|
1478
1488
|
return;
|
|
1489
|
+
case "field":
|
|
1490
|
+
visit(def.parser, true);
|
|
1491
|
+
return;
|
|
1479
1492
|
case "skip":
|
|
1480
1493
|
visit(def.main, consumed);
|
|
1481
1494
|
visit(def.skipped, false);
|
|
@@ -1527,6 +1540,11 @@ function markUnusedValues(root) {
|
|
|
1527
1540
|
}
|
|
1528
1541
|
|
|
1529
1542
|
// src/combinators/parser.ts
|
|
1543
|
+
function tagRule(r, key) {
|
|
1544
|
+
;
|
|
1545
|
+
r._ruleName = key;
|
|
1546
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1547
|
+
}
|
|
1530
1548
|
function rules(factory) {
|
|
1531
1549
|
const cache = {};
|
|
1532
1550
|
const proxy = new Proxy(cache, {
|
|
@@ -1535,7 +1553,7 @@ function rules(factory) {
|
|
|
1535
1553
|
const record = target;
|
|
1536
1554
|
if (!(key in record)) {
|
|
1537
1555
|
const r = ref();
|
|
1538
|
-
r
|
|
1556
|
+
tagRule(r, key);
|
|
1539
1557
|
record[key] = r;
|
|
1540
1558
|
}
|
|
1541
1559
|
return record[key];
|
|
@@ -1546,12 +1564,12 @@ function rules(factory) {
|
|
|
1546
1564
|
const placeholder = cache[key];
|
|
1547
1565
|
const parser2 = definitions[key];
|
|
1548
1566
|
if (placeholder !== void 0 && typeof placeholder.define === "function") {
|
|
1549
|
-
;
|
|
1567
|
+
tagRule(parser2, key);
|
|
1550
1568
|
placeholder.define(parser2);
|
|
1551
1569
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1552
1570
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1553
1571
|
} else {
|
|
1554
|
-
;
|
|
1572
|
+
tagRule(parser2, key);
|
|
1555
1573
|
cache[key] = parser2;
|
|
1556
1574
|
}
|
|
1557
1575
|
}
|
|
@@ -1608,44 +1626,130 @@ function buildReadsTrivia(def) {
|
|
|
1608
1626
|
const src = def.buildSrc ?? def.build.toString();
|
|
1609
1627
|
const arity = confirmedBuildArity(src);
|
|
1610
1628
|
if (arity === null) return true;
|
|
1611
|
-
return arity >=
|
|
1629
|
+
return arity >= 5;
|
|
1612
1630
|
}
|
|
1613
1631
|
function buildReadsState(def) {
|
|
1614
1632
|
if (!def.build) return true;
|
|
1615
1633
|
const src = def.buildSrc ?? def.build.toString();
|
|
1616
1634
|
const arity = confirmedBuildArity(src);
|
|
1617
1635
|
if (arity === null) return true;
|
|
1618
|
-
return arity >=
|
|
1636
|
+
return arity >= 6;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
// src/compiler/fields.ts
|
|
1640
|
+
function buildReadsFields(def) {
|
|
1641
|
+
if (!def.build) return true;
|
|
1642
|
+
const src = def.buildSrc ?? def.build.toString();
|
|
1643
|
+
const arity = confirmedBuildArity(src);
|
|
1644
|
+
if (arity === null) return true;
|
|
1645
|
+
return arity >= 2;
|
|
1646
|
+
}
|
|
1647
|
+
function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
1648
|
+
if (seen.has(p)) return false;
|
|
1649
|
+
seen.add(p);
|
|
1650
|
+
const d = p._def;
|
|
1651
|
+
switch (d.tag) {
|
|
1652
|
+
case "field":
|
|
1653
|
+
return true;
|
|
1654
|
+
case "node":
|
|
1655
|
+
return false;
|
|
1656
|
+
case "lazy": {
|
|
1657
|
+
try {
|
|
1658
|
+
return parserHasOwnFields(d.thunk(), seen);
|
|
1659
|
+
} catch {
|
|
1660
|
+
return false;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
case "sequence":
|
|
1664
|
+
case "choice":
|
|
1665
|
+
return d.parsers.some((x) => parserHasOwnFields(x, seen));
|
|
1666
|
+
case "sepBy":
|
|
1667
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.separator, seen);
|
|
1668
|
+
case "skip":
|
|
1669
|
+
return parserHasOwnFields(d.main, seen) || parserHasOwnFields(d.skipped, seen);
|
|
1670
|
+
case "grammar":
|
|
1671
|
+
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
1672
|
+
case "scanTo":
|
|
1673
|
+
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
|
|
1674
|
+
case "recover":
|
|
1675
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
1676
|
+
case "many":
|
|
1677
|
+
case "oneOrMore":
|
|
1678
|
+
case "optional":
|
|
1679
|
+
case "transform":
|
|
1680
|
+
case "trivia":
|
|
1681
|
+
case "token":
|
|
1682
|
+
case "label":
|
|
1683
|
+
case "expect":
|
|
1684
|
+
case "withCtx":
|
|
1685
|
+
case "not":
|
|
1686
|
+
return parserHasOwnFields(d.parser, seen);
|
|
1687
|
+
default:
|
|
1688
|
+
return false;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
function buildFieldMap(captures) {
|
|
1692
|
+
if (!captures?.length) return void 0;
|
|
1693
|
+
const out = {};
|
|
1694
|
+
for (const cap of captures) {
|
|
1695
|
+
const entry = { value: cap.value, span: cap.span };
|
|
1696
|
+
const current = out[cap.name];
|
|
1697
|
+
if (current === void 0) out[cap.name] = entry;
|
|
1698
|
+
else if (Array.isArray(current)) current.push(entry);
|
|
1699
|
+
else out[cap.name] = [current, entry];
|
|
1700
|
+
}
|
|
1701
|
+
return out;
|
|
1619
1702
|
}
|
|
1620
1703
|
|
|
1621
1704
|
// src/combinators/node.ts
|
|
1622
|
-
function
|
|
1705
|
+
function unwrapChild(child) {
|
|
1623
1706
|
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
1624
1707
|
}
|
|
1625
|
-
function
|
|
1708
|
+
function isCstChild(value) {
|
|
1709
|
+
return typeof value === "object" && value !== null && (value._tag === "node" || value._tag === "leaf" || value._tag === "error");
|
|
1710
|
+
}
|
|
1711
|
+
function missingInferredType() {
|
|
1712
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
1713
|
+
}
|
|
1714
|
+
function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
1715
|
+
const hasExplicitType = typeof typeOrCombinator === "string";
|
|
1716
|
+
const type = hasExplicitType ? typeOrCombinator : void 0;
|
|
1717
|
+
const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
|
|
1718
|
+
const build = hasExplicitType ? buildOrOpts : combinatorOrBuild;
|
|
1719
|
+
const opts = hasExplicitType ? maybeOpts : buildOrOpts;
|
|
1720
|
+
const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
|
|
1626
1721
|
const meta = {
|
|
1627
1722
|
firstSet: combinator._meta.firstSet,
|
|
1628
1723
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1629
1724
|
isTrivia: false
|
|
1630
1725
|
};
|
|
1726
|
+
const unwrap = opts?.unwrap === true;
|
|
1631
1727
|
const collapse = opts?.collapse === true;
|
|
1632
|
-
|
|
1728
|
+
if (unwrap && collapse) {
|
|
1729
|
+
throw new Error("node() options cannot set both unwrap and collapse");
|
|
1730
|
+
}
|
|
1731
|
+
const def = unwrap || collapse ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {} } : baseDef;
|
|
1633
1732
|
const capturesTrivia = build ? buildReadsTrivia(def) : true;
|
|
1634
1733
|
const clonesState = build ? buildReadsState(def) : true;
|
|
1734
|
+
const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
|
|
1635
1735
|
return {
|
|
1636
1736
|
_tag: "node",
|
|
1637
1737
|
_meta: meta,
|
|
1638
1738
|
_def: def,
|
|
1639
1739
|
parse(input, pos, ctx) {
|
|
1640
1740
|
const saved = beginCstNodeCapture(ctx);
|
|
1741
|
+
const savedFields = ctx._fields;
|
|
1742
|
+
ctx._fields = capturesFields ? [] : void 0;
|
|
1641
1743
|
if (!capturesTrivia) ctx.captureTrivia = false;
|
|
1642
1744
|
const r = combinator.parse(input, pos, ctx);
|
|
1745
|
+
const fields = capturesFields ? buildFieldMap(ctx._fields) : void 0;
|
|
1746
|
+
ctx._fields = savedFields;
|
|
1643
1747
|
const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
1644
1748
|
if (!r.ok) return r;
|
|
1645
1749
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
1646
|
-
const
|
|
1647
|
-
const
|
|
1648
|
-
const rawEntry =
|
|
1750
|
+
const nodeType = def.type ?? missingInferredType();
|
|
1751
|
+
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 };
|
|
1752
|
+
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
|
|
1649
1753
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
1650
1754
|
pushCstChild(ctx, built, rawEntry);
|
|
1651
1755
|
}
|
|
@@ -1706,6 +1810,19 @@ function label(name, combinator) {
|
|
|
1706
1810
|
}
|
|
1707
1811
|
};
|
|
1708
1812
|
}
|
|
1813
|
+
function field(name, combinator) {
|
|
1814
|
+
return {
|
|
1815
|
+
_tag: combinator._tag,
|
|
1816
|
+
_meta: combinator._meta,
|
|
1817
|
+
_def: { tag: "field", name, parser: combinator },
|
|
1818
|
+
parse(input, pos, ctx) {
|
|
1819
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1820
|
+
if (!result.ok) return result;
|
|
1821
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
1822
|
+
return result;
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1709
1826
|
|
|
1710
1827
|
// src/compiler/line-index.ts
|
|
1711
1828
|
function buildLineIndex(input) {
|
|
@@ -3165,21 +3282,22 @@ function emitScannableTerminal(shape, c) {
|
|
|
3165
3282
|
}
|
|
3166
3283
|
|
|
3167
3284
|
// src/compiler/inline-build.ts
|
|
3168
|
-
var MK_BUILD_RE = /^\(\s*(
|
|
3285
|
+
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*$/;
|
|
3169
3286
|
function escapeRegExp(s) {
|
|
3170
3287
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3171
3288
|
}
|
|
3172
3289
|
function looseMkBuildRe(type) {
|
|
3173
3290
|
return new RegExp(
|
|
3174
|
-
String.raw`^\(\s*(
|
|
3291
|
+
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*$`
|
|
3175
3292
|
);
|
|
3176
3293
|
}
|
|
3177
3294
|
function analyzeMkInlineBuild(def) {
|
|
3178
3295
|
if (!def.build) return null;
|
|
3296
|
+
if (def.type === void 0) return null;
|
|
3179
3297
|
const src = (def.buildSrc ?? def.build.toString()).trim();
|
|
3180
3298
|
const strict = src.match(MK_BUILD_RE);
|
|
3181
3299
|
if (strict) {
|
|
3182
|
-
const mkType = strict[
|
|
3300
|
+
const mkType = strict[6];
|
|
3183
3301
|
return mkType === def.type ? def.type : null;
|
|
3184
3302
|
}
|
|
3185
3303
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
@@ -3514,8 +3632,9 @@ function planDisjointDispatch(parsers) {
|
|
|
3514
3632
|
}
|
|
3515
3633
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
3516
3634
|
}
|
|
3517
|
-
function captureRestoreBody(mL, mR, mTl, mLg) {
|
|
3518
|
-
const
|
|
3635
|
+
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
3636
|
+
const fieldRestore = mF ? `; if (_ctx._fields) _ctx._fields.length = ${mF}` : "";
|
|
3637
|
+
const base = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
|
|
3519
3638
|
return mLg ? `${base}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg}` : base;
|
|
3520
3639
|
}
|
|
3521
3640
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -3563,6 +3682,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3563
3682
|
// Delegating wrappers: defer to the wrapped parser.
|
|
3564
3683
|
case "transform":
|
|
3565
3684
|
case "label":
|
|
3685
|
+
case "field":
|
|
3566
3686
|
case "expect":
|
|
3567
3687
|
case "withCtx":
|
|
3568
3688
|
case "grammar":
|
|
@@ -3609,6 +3729,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3609
3729
|
case "optional":
|
|
3610
3730
|
case "transform":
|
|
3611
3731
|
case "label":
|
|
3732
|
+
case "field":
|
|
3612
3733
|
case "expect":
|
|
3613
3734
|
case "withCtx":
|
|
3614
3735
|
case "grammar":
|
|
@@ -3646,22 +3767,25 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
3646
3767
|
ctx.recordFail = savedRecord;
|
|
3647
3768
|
const ind0 = ind(ctx);
|
|
3648
3769
|
const needsRollback = ctx.capturing && mayLeavePartialCapture(inner);
|
|
3770
|
+
const needsFieldRollback = needsRollback && parserHasOwnFields(inner);
|
|
3649
3771
|
const mL = needsRollback ? v(ctx, "_fcl") : null;
|
|
3650
3772
|
const mR = needsRollback ? v(ctx, "_fcr") : null;
|
|
3651
3773
|
const mTl = needsRollback ? v(ctx, "_fctl") : null;
|
|
3774
|
+
const mF = needsFieldRollback ? v(ctx, "_fcf") : null;
|
|
3652
3775
|
const stmts = [
|
|
3653
3776
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
3654
3777
|
...mL ? [
|
|
3655
3778
|
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
3656
3779
|
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
3657
|
-
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0
|
|
3780
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
3781
|
+
...mF ? [`${ind0}const ${mF} = _ctx._fields?.length ?? 0`] : []
|
|
3658
3782
|
] : [],
|
|
3659
3783
|
`${ind0}${lbl}: {`,
|
|
3660
3784
|
...r.stmts,
|
|
3661
3785
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
3662
3786
|
`${ind0}}`,
|
|
3663
3787
|
...mL ? [
|
|
3664
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null)} }`
|
|
3788
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
3665
3789
|
] : []
|
|
3666
3790
|
];
|
|
3667
3791
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
@@ -3888,6 +4012,7 @@ function failsAtStart(p) {
|
|
|
3888
4012
|
return true;
|
|
3889
4013
|
case "transform":
|
|
3890
4014
|
case "label":
|
|
4015
|
+
case "field":
|
|
3891
4016
|
return failsAtStart(d.parser);
|
|
3892
4017
|
default:
|
|
3893
4018
|
return false;
|
|
@@ -3907,6 +4032,7 @@ function canMatchEmptyAtStart(p) {
|
|
|
3907
4032
|
return true;
|
|
3908
4033
|
case "transform":
|
|
3909
4034
|
case "label":
|
|
4035
|
+
case "field":
|
|
3910
4036
|
return canMatchEmptyAtStart(d.parser);
|
|
3911
4037
|
case "literal":
|
|
3912
4038
|
return d.value.length === 0;
|
|
@@ -4089,11 +4215,13 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4089
4215
|
const skipCond = gateCond ? `!${resOkV} && ${gateCond}` : `!${resOkV}`;
|
|
4090
4216
|
const armHasAutoNot = !!(autoNot && autoNot.length > 0);
|
|
4091
4217
|
const armNeedsRollback = ctx.capturing && (mayLeavePartialCapture(p) || armHasAutoNot && capturesLeaf(p));
|
|
4218
|
+
const armNeedsFieldRollback = armNeedsRollback && parserHasOwnFields(p);
|
|
4092
4219
|
const markLeaves = armNeedsRollback ? v(ctx, "_cml") : null;
|
|
4093
4220
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
4094
4221
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
4095
4222
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
4096
|
-
const
|
|
4223
|
+
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
4224
|
+
const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
4097
4225
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
4098
4226
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
4099
4227
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -4103,7 +4231,8 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4103
4231
|
`${ind(ctx)}const ${markLeaves} = _ctx._cstLeaves?.length ?? 0`,
|
|
4104
4232
|
`${ind(ctx)}const ${markRaw} = _ctx._cstRawChildren?.length ?? 0`,
|
|
4105
4233
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
4106
|
-
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0
|
|
4234
|
+
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`,
|
|
4235
|
+
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
4107
4236
|
);
|
|
4108
4237
|
}
|
|
4109
4238
|
const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos, atStart);
|
|
@@ -4496,6 +4625,9 @@ function emitToken(def, ctx, pos) {
|
|
|
4496
4625
|
};
|
|
4497
4626
|
}
|
|
4498
4627
|
function emitNode(def, ctx, pos) {
|
|
4628
|
+
if (def.type === void 0) {
|
|
4629
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
4630
|
+
}
|
|
4499
4631
|
const structural = def.build === void 0;
|
|
4500
4632
|
const mkType = structural ? null : analyzeMkInlineBuild(def);
|
|
4501
4633
|
let buildIdx = null;
|
|
@@ -4507,25 +4639,36 @@ function emitNode(def, ctx, pos) {
|
|
|
4507
4639
|
const i = ind(ctx);
|
|
4508
4640
|
const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
|
|
4509
4641
|
const clonesState = !structural && buildReadsState(def);
|
|
4642
|
+
const hasFields = parserHasOwnFields(def.parser);
|
|
4643
|
+
const capturesFields = hasFields && !structural && buildReadsFields(def);
|
|
4510
4644
|
const chV = v(ctx, "_ch");
|
|
4511
4645
|
const rawV = v(ctx, "_raw");
|
|
4512
4646
|
const capTLv = structural ? v(ctx, "_ctl") : null;
|
|
4513
4647
|
const capSTv = structural ? v(ctx, "_cst") : null;
|
|
4648
|
+
const capFv = structural && hasFields ? v(ctx, "_cf") : null;
|
|
4514
4649
|
const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
|
|
4515
4650
|
if (!capturesTrivia) ctx.needsEmptyTl = true;
|
|
4516
4651
|
const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
|
|
4517
4652
|
if (structural) ctx.needsHostReads = true;
|
|
4518
|
-
const
|
|
4653
|
+
const hostTriviaGate = `_ctx.build !== undefined && (_ctx.build._parsemanCaptureTrivia !== undefined ? _ctx.build._parsemanCaptureTrivia(${JSON.stringify(def.type)}) : (_ctx._pmCapTL ??= _hostReads(_ctx.build, 5)))`;
|
|
4654
|
+
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)` : ""}
|
|
4519
4655
|
${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
|
|
4520
4656
|
const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
|
|
4657
|
+
const fieldsOn = structural ? capFv ?? "false" : capturesFields ? "true" : "false";
|
|
4658
|
+
const sf = hasFields ? v(ctx, "_sf") : null;
|
|
4659
|
+
const fArr = hasFields ? v(ctx, "_fa") : null;
|
|
4660
|
+
const fObj = hasFields ? v(ctx, "_fields") : "undefined";
|
|
4521
4661
|
const stmts = [
|
|
4522
4662
|
allocStmt,
|
|
4523
|
-
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
|
|
4524
|
-
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
|
|
4663
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${sf ? `, ${sf} = _ctx._fields` : ""}`,
|
|
4664
|
+
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
|
|
4525
4665
|
];
|
|
4526
4666
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
4527
4667
|
stmts.push(...innerStmts);
|
|
4528
|
-
|
|
4668
|
+
if (sf && fArr) {
|
|
4669
|
+
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
4670
|
+
}
|
|
4671
|
+
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${sf ? `; _ctx._fields = ${sf}` : ""}`);
|
|
4529
4672
|
stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
|
|
4530
4673
|
let stV = "undefined";
|
|
4531
4674
|
if (structural) {
|
|
@@ -4535,14 +4678,33 @@ ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capt
|
|
|
4535
4678
|
stV = v(ctx, "_nst");
|
|
4536
4679
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
4537
4680
|
}
|
|
4681
|
+
if (sf && fArr) {
|
|
4682
|
+
const fe = v(ctx, "_fe");
|
|
4683
|
+
const cur = v(ctx, "_fc");
|
|
4684
|
+
stmts.push(
|
|
4685
|
+
`${i}let ${fObj} = undefined`,
|
|
4686
|
+
`${i}if (${fArr} && ${fArr}.length) {`,
|
|
4687
|
+
`${i} ${fObj} = {}`,
|
|
4688
|
+
`${i} for (const ${fe} of ${fArr}) {`,
|
|
4689
|
+
`${i} const ${cur} = ${fObj}[${fe}.name], _entry = { value: ${fe}.value, span: ${fe}.span }`,
|
|
4690
|
+
`${i} if (${cur} === undefined) ${fObj}[${fe}.name] = _entry`,
|
|
4691
|
+
`${i} else if (Array.isArray(${cur})) ${cur}.push(_entry)`,
|
|
4692
|
+
`${i} else ${fObj}[${fe}.name] = [${cur}, _entry]`,
|
|
4693
|
+
`${i} }`,
|
|
4694
|
+
`${i}}`
|
|
4695
|
+
);
|
|
4696
|
+
}
|
|
4538
4697
|
const ndV = v(ctx, "_nd");
|
|
4539
|
-
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}, ${
|
|
4540
|
-
const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${
|
|
4541
|
-
const
|
|
4698
|
+
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})`;
|
|
4699
|
+
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;
|
|
4700
|
+
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;
|
|
4701
|
+
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
4702
|
+
const collapseExpr = `${chV}.length === 1 ? ${chV}[0] : (${ndExpr})`;
|
|
4703
|
+
const finalExpr = def.unwrap ? unwrapExpr : def.collapse ? collapseExpr : hostCollapseExpr;
|
|
4542
4704
|
stmts.push(
|
|
4543
4705
|
`${i}const ${ndV} = ${finalExpr}`,
|
|
4544
4706
|
`${i}if (${sc}) ${sc}.push(${ndV})`,
|
|
4545
|
-
`${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} } })`
|
|
4707
|
+
`${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} } })`
|
|
4546
4708
|
);
|
|
4547
4709
|
return { stmts, valueVar: ndV, endVar };
|
|
4548
4710
|
}
|
|
@@ -4757,6 +4919,17 @@ function emitDispatch(p, ctx, pos) {
|
|
|
4757
4919
|
endVar: inner.endVar
|
|
4758
4920
|
};
|
|
4759
4921
|
}
|
|
4922
|
+
case "field": {
|
|
4923
|
+
const inner = emit(def.parser, ctx, pos);
|
|
4924
|
+
return {
|
|
4925
|
+
stmts: [
|
|
4926
|
+
...inner.stmts,
|
|
4927
|
+
`${ind(ctx)}if (_ctx._fields) _ctx._fields.push({ name: ${JSON.stringify(def.name)}, value: ${inner.valueVar}, span: { start: ${pos}, end: ${inner.endVar} } })`
|
|
4928
|
+
],
|
|
4929
|
+
valueVar: inner.valueVar,
|
|
4930
|
+
endVar: inner.endVar
|
|
4931
|
+
};
|
|
4932
|
+
}
|
|
4760
4933
|
case "grammar": {
|
|
4761
4934
|
const savedTrivia = ctx.activeTrivia;
|
|
4762
4935
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
@@ -4858,6 +5031,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4858
5031
|
case "trivia":
|
|
4859
5032
|
case "token":
|
|
4860
5033
|
case "label":
|
|
5034
|
+
case "field":
|
|
4861
5035
|
case "optional":
|
|
4862
5036
|
case "many":
|
|
4863
5037
|
case "oneOrMore":
|
|
@@ -4894,6 +5068,7 @@ function childrenOf(def) {
|
|
|
4894
5068
|
case "trivia":
|
|
4895
5069
|
case "token":
|
|
4896
5070
|
case "label":
|
|
5071
|
+
case "field":
|
|
4897
5072
|
case "grammar":
|
|
4898
5073
|
case "not":
|
|
4899
5074
|
case "node":
|
|
@@ -5135,6 +5310,11 @@ function assertRuleName(name) {
|
|
|
5135
5310
|
);
|
|
5136
5311
|
}
|
|
5137
5312
|
}
|
|
5313
|
+
function publicRuleWrapperSource(rule, fnSource) {
|
|
5314
|
+
const labels = rule._meta.triviaKindLabels;
|
|
5315
|
+
if (labels === void 0) return fnSource;
|
|
5316
|
+
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5317
|
+
}
|
|
5138
5318
|
function compileRuleMap(ruleMap) {
|
|
5139
5319
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
5140
5320
|
const ctx = {
|
|
@@ -5167,7 +5347,7 @@ function compileRuleMap(ruleMap) {
|
|
|
5167
5347
|
ruleNames.set(rule, n === 0 ? base : `${base}$${n}`);
|
|
5168
5348
|
}
|
|
5169
5349
|
ctx.ruleNames = ruleNames;
|
|
5170
|
-
const perEntry = ruleMap.map(([key, rule]) => ({ key, r: emit(rule, ctx, "_pos") }));
|
|
5350
|
+
const perEntry = ruleMap.map(([key, rule]) => ({ key, rule, r: emit(rule, ctx, "_pos") }));
|
|
5171
5351
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
5172
5352
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
5173
5353
|
const buildSources = ctx.buildFns.length === 0 ? void 0 : ctx.buildSrcs;
|
|
@@ -5197,7 +5377,10 @@ function compileRuleMap(ruleMap) {
|
|
|
5197
5377
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
5198
5378
|
`}`
|
|
5199
5379
|
].join("\n");
|
|
5200
|
-
const objBody = perEntry.map(({ key, r }) =>
|
|
5380
|
+
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
5381
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r));
|
|
5382
|
+
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
5383
|
+
}).join(",\n");
|
|
5201
5384
|
const replacement = [
|
|
5202
5385
|
`/* @__PURE__ */ (() => {`,
|
|
5203
5386
|
...hoistedDecls,
|
|
@@ -5310,7 +5493,7 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5310
5493
|
ctx.recordFail = savedRec;
|
|
5311
5494
|
pushNamedFnDecl(ctx, fn, body.stmts, body.valueVar, body.endVar);
|
|
5312
5495
|
}
|
|
5313
|
-
perEntry.push({ key, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5496
|
+
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5314
5497
|
}
|
|
5315
5498
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
5316
5499
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
@@ -5333,14 +5516,14 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5333
5516
|
...privateFns
|
|
5334
5517
|
].filter(Boolean);
|
|
5335
5518
|
const wrappers = /* @__PURE__ */ new Map();
|
|
5336
|
-
for (const { key, r } of perEntry) {
|
|
5337
|
-
wrappers.set(key, [
|
|
5519
|
+
for (const { key, rule, r } of perEntry) {
|
|
5520
|
+
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
5338
5521
|
`function(input, _pos, _ctx) {`,
|
|
5339
5522
|
` let pos = _pos`,
|
|
5340
5523
|
...r.stmts,
|
|
5341
5524
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
5342
5525
|
`}`
|
|
5343
|
-
].join("\n"));
|
|
5526
|
+
].join("\n")));
|
|
5344
5527
|
}
|
|
5345
5528
|
const firstSets = /* @__PURE__ */ new Map();
|
|
5346
5529
|
for (const [key, rule] of ruleMap) {
|
|
@@ -5515,6 +5698,7 @@ function childrenOf2(def) {
|
|
|
5515
5698
|
case "trivia":
|
|
5516
5699
|
case "token":
|
|
5517
5700
|
case "label":
|
|
5701
|
+
case "field":
|
|
5518
5702
|
case "not":
|
|
5519
5703
|
case "node":
|
|
5520
5704
|
case "expect":
|
|
@@ -5600,6 +5784,7 @@ function evalRuleMapIR(ir) {
|
|
|
5600
5784
|
"skip",
|
|
5601
5785
|
"trivia",
|
|
5602
5786
|
"label",
|
|
5787
|
+
"field",
|
|
5603
5788
|
"expect",
|
|
5604
5789
|
"_tf",
|
|
5605
5790
|
"_nd",
|
|
@@ -5626,6 +5811,7 @@ function evalRuleMapIR(ir) {
|
|
|
5626
5811
|
skip,
|
|
5627
5812
|
trivia,
|
|
5628
5813
|
label,
|
|
5814
|
+
field,
|
|
5629
5815
|
expect,
|
|
5630
5816
|
_tf,
|
|
5631
5817
|
_nd
|
|
@@ -5759,6 +5945,8 @@ ${body}
|
|
|
5759
5945
|
return `token(${kid(def.parser)})`;
|
|
5760
5946
|
case "label":
|
|
5761
5947
|
return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
|
|
5948
|
+
case "field":
|
|
5949
|
+
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
|
|
5762
5950
|
case "expect":
|
|
5763
5951
|
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
5764
5952
|
case "skip":
|
|
@@ -5771,7 +5959,11 @@ ${body}
|
|
|
5771
5959
|
}
|
|
5772
5960
|
case "node": {
|
|
5773
5961
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
5774
|
-
const opts = def.collapse ? `, { collapse: true }` : "";
|
|
5962
|
+
const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
|
|
5963
|
+
if (def.type === void 0) {
|
|
5964
|
+
if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
|
|
5965
|
+
return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
|
|
5966
|
+
}
|
|
5775
5967
|
if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
|
|
5776
5968
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
5777
5969
|
}
|
|
@@ -5798,8 +5990,9 @@ function fusedBody(pieces) {
|
|
|
5798
5990
|
}
|
|
5799
5991
|
}
|
|
5800
5992
|
const contributing = new Set(winner.values());
|
|
5801
|
-
const
|
|
5802
|
-
const
|
|
5993
|
+
const contributingPieces = [...contributing];
|
|
5994
|
+
const needsEmptyTl = contributingPieces.some((p) => p.needsEmptyTl);
|
|
5995
|
+
const needsHostReads = contributingPieces.some((p) => p.needsHostReads);
|
|
5803
5996
|
const lines = [
|
|
5804
5997
|
// Shared sentinel protocol (must match NAMED_FN_FAIL / NAMED_FN_END in codegen).
|
|
5805
5998
|
"const _pfFail = {}",
|
|
@@ -5807,7 +6000,7 @@ function fusedBody(pieces) {
|
|
|
5807
6000
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5808
6001
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5809
6002
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5810
|
-
...[...
|
|
6003
|
+
...[...new Set(contributingPieces.flatMap((p) => p.prelude))],
|
|
5811
6004
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5812
6005
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5813
6006
|
];
|
|
@@ -5830,7 +6023,7 @@ function fusedBody(pieces) {
|
|
|
5830
6023
|
}
|
|
5831
6024
|
);
|
|
5832
6025
|
const env = {};
|
|
5833
|
-
for (const p of
|
|
6026
|
+
for (const p of contributingPieces) {
|
|
5834
6027
|
if (p.mfFns.length) env[`${p.ns}mf`] = p.mfFns;
|
|
5835
6028
|
if (p.buildFns.length) env[`${p.ns}build`] = p.buildFns;
|
|
5836
6029
|
}
|
|
@@ -5878,6 +6071,7 @@ var SUPPORTED = {
|
|
|
5878
6071
|
sepBy: (...a) => sepBy(a[0], a[1]),
|
|
5879
6072
|
trivia: (...a) => trivia(a[0]),
|
|
5880
6073
|
label: (...a) => label(a[0], a[1]),
|
|
6074
|
+
field: (...a) => field(a[0], a[1]),
|
|
5881
6075
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
5882
6076
|
token: (...a) => token(a[0]),
|
|
5883
6077
|
expect: (...a) => expect(a[0], a[1])
|
|
@@ -5898,19 +6092,20 @@ function scopeGet(scope, name, mfs) {
|
|
|
5898
6092
|
if (isCombinator(entry)) return entry;
|
|
5899
6093
|
return null;
|
|
5900
6094
|
}
|
|
5901
|
-
function
|
|
5902
|
-
if (expr.type !== "ObjectExpression") return
|
|
6095
|
+
function staticNodeOptions(expr) {
|
|
6096
|
+
if (expr.type !== "ObjectExpression") return void 0;
|
|
6097
|
+
const opts = {};
|
|
5903
6098
|
for (const prop of expr.properties) {
|
|
5904
6099
|
const p = prop;
|
|
5905
6100
|
if (p.computed) continue;
|
|
5906
6101
|
const key = p.key;
|
|
5907
6102
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
5908
|
-
if (name === "collapse") {
|
|
6103
|
+
if (name === "unwrap" || name === "collapse") {
|
|
5909
6104
|
const val = p.value;
|
|
5910
|
-
|
|
6105
|
+
if ((val.type === "Literal" || val.type === "BooleanLiteral") && val.value === true) opts[name] = true;
|
|
5911
6106
|
}
|
|
5912
6107
|
}
|
|
5913
|
-
return
|
|
6108
|
+
return opts.unwrap || opts.collapse ? opts : void 0;
|
|
5914
6109
|
}
|
|
5915
6110
|
function exprToCombi(node2, scope, code, mfs) {
|
|
5916
6111
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -5960,18 +6155,22 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
5960
6155
|
}
|
|
5961
6156
|
}
|
|
5962
6157
|
if (callee.name === "node" && code !== void 0) {
|
|
5963
|
-
const [
|
|
5964
|
-
if (!
|
|
5965
|
-
const
|
|
5966
|
-
|
|
6158
|
+
const [firstArg, secondArg, thirdArg, fourthArg] = node2.arguments;
|
|
6159
|
+
if (!firstArg || firstArg.type === "SpreadElement") return null;
|
|
6160
|
+
const firstVal = anyValue(firstArg, scope, code, mfs);
|
|
6161
|
+
const explicitType = typeof firstVal === "string" ? firstVal : void 0;
|
|
6162
|
+
const parserArg = explicitType !== void 0 ? secondArg : firstArg;
|
|
6163
|
+
const buildArg = explicitType !== void 0 ? thirdArg : secondArg;
|
|
6164
|
+
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
6165
|
+
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
5967
6166
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
5968
6167
|
if (!isCombinator(inner)) return null;
|
|
5969
6168
|
const be = buildArg;
|
|
5970
6169
|
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !(be.type === "Identifier" && be.name === "undefined");
|
|
5971
6170
|
const buildSrc = hasBuild ? code.slice(be.start, be.end) : void 0;
|
|
5972
|
-
const
|
|
6171
|
+
const opts = optsArg !== void 0 && optsArg.type !== "SpreadElement" ? staticNodeOptions(optsArg) : void 0;
|
|
5973
6172
|
try {
|
|
5974
|
-
const combi = node(
|
|
6173
|
+
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
5975
6174
|
if (combi._def.tag === "node" && buildSrc !== void 0) combi._def.buildSrc = buildSrc;
|
|
5976
6175
|
return combi;
|
|
5977
6176
|
} catch {
|
|
@@ -6237,7 +6436,9 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
|
|
|
6237
6436
|
if (!keys) return null;
|
|
6238
6437
|
const ruleRefs = /* @__PURE__ */ new Map();
|
|
6239
6438
|
const tagRef = (r, name) => {
|
|
6439
|
+
;
|
|
6240
6440
|
r._ruleName = name;
|
|
6441
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = name;
|
|
6241
6442
|
};
|
|
6242
6443
|
for (const key of keys) {
|
|
6243
6444
|
if (!ruleRefs.has(key)) {
|
|
@@ -6269,6 +6470,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
|
|
|
6269
6470
|
for (const [key, e] of finalByKey) {
|
|
6270
6471
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
6271
6472
|
if (!isCombinator(val)) return null;
|
|
6473
|
+
tagRef(val, key);
|
|
6272
6474
|
ruleRefs.get(key).define(val);
|
|
6273
6475
|
}
|
|
6274
6476
|
return ruleRefs;
|