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.js
CHANGED
|
@@ -182,6 +182,13 @@ function ref() {
|
|
|
182
182
|
define(p) {
|
|
183
183
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
184
184
|
resolved = p;
|
|
185
|
+
meta.firstSet = p._meta.firstSet;
|
|
186
|
+
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
187
|
+
meta.isTrivia = p._meta.isTrivia;
|
|
188
|
+
if (p._meta.triviaKindLabels !== void 0) meta.triviaKindLabels = p._meta.triviaKindLabels;
|
|
189
|
+
else delete meta.triviaKindLabels;
|
|
190
|
+
if (p._meta.disjoint !== void 0) meta.disjoint = p._meta.disjoint;
|
|
191
|
+
else delete meta.disjoint;
|
|
185
192
|
}
|
|
186
193
|
};
|
|
187
194
|
return slot;
|
|
@@ -289,7 +296,8 @@ function saveCstMark(ctx) {
|
|
|
289
296
|
return {
|
|
290
297
|
raw: cstRawLen(ctx),
|
|
291
298
|
tlog: cstTlLen(ctx),
|
|
292
|
-
leaves: cstLeavesLen(ctx)
|
|
299
|
+
leaves: cstLeavesLen(ctx),
|
|
300
|
+
fields: ctx._fields?.length ?? 0
|
|
293
301
|
};
|
|
294
302
|
}
|
|
295
303
|
function rollbackBufList(b, keyMulti, keySingle, len) {
|
|
@@ -313,11 +321,13 @@ function rollbackCstCapture(ctx, mark) {
|
|
|
313
321
|
if (mark.tlog === 0) b.tl = void 0;
|
|
314
322
|
else b.tl.length = mark.tlog;
|
|
315
323
|
}
|
|
324
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
316
325
|
return;
|
|
317
326
|
}
|
|
318
327
|
if (ctx._cstRawChildren) ctx._cstRawChildren.length = mark.raw;
|
|
319
328
|
if (ctx._cstTriviaLog) ctx._cstTriviaLog.length = mark.tlog;
|
|
320
329
|
if (ctx._cstLeaves) ctx._cstLeaves.length = mark.leaves;
|
|
330
|
+
if (ctx._fields) ctx._fields.length = mark.fields;
|
|
321
331
|
}
|
|
322
332
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
323
333
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -1054,10 +1064,10 @@ function needsDeferredTriviaCommit(ctx) {
|
|
|
1054
1064
|
}
|
|
1055
1065
|
function saveTriviaMark(ctx) {
|
|
1056
1066
|
const m = saveCstMark(ctx);
|
|
1057
|
-
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1067
|
+
return { raw: m.raw, tlog: m.tlog, leaves: m.leaves, fields: m.fields, log: ctx._triviaLog ? ctx._triviaLog.length : 0 };
|
|
1058
1068
|
}
|
|
1059
1069
|
function rollbackTrivia(ctx, mark) {
|
|
1060
|
-
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves });
|
|
1070
|
+
rollbackCstCapture(ctx, { raw: mark.raw, tlog: mark.tlog, leaves: mark.leaves, fields: mark.fields });
|
|
1061
1071
|
if (ctx._triviaLog) ctx._triviaLog.length = mark.log;
|
|
1062
1072
|
}
|
|
1063
1073
|
function scanWithLabels(input, cur, ctx) {
|
|
@@ -1441,6 +1451,9 @@ function markUnusedValues(root) {
|
|
|
1441
1451
|
case "transform":
|
|
1442
1452
|
visit(def.parser, true);
|
|
1443
1453
|
return;
|
|
1454
|
+
case "field":
|
|
1455
|
+
visit(def.parser, true);
|
|
1456
|
+
return;
|
|
1444
1457
|
case "skip":
|
|
1445
1458
|
visit(def.main, consumed);
|
|
1446
1459
|
visit(def.skipped, false);
|
|
@@ -1492,6 +1505,11 @@ function markUnusedValues(root) {
|
|
|
1492
1505
|
}
|
|
1493
1506
|
|
|
1494
1507
|
// src/combinators/parser.ts
|
|
1508
|
+
function tagRule(r, key) {
|
|
1509
|
+
;
|
|
1510
|
+
r._ruleName = key;
|
|
1511
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
|
|
1512
|
+
}
|
|
1495
1513
|
function rules(factory) {
|
|
1496
1514
|
const cache = {};
|
|
1497
1515
|
const proxy = new Proxy(cache, {
|
|
@@ -1500,7 +1518,7 @@ function rules(factory) {
|
|
|
1500
1518
|
const record = target;
|
|
1501
1519
|
if (!(key in record)) {
|
|
1502
1520
|
const r = ref();
|
|
1503
|
-
r
|
|
1521
|
+
tagRule(r, key);
|
|
1504
1522
|
record[key] = r;
|
|
1505
1523
|
}
|
|
1506
1524
|
return record[key];
|
|
@@ -1511,12 +1529,12 @@ function rules(factory) {
|
|
|
1511
1529
|
const placeholder = cache[key];
|
|
1512
1530
|
const parser2 = definitions[key];
|
|
1513
1531
|
if (placeholder !== void 0 && typeof placeholder.define === "function") {
|
|
1514
|
-
;
|
|
1532
|
+
tagRule(parser2, key);
|
|
1515
1533
|
placeholder.define(parser2);
|
|
1516
1534
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1517
1535
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1518
1536
|
} else {
|
|
1519
|
-
;
|
|
1537
|
+
tagRule(parser2, key);
|
|
1520
1538
|
cache[key] = parser2;
|
|
1521
1539
|
}
|
|
1522
1540
|
}
|
|
@@ -1573,44 +1591,130 @@ function buildReadsTrivia(def) {
|
|
|
1573
1591
|
const src = def.buildSrc ?? def.build.toString();
|
|
1574
1592
|
const arity = confirmedBuildArity(src);
|
|
1575
1593
|
if (arity === null) return true;
|
|
1576
|
-
return arity >=
|
|
1594
|
+
return arity >= 5;
|
|
1577
1595
|
}
|
|
1578
1596
|
function buildReadsState(def) {
|
|
1579
1597
|
if (!def.build) return true;
|
|
1580
1598
|
const src = def.buildSrc ?? def.build.toString();
|
|
1581
1599
|
const arity = confirmedBuildArity(src);
|
|
1582
1600
|
if (arity === null) return true;
|
|
1583
|
-
return arity >=
|
|
1601
|
+
return arity >= 6;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
// src/compiler/fields.ts
|
|
1605
|
+
function buildReadsFields(def) {
|
|
1606
|
+
if (!def.build) return true;
|
|
1607
|
+
const src = def.buildSrc ?? def.build.toString();
|
|
1608
|
+
const arity = confirmedBuildArity(src);
|
|
1609
|
+
if (arity === null) return true;
|
|
1610
|
+
return arity >= 2;
|
|
1611
|
+
}
|
|
1612
|
+
function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
1613
|
+
if (seen.has(p)) return false;
|
|
1614
|
+
seen.add(p);
|
|
1615
|
+
const d = p._def;
|
|
1616
|
+
switch (d.tag) {
|
|
1617
|
+
case "field":
|
|
1618
|
+
return true;
|
|
1619
|
+
case "node":
|
|
1620
|
+
return false;
|
|
1621
|
+
case "lazy": {
|
|
1622
|
+
try {
|
|
1623
|
+
return parserHasOwnFields(d.thunk(), seen);
|
|
1624
|
+
} catch {
|
|
1625
|
+
return false;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
case "sequence":
|
|
1629
|
+
case "choice":
|
|
1630
|
+
return d.parsers.some((x) => parserHasOwnFields(x, seen));
|
|
1631
|
+
case "sepBy":
|
|
1632
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.separator, seen);
|
|
1633
|
+
case "skip":
|
|
1634
|
+
return parserHasOwnFields(d.main, seen) || parserHasOwnFields(d.skipped, seen);
|
|
1635
|
+
case "grammar":
|
|
1636
|
+
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
1637
|
+
case "scanTo":
|
|
1638
|
+
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
|
|
1639
|
+
case "recover":
|
|
1640
|
+
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
1641
|
+
case "many":
|
|
1642
|
+
case "oneOrMore":
|
|
1643
|
+
case "optional":
|
|
1644
|
+
case "transform":
|
|
1645
|
+
case "trivia":
|
|
1646
|
+
case "token":
|
|
1647
|
+
case "label":
|
|
1648
|
+
case "expect":
|
|
1649
|
+
case "withCtx":
|
|
1650
|
+
case "not":
|
|
1651
|
+
return parserHasOwnFields(d.parser, seen);
|
|
1652
|
+
default:
|
|
1653
|
+
return false;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
function buildFieldMap(captures) {
|
|
1657
|
+
if (!captures?.length) return void 0;
|
|
1658
|
+
const out = {};
|
|
1659
|
+
for (const cap of captures) {
|
|
1660
|
+
const entry = { value: cap.value, span: cap.span };
|
|
1661
|
+
const current = out[cap.name];
|
|
1662
|
+
if (current === void 0) out[cap.name] = entry;
|
|
1663
|
+
else if (Array.isArray(current)) current.push(entry);
|
|
1664
|
+
else out[cap.name] = [current, entry];
|
|
1665
|
+
}
|
|
1666
|
+
return out;
|
|
1584
1667
|
}
|
|
1585
1668
|
|
|
1586
1669
|
// src/combinators/node.ts
|
|
1587
|
-
function
|
|
1670
|
+
function unwrapChild(child) {
|
|
1588
1671
|
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
1589
1672
|
}
|
|
1590
|
-
function
|
|
1673
|
+
function isCstChild(value) {
|
|
1674
|
+
return typeof value === "object" && value !== null && (value._tag === "node" || value._tag === "leaf" || value._tag === "error");
|
|
1675
|
+
}
|
|
1676
|
+
function missingInferredType() {
|
|
1677
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
1678
|
+
}
|
|
1679
|
+
function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
1680
|
+
const hasExplicitType = typeof typeOrCombinator === "string";
|
|
1681
|
+
const type = hasExplicitType ? typeOrCombinator : void 0;
|
|
1682
|
+
const combinator = hasExplicitType ? combinatorOrBuild : typeOrCombinator;
|
|
1683
|
+
const build = hasExplicitType ? buildOrOpts : combinatorOrBuild;
|
|
1684
|
+
const opts = hasExplicitType ? maybeOpts : buildOrOpts;
|
|
1685
|
+
const baseDef = { tag: "node", parser: combinator, ...type === void 0 ? {} : { type }, ...build === void 0 ? {} : { build } };
|
|
1591
1686
|
const meta = {
|
|
1592
1687
|
firstSet: combinator._meta.firstSet,
|
|
1593
1688
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1594
1689
|
isTrivia: false
|
|
1595
1690
|
};
|
|
1691
|
+
const unwrap = opts?.unwrap === true;
|
|
1596
1692
|
const collapse = opts?.collapse === true;
|
|
1597
|
-
|
|
1693
|
+
if (unwrap && collapse) {
|
|
1694
|
+
throw new Error("node() options cannot set both unwrap and collapse");
|
|
1695
|
+
}
|
|
1696
|
+
const def = unwrap || collapse ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {} } : baseDef;
|
|
1598
1697
|
const capturesTrivia = build ? buildReadsTrivia(def) : true;
|
|
1599
1698
|
const clonesState = build ? buildReadsState(def) : true;
|
|
1699
|
+
const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
|
|
1600
1700
|
return {
|
|
1601
1701
|
_tag: "node",
|
|
1602
1702
|
_meta: meta,
|
|
1603
1703
|
_def: def,
|
|
1604
1704
|
parse(input, pos, ctx) {
|
|
1605
1705
|
const saved = beginCstNodeCapture(ctx);
|
|
1706
|
+
const savedFields = ctx._fields;
|
|
1707
|
+
ctx._fields = capturesFields ? [] : void 0;
|
|
1606
1708
|
if (!capturesTrivia) ctx.captureTrivia = false;
|
|
1607
1709
|
const r = combinator.parse(input, pos, ctx);
|
|
1710
|
+
const fields = capturesFields ? buildFieldMap(ctx._fields) : void 0;
|
|
1711
|
+
ctx._fields = savedFields;
|
|
1608
1712
|
const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
1609
1713
|
if (!r.ok) return r;
|
|
1610
1714
|
const st = clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
1611
|
-
const
|
|
1612
|
-
const
|
|
1613
|
-
const rawEntry =
|
|
1715
|
+
const nodeType = def.type ?? missingInferredType();
|
|
1716
|
+
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 };
|
|
1717
|
+
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
|
|
1614
1718
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
1615
1719
|
pushCstChild(ctx, built, rawEntry);
|
|
1616
1720
|
}
|
|
@@ -1671,6 +1775,19 @@ function label(name, combinator) {
|
|
|
1671
1775
|
}
|
|
1672
1776
|
};
|
|
1673
1777
|
}
|
|
1778
|
+
function field(name, combinator) {
|
|
1779
|
+
return {
|
|
1780
|
+
_tag: combinator._tag,
|
|
1781
|
+
_meta: combinator._meta,
|
|
1782
|
+
_def: { tag: "field", name, parser: combinator },
|
|
1783
|
+
parse(input, pos, ctx) {
|
|
1784
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1785
|
+
if (!result.ok) return result;
|
|
1786
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
1787
|
+
return result;
|
|
1788
|
+
}
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1674
1791
|
|
|
1675
1792
|
// src/compiler/line-index.ts
|
|
1676
1793
|
function buildLineIndex(input) {
|
|
@@ -3130,21 +3247,22 @@ function emitScannableTerminal(shape, c) {
|
|
|
3130
3247
|
}
|
|
3131
3248
|
|
|
3132
3249
|
// src/compiler/inline-build.ts
|
|
3133
|
-
var MK_BUILD_RE = /^\(\s*(
|
|
3250
|
+
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*$/;
|
|
3134
3251
|
function escapeRegExp(s) {
|
|
3135
3252
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3136
3253
|
}
|
|
3137
3254
|
function looseMkBuildRe(type) {
|
|
3138
3255
|
return new RegExp(
|
|
3139
|
-
String.raw`^\(\s*(
|
|
3256
|
+
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*$`
|
|
3140
3257
|
);
|
|
3141
3258
|
}
|
|
3142
3259
|
function analyzeMkInlineBuild(def) {
|
|
3143
3260
|
if (!def.build) return null;
|
|
3261
|
+
if (def.type === void 0) return null;
|
|
3144
3262
|
const src = (def.buildSrc ?? def.build.toString()).trim();
|
|
3145
3263
|
const strict = src.match(MK_BUILD_RE);
|
|
3146
3264
|
if (strict) {
|
|
3147
|
-
const mkType = strict[
|
|
3265
|
+
const mkType = strict[6];
|
|
3148
3266
|
return mkType === def.type ? def.type : null;
|
|
3149
3267
|
}
|
|
3150
3268
|
if (looseMkBuildRe(def.type).test(src)) return def.type;
|
|
@@ -3479,8 +3597,9 @@ function planDisjointDispatch(parsers) {
|
|
|
3479
3597
|
}
|
|
3480
3598
|
return total >= SWITCH_MIN_CASES ? { kind: "switch", cases } : { kind: "if" };
|
|
3481
3599
|
}
|
|
3482
|
-
function captureRestoreBody(mL, mR, mTl, mLg) {
|
|
3483
|
-
const
|
|
3600
|
+
function captureRestoreBody(mL, mR, mTl, mLg, mF = null) {
|
|
3601
|
+
const fieldRestore = mF ? `; if (_ctx._fields) _ctx._fields.length = ${mF}` : "";
|
|
3602
|
+
const base = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}${fieldRestore}`;
|
|
3484
3603
|
return mLg ? `${base}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg}` : base;
|
|
3485
3604
|
}
|
|
3486
3605
|
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -3528,6 +3647,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3528
3647
|
// Delegating wrappers: defer to the wrapped parser.
|
|
3529
3648
|
case "transform":
|
|
3530
3649
|
case "label":
|
|
3650
|
+
case "field":
|
|
3531
3651
|
case "expect":
|
|
3532
3652
|
case "withCtx":
|
|
3533
3653
|
case "grammar":
|
|
@@ -3574,6 +3694,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3574
3694
|
case "optional":
|
|
3575
3695
|
case "transform":
|
|
3576
3696
|
case "label":
|
|
3697
|
+
case "field":
|
|
3577
3698
|
case "expect":
|
|
3578
3699
|
case "withCtx":
|
|
3579
3700
|
case "grammar":
|
|
@@ -3611,22 +3732,25 @@ function emitFallible(inner, ctx, pos, swallow = false) {
|
|
|
3611
3732
|
ctx.recordFail = savedRecord;
|
|
3612
3733
|
const ind0 = ind(ctx);
|
|
3613
3734
|
const needsRollback = ctx.capturing && mayLeavePartialCapture(inner);
|
|
3735
|
+
const needsFieldRollback = needsRollback && parserHasOwnFields(inner);
|
|
3614
3736
|
const mL = needsRollback ? v(ctx, "_fcl") : null;
|
|
3615
3737
|
const mR = needsRollback ? v(ctx, "_fcr") : null;
|
|
3616
3738
|
const mTl = needsRollback ? v(ctx, "_fctl") : null;
|
|
3739
|
+
const mF = needsFieldRollback ? v(ctx, "_fcf") : null;
|
|
3617
3740
|
const stmts = [
|
|
3618
3741
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
3619
3742
|
...mL ? [
|
|
3620
3743
|
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
3621
3744
|
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
3622
|
-
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0
|
|
3745
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
3746
|
+
...mF ? [`${ind0}const ${mF} = _ctx._fields?.length ?? 0`] : []
|
|
3623
3747
|
] : [],
|
|
3624
3748
|
`${ind0}${lbl}: {`,
|
|
3625
3749
|
...r.stmts,
|
|
3626
3750
|
`${ind0} ${valV} = ${r.valueVar}; ${endV} = ${r.endVar}; ${okV} = true`,
|
|
3627
3751
|
`${ind0}}`,
|
|
3628
3752
|
...mL ? [
|
|
3629
|
-
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null)} }`
|
|
3753
|
+
`${ind0}if (!${okV}) { ${captureRestoreBody(mL, mR, mTl, null, mF)} }`
|
|
3630
3754
|
] : []
|
|
3631
3755
|
];
|
|
3632
3756
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
@@ -3853,6 +3977,7 @@ function failsAtStart(p) {
|
|
|
3853
3977
|
return true;
|
|
3854
3978
|
case "transform":
|
|
3855
3979
|
case "label":
|
|
3980
|
+
case "field":
|
|
3856
3981
|
return failsAtStart(d.parser);
|
|
3857
3982
|
default:
|
|
3858
3983
|
return false;
|
|
@@ -3872,6 +3997,7 @@ function canMatchEmptyAtStart(p) {
|
|
|
3872
3997
|
return true;
|
|
3873
3998
|
case "transform":
|
|
3874
3999
|
case "label":
|
|
4000
|
+
case "field":
|
|
3875
4001
|
return canMatchEmptyAtStart(d.parser);
|
|
3876
4002
|
case "literal":
|
|
3877
4003
|
return d.value.length === 0;
|
|
@@ -4054,11 +4180,13 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4054
4180
|
const skipCond = gateCond ? `!${resOkV} && ${gateCond}` : `!${resOkV}`;
|
|
4055
4181
|
const armHasAutoNot = !!(autoNot && autoNot.length > 0);
|
|
4056
4182
|
const armNeedsRollback = ctx.capturing && (mayLeavePartialCapture(p) || armHasAutoNot && capturesLeaf(p));
|
|
4183
|
+
const armNeedsFieldRollback = armNeedsRollback && parserHasOwnFields(p);
|
|
4057
4184
|
const markLeaves = armNeedsRollback ? v(ctx, "_cml") : null;
|
|
4058
4185
|
const markRaw = armNeedsRollback ? v(ctx, "_cmr") : null;
|
|
4059
4186
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
4060
4187
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
4061
|
-
const
|
|
4188
|
+
const markFields = armNeedsFieldRollback ? v(ctx, "_cmf") : null;
|
|
4189
|
+
const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog, markFields) : "";
|
|
4062
4190
|
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
4063
4191
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
4064
4192
|
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
@@ -4068,7 +4196,8 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
4068
4196
|
`${ind(ctx)}const ${markLeaves} = _ctx._cstLeaves?.length ?? 0`,
|
|
4069
4197
|
`${ind(ctx)}const ${markRaw} = _ctx._cstRawChildren?.length ?? 0`,
|
|
4070
4198
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
4071
|
-
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0
|
|
4199
|
+
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`,
|
|
4200
|
+
...markFields ? [`${ind(ctx)}const ${markFields} = _ctx._fields?.length ?? 0`] : []
|
|
4072
4201
|
);
|
|
4073
4202
|
}
|
|
4074
4203
|
const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos, atStart);
|
|
@@ -4461,6 +4590,9 @@ function emitToken(def, ctx, pos) {
|
|
|
4461
4590
|
};
|
|
4462
4591
|
}
|
|
4463
4592
|
function emitNode(def, ctx, pos) {
|
|
4593
|
+
if (def.type === void 0) {
|
|
4594
|
+
throw new Error('node(): inferred node type requires a rules() key; pass node("Type", parser) outside rules()');
|
|
4595
|
+
}
|
|
4464
4596
|
const structural = def.build === void 0;
|
|
4465
4597
|
const mkType = structural ? null : analyzeMkInlineBuild(def);
|
|
4466
4598
|
let buildIdx = null;
|
|
@@ -4472,25 +4604,36 @@ function emitNode(def, ctx, pos) {
|
|
|
4472
4604
|
const i = ind(ctx);
|
|
4473
4605
|
const capturesTrivia = mkType !== null || !structural && buildReadsTrivia(def);
|
|
4474
4606
|
const clonesState = !structural && buildReadsState(def);
|
|
4607
|
+
const hasFields = parserHasOwnFields(def.parser);
|
|
4608
|
+
const capturesFields = hasFields && !structural && buildReadsFields(def);
|
|
4475
4609
|
const chV = v(ctx, "_ch");
|
|
4476
4610
|
const rawV = v(ctx, "_raw");
|
|
4477
4611
|
const capTLv = structural ? v(ctx, "_ctl") : null;
|
|
4478
4612
|
const capSTv = structural ? v(ctx, "_cst") : null;
|
|
4613
|
+
const capFv = structural && hasFields ? v(ctx, "_cf") : null;
|
|
4479
4614
|
const tlV = capturesTrivia || structural ? v(ctx, "_tl") : "_EMPTY_TL";
|
|
4480
4615
|
if (!capturesTrivia) ctx.needsEmptyTl = true;
|
|
4481
4616
|
const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
|
|
4482
4617
|
if (structural) ctx.needsHostReads = true;
|
|
4483
|
-
const
|
|
4618
|
+
const hostTriviaGate = `_ctx.build !== undefined && (_ctx.build._parsemanCaptureTrivia !== undefined ? _ctx.build._parsemanCaptureTrivia(${JSON.stringify(def.type)}) : (_ctx._pmCapTL ??= _hostReads(_ctx.build, 5)))`;
|
|
4619
|
+
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)` : ""}
|
|
4484
4620
|
${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
|
|
4485
4621
|
const innerTl = structural ? `${capTLv} ? ${tlV} : undefined` : capturesTrivia ? tlV : "undefined";
|
|
4622
|
+
const fieldsOn = structural ? capFv ?? "false" : capturesFields ? "true" : "false";
|
|
4623
|
+
const sf = hasFields ? v(ctx, "_sf") : null;
|
|
4624
|
+
const fArr = hasFields ? v(ctx, "_fa") : null;
|
|
4625
|
+
const fObj = hasFields ? v(ctx, "_fields") : "undefined";
|
|
4486
4626
|
const stmts = [
|
|
4487
4627
|
allocStmt,
|
|
4488
|
-
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
|
|
4489
|
-
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
|
|
4628
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${sf ? `, ${sf} = _ctx._fields` : ""}`,
|
|
4629
|
+
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}${sf ? `; _ctx._fields = ${fieldsOn} ? [] : undefined` : ""}`
|
|
4490
4630
|
];
|
|
4491
4631
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
4492
4632
|
stmts.push(...innerStmts);
|
|
4493
|
-
|
|
4633
|
+
if (sf && fArr) {
|
|
4634
|
+
stmts.push(`${i}const ${fArr} = _ctx._fields`);
|
|
4635
|
+
}
|
|
4636
|
+
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${sf ? `; _ctx._fields = ${sf}` : ""}`);
|
|
4494
4637
|
stmts.push(...emitIfFail(ctx, `!${okVar}`, propagateFailBody(ctx)));
|
|
4495
4638
|
let stV = "undefined";
|
|
4496
4639
|
if (structural) {
|
|
@@ -4500,14 +4643,33 @@ ${i}const ${chV} = [], ${rawV} = [], ${tlV} = ${capTLv} ? [] : _EMPTY_TL` : capt
|
|
|
4500
4643
|
stV = v(ctx, "_nst");
|
|
4501
4644
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
4502
4645
|
}
|
|
4646
|
+
if (sf && fArr) {
|
|
4647
|
+
const fe = v(ctx, "_fe");
|
|
4648
|
+
const cur = v(ctx, "_fc");
|
|
4649
|
+
stmts.push(
|
|
4650
|
+
`${i}let ${fObj} = undefined`,
|
|
4651
|
+
`${i}if (${fArr} && ${fArr}.length) {`,
|
|
4652
|
+
`${i} ${fObj} = {}`,
|
|
4653
|
+
`${i} for (const ${fe} of ${fArr}) {`,
|
|
4654
|
+
`${i} const ${cur} = ${fObj}[${fe}.name], _entry = { value: ${fe}.value, span: ${fe}.span }`,
|
|
4655
|
+
`${i} if (${cur} === undefined) ${fObj}[${fe}.name] = _entry`,
|
|
4656
|
+
`${i} else if (Array.isArray(${cur})) ${cur}.push(_entry)`,
|
|
4657
|
+
`${i} else ${fObj}[${fe}.name] = [${cur}, _entry]`,
|
|
4658
|
+
`${i} }`,
|
|
4659
|
+
`${i}}`
|
|
4660
|
+
);
|
|
4661
|
+
}
|
|
4503
4662
|
const ndV = v(ctx, "_nd");
|
|
4504
|
-
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}, ${
|
|
4505
|
-
const ndExpr = ctx.ns || structural ? `_ctx.build !== undefined ? _ctx.build(${JSON.stringify(def.type)}, ${chV}, ${
|
|
4506
|
-
const
|
|
4663
|
+
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})`;
|
|
4664
|
+
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;
|
|
4665
|
+
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;
|
|
4666
|
+
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
4667
|
+
const collapseExpr = `${chV}.length === 1 ? ${chV}[0] : (${ndExpr})`;
|
|
4668
|
+
const finalExpr = def.unwrap ? unwrapExpr : def.collapse ? collapseExpr : hostCollapseExpr;
|
|
4507
4669
|
stmts.push(
|
|
4508
4670
|
`${i}const ${ndV} = ${finalExpr}`,
|
|
4509
4671
|
`${i}if (${sc}) ${sc}.push(${ndV})`,
|
|
4510
|
-
`${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} } })`
|
|
4672
|
+
`${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} } })`
|
|
4511
4673
|
);
|
|
4512
4674
|
return { stmts, valueVar: ndV, endVar };
|
|
4513
4675
|
}
|
|
@@ -4722,6 +4884,17 @@ function emitDispatch(p, ctx, pos) {
|
|
|
4722
4884
|
endVar: inner.endVar
|
|
4723
4885
|
};
|
|
4724
4886
|
}
|
|
4887
|
+
case "field": {
|
|
4888
|
+
const inner = emit(def.parser, ctx, pos);
|
|
4889
|
+
return {
|
|
4890
|
+
stmts: [
|
|
4891
|
+
...inner.stmts,
|
|
4892
|
+
`${ind(ctx)}if (_ctx._fields) _ctx._fields.push({ name: ${JSON.stringify(def.name)}, value: ${inner.valueVar}, span: { start: ${pos}, end: ${inner.endVar} } })`
|
|
4893
|
+
],
|
|
4894
|
+
valueVar: inner.valueVar,
|
|
4895
|
+
endVar: inner.endVar
|
|
4896
|
+
};
|
|
4897
|
+
}
|
|
4725
4898
|
case "grammar": {
|
|
4726
4899
|
const savedTrivia = ctx.activeTrivia;
|
|
4727
4900
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
@@ -4823,6 +4996,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4823
4996
|
case "trivia":
|
|
4824
4997
|
case "token":
|
|
4825
4998
|
case "label":
|
|
4999
|
+
case "field":
|
|
4826
5000
|
case "optional":
|
|
4827
5001
|
case "many":
|
|
4828
5002
|
case "oneOrMore":
|
|
@@ -4859,6 +5033,7 @@ function childrenOf(def) {
|
|
|
4859
5033
|
case "trivia":
|
|
4860
5034
|
case "token":
|
|
4861
5035
|
case "label":
|
|
5036
|
+
case "field":
|
|
4862
5037
|
case "grammar":
|
|
4863
5038
|
case "not":
|
|
4864
5039
|
case "node":
|
|
@@ -5100,6 +5275,11 @@ function assertRuleName(name) {
|
|
|
5100
5275
|
);
|
|
5101
5276
|
}
|
|
5102
5277
|
}
|
|
5278
|
+
function publicRuleWrapperSource(rule, fnSource) {
|
|
5279
|
+
const labels = rule._meta.triviaKindLabels;
|
|
5280
|
+
if (labels === void 0) return fnSource;
|
|
5281
|
+
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5282
|
+
}
|
|
5103
5283
|
function compileRuleMap(ruleMap) {
|
|
5104
5284
|
for (const [, rule] of ruleMap) markUnusedValues(rule);
|
|
5105
5285
|
const ctx = {
|
|
@@ -5132,7 +5312,7 @@ function compileRuleMap(ruleMap) {
|
|
|
5132
5312
|
ruleNames.set(rule, n === 0 ? base : `${base}$${n}`);
|
|
5133
5313
|
}
|
|
5134
5314
|
ctx.ruleNames = ruleNames;
|
|
5135
|
-
const perEntry = ruleMap.map(([key, rule]) => ({ key, r: emit(rule, ctx, "_pos") }));
|
|
5315
|
+
const perEntry = ruleMap.map(([key, rule]) => ({ key, rule, r: emit(rule, ctx, "_pos") }));
|
|
5136
5316
|
const derivedSrcs = ctx.mapFnSrcs.length === ctx.mapFns.length && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : void 0;
|
|
5137
5317
|
const buildCovered = ctx.buildFns.length === 0 || ctx.buildSrcs.every((s) => s !== null);
|
|
5138
5318
|
const buildSources = ctx.buildFns.length === 0 ? void 0 : ctx.buildSrcs;
|
|
@@ -5162,7 +5342,10 @@ function compileRuleMap(ruleMap) {
|
|
|
5162
5342
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
5163
5343
|
`}`
|
|
5164
5344
|
].join("\n");
|
|
5165
|
-
const objBody = perEntry.map(({ key, r }) =>
|
|
5345
|
+
const objBody = perEntry.map(({ key, rule, r }) => {
|
|
5346
|
+
const src = publicRuleWrapperSource(rule, entryFnText(r));
|
|
5347
|
+
return ` ${JSON.stringify(key)}: ${src.split("\n").join("\n ")}`;
|
|
5348
|
+
}).join(",\n");
|
|
5166
5349
|
const replacement = [
|
|
5167
5350
|
`/* @__PURE__ */ (() => {`,
|
|
5168
5351
|
...hoistedDecls,
|
|
@@ -5275,7 +5458,7 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5275
5458
|
ctx.recordFail = savedRec;
|
|
5276
5459
|
pushNamedFnDecl(ctx, fn, body.stmts, body.valueVar, body.endVar);
|
|
5277
5460
|
}
|
|
5278
|
-
perEntry.push({ key, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5461
|
+
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
5279
5462
|
}
|
|
5280
5463
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
5281
5464
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
@@ -5298,14 +5481,14 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5298
5481
|
...privateFns
|
|
5299
5482
|
].filter(Boolean);
|
|
5300
5483
|
const wrappers = /* @__PURE__ */ new Map();
|
|
5301
|
-
for (const { key, r } of perEntry) {
|
|
5302
|
-
wrappers.set(key, [
|
|
5484
|
+
for (const { key, rule, r } of perEntry) {
|
|
5485
|
+
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
5303
5486
|
`function(input, _pos, _ctx) {`,
|
|
5304
5487
|
` let pos = _pos`,
|
|
5305
5488
|
...r.stmts,
|
|
5306
5489
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
|
|
5307
5490
|
`}`
|
|
5308
|
-
].join("\n"));
|
|
5491
|
+
].join("\n")));
|
|
5309
5492
|
}
|
|
5310
5493
|
const firstSets = /* @__PURE__ */ new Map();
|
|
5311
5494
|
for (const [key, rule] of ruleMap) {
|
|
@@ -5480,6 +5663,7 @@ function childrenOf2(def) {
|
|
|
5480
5663
|
case "trivia":
|
|
5481
5664
|
case "token":
|
|
5482
5665
|
case "label":
|
|
5666
|
+
case "field":
|
|
5483
5667
|
case "not":
|
|
5484
5668
|
case "node":
|
|
5485
5669
|
case "expect":
|
|
@@ -5565,6 +5749,7 @@ function evalRuleMapIR(ir) {
|
|
|
5565
5749
|
"skip",
|
|
5566
5750
|
"trivia",
|
|
5567
5751
|
"label",
|
|
5752
|
+
"field",
|
|
5568
5753
|
"expect",
|
|
5569
5754
|
"_tf",
|
|
5570
5755
|
"_nd",
|
|
@@ -5591,6 +5776,7 @@ function evalRuleMapIR(ir) {
|
|
|
5591
5776
|
skip,
|
|
5592
5777
|
trivia,
|
|
5593
5778
|
label,
|
|
5779
|
+
field,
|
|
5594
5780
|
expect,
|
|
5595
5781
|
_tf,
|
|
5596
5782
|
_nd
|
|
@@ -5724,6 +5910,8 @@ ${body}
|
|
|
5724
5910
|
return `token(${kid(def.parser)})`;
|
|
5725
5911
|
case "label":
|
|
5726
5912
|
return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
|
|
5913
|
+
case "field":
|
|
5914
|
+
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
|
|
5727
5915
|
case "expect":
|
|
5728
5916
|
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
5729
5917
|
case "skip":
|
|
@@ -5736,7 +5924,11 @@ ${body}
|
|
|
5736
5924
|
}
|
|
5737
5925
|
case "node": {
|
|
5738
5926
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
5739
|
-
const opts = def.collapse ? `, { collapse: true }` : "";
|
|
5927
|
+
const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
|
|
5928
|
+
if (def.type === void 0) {
|
|
5929
|
+
if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
|
|
5930
|
+
return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
|
|
5931
|
+
}
|
|
5740
5932
|
if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
|
|
5741
5933
|
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
5742
5934
|
}
|
|
@@ -5763,8 +5955,9 @@ function fusedBody(pieces) {
|
|
|
5763
5955
|
}
|
|
5764
5956
|
}
|
|
5765
5957
|
const contributing = new Set(winner.values());
|
|
5766
|
-
const
|
|
5767
|
-
const
|
|
5958
|
+
const contributingPieces = [...contributing];
|
|
5959
|
+
const needsEmptyTl = contributingPieces.some((p) => p.needsEmptyTl);
|
|
5960
|
+
const needsHostReads = contributingPieces.some((p) => p.needsHostReads);
|
|
5768
5961
|
const lines = [
|
|
5769
5962
|
// Shared sentinel protocol (must match NAMED_FN_FAIL / NAMED_FN_END in codegen).
|
|
5770
5963
|
"const _pfFail = {}",
|
|
@@ -5772,7 +5965,7 @@ function fusedBody(pieces) {
|
|
|
5772
5965
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5773
5966
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5774
5967
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5775
|
-
...[...
|
|
5968
|
+
...[...new Set(contributingPieces.flatMap((p) => p.prelude))],
|
|
5776
5969
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5777
5970
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5778
5971
|
];
|
|
@@ -5795,7 +5988,7 @@ function fusedBody(pieces) {
|
|
|
5795
5988
|
}
|
|
5796
5989
|
);
|
|
5797
5990
|
const env = {};
|
|
5798
|
-
for (const p of
|
|
5991
|
+
for (const p of contributingPieces) {
|
|
5799
5992
|
if (p.mfFns.length) env[`${p.ns}mf`] = p.mfFns;
|
|
5800
5993
|
if (p.buildFns.length) env[`${p.ns}build`] = p.buildFns;
|
|
5801
5994
|
}
|
|
@@ -5843,6 +6036,7 @@ var SUPPORTED = {
|
|
|
5843
6036
|
sepBy: (...a) => sepBy(a[0], a[1]),
|
|
5844
6037
|
trivia: (...a) => trivia(a[0]),
|
|
5845
6038
|
label: (...a) => label(a[0], a[1]),
|
|
6039
|
+
field: (...a) => field(a[0], a[1]),
|
|
5846
6040
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
5847
6041
|
token: (...a) => token(a[0]),
|
|
5848
6042
|
expect: (...a) => expect(a[0], a[1])
|
|
@@ -5863,19 +6057,20 @@ function scopeGet(scope, name, mfs) {
|
|
|
5863
6057
|
if (isCombinator(entry)) return entry;
|
|
5864
6058
|
return null;
|
|
5865
6059
|
}
|
|
5866
|
-
function
|
|
5867
|
-
if (expr.type !== "ObjectExpression") return
|
|
6060
|
+
function staticNodeOptions(expr) {
|
|
6061
|
+
if (expr.type !== "ObjectExpression") return void 0;
|
|
6062
|
+
const opts = {};
|
|
5868
6063
|
for (const prop of expr.properties) {
|
|
5869
6064
|
const p = prop;
|
|
5870
6065
|
if (p.computed) continue;
|
|
5871
6066
|
const key = p.key;
|
|
5872
6067
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
5873
|
-
if (name === "collapse") {
|
|
6068
|
+
if (name === "unwrap" || name === "collapse") {
|
|
5874
6069
|
const val = p.value;
|
|
5875
|
-
|
|
6070
|
+
if ((val.type === "Literal" || val.type === "BooleanLiteral") && val.value === true) opts[name] = true;
|
|
5876
6071
|
}
|
|
5877
6072
|
}
|
|
5878
|
-
return
|
|
6073
|
+
return opts.unwrap || opts.collapse ? opts : void 0;
|
|
5879
6074
|
}
|
|
5880
6075
|
function exprToCombi(node2, scope, code, mfs) {
|
|
5881
6076
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -5925,18 +6120,22 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
5925
6120
|
}
|
|
5926
6121
|
}
|
|
5927
6122
|
if (callee.name === "node" && code !== void 0) {
|
|
5928
|
-
const [
|
|
5929
|
-
if (!
|
|
5930
|
-
const
|
|
5931
|
-
|
|
6123
|
+
const [firstArg, secondArg, thirdArg, fourthArg] = node2.arguments;
|
|
6124
|
+
if (!firstArg || firstArg.type === "SpreadElement") return null;
|
|
6125
|
+
const firstVal = anyValue(firstArg, scope, code, mfs);
|
|
6126
|
+
const explicitType = typeof firstVal === "string" ? firstVal : void 0;
|
|
6127
|
+
const parserArg = explicitType !== void 0 ? secondArg : firstArg;
|
|
6128
|
+
const buildArg = explicitType !== void 0 ? thirdArg : secondArg;
|
|
6129
|
+
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
6130
|
+
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
5932
6131
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
5933
6132
|
if (!isCombinator(inner)) return null;
|
|
5934
6133
|
const be = buildArg;
|
|
5935
6134
|
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !(be.type === "Identifier" && be.name === "undefined");
|
|
5936
6135
|
const buildSrc = hasBuild ? code.slice(be.start, be.end) : void 0;
|
|
5937
|
-
const
|
|
6136
|
+
const opts = optsArg !== void 0 && optsArg.type !== "SpreadElement" ? staticNodeOptions(optsArg) : void 0;
|
|
5938
6137
|
try {
|
|
5939
|
-
const combi = node(
|
|
6138
|
+
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
5940
6139
|
if (combi._def.tag === "node" && buildSrc !== void 0) combi._def.buildSrc = buildSrc;
|
|
5941
6140
|
return combi;
|
|
5942
6141
|
} catch {
|
|
@@ -6202,7 +6401,9 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
|
|
|
6202
6401
|
if (!keys) return null;
|
|
6203
6402
|
const ruleRefs = /* @__PURE__ */ new Map();
|
|
6204
6403
|
const tagRef = (r, name) => {
|
|
6404
|
+
;
|
|
6205
6405
|
r._ruleName = name;
|
|
6406
|
+
if (r._def.tag === "node" && r._def.type === void 0) r._def.type = name;
|
|
6206
6407
|
};
|
|
6207
6408
|
for (const key of keys) {
|
|
6208
6409
|
if (!ruleRefs.has(key)) {
|
|
@@ -6234,6 +6435,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
|
|
|
6234
6435
|
for (const [key, e] of finalByKey) {
|
|
6235
6436
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
6236
6437
|
if (!isCombinator(val)) return null;
|
|
6438
|
+
tagRef(val, key);
|
|
6237
6439
|
ruleRefs.get(key).define(val);
|
|
6238
6440
|
}
|
|
6239
6441
|
return ruleRefs;
|