parseman 0.52.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.js +636 -126
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +6191 -6274
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/field-trivia.d.ts +40 -0
- package/dist/combinators/field-trivia.d.ts.map +1 -0
- package/dist/combinators/map.d.ts +19 -2
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +34 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts +0 -13
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/compiler/borrowed-rules.d.ts +30 -0
- package/dist/compiler/borrowed-rules.d.ts.map +1 -0
- package/dist/compiler/compile-linkable-table.d.ts +1 -1
- package/dist/compiler/fields.d.ts +2 -0
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts +10 -4
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +48 -91
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/trivia-charscan.d.ts +11 -3
- package/dist/cst/trivia-charscan.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +11 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +764 -888
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/evaluator.d.ts +38 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1443 -729
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +21 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -0
- package/dist/plugin/reducer-resolver.d.ts +6 -0
- package/dist/plugin/reducer-resolver.d.ts.map +1 -1
- package/dist/spec/index.js +555 -6109
- package/dist/spec/index.js.map +3 -3
- package/dist/spec/railroad-lib.d.ts +7 -2
- package/dist/spec/railroad-lib.d.ts.map +1 -1
- package/dist/spec/railroad.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +9 -0
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +11 -4
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/compile.d.ts +16 -0
- package/dist/table/compile.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +6 -2
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/field-spec.d.ts +13 -0
- package/dist/table/field-spec.d.ts.map +1 -0
- package/dist/table/index.js +480 -199
- package/dist/table/index.js.map +2 -2
- package/dist/table/scalar-terminal.d.ts +11 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/duplication.ts +1 -1
- package/src/analysis/rebuild.ts +1 -1
- package/src/combinators/field-trivia.ts +44 -0
- package/src/combinators/map.ts +48 -6
- package/src/combinators/parser.ts +133 -67
- package/src/combinators/ref.ts +10 -1
- package/src/combinators/repeat.ts +6 -1
- package/src/combinators/sequence.ts +9 -1
- package/src/compiler/borrowed-rules.ts +88 -0
- package/src/compiler/compile-linkable-table.ts +1 -1
- package/src/compiler/fields.ts +5 -2
- package/src/compiler/grammar-coverage-ids.ts +35 -6
- package/src/compiler/ir-serialize.ts +19 -119
- package/src/compiler/linker.ts +190 -666
- package/src/coverage.ts +7 -5
- package/src/cst/reflection.ts +6 -1
- package/src/cst/trivia-charscan.ts +17 -56
- package/src/cst/trivia-kinds.ts +24 -8
- package/src/index.ts +1 -0
- package/src/plugin/evaluator.ts +114 -14
- package/src/plugin/index.ts +588 -110
- package/src/plugin/ir-eval.ts +165 -0
- package/src/plugin/reducer-resolver.ts +20 -3
- package/src/spec/railroad-lib.ts +18 -8
- package/src/spec/railroad.ts +3 -4
- package/src/table/assemble.ts +126 -22
- package/src/table/compile-rule-map.ts +18 -8
- package/src/table/compile.ts +61 -0
- package/src/table/emit-assembly.ts +38 -18
- package/src/table/emit.ts +15 -4
- package/src/table/encode.ts +18 -2
- package/src/table/exec.ts +15 -1
- package/src/table/field-spec.ts +17 -0
- package/src/table/scalar-terminal.ts +25 -0
- package/src/types.ts +12 -2
- package/src/version.ts +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -367,6 +367,7 @@ function withRuleTrivia(trivia2, ctx, run) {
|
|
|
367
367
|
ctx.triviaKindLabels = savedLabels;
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
|
+
var UNDEFINED_REF = new Error("ref<T>() used before .define() was called");
|
|
370
371
|
function ref() {
|
|
371
372
|
let resolved = null;
|
|
372
373
|
let resolvedScalar = null;
|
|
@@ -382,7 +383,7 @@ function ref() {
|
|
|
382
383
|
_def: {
|
|
383
384
|
tag: "lazy",
|
|
384
385
|
thunk: () => {
|
|
385
|
-
if (!resolved) throw
|
|
386
|
+
if (!resolved) throw UNDEFINED_REF;
|
|
386
387
|
return resolved;
|
|
387
388
|
}
|
|
388
389
|
},
|
|
@@ -1268,65 +1269,17 @@ function plainRegexSource(p) {
|
|
|
1268
1269
|
const d = p._def;
|
|
1269
1270
|
return d.tag === "regex" && d.flags === "" ? d.source : null;
|
|
1270
1271
|
}
|
|
1271
|
-
var visitSpec0;
|
|
1272
|
-
var visitSpec1;
|
|
1273
|
-
var visitSpec2;
|
|
1274
|
-
var visitSpec3;
|
|
1275
|
-
var visitValue0;
|
|
1276
|
-
var visitValue1;
|
|
1277
|
-
var visitValue2;
|
|
1278
|
-
var visitValue3;
|
|
1279
1272
|
function commonLabeledTriviaVisitor(spec) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
if (spec === visitSpec2) return visitValue2;
|
|
1283
|
-
if (spec === visitSpec3) return visitValue3;
|
|
1284
|
-
const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
|
|
1285
|
-
const visitor = commonCssTriviaVisitor(sources);
|
|
1286
|
-
visitSpec3 = visitSpec2;
|
|
1287
|
-
visitValue3 = visitValue2;
|
|
1288
|
-
visitSpec2 = visitSpec1;
|
|
1289
|
-
visitValue2 = visitValue1;
|
|
1290
|
-
visitSpec1 = visitSpec0;
|
|
1291
|
-
visitValue1 = visitValue0;
|
|
1292
|
-
visitSpec0 = spec;
|
|
1293
|
-
visitValue0 = visitor;
|
|
1294
|
-
return visitor;
|
|
1295
|
-
}
|
|
1296
|
-
var armSpec0;
|
|
1297
|
-
var armSpec1;
|
|
1298
|
-
var armSpec2;
|
|
1299
|
-
var armSpec3;
|
|
1300
|
-
var armValue0;
|
|
1301
|
-
var armValue1;
|
|
1302
|
-
var armValue2;
|
|
1303
|
-
var armValue3;
|
|
1273
|
+
return commonCssTriviaVisitor(spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : []);
|
|
1274
|
+
}
|
|
1304
1275
|
function charArmsFor(spec) {
|
|
1305
|
-
if (spec
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
arms = null;
|
|
1312
|
-
} else {
|
|
1313
|
-
for (const arm of spec.arms) {
|
|
1314
|
-
const c = classifyParser(arm.parser);
|
|
1315
|
-
if (!c) {
|
|
1316
|
-
arms = null;
|
|
1317
|
-
break;
|
|
1318
|
-
}
|
|
1319
|
-
arms.push(c);
|
|
1320
|
-
}
|
|
1276
|
+
if (spec.minRepeats > 1) return null;
|
|
1277
|
+
const arms = [];
|
|
1278
|
+
for (const arm of spec.arms) {
|
|
1279
|
+
const c = classifyParser(arm.parser);
|
|
1280
|
+
if (!c) return null;
|
|
1281
|
+
arms.push(c);
|
|
1321
1282
|
}
|
|
1322
|
-
armSpec3 = armSpec2;
|
|
1323
|
-
armValue3 = armValue2;
|
|
1324
|
-
armSpec2 = armSpec1;
|
|
1325
|
-
armValue2 = armValue1;
|
|
1326
|
-
armSpec1 = armSpec0;
|
|
1327
|
-
armValue1 = armValue0;
|
|
1328
|
-
armSpec0 = spec;
|
|
1329
|
-
armValue0 = arms;
|
|
1330
1283
|
return arms;
|
|
1331
1284
|
}
|
|
1332
1285
|
function charTriviaEnd(input, cur, arms) {
|
|
@@ -1442,12 +1395,16 @@ function analyzeLabeledTrivia(trivia2) {
|
|
|
1442
1395
|
}
|
|
1443
1396
|
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1444
1397
|
}
|
|
1445
|
-
|
|
1398
|
+
return cacheLabeledTrivia(trivia2, labeledTriviaSpec(arms, minRepeats));
|
|
1399
|
+
}
|
|
1400
|
+
function labeledTriviaSpec(arms, minRepeats) {
|
|
1401
|
+
return {
|
|
1446
1402
|
labels: arms.map((a) => a.label),
|
|
1447
1403
|
arms,
|
|
1448
|
-
minRepeats
|
|
1404
|
+
minRepeats,
|
|
1405
|
+
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1406
|
+
charArms: charArmsFor({ arms, minRepeats })
|
|
1449
1407
|
};
|
|
1450
|
-
return cacheLabeledTrivia(trivia2, spec);
|
|
1451
1408
|
}
|
|
1452
1409
|
function matchArmAt(input, pos, arm, state) {
|
|
1453
1410
|
if (!startsFirstSet(arm, input, pos)) return null;
|
|
@@ -1477,7 +1434,7 @@ function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
|
1477
1434
|
return { end: pos, chunks };
|
|
1478
1435
|
}
|
|
1479
1436
|
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1480
|
-
const chars =
|
|
1437
|
+
const chars = spec.charArms;
|
|
1481
1438
|
if (chars !== null) return charTriviaEnd(input, cur, chars);
|
|
1482
1439
|
let pos = cur;
|
|
1483
1440
|
let count = 0;
|
|
@@ -1495,9 +1452,9 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
|
1495
1452
|
}
|
|
1496
1453
|
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1497
1454
|
if (spec.minRepeats > 1) return void 0;
|
|
1498
|
-
const common =
|
|
1455
|
+
const common = spec.visitor;
|
|
1499
1456
|
if (common !== null) return common(input, cur, visit);
|
|
1500
|
-
const chars =
|
|
1457
|
+
const chars = spec.charArms;
|
|
1501
1458
|
if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
|
|
1502
1459
|
let pos = cur;
|
|
1503
1460
|
let count = 0;
|
|
@@ -1564,7 +1521,7 @@ function resolveAdjacencyKindMask(trivia2, kinds) {
|
|
|
1564
1521
|
return mask;
|
|
1565
1522
|
}
|
|
1566
1523
|
function triviaKindMaskAt(input, pos, spec, state) {
|
|
1567
|
-
const chars =
|
|
1524
|
+
const chars = spec.charArms;
|
|
1568
1525
|
if (chars !== null) return charTriviaKindMask(input, pos, chars);
|
|
1569
1526
|
let cur = pos;
|
|
1570
1527
|
let mask = 0;
|
|
@@ -1810,6 +1767,7 @@ function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
|
1810
1767
|
function collectGrammarReflection(ruleMap, opts) {
|
|
1811
1768
|
const byType = /* @__PURE__ */ new Map();
|
|
1812
1769
|
const followLazy = opts?.followLazy !== false;
|
|
1770
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1813
1771
|
for (const [, rule] of ruleMap) {
|
|
1814
1772
|
if (!followLazy && rule._def.tag === "lazy") {
|
|
1815
1773
|
try {
|
|
@@ -1819,7 +1777,7 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
1819
1777
|
}
|
|
1820
1778
|
continue;
|
|
1821
1779
|
}
|
|
1822
|
-
collectFromCombinator(rule, byType,
|
|
1780
|
+
collectFromCombinator(rule, byType, seen, followLazy);
|
|
1823
1781
|
}
|
|
1824
1782
|
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
1825
1783
|
}
|
|
@@ -1850,9 +1808,26 @@ function isNamedRuleRefForAnotherRule(r, key) {
|
|
|
1850
1808
|
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1851
1809
|
return name !== void 0 && name !== key;
|
|
1852
1810
|
}
|
|
1811
|
+
var claimedRules = /* @__PURE__ */ new WeakSet();
|
|
1812
|
+
function ownRule(p, copies) {
|
|
1813
|
+
if (!claimedRules.has(p) || p._meta.isTrivia) return p;
|
|
1814
|
+
let own = copies.get(p);
|
|
1815
|
+
if (own === void 0) {
|
|
1816
|
+
const { grammarTrivia: _t, grammarScanSkip: _s, grammarHostMode: _h, grammarTrackLines: _l, ...meta } = p._meta;
|
|
1817
|
+
copies.set(p, own = { ...p, _meta: meta });
|
|
1818
|
+
}
|
|
1819
|
+
return own;
|
|
1820
|
+
}
|
|
1853
1821
|
function rules(a, b) {
|
|
1854
1822
|
const factory = typeof a === "function" ? a : b;
|
|
1855
1823
|
const options = typeof a === "function" ? b : a;
|
|
1824
|
+
const recipe = { factory, options };
|
|
1825
|
+
const map = linkRules([recipe]);
|
|
1826
|
+
Object.defineProperty(map, RULES_RECIPE, { value: [recipe], enumerable: false });
|
|
1827
|
+
return map;
|
|
1828
|
+
}
|
|
1829
|
+
var RULES_RECIPE = /* @__PURE__ */ Symbol.for("parseman.rulesRecipe");
|
|
1830
|
+
function linkRules(recipes, link) {
|
|
1856
1831
|
const cache = {};
|
|
1857
1832
|
const proxy = new Proxy(cache, {
|
|
1858
1833
|
get(target, key) {
|
|
@@ -1866,10 +1841,18 @@ function rules(a, b) {
|
|
|
1866
1841
|
return record[key];
|
|
1867
1842
|
}
|
|
1868
1843
|
});
|
|
1869
|
-
const
|
|
1870
|
-
for (const
|
|
1844
|
+
const winners = /* @__PURE__ */ new Map();
|
|
1845
|
+
for (const recipe of recipes) {
|
|
1846
|
+
const definitions = recipe.factory(proxy);
|
|
1847
|
+
for (const key of Object.keys(definitions)) {
|
|
1848
|
+
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
const keys = [...winners.keys()];
|
|
1852
|
+
const copies = /* @__PURE__ */ new Map();
|
|
1853
|
+
for (const [key, { parser: defined }] of winners) {
|
|
1871
1854
|
const placeholder = cache[key];
|
|
1872
|
-
const parser2 =
|
|
1855
|
+
const parser2 = ownRule(defined, copies);
|
|
1873
1856
|
if (placeholder === parser2) {
|
|
1874
1857
|
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1875
1858
|
}
|
|
@@ -1878,7 +1861,8 @@ function rules(a, b) {
|
|
|
1878
1861
|
placeholder.define(parser2);
|
|
1879
1862
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1880
1863
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1881
|
-
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1864
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key) || link !== void 0) {
|
|
1865
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1882
1866
|
const alias = ref();
|
|
1883
1867
|
tagRule(alias, key);
|
|
1884
1868
|
alias.define(parser2);
|
|
@@ -1890,48 +1874,34 @@ function rules(a, b) {
|
|
|
1890
1874
|
cache[key] = parser2;
|
|
1891
1875
|
}
|
|
1892
1876
|
}
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
if (
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
}
|
|
1911
|
-
if (options?.trackLines === true) {
|
|
1912
|
-
for (const key of Object.keys(definitions)) {
|
|
1913
|
-
const rule = cache[key];
|
|
1914
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
1915
|
-
}
|
|
1916
|
-
for (const key of Object.keys(definitions)) {
|
|
1917
|
-
const rule = cache[key];
|
|
1918
|
-
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
1919
|
-
const wrapped = parser({ trackLines: true }, rule);
|
|
1920
|
-
tagRule(wrapped, key);
|
|
1921
|
-
wrapped._meta.grammarTrackLines = true;
|
|
1922
|
-
cache[key] = wrapped;
|
|
1877
|
+
for (const key of keys) {
|
|
1878
|
+
const options = winners.get(key).options;
|
|
1879
|
+
let rule = cache[key];
|
|
1880
|
+
if (!rule._meta.isTrivia) {
|
|
1881
|
+
const meta = rule._meta;
|
|
1882
|
+
const trivia2 = link !== void 0 ? link.trivia : options?.trivia;
|
|
1883
|
+
if (trivia2 != null) meta.grammarTrivia = trivia2;
|
|
1884
|
+
if (options?.scanSkip != null) meta.grammarScanSkip = options.scanSkip;
|
|
1885
|
+
if ((link?.hostMode ?? options?.hostMode) === "cst") meta.grammarHostMode = "cst";
|
|
1886
|
+
if (options?.trackLines === true) {
|
|
1887
|
+
meta.grammarTrackLines = true;
|
|
1888
|
+
if (rule._def.tag !== "grammar") {
|
|
1889
|
+
rule = parser({ trackLines: true }, rule);
|
|
1890
|
+
tagRule(rule, key);
|
|
1891
|
+
rule._meta.grammarTrackLines = true;
|
|
1892
|
+
cache[key] = rule;
|
|
1893
|
+
}
|
|
1923
1894
|
}
|
|
1924
1895
|
}
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
markUnusedValues(cache[key]);
|
|
1896
|
+
markUnusedValues(rule);
|
|
1897
|
+
claimedRules.add(winners.get(key).parser).add(rule);
|
|
1928
1898
|
}
|
|
1929
1899
|
Object.defineProperty(cache, RULE_ORDER, {
|
|
1930
|
-
value:
|
|
1900
|
+
value: keys,
|
|
1931
1901
|
enumerable: false,
|
|
1932
1902
|
configurable: true
|
|
1933
1903
|
});
|
|
1934
|
-
attachGrammarReflection(cache, collectGrammarReflection(
|
|
1904
|
+
attachGrammarReflection(cache, collectGrammarReflection(keys.map((key) => [key, cache[key]])));
|
|
1935
1905
|
return cache;
|
|
1936
1906
|
}
|
|
1937
1907
|
|
|
@@ -3265,6 +3235,23 @@ function notAdjacent(options) {
|
|
|
3265
3235
|
);
|
|
3266
3236
|
}
|
|
3267
3237
|
|
|
3238
|
+
// src/combinators/field-trivia.ts
|
|
3239
|
+
var LEAD = { at: -1 };
|
|
3240
|
+
var FIELD_LEADING_TRIVIA = 1;
|
|
3241
|
+
var FIELD_TRAILING_TRIVIA = 2;
|
|
3242
|
+
function triviaFieldCapture(name, value, input, start, end, leadFrom, trailEnd) {
|
|
3243
|
+
return {
|
|
3244
|
+
name,
|
|
3245
|
+
value,
|
|
3246
|
+
span: { start, end },
|
|
3247
|
+
leading: leadFrom >= 0 && leadFrom < start ? input.slice(leadFrom, start) : "",
|
|
3248
|
+
trailing: trailEnd > end ? input.slice(end, trailEnd) : ""
|
|
3249
|
+
};
|
|
3250
|
+
}
|
|
3251
|
+
function leadsTrivia(p) {
|
|
3252
|
+
return p._def.tag === "field" && p._def.leadingTrivia === true;
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3268
3255
|
// src/combinators/sequence.ts
|
|
3269
3256
|
function sequence(...parsers) {
|
|
3270
3257
|
let adjacency = null;
|
|
@@ -3280,6 +3267,10 @@ function sequence(...parsers) {
|
|
|
3280
3267
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
3281
3268
|
}
|
|
3282
3269
|
const hasAdjacency = adjacency !== null;
|
|
3270
|
+
let leading = null;
|
|
3271
|
+
for (let i = 1; i < parsers.length; i++) {
|
|
3272
|
+
if (leadsTrivia(parsers[i])) (leading ??= Array.from({ length: parsers.length }, () => false))[i] = true;
|
|
3273
|
+
}
|
|
3283
3274
|
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
3284
3275
|
const meta = {
|
|
3285
3276
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
@@ -3327,7 +3318,7 @@ function sequence(...parsers) {
|
|
|
3327
3318
|
_tag: "sequence",
|
|
3328
3319
|
_meta: meta,
|
|
3329
3320
|
_def: def,
|
|
3330
|
-
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
3321
|
+
_parseScalar: hasAdjacency || leading !== null ? void 0 : parseScalar,
|
|
3331
3322
|
parse(input, pos, ctx) {
|
|
3332
3323
|
const tolerant = ctx._tolerant === true;
|
|
3333
3324
|
if (tolerant) {
|
|
@@ -3361,6 +3352,7 @@ function sequence(...parsers) {
|
|
|
3361
3352
|
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3362
3353
|
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3363
3354
|
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3355
|
+
if (leading?.[i] === true) LEAD.at = cur;
|
|
3364
3356
|
const result = parsers[i].parse(input, termPos, ctx);
|
|
3365
3357
|
if (!result.ok) return result;
|
|
3366
3358
|
if (values !== void 0) values.push(result.value);
|
|
@@ -4336,6 +4328,7 @@ function unwrapSeparator(separator) {
|
|
|
4336
4328
|
}
|
|
4337
4329
|
function sepBy(combinator, separatorArg, opts = {}) {
|
|
4338
4330
|
const { sep: separator, keep: keepSeparators } = unwrapSeparator(separatorArg);
|
|
4331
|
+
const separatorLeads = leadsTrivia(separator);
|
|
4339
4332
|
const { min, max } = resolveBounds("sepBy()", opts);
|
|
4340
4333
|
const trailing = opts.trailing ?? "forbid";
|
|
4341
4334
|
const meta = {
|
|
@@ -4400,7 +4393,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4400
4393
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4401
4394
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4402
4395
|
},
|
|
4403
|
-
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4396
|
+
_parseScalar: keepSeparators || separatorLeads ? void 0 : parseScalar,
|
|
4404
4397
|
parse(input, pos, ctx) {
|
|
4405
4398
|
const first = combinator.parse(input, pos, ctx);
|
|
4406
4399
|
const values = [];
|
|
@@ -4432,6 +4425,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4432
4425
|
sepPos = advanceTrivia(input, cur, ctx);
|
|
4433
4426
|
}
|
|
4434
4427
|
}
|
|
4428
|
+
if (separatorLeads) LEAD.at = cur;
|
|
4435
4429
|
const sep2 = separator.parse(input, sepPos, ctx);
|
|
4436
4430
|
if (!sep2.ok) {
|
|
4437
4431
|
rollbackTrivia(ctx, loopMark);
|
|
@@ -4889,7 +4883,7 @@ function buildFieldMap(captures) {
|
|
|
4889
4883
|
if (!captures?.length) return void 0;
|
|
4890
4884
|
const out = {};
|
|
4891
4885
|
for (const cap of captures) {
|
|
4892
|
-
const entry = { value: cap.value, span: cap.span };
|
|
4886
|
+
const entry = cap.leading === void 0 ? { value: cap.value, span: cap.span } : { value: cap.value, span: cap.span, leading: cap.leading, trailing: cap.trailing };
|
|
4893
4887
|
const current = out[cap.name];
|
|
4894
4888
|
if (current === void 0) out[cap.name] = entry;
|
|
4895
4889
|
else if (Array.isArray(current)) current.push(entry);
|
|
@@ -5121,16 +5115,41 @@ function label(name, combinator) {
|
|
|
5121
5115
|
}
|
|
5122
5116
|
};
|
|
5123
5117
|
}
|
|
5124
|
-
function field(name, combinator) {
|
|
5118
|
+
function field(name, combinator, opts) {
|
|
5119
|
+
const leadingTrivia = opts?.leadingTrivia === true;
|
|
5120
|
+
const trailingTrivia = opts?.trailingTrivia === true;
|
|
5121
|
+
if (!leadingTrivia && !trailingTrivia) {
|
|
5122
|
+
return {
|
|
5123
|
+
_tag: combinator._tag,
|
|
5124
|
+
_meta: combinator._meta,
|
|
5125
|
+
_def: { tag: "field", name, parser: combinator },
|
|
5126
|
+
parse(input, pos, ctx) {
|
|
5127
|
+
const result = combinator.parse(input, pos, ctx);
|
|
5128
|
+
if (!result.ok) return result;
|
|
5129
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
5130
|
+
return result;
|
|
5131
|
+
}
|
|
5132
|
+
};
|
|
5133
|
+
}
|
|
5125
5134
|
return {
|
|
5126
5135
|
_tag: combinator._tag,
|
|
5127
5136
|
_meta: combinator._meta,
|
|
5128
|
-
_def: {
|
|
5137
|
+
_def: {
|
|
5138
|
+
tag: "field",
|
|
5139
|
+
name,
|
|
5140
|
+
parser: combinator,
|
|
5141
|
+
...leadingTrivia ? { leadingTrivia: true } : {},
|
|
5142
|
+
...trailingTrivia ? { trailingTrivia: true } : {}
|
|
5143
|
+
},
|
|
5129
5144
|
parse(input, pos, ctx) {
|
|
5145
|
+
const leadFrom = LEAD.at;
|
|
5146
|
+
LEAD.at = -1;
|
|
5130
5147
|
const result = combinator.parse(input, pos, ctx);
|
|
5131
5148
|
if (!result.ok) return result;
|
|
5132
|
-
|
|
5133
|
-
|
|
5149
|
+
const end = result.span.end;
|
|
5150
|
+
const trailEnd = trailingTrivia && ctx.trivia ? consumeTrivia(input, end, ctx) : end;
|
|
5151
|
+
ctx._fields?.push(triviaFieldCapture(name, result.value, input, result.span.start, end, leadingTrivia ? leadFrom : -1, trailEnd));
|
|
5152
|
+
return trailEnd === end ? result : { ok: true, value: result.value, span: { start: result.span.start, end: trailEnd } };
|
|
5134
5153
|
}
|
|
5135
5154
|
};
|
|
5136
5155
|
}
|
|
@@ -7192,6 +7211,16 @@ var Encoder = class {
|
|
|
7192
7211
|
this.kIndex.set(key, i);
|
|
7193
7212
|
return i;
|
|
7194
7213
|
}
|
|
7214
|
+
fieldSpecIndex = /* @__PURE__ */ new Map();
|
|
7215
|
+
fieldSpecSlot(name, bits) {
|
|
7216
|
+
const key = JSON.stringify([name, bits]);
|
|
7217
|
+
const hit = this.fieldSpecIndex.get(key);
|
|
7218
|
+
if (hit !== void 0) return hit;
|
|
7219
|
+
const i = this.k.length;
|
|
7220
|
+
this.k.push([name, bits]);
|
|
7221
|
+
this.fieldSpecIndex.set(key, i);
|
|
7222
|
+
return i;
|
|
7223
|
+
}
|
|
7195
7224
|
/**
|
|
7196
7225
|
* A `notAdjacent({ kinds })` filter, pooled by its CONTENTS.
|
|
7197
7226
|
*
|
|
@@ -7812,8 +7841,10 @@ var Encoder = class {
|
|
|
7812
7841
|
for (let i = 0; i < arms.length; i++) this.code[head + 6 + i] = arms[i];
|
|
7813
7842
|
return head;
|
|
7814
7843
|
}
|
|
7815
|
-
case "field":
|
|
7816
|
-
|
|
7844
|
+
case "field": {
|
|
7845
|
+
const bits = (d.leadingTrivia === true ? FIELD_LEADING_TRIVIA : 0) | (d.trailingTrivia === true ? FIELD_TRAILING_TRIVIA : 0);
|
|
7846
|
+
return this.emit(OP_FIELD, bits === 0 ? this.constant(d.name) : this.fieldSpecSlot(d.name, bits), this.node(d.parser).ip);
|
|
7847
|
+
}
|
|
7817
7848
|
case "lazy": {
|
|
7818
7849
|
const refName = p._ruleName;
|
|
7819
7850
|
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
@@ -9486,6 +9517,26 @@ function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
|
|
|
9486
9517
|
};
|
|
9487
9518
|
return walk(ip, 0);
|
|
9488
9519
|
}
|
|
9520
|
+
function largeChoiceLiteralPretest(code, constants, armIp) {
|
|
9521
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
9522
|
+
if (child >= 0) {
|
|
9523
|
+
const spec = constants[code[child + 1]];
|
|
9524
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) return [child];
|
|
9525
|
+
}
|
|
9526
|
+
const family = leadingLiteralFamily(code, constants, armIp);
|
|
9527
|
+
return family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
9528
|
+
const value = constants[code[terminal + 1]];
|
|
9529
|
+
return typeof value === "string" && value.length >= 2;
|
|
9530
|
+
}) ? family : void 0;
|
|
9531
|
+
}
|
|
9532
|
+
|
|
9533
|
+
// src/table/field-spec.ts
|
|
9534
|
+
function fieldSpec(slot) {
|
|
9535
|
+
return Array.isArray(slot) ? { name: slot[0], bits: slot[1] } : { name: slot, bits: 0 };
|
|
9536
|
+
}
|
|
9537
|
+
function leadingTriviaFieldAt(code, k, ip) {
|
|
9538
|
+
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
9539
|
+
}
|
|
9489
9540
|
|
|
9490
9541
|
// src/table/emit-assembly.ts
|
|
9491
9542
|
var Unemittable = class extends Error {
|
|
@@ -9560,7 +9611,11 @@ var EMITTED_PARAMS = [
|
|
|
9560
9611
|
// Appended for old precompiled-factory ABI: old factories ignore it.
|
|
9561
9612
|
"adjacencyHolds",
|
|
9562
9613
|
// Appended for selected composite lexical programs; old factories ignore it.
|
|
9563
|
-
"LEXPROG"
|
|
9614
|
+
"LEXPROG",
|
|
9615
|
+
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
9616
|
+
// old factories ignore them.
|
|
9617
|
+
"LEAD",
|
|
9618
|
+
"triviaFieldCapture"
|
|
9564
9619
|
];
|
|
9565
9620
|
var RUNTIME_PRELUDE = `
|
|
9566
9621
|
let _pfScan=null
|
|
@@ -9820,20 +9875,12 @@ function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9820
9875
|
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
9821
9876
|
continue;
|
|
9822
9877
|
}
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
continue;
|
|
9828
|
-
}
|
|
9829
|
-
}
|
|
9830
|
-
const family = leadingLiteralFamily(code, k, armIp);
|
|
9831
|
-
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
9832
|
-
const value = k[code[terminal + 1]];
|
|
9833
|
-
return typeof value === "string" && value.length >= 2;
|
|
9834
|
-
})) {
|
|
9835
|
-
largeChoiceLiteralFamilies.set(armIp, family);
|
|
9878
|
+
const literals = largeChoiceLiteralPretest(code, k, armIp);
|
|
9879
|
+
if (literals !== void 0 && literals.length === 1 && literals[0] === child) {
|
|
9880
|
+
largeChoiceScalarSpecs.add(code[child + 1]);
|
|
9881
|
+
continue;
|
|
9836
9882
|
}
|
|
9883
|
+
if (literals !== void 0) largeChoiceLiteralFamilies.set(armIp, literals);
|
|
9837
9884
|
const sequence6 = leadingScalarSequence(code, armIp);
|
|
9838
9885
|
if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t.triviaScan[sequence6.trivia] != null)) {
|
|
9839
9886
|
largeChoiceScalarSequences.set(armIp, sequence6);
|
|
@@ -10257,14 +10304,31 @@ return v
|
|
|
10257
10304
|
}`;
|
|
10258
10305
|
}
|
|
10259
10306
|
case OP_FIELD: {
|
|
10260
|
-
const
|
|
10307
|
+
const spec = fieldSpec(k[code[ip + 1]]);
|
|
10308
|
+
const name = q(spec.name);
|
|
10261
10309
|
const child = link(code[ip + 2]);
|
|
10262
|
-
|
|
10310
|
+
if (spec.bits === 0) {
|
|
10311
|
+
return `${head}
|
|
10263
10312
|
const v=${child}(input,pos,ctx)
|
|
10264
10313
|
if(v===FAIL)return FAIL
|
|
10265
10314
|
const f=ctx._fields
|
|
10266
10315
|
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
10267
10316
|
return v
|
|
10317
|
+
}`;
|
|
10318
|
+
}
|
|
10319
|
+
const leading = (spec.bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
10320
|
+
const trailing = (spec.bits & FIELD_TRAILING_TRIVIA) !== 0;
|
|
10321
|
+
return `${head}
|
|
10322
|
+
const lf=${leading ? "LEAD.at" : "-1"}
|
|
10323
|
+
LEAD.at=-1
|
|
10324
|
+
const v=${child}(input,pos,ctx)
|
|
10325
|
+
if(v===FAIL)return FAIL
|
|
10326
|
+
const e=EC.e
|
|
10327
|
+
const te=${trailing ? "ctx.trivia!==undefined?consumeTrivia(input,e,ctx):e" : "e"}
|
|
10328
|
+
const f=ctx._fields
|
|
10329
|
+
if(f!==undefined)f.push(triviaFieldCapture(${name},v,input,pos,e,lf,te))
|
|
10330
|
+
EC.e=te
|
|
10331
|
+
return v
|
|
10268
10332
|
}`;
|
|
10269
10333
|
}
|
|
10270
10334
|
case OP_EXPECT: {
|
|
@@ -10560,7 +10624,10 @@ return v
|
|
|
10560
10624
|
`if(!adjacencyHolds(input,cur,ctx,${negated ? "true" : "false"},${kinds})){ctx._fe=cur;ctx._fx=${expected};return FAIL}`,
|
|
10561
10625
|
`${vn}=null`
|
|
10562
10626
|
);
|
|
10563
|
-
} else
|
|
10627
|
+
} else {
|
|
10628
|
+
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
10629
|
+
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
10630
|
+
}
|
|
10564
10631
|
names.push(vn);
|
|
10565
10632
|
}
|
|
10566
10633
|
parts.push("EC.e=cur");
|
|
@@ -10960,7 +11027,7 @@ let sp=cur
|
|
|
10960
11027
|
${hasTrivia === "false" ? "" : hasTrivia === "true" ? `sp=${skip}(input,sp,ctx)
|
|
10961
11028
|
` : `if(hasTrivia)sp=${skip}(input,sp,ctx)
|
|
10962
11029
|
`}ctx._fc=false
|
|
10963
|
-
const sv=${sep2}(input,sp,ctx)
|
|
11030
|
+
${sepIp >= 0 && leadingTriviaFieldAt(code, k, sepIp) ? "LEAD.at=cur\n" : ""}const sv=${sep2}(input,sp,ctx)
|
|
10964
11031
|
if(sv===FAIL){
|
|
10965
11032
|
${rb}
|
|
10966
11033
|
if(ctx._fc===true)return FAIL
|
|
@@ -12057,6 +12124,12 @@ function assemble(t, prog, cfg) {
|
|
|
12057
12124
|
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
12058
12125
|
return cur;
|
|
12059
12126
|
}
|
|
12127
|
+
function leadingFieldTerm(step, child, input, cur, ctx) {
|
|
12128
|
+
return step((i, p, c) => {
|
|
12129
|
+
LEAD.at = cur;
|
|
12130
|
+
return child(i, p, c);
|
|
12131
|
+
}, input, cur, ctx);
|
|
12132
|
+
}
|
|
12060
12133
|
function committed3(c) {
|
|
12061
12134
|
return c._fc === true;
|
|
12062
12135
|
}
|
|
@@ -12694,12 +12767,27 @@ function assemble(t, prog, cfg) {
|
|
|
12694
12767
|
};
|
|
12695
12768
|
}
|
|
12696
12769
|
case OP_FIELD: {
|
|
12697
|
-
const name = k[code[ip + 1]];
|
|
12770
|
+
const { name, bits } = fieldSpec(k[code[ip + 1]]);
|
|
12698
12771
|
const child = link(code[ip + 2]);
|
|
12772
|
+
if (bits === 0) {
|
|
12773
|
+
return (input, pos, ctx) => {
|
|
12774
|
+
const v = child(input, pos, ctx);
|
|
12775
|
+
if (v === FAIL) return FAIL;
|
|
12776
|
+
ctx._fields?.push({ name, value: v, span: { start: pos, end: EC.e } });
|
|
12777
|
+
return v;
|
|
12778
|
+
};
|
|
12779
|
+
}
|
|
12780
|
+
const leading = (bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
12781
|
+
const trailing = (bits & FIELD_TRAILING_TRIVIA) !== 0;
|
|
12699
12782
|
return (input, pos, ctx) => {
|
|
12783
|
+
const leadFrom = leading ? LEAD.at : -1;
|
|
12784
|
+
LEAD.at = -1;
|
|
12700
12785
|
const v = child(input, pos, ctx);
|
|
12701
12786
|
if (v === FAIL) return FAIL;
|
|
12702
|
-
|
|
12787
|
+
const end = EC.e;
|
|
12788
|
+
const trailEnd = trailing && ctx.trivia !== void 0 ? consumeTrivia(input, end, ctx) : end;
|
|
12789
|
+
ctx._fields?.push(triviaFieldCapture(name, v, input, pos, end, leadFrom, trailEnd));
|
|
12790
|
+
EC.e = trailEnd;
|
|
12703
12791
|
return v;
|
|
12704
12792
|
};
|
|
12705
12793
|
}
|
|
@@ -13133,6 +13221,12 @@ function assemble(t, prog, cfg) {
|
|
|
13133
13221
|
const kidIp = code[base + i];
|
|
13134
13222
|
if (code[kidIp] !== OP_ADJ) {
|
|
13135
13223
|
const kid = link(kidIp);
|
|
13224
|
+
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
13225
|
+
return (input, cur, ctx, inherited) => {
|
|
13226
|
+
ctx._sync = sync ?? inherited;
|
|
13227
|
+
return leadingFieldTerm(step, kid, input, cur, ctx);
|
|
13228
|
+
};
|
|
13229
|
+
}
|
|
13136
13230
|
return (input, cur, ctx, inherited) => {
|
|
13137
13231
|
ctx._sync = sync ?? inherited;
|
|
13138
13232
|
return step(kid, input, cur, ctx);
|
|
@@ -13210,9 +13304,12 @@ function assemble(t, prog, cfg) {
|
|
|
13210
13304
|
};
|
|
13211
13305
|
}
|
|
13212
13306
|
let hasAdj = false;
|
|
13213
|
-
for (let i = 1; i < n; i++)
|
|
13214
|
-
|
|
13215
|
-
|
|
13307
|
+
for (let i = 1; i < n; i++) {
|
|
13308
|
+
const kidIp = code[base + i];
|
|
13309
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
13310
|
+
hasAdj = true;
|
|
13311
|
+
break;
|
|
13312
|
+
}
|
|
13216
13313
|
}
|
|
13217
13314
|
if (hasAdj) {
|
|
13218
13315
|
const first2 = link(code[base]);
|
|
@@ -13220,6 +13317,9 @@ function assemble(t, prog, cfg) {
|
|
|
13220
13317
|
const kidIp = code[base + i];
|
|
13221
13318
|
if (code[kidIp] !== OP_ADJ) {
|
|
13222
13319
|
const kid = link(kidIp);
|
|
13320
|
+
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
13321
|
+
return (input, cur, ctx) => leadingFieldTerm(step, kid, input, cur, ctx);
|
|
13322
|
+
}
|
|
13223
13323
|
return (input, cur, ctx) => step(kid, input, cur, ctx);
|
|
13224
13324
|
}
|
|
13225
13325
|
const negated = code[kidIp + 1] === 1;
|
|
@@ -13582,7 +13682,7 @@ function assemble(t, prog, cfg) {
|
|
|
13582
13682
|
if (n === 2 || n === 3) {
|
|
13583
13683
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
13584
13684
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
13585
|
-
const predecide = !
|
|
13685
|
+
const predecide = !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
13586
13686
|
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
13587
13687
|
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
13588
13688
|
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
@@ -13805,6 +13905,75 @@ function assemble(t, prog, cfg) {
|
|
|
13805
13905
|
);
|
|
13806
13906
|
};
|
|
13807
13907
|
const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
|
|
13908
|
+
const pBit = [];
|
|
13909
|
+
const pRec = [];
|
|
13910
|
+
if (!REC && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
13911
|
+
for (let i = 0; i < n; i++) {
|
|
13912
|
+
for (const terminal of largeChoiceLiteralPretest(code, k, code[base + i]) ?? []) {
|
|
13913
|
+
pBit.push(1 << i);
|
|
13914
|
+
pRec.push(scalarFor(terminal));
|
|
13915
|
+
}
|
|
13916
|
+
}
|
|
13917
|
+
}
|
|
13918
|
+
const pn = pBit.length;
|
|
13919
|
+
if (pn !== 0) {
|
|
13920
|
+
return (input, pos, ctx) => {
|
|
13921
|
+
const c = lead(input, pos);
|
|
13922
|
+
const need = markCst(ctx);
|
|
13923
|
+
const mRaw = MRAW;
|
|
13924
|
+
const mTl = MTL;
|
|
13925
|
+
const mLv = MLV;
|
|
13926
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13927
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13928
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13929
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
13930
|
+
if (c < 128) {
|
|
13931
|
+
const bits = mask[c < 0 ? 128 : c];
|
|
13932
|
+
let tested = 0;
|
|
13933
|
+
let hit = 0;
|
|
13934
|
+
for (let i = 0; i < pn; i++) {
|
|
13935
|
+
const b = pBit[i];
|
|
13936
|
+
if ((bits & b) === 0 || (hit & b) !== 0) continue;
|
|
13937
|
+
tested |= b;
|
|
13938
|
+
if (pRec[i](input, pos) >= 0) hit |= b;
|
|
13939
|
+
}
|
|
13940
|
+
return masked(
|
|
13941
|
+
input,
|
|
13942
|
+
pos,
|
|
13943
|
+
ctx,
|
|
13944
|
+
bits & (~tested | hit),
|
|
13945
|
+
need,
|
|
13946
|
+
mRaw,
|
|
13947
|
+
mTl,
|
|
13948
|
+
mLv,
|
|
13949
|
+
mFl,
|
|
13950
|
+
mEr,
|
|
13951
|
+
mLog,
|
|
13952
|
+
mRoot,
|
|
13953
|
+
void 0,
|
|
13954
|
+
0,
|
|
13955
|
+
pos
|
|
13956
|
+
);
|
|
13957
|
+
}
|
|
13958
|
+
return general(
|
|
13959
|
+
input,
|
|
13960
|
+
pos,
|
|
13961
|
+
ctx,
|
|
13962
|
+
c,
|
|
13963
|
+
need,
|
|
13964
|
+
mRaw,
|
|
13965
|
+
mTl,
|
|
13966
|
+
mLv,
|
|
13967
|
+
mFl,
|
|
13968
|
+
mEr,
|
|
13969
|
+
mLog,
|
|
13970
|
+
mRoot,
|
|
13971
|
+
void 0,
|
|
13972
|
+
0,
|
|
13973
|
+
pos
|
|
13974
|
+
);
|
|
13975
|
+
};
|
|
13976
|
+
}
|
|
13808
13977
|
return (input, pos, ctx) => {
|
|
13809
13978
|
const c = lead(input, pos);
|
|
13810
13979
|
const need = markCst(ctx);
|
|
@@ -13966,6 +14135,7 @@ function assemble(t, prog, cfg) {
|
|
|
13966
14135
|
const max = code[ip + 3];
|
|
13967
14136
|
const sepIp = code[ip + 4];
|
|
13968
14137
|
const sep2 = sepIp >= 0 ? link(sepIp) : void 0;
|
|
14138
|
+
const sepLeads = sepIp >= 0 && leadingTriviaFieldAt(code, k, sepIp);
|
|
13969
14139
|
const flags = code[ip + 5];
|
|
13970
14140
|
const keepSeparators = (flags & 2) !== 0;
|
|
13971
14141
|
const trailingAllowed = (flags & 1) !== 0;
|
|
@@ -14005,6 +14175,7 @@ function assemble(t, prog, cfg) {
|
|
|
14005
14175
|
let sp = cur;
|
|
14006
14176
|
if (hasTrivia) sp = skipTrivia(input, sp, ctx);
|
|
14007
14177
|
ctx._fc = false;
|
|
14178
|
+
if (sepLeads) LEAD.at = cur;
|
|
14008
14179
|
const sv = sep2(input, sp, ctx);
|
|
14009
14180
|
if (sv === FAIL) {
|
|
14010
14181
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
@@ -14094,6 +14265,7 @@ function assemble(t, prog, cfg) {
|
|
|
14094
14265
|
let sp = cur;
|
|
14095
14266
|
if (hasTrivia) sp = skipTrivia(input, sp, ctx);
|
|
14096
14267
|
ctx._fc = false;
|
|
14268
|
+
if (sepLeads) LEAD.at = cur;
|
|
14097
14269
|
const sv = sep2(input, sp, ctx);
|
|
14098
14270
|
if (sv === FAIL) {
|
|
14099
14271
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
@@ -14416,20 +14588,9 @@ function assemble(t, prog, cfg) {
|
|
|
14416
14588
|
if (child >= 0) scalarFor(child);
|
|
14417
14589
|
continue;
|
|
14418
14590
|
}
|
|
14419
|
-
|
|
14420
|
-
|
|
14421
|
-
|
|
14422
|
-
scalarFor(child);
|
|
14423
|
-
continue;
|
|
14424
|
-
}
|
|
14425
|
-
}
|
|
14426
|
-
const family = leadingLiteralFamily(code, k, armIp);
|
|
14427
|
-
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
14428
|
-
const value = k[code[terminal + 1]];
|
|
14429
|
-
return typeof value === "string" && value.length >= 2;
|
|
14430
|
-
})) {
|
|
14431
|
-
for (const terminal of family) scalarFor(terminal);
|
|
14432
|
-
}
|
|
14591
|
+
const literals = largeChoiceLiteralPretest(code, k, armIp);
|
|
14592
|
+
if (literals !== void 0) for (const terminal of literals) scalarFor(terminal);
|
|
14593
|
+
if (literals !== void 0 && literals.length === 1 && literals[0] === child) continue;
|
|
14433
14594
|
const sequence6 = leadingScalarSequence(code, armIp);
|
|
14434
14595
|
if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
|
|
14435
14596
|
for (const terminal of sequence6.terminals) scalarFor(terminal);
|
|
@@ -14495,7 +14656,9 @@ function assemble(t, prog, cfg) {
|
|
|
14495
14656
|
scanTriviaCompact,
|
|
14496
14657
|
t.lex,
|
|
14497
14658
|
adjacencyHolds,
|
|
14498
|
-
t.lexPrograms
|
|
14659
|
+
t.lexPrograms,
|
|
14660
|
+
LEAD,
|
|
14661
|
+
triviaFieldCapture
|
|
14499
14662
|
);
|
|
14500
14663
|
emitReached = new Set(pre.reached);
|
|
14501
14664
|
}
|
|
@@ -14577,7 +14740,9 @@ function assemble(t, prog, cfg) {
|
|
|
14577
14740
|
scanTriviaCompact,
|
|
14578
14741
|
t.lex,
|
|
14579
14742
|
adjacencyHolds,
|
|
14580
|
-
t.lexPrograms
|
|
14743
|
+
t.lexPrograms,
|
|
14744
|
+
LEAD,
|
|
14745
|
+
triviaFieldCapture
|
|
14581
14746
|
);
|
|
14582
14747
|
emitReached = em.reached;
|
|
14583
14748
|
} catch (e) {
|
|
@@ -14753,7 +14918,9 @@ var AssemblyCache = class {
|
|
|
14753
14918
|
return made;
|
|
14754
14919
|
}
|
|
14755
14920
|
};
|
|
14756
|
-
function tableRules(source,
|
|
14921
|
+
function tableRules(source, metadataOrEntry = {}) {
|
|
14922
|
+
const entry = typeof metadataOrEntry === "string" ? metadataOrEntry : void 0;
|
|
14923
|
+
const artifactMetadata = typeof metadataOrEntry === "string" ? {} : metadataOrEntry;
|
|
14757
14924
|
const prog = expandCompact(source);
|
|
14758
14925
|
const resolved = resolveTable(prog);
|
|
14759
14926
|
const cache = new AssemblyCache(prog, resolved);
|
|
@@ -14761,7 +14928,7 @@ function tableRules(source, artifactMetadata = {}) {
|
|
|
14761
14928
|
const skipOf = prog.scanSkipOf;
|
|
14762
14929
|
let last;
|
|
14763
14930
|
let selected;
|
|
14764
|
-
|
|
14931
|
+
const map = stampRuleMap(prog, {
|
|
14765
14932
|
runRule: (ri, input, pos, ctx) => {
|
|
14766
14933
|
const a = selected ?? cache.forCtx(ctx);
|
|
14767
14934
|
selected = void 0;
|
|
@@ -14782,6 +14949,9 @@ function tableRules(source, artifactMetadata = {}) {
|
|
|
14782
14949
|
return a.scanSkip[skipOf?.[ri] ?? -1];
|
|
14783
14950
|
}
|
|
14784
14951
|
}, artifactMetadata, resolved);
|
|
14952
|
+
if (entry === void 0) return map;
|
|
14953
|
+
if (!Object.hasOwn(map, entry)) throw new Error(`tableRules: the program has no rule ${JSON.stringify(entry)}`);
|
|
14954
|
+
return map[entry];
|
|
14785
14955
|
}
|
|
14786
14956
|
|
|
14787
14957
|
// src/table/emit.ts
|
|
@@ -14947,11 +15117,15 @@ function emitTableExpression(prog, opts = {}) {
|
|
|
14947
15117
|
const entry = opts.entry === void 0 ? "grammar" : opts.entry;
|
|
14948
15118
|
const ref2 = opts.runtimeRef ?? "tableRules";
|
|
14949
15119
|
const fns = opts.fnSources ?? prog.fns.map(() => "() => {}");
|
|
14950
|
-
const
|
|
15120
|
+
const meta = opts.metadataSource;
|
|
15121
|
+
if (entry !== null && meta !== void 0) {
|
|
15122
|
+
throw new Error("emitTableExpression: metadataSource is for the rule-map form (entry: null); a single entry carries none");
|
|
15123
|
+
}
|
|
15124
|
+
const tail = entry !== null ? `,${jsString(entry)}` : meta === void 0 ? "" : `,${meta}`;
|
|
14951
15125
|
return [
|
|
14952
15126
|
`/* @__PURE__ */ ${ref2}({`,
|
|
14953
15127
|
...programFields(prog, fns, opts),
|
|
14954
|
-
|
|
15128
|
+
`}${tail})`
|
|
14955
15129
|
].join("\n");
|
|
14956
15130
|
}
|
|
14957
15131
|
|
|
@@ -15020,7 +15194,8 @@ function children(def, winners) {
|
|
|
15020
15194
|
return [];
|
|
15021
15195
|
}
|
|
15022
15196
|
const name = resolved._ruleName;
|
|
15023
|
-
|
|
15197
|
+
const winner = name ? winners?.[name] : void 0;
|
|
15198
|
+
return winner !== void 0 && winner._def !== def ? [winner] : [resolved];
|
|
15024
15199
|
}
|
|
15025
15200
|
default:
|
|
15026
15201
|
return [];
|
|
@@ -15045,16 +15220,39 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15045
15220
|
}
|
|
15046
15221
|
}
|
|
15047
15222
|
}
|
|
15223
|
+
const selfWinnerBody = (parser2) => {
|
|
15224
|
+
if (parser2._def.tag !== "lazy" || winners === void 0) return void 0;
|
|
15225
|
+
const name = winnerNames.get(parser2);
|
|
15226
|
+
if (name === void 0 || winners[name] !== parser2) return void 0;
|
|
15227
|
+
try {
|
|
15228
|
+
return parser2._def.thunk();
|
|
15229
|
+
} catch {
|
|
15230
|
+
return void 0;
|
|
15231
|
+
}
|
|
15232
|
+
};
|
|
15233
|
+
const slotsPerBody = /* @__PURE__ */ new Map();
|
|
15234
|
+
if (winners) {
|
|
15235
|
+
for (const winner of Object.values(winners)) {
|
|
15236
|
+
const body = selfWinnerBody(winner);
|
|
15237
|
+
if (body !== void 0) slotsPerBody.set(body, (slotsPerBody.get(body) ?? 0) + 1);
|
|
15238
|
+
}
|
|
15239
|
+
}
|
|
15240
|
+
const sharedBody = (parser2) => (slotsPerBody.get(parser2) ?? 0) > 1;
|
|
15241
|
+
const ownRule2 = (parser2, rule) => {
|
|
15242
|
+
const id = `rule:${rule}`;
|
|
15243
|
+
definitions.set(id, { id, kind: "rule" });
|
|
15244
|
+
rules2.set(parser2, id);
|
|
15245
|
+
};
|
|
15048
15246
|
const seen = /* @__PURE__ */ new Set();
|
|
15049
15247
|
const visit = (parser2, path3) => {
|
|
15050
15248
|
if (seen.has(parser2)) return;
|
|
15051
15249
|
seen.add(parser2);
|
|
15052
15250
|
const rule = winnerNames.get(parser2) ?? parser2._ruleName;
|
|
15053
|
-
|
|
15054
|
-
|
|
15055
|
-
|
|
15056
|
-
rules2.set(parser2, id);
|
|
15251
|
+
const body = selfWinnerBody(parser2);
|
|
15252
|
+
if (rule && body === void 0 && !sharedBody(parser2) && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
15253
|
+
ownRule2(parser2, rule);
|
|
15057
15254
|
}
|
|
15255
|
+
if (rule && body !== void 0 && sharedBody(body)) ownRule2(parser2, rule);
|
|
15058
15256
|
if (parser2._def.tag === "choice") {
|
|
15059
15257
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path3}/arm:${index}`);
|
|
15060
15258
|
choices.set(parser2, ids);
|
|
@@ -15075,7 +15273,13 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15075
15273
|
};
|
|
15076
15274
|
const roots = Array.isArray(entry) ? entry : [entry];
|
|
15077
15275
|
for (const root of roots) {
|
|
15078
|
-
|
|
15276
|
+
const name = winnerNames.get(root) ?? root._ruleName ?? "entry";
|
|
15277
|
+
const body = selfWinnerBody(root);
|
|
15278
|
+
if (body !== void 0 && sharedBody(body) && !seen.has(root)) {
|
|
15279
|
+
seen.add(root);
|
|
15280
|
+
ownRule2(root, name);
|
|
15281
|
+
}
|
|
15282
|
+
visit(body ?? root, name);
|
|
15079
15283
|
}
|
|
15080
15284
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
15081
15285
|
}
|
|
@@ -15099,7 +15303,7 @@ function payloadKey(p, d) {
|
|
|
15099
15303
|
case "label":
|
|
15100
15304
|
return `label\0${d.label}`;
|
|
15101
15305
|
case "field":
|
|
15102
|
-
return `field\0${d.name}`;
|
|
15306
|
+
return `field\0${d.name}\0${d.leadingTrivia === true}\0${d.trailingTrivia === true}`;
|
|
15103
15307
|
case "node":
|
|
15104
15308
|
return `node\0${d.type ?? ""}\0${d.unwrap === true}\0${d.collapse === true}\0${fnKey(d.buildSrc, d.build)}`;
|
|
15105
15309
|
case "transform":
|
|
@@ -16381,105 +16585,299 @@ function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
|
16381
16585
|
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16382
16586
|
}
|
|
16383
16587
|
|
|
16384
|
-
// src/table/compile.ts
|
|
16385
|
-
var
|
|
16386
|
-
function
|
|
16387
|
-
|
|
16388
|
-
const text = Function.prototype.toString.call(fn);
|
|
16389
|
-
if (!text.includes("[native code]")) return text;
|
|
16390
|
-
const name = fn.name;
|
|
16391
|
-
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
16588
|
+
// src/table/compile-rule-map.ts
|
|
16589
|
+
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
16590
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
16591
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16392
16592
|
}
|
|
16393
|
-
function
|
|
16394
|
-
|
|
16395
|
-
const drain = beginCompileDegradationDrain();
|
|
16396
|
-
let compiled = false;
|
|
16397
|
-
try {
|
|
16398
|
-
const out = compileImpl(combinator, mapFnSources, opts);
|
|
16399
|
-
compiled = true;
|
|
16400
|
-
return out;
|
|
16401
|
-
} finally {
|
|
16402
|
-
drain(compiled);
|
|
16403
|
-
}
|
|
16593
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
16594
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16404
16595
|
}
|
|
16405
|
-
function
|
|
16406
|
-
|
|
16407
|
-
const
|
|
16408
|
-
|
|
16409
|
-
|
|
16410
|
-
|
|
16411
|
-
|
|
16412
|
-
|
|
16596
|
+
function withAmbient(ruleMap, opts) {
|
|
16597
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16598
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
16599
|
+
return ruleMap.map(([name, rule]) => {
|
|
16600
|
+
if (rule._meta.isTrivia) return [name, rule];
|
|
16601
|
+
const addTrivia = opts.trivia !== void 0 && rule._meta.grammarTrivia === void 0;
|
|
16602
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule._meta.grammarScanSkip === void 0;
|
|
16603
|
+
if (!addTrivia && !addScanSkip) return [name, rule];
|
|
16604
|
+
let wrapped = wrappers.get(rule);
|
|
16605
|
+
if (wrapped === void 0) {
|
|
16606
|
+
wrapped = {
|
|
16607
|
+
...rule,
|
|
16608
|
+
_meta: {
|
|
16609
|
+
...rule._meta,
|
|
16610
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16611
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16612
|
+
}
|
|
16613
|
+
};
|
|
16614
|
+
wrappers.set(rule, wrapped);
|
|
16615
|
+
}
|
|
16616
|
+
return [name, wrapped];
|
|
16617
|
+
});
|
|
16618
|
+
}
|
|
16619
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16620
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16621
|
+
if (encoded === null) return null;
|
|
16622
|
+
const { prog, hostMode, plan } = encoded;
|
|
16413
16623
|
const artifact = closureArtifact(prog);
|
|
16414
|
-
const
|
|
16415
|
-
const offered = opts.fnSources ?? mapFnSources;
|
|
16416
|
-
const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
|
|
16417
|
-
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
|
|
16418
|
-
const unsourced = sources.reduce((acc, s, i) => s === null ? [...acc, i] : acc, []);
|
|
16419
|
-
const runtimeOnly = [
|
|
16420
|
-
...prog.runtimeOnly ?? [],
|
|
16421
|
-
...unsourced.length === 0 ? [] : [`author reducer source missing for prog.fns[${unsourced.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`]
|
|
16422
|
-
];
|
|
16423
|
-
const printable = runtimeOnly.length === 0;
|
|
16424
|
-
const emitOpts = { fnSources: sources };
|
|
16425
|
-
const source = printable ? emitTableModule(artifact, { name: "grammar", ...emitOpts }) : "";
|
|
16426
|
-
const inlineExpression = printable ? emitTableExpression(artifact, { entry: ENTRY, runtimeRef: opts.runtimeRef ?? "tableRules", ...emitOpts }) : null;
|
|
16427
|
-
const runOnce = (input, pos, ctx) => entry(input, pos, ctx);
|
|
16624
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
16428
16625
|
return {
|
|
16429
|
-
|
|
16430
|
-
|
|
16431
|
-
|
|
16432
|
-
|
|
16433
|
-
// `plugin/index.ts` prefers a compiler-supplied `coverageDefinitions` and only
|
|
16434
|
-
// falls back to regex-scanning generated hooks; a table has no hooks to scan,
|
|
16435
|
-
// so this is the channel.
|
|
16626
|
+
keys: ruleMap.map(([key]) => key),
|
|
16627
|
+
hostMode,
|
|
16628
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16629
|
+
reflection,
|
|
16436
16630
|
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16437
|
-
|
|
16438
|
-
|
|
16439
|
-
},
|
|
16440
|
-
|
|
16441
|
-
return runOnce(input, pos, parseCtx);
|
|
16442
|
-
},
|
|
16443
|
-
/**
|
|
16444
|
-
* NO LONGER REFUSES. It used to throw unless the caller passed
|
|
16445
|
-
* `{ recovery: true }`, because setting `_tolerant` on a table with no
|
|
16446
|
-
* recovery rows would report a clean parse with an empty error list whatever
|
|
16447
|
-
* the input — refusing was the right answer to that, and OPTIONAL RECOVERY
|
|
16448
|
-
* was the wrong question. `compile()` requires no such flag, so the refusal
|
|
16449
|
-
* was a `CompiledParser` contract break; recovery is now always lowered and
|
|
16450
|
-
* there is nothing left to refuse.
|
|
16451
|
-
*/
|
|
16452
|
-
parseWithErrors(input, pos = 0) {
|
|
16453
|
-
const ctx = createParseContext();
|
|
16454
|
-
const errors = [];
|
|
16455
|
-
ctx._errors = errors;
|
|
16456
|
-
ctx._tolerant = true;
|
|
16457
|
-
const r = runOnce(input, pos, ctx);
|
|
16458
|
-
return { ...r, errors };
|
|
16459
|
-
}
|
|
16631
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16632
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
16633
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16634
|
+
prog: artifact
|
|
16460
16635
|
};
|
|
16461
16636
|
}
|
|
16462
|
-
|
|
16463
|
-
|
|
16464
|
-
|
|
16465
|
-
const
|
|
16466
|
-
|
|
16467
|
-
|
|
16468
|
-
|
|
16637
|
+
function encodeForRun(ruleMap, opts) {
|
|
16638
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16639
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
16640
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16641
|
+
encodeMap.map(([, rule]) => rule),
|
|
16642
|
+
Object.fromEntries(encodeMap.filter(([, rule]) => rule._def.tag !== "lazy"))
|
|
16643
|
+
) : void 0;
|
|
16644
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16645
|
+
const settings = {
|
|
16646
|
+
hostMode,
|
|
16647
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16648
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
16649
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
16469
16650
|
};
|
|
16470
|
-
|
|
16471
|
-
|
|
16472
|
-
|
|
16473
|
-
|
|
16474
|
-
|
|
16475
|
-
|
|
16476
|
-
|
|
16651
|
+
try {
|
|
16652
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16653
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
16654
|
+
} catch (e) {
|
|
16655
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16656
|
+
return null;
|
|
16657
|
+
}
|
|
16658
|
+
}
|
|
16659
|
+
function compileRuleMap(ruleMap, opts = {}) {
|
|
16660
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16661
|
+
if (encoded === null) return null;
|
|
16662
|
+
const { prog, fnSrcs, hostMode, plan } = encoded;
|
|
16663
|
+
const artifact = closureArtifact(prog);
|
|
16664
|
+
if (artifact.runtimeOnly !== void 0 && artifact.runtimeOnly.length > 0) {
|
|
16665
|
+
opts.refusals?.push(...artifact.runtimeOnly);
|
|
16666
|
+
return null;
|
|
16667
|
+
}
|
|
16668
|
+
const supplied = opts.fnSources;
|
|
16669
|
+
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? null);
|
|
16670
|
+
if (sources.some((s) => s === null)) {
|
|
16671
|
+
const missing = sources.flatMap((s, i) => s === null ? [i] : []);
|
|
16672
|
+
opts.refusals?.push(
|
|
16673
|
+
`author reducer source missing for prog.fns[${missing.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`
|
|
16674
|
+
);
|
|
16675
|
+
return null;
|
|
16676
|
+
}
|
|
16677
|
+
if (supplied !== void 0 && supplied.length > fnSrcs.length) {
|
|
16678
|
+
throw new Error(
|
|
16679
|
+
`compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
|
|
16680
|
+
);
|
|
16681
|
+
}
|
|
16682
|
+
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
16683
|
+
entry: null,
|
|
16684
|
+
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
16685
|
+
fnSources: sources,
|
|
16686
|
+
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
16687
|
+
...metadataSource === void 0 ? {} : { metadataSource }
|
|
16688
|
+
});
|
|
16689
|
+
const replacement = replacementWithMetadata();
|
|
16690
|
+
return {
|
|
16691
|
+
keys: ruleMap.map(([key]) => key),
|
|
16692
|
+
replacement,
|
|
16693
|
+
replacementWithMetadata,
|
|
16694
|
+
hostMode,
|
|
16695
|
+
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
16696
|
+
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
16697
|
+
// off. `mode === 'ast'` alone over-reports it: an all-STRUCTURAL grammar has no
|
|
16698
|
+
// direct builder, so there was no branch to drop and it stays usable with either
|
|
16699
|
+
// host — the long-standing `node(parser)` contract. Same predicate codegen uses
|
|
16700
|
+
// for its own `hasDirectBuilders` (both read `analysis/commitment.ts`), so the two
|
|
16701
|
+
// lowerings stamp the same artifact rather than disagreeing about it.
|
|
16702
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16703
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
16704
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16705
|
+
rules: tableRules(artifact),
|
|
16706
|
+
prog: artifact
|
|
16707
|
+
};
|
|
16708
|
+
}
|
|
16709
|
+
|
|
16710
|
+
// src/compiler/borrowed-rules.ts
|
|
16711
|
+
var nameOf = (c) => c._ruleName;
|
|
16712
|
+
function deref(c) {
|
|
16713
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16714
|
+
let current = c;
|
|
16715
|
+
while (current._def.tag === "lazy" && !seen.has(current)) {
|
|
16716
|
+
seen.add(current);
|
|
16717
|
+
try {
|
|
16718
|
+
current = current._def.thunk();
|
|
16719
|
+
} catch {
|
|
16720
|
+
return void 0;
|
|
16721
|
+
}
|
|
16722
|
+
}
|
|
16723
|
+
return current;
|
|
16724
|
+
}
|
|
16725
|
+
function borrowedRuleReference(map) {
|
|
16726
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16727
|
+
for (const [rule, self] of Object.entries(map)) {
|
|
16728
|
+
let found;
|
|
16729
|
+
const visit = (c) => {
|
|
16730
|
+
if (found !== void 0) return;
|
|
16731
|
+
if (c._def.tag === "lazy") {
|
|
16732
|
+
if (!winnerWrapsReference(self, c)) {
|
|
16733
|
+
const name = nameOf(c);
|
|
16734
|
+
const winner = name !== void 0 && Object.hasOwn(map, name) ? map[name] : void 0;
|
|
16735
|
+
if (winner !== void 0) {
|
|
16736
|
+
if (winnerWrapsReference(winner, c) || deref(c) === deref(winner)) return;
|
|
16737
|
+
found = name;
|
|
16738
|
+
return;
|
|
16739
|
+
}
|
|
16740
|
+
}
|
|
16741
|
+
if (seen.has(c)) return;
|
|
16742
|
+
seen.add(c);
|
|
16743
|
+
let body;
|
|
16744
|
+
try {
|
|
16745
|
+
body = c._def.thunk();
|
|
16746
|
+
} catch {
|
|
16747
|
+
return;
|
|
16748
|
+
}
|
|
16749
|
+
visit(body);
|
|
16750
|
+
return;
|
|
16751
|
+
}
|
|
16752
|
+
if (seen.has(c)) return;
|
|
16753
|
+
seen.add(c);
|
|
16754
|
+
for (const child of childrenOf2(c._def)) visit(child);
|
|
16755
|
+
};
|
|
16756
|
+
visit(self);
|
|
16757
|
+
if (found !== void 0) return { rule, reference: found };
|
|
16758
|
+
}
|
|
16759
|
+
return void 0;
|
|
16760
|
+
}
|
|
16761
|
+
function borrowedRuleMessage(api, hit) {
|
|
16762
|
+
return `${api}: rule "${hit.rule}" is a rule object borrowed from another grammar, and its graph references "${hit.reference}", which this grammar also defines. The interpreter would keep the other grammar's "${hit.reference}" while a compiled table binds this grammar's, so the two would accept different input. Compose the grammar that defines "${hit.rule}" instead of borrowing its rule object, so its references resolve to this grammar's rules.`;
|
|
16763
|
+
}
|
|
16764
|
+
|
|
16765
|
+
// src/table/compile.ts
|
|
16766
|
+
var ENTRY = "Entry";
|
|
16767
|
+
function ownSource(fn) {
|
|
16768
|
+
if (typeof fn !== "function") return null;
|
|
16769
|
+
const text = Function.prototype.toString.call(fn);
|
|
16770
|
+
if (!text.includes("[native code]")) return text;
|
|
16771
|
+
const name = fn.name;
|
|
16772
|
+
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
16773
|
+
}
|
|
16774
|
+
function compile(target, second, third) {
|
|
16775
|
+
if (!isCombinator(target)) return compileMap(target, second);
|
|
16776
|
+
return compileRoot(target, second, third);
|
|
16777
|
+
}
|
|
16778
|
+
function isCombinator(x) {
|
|
16779
|
+
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
16780
|
+
}
|
|
16781
|
+
function compileMap(grammar, opts = {}) {
|
|
16782
|
+
const entries = [];
|
|
16783
|
+
for (const [key, value] of Object.entries(grammar)) {
|
|
16784
|
+
if (!isCombinator(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
16785
|
+
if (value._def.tag === "lazy") {
|
|
16477
16786
|
try {
|
|
16478
|
-
|
|
16479
|
-
}
|
|
16480
|
-
|
|
16787
|
+
value._def.thunk();
|
|
16788
|
+
} catch {
|
|
16789
|
+
continue;
|
|
16481
16790
|
}
|
|
16482
16791
|
}
|
|
16792
|
+
entries.push([key, value]);
|
|
16793
|
+
}
|
|
16794
|
+
const borrowed = borrowedRuleReference(Object.fromEntries(entries));
|
|
16795
|
+
if (borrowed !== void 0) throw new Error(borrowedRuleMessage("compile", borrowed));
|
|
16796
|
+
const drain = beginCompileDegradationDrain();
|
|
16797
|
+
let done = false;
|
|
16798
|
+
try {
|
|
16799
|
+
const refusals = [];
|
|
16800
|
+
const compiled = compileRuleMapRunnable(entries, {
|
|
16801
|
+
...opts.hostMode ? { hostMode: opts.hostMode } : {},
|
|
16802
|
+
refusals,
|
|
16803
|
+
specialise: true
|
|
16804
|
+
});
|
|
16805
|
+
if (compiled === null) {
|
|
16806
|
+
throw new Error(`compile: this grammar could not be encoded to a table${refusals.length ? ` \u2014 ${refusals.join("; ")}` : ""}`);
|
|
16807
|
+
}
|
|
16808
|
+
done = true;
|
|
16809
|
+
return compiled.rules;
|
|
16810
|
+
} finally {
|
|
16811
|
+
drain(done);
|
|
16812
|
+
}
|
|
16813
|
+
}
|
|
16814
|
+
function compileRoot(combinator, mapFnSources, opts = {}) {
|
|
16815
|
+
runDuplicationDiagnostic(combinator, opts.duplication);
|
|
16816
|
+
const drain = beginCompileDegradationDrain();
|
|
16817
|
+
let compiled = false;
|
|
16818
|
+
try {
|
|
16819
|
+
const out = compileImpl(combinator, mapFnSources, opts);
|
|
16820
|
+
compiled = true;
|
|
16821
|
+
return out;
|
|
16822
|
+
} finally {
|
|
16823
|
+
drain(compiled);
|
|
16824
|
+
}
|
|
16825
|
+
}
|
|
16826
|
+
function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
16827
|
+
const plan = opts.coverage === true ? buildGrammarPlan(combinator) : void 0;
|
|
16828
|
+
const settings = {
|
|
16829
|
+
...opts.hostMode === void 0 ? {} : { hostMode: opts.hostMode },
|
|
16830
|
+
...opts.trackLines === void 0 ? {} : { trackLines: opts.trackLines },
|
|
16831
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
16832
|
+
};
|
|
16833
|
+
const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
|
|
16834
|
+
const artifact = closureArtifact(prog);
|
|
16835
|
+
const entry = tableRules(prog)[ENTRY];
|
|
16836
|
+
const offered = opts.fnSources ?? mapFnSources;
|
|
16837
|
+
const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
|
|
16838
|
+
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
|
|
16839
|
+
const unsourced = sources.reduce((acc, s, i) => s === null ? [...acc, i] : acc, []);
|
|
16840
|
+
const runtimeOnly = [
|
|
16841
|
+
...prog.runtimeOnly ?? [],
|
|
16842
|
+
...unsourced.length === 0 ? [] : [`author reducer source missing for prog.fns[${unsourced.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`]
|
|
16843
|
+
];
|
|
16844
|
+
const printable = runtimeOnly.length === 0;
|
|
16845
|
+
const emitOpts = { fnSources: sources };
|
|
16846
|
+
const source = printable ? emitTableModule(artifact, { name: "grammar", ...emitOpts }) : "";
|
|
16847
|
+
const inlineExpression = printable ? emitTableExpression(artifact, { entry: ENTRY, runtimeRef: opts.runtimeRef ?? "tableRules", ...emitOpts }) : null;
|
|
16848
|
+
const runOnce = (input, pos, ctx) => entry(input, pos, ctx);
|
|
16849
|
+
return {
|
|
16850
|
+
source,
|
|
16851
|
+
inlineExpression,
|
|
16852
|
+
...printable ? {} : { runtimeOnly },
|
|
16853
|
+
// The DENOMINATOR, handed back rather than scraped out of the emitted text.
|
|
16854
|
+
// `plugin/index.ts` prefers a compiler-supplied `coverageDefinitions` and only
|
|
16855
|
+
// falls back to regex-scanning generated hooks; a table has no hooks to scan,
|
|
16856
|
+
// so this is the channel.
|
|
16857
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16858
|
+
parse(input, pos = 0) {
|
|
16859
|
+
return runOnce(input, pos, createParseContext());
|
|
16860
|
+
},
|
|
16861
|
+
parseWithContext(input, parseCtx, pos = 0) {
|
|
16862
|
+
return runOnce(input, pos, parseCtx);
|
|
16863
|
+
},
|
|
16864
|
+
/**
|
|
16865
|
+
* NO LONGER REFUSES. It used to throw unless the caller passed
|
|
16866
|
+
* `{ recovery: true }`, because setting `_tolerant` on a table with no
|
|
16867
|
+
* recovery rows would report a clean parse with an empty error list whatever
|
|
16868
|
+
* the input — refusing was the right answer to that, and OPTIONAL RECOVERY
|
|
16869
|
+
* was the wrong question. `compile()` requires no such flag, so the refusal
|
|
16870
|
+
* was a `CompiledParser` contract break; recovery is now always lowered and
|
|
16871
|
+
* there is nothing left to refuse.
|
|
16872
|
+
*/
|
|
16873
|
+
parseWithErrors(input, pos = 0) {
|
|
16874
|
+
const ctx = createParseContext();
|
|
16875
|
+
const errors = [];
|
|
16876
|
+
ctx._errors = errors;
|
|
16877
|
+
ctx._tolerant = true;
|
|
16878
|
+
const r = runOnce(input, pos, ctx);
|
|
16879
|
+
return { ...r, errors };
|
|
16880
|
+
}
|
|
16483
16881
|
};
|
|
16484
16882
|
}
|
|
16485
16883
|
|
|
@@ -16535,219 +16933,52 @@ var ruleNameOf3 = (c) => c._ruleName;
|
|
|
16535
16933
|
var balancedOf = (c) => c._balancedAmbient;
|
|
16536
16934
|
function lazyTarget(c) {
|
|
16537
16935
|
if (c._def.tag !== "lazy") return null;
|
|
16538
|
-
try {
|
|
16539
|
-
return c._def.thunk();
|
|
16540
|
-
} catch {
|
|
16541
|
-
return null;
|
|
16542
|
-
}
|
|
16543
|
-
}
|
|
16544
|
-
var Unserializable = class extends Error {
|
|
16545
|
-
};
|
|
16546
|
-
function repeatOpts(min, max, trailing) {
|
|
16547
|
-
const parts = [];
|
|
16548
|
-
if (min !== 0) parts.push(`min: ${min}`);
|
|
16549
|
-
if (max !== void 0) parts.push(`max: ${max}`);
|
|
16550
|
-
if (trailing !== void 0) parts.push(`trailing: ${JSON.stringify(trailing)}`);
|
|
16551
|
-
return parts.length === 0 ? "" : `, { ${parts.join(", ")} }`;
|
|
16552
|
-
}
|
|
16553
|
-
function projectOpt(project) {
|
|
16554
|
-
if (project === void 0) return void 0;
|
|
16555
|
-
return `project: ${project}`;
|
|
16556
|
-
}
|
|
16557
|
-
function tagsOpt(tags) {
|
|
16558
|
-
if (tags === void 0 || tags.length === 0) return void 0;
|
|
16559
|
-
return `tags: ${JSON.stringify(tags)}`;
|
|
16560
|
-
}
|
|
16561
|
-
function matcherExpr(entry) {
|
|
16562
|
-
switch (entry.kind) {
|
|
16563
|
-
case "startsWith":
|
|
16564
|
-
return `startsWith(${JSON.stringify(entry.value)})`;
|
|
16565
|
-
case "endsWith":
|
|
16566
|
-
return `endsWith(${JSON.stringify(entry.value)})`;
|
|
16567
|
-
case "matches":
|
|
16568
|
-
return `matches(${new RegExp(entry.value, entry.flags ?? "").toString()})`;
|
|
16569
|
-
}
|
|
16570
|
-
}
|
|
16571
|
-
function serializeRuleMap(ruleMap, scanSkip) {
|
|
16572
|
-
try {
|
|
16573
|
-
return new Serializer(ruleMap, scanSkip ?? []).run();
|
|
16574
|
-
} catch (e) {
|
|
16575
|
-
if (e instanceof Unserializable) {
|
|
16576
|
-
if (process.env.PARSEMAN_IR_DEBUG) console.error(`[ir] fallback: ${e.message}`);
|
|
16577
|
-
return null;
|
|
16578
|
-
}
|
|
16579
|
-
throw e;
|
|
16580
|
-
}
|
|
16581
|
-
}
|
|
16582
|
-
function
|
|
16583
|
-
|
|
16584
|
-
let fn2;
|
|
16585
|
-
try {
|
|
16586
|
-
fn2 = (0, eval)(`(${src})`);
|
|
16587
|
-
} catch {
|
|
16588
|
-
fn2 = () => {
|
|
16589
|
-
throw new Error("IR transform fn not materialized");
|
|
16590
|
-
};
|
|
16591
|
-
}
|
|
16592
|
-
const t = transform(child, fn2);
|
|
16593
|
-
t._def.fnSrc = src;
|
|
16594
|
-
if (recognitionOnly) t._def.recognitionOnly = true;
|
|
16595
|
-
return t;
|
|
16596
|
-
};
|
|
16597
|
-
const _lf = (child, src, source = false) => {
|
|
16598
|
-
let fn2;
|
|
16599
|
-
try {
|
|
16600
|
-
fn2 = (0, eval)(`(${src})`);
|
|
16601
|
-
} catch {
|
|
16602
|
-
fn2 = () => {
|
|
16603
|
-
throw new Error("IR leaf fn not materialized");
|
|
16604
|
-
};
|
|
16605
|
-
}
|
|
16606
|
-
const l = source ? sourceLeaf(child, fn2) : leaf(child, fn2);
|
|
16607
|
-
l._def.fnSrc = src;
|
|
16608
|
-
return l;
|
|
16609
|
-
};
|
|
16610
|
-
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
16611
|
-
if (staticError !== void 0 && staticError.length > 0) {
|
|
16612
|
-
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
16613
|
-
}
|
|
16614
|
-
const n = node(type, child, (() => {
|
|
16615
|
-
throw new Error("IR node build requires static re-lowering");
|
|
16616
|
-
}), opts);
|
|
16617
|
-
n._def.buildSrc = src;
|
|
16618
|
-
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
16619
|
-
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
16620
|
-
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
16621
|
-
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
16622
|
-
return n;
|
|
16623
|
-
};
|
|
16624
|
-
const _gch = (items) => {
|
|
16625
|
-
const gateSrcs = [];
|
|
16626
|
-
const arms = items.map((it) => {
|
|
16627
|
-
if (Array.isArray(it)) {
|
|
16628
|
-
const [src, comb] = it;
|
|
16629
|
-
gateSrcs.push(src);
|
|
16630
|
-
let gate2;
|
|
16631
|
-
try {
|
|
16632
|
-
gate2 = (0, eval)(`(${src})`);
|
|
16633
|
-
} catch {
|
|
16634
|
-
gate2 = () => {
|
|
16635
|
-
throw new Error("IR gate fn not materialized");
|
|
16636
|
-
};
|
|
16637
|
-
}
|
|
16638
|
-
return { gate: gate2, combinator: comb };
|
|
16639
|
-
}
|
|
16640
|
-
gateSrcs.push(null);
|
|
16641
|
-
return it;
|
|
16642
|
-
});
|
|
16643
|
-
const c = choice(...arms);
|
|
16644
|
-
const gates = c._def.gates;
|
|
16645
|
-
if (gates && gates.length !== gateSrcs.length) {
|
|
16646
|
-
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
16647
|
-
}
|
|
16648
|
-
;
|
|
16649
|
-
c._def.gateSrcs = gateSrcs;
|
|
16650
|
-
return c;
|
|
16651
|
-
};
|
|
16652
|
-
const _wc = (src, inner) => {
|
|
16653
|
-
let extra;
|
|
16654
|
-
try {
|
|
16655
|
-
extra = (0, eval)(`(${src})`);
|
|
16656
|
-
} catch {
|
|
16657
|
-
extra = void 0;
|
|
16658
|
-
}
|
|
16659
|
-
const w = withCtx(extra, inner);
|
|
16660
|
-
w._def.extraSrc = src;
|
|
16661
|
-
return w;
|
|
16662
|
-
};
|
|
16663
|
-
const fn = new Function(
|
|
16664
|
-
"rules",
|
|
16665
|
-
"ref",
|
|
16666
|
-
"regex",
|
|
16667
|
-
"literal",
|
|
16668
|
-
"keywords",
|
|
16669
|
-
"sequence",
|
|
16670
|
-
"choice",
|
|
16671
|
-
"dispatch",
|
|
16672
|
-
"when",
|
|
16673
|
-
"startsWith",
|
|
16674
|
-
"endsWith",
|
|
16675
|
-
"matches",
|
|
16676
|
-
"otherwise",
|
|
16677
|
-
"routed",
|
|
16678
|
-
"attempt",
|
|
16679
|
-
"many",
|
|
16680
|
-
"oneOrMore",
|
|
16681
|
-
"optional",
|
|
16682
|
-
"sepBy",
|
|
16683
|
-
"keepSeparator",
|
|
16684
|
-
"not",
|
|
16685
|
-
"peek",
|
|
16686
|
-
"node",
|
|
16687
|
-
"parser",
|
|
16688
|
-
"scanTo",
|
|
16689
|
-
"balanced",
|
|
16690
|
-
"token",
|
|
16691
|
-
"leaf",
|
|
16692
|
-
"transform",
|
|
16693
|
-
"trivia",
|
|
16694
|
-
"classifiedTrivia",
|
|
16695
|
-
"label",
|
|
16696
|
-
"field",
|
|
16697
|
-
"expect",
|
|
16698
|
-
"adjacent",
|
|
16699
|
-
"notAdjacent",
|
|
16700
|
-
"_tf",
|
|
16701
|
-
"_lf",
|
|
16702
|
-
"_nd",
|
|
16703
|
-
"_gch",
|
|
16704
|
-
"_wc",
|
|
16705
|
-
`return (${ir})`
|
|
16706
|
-
);
|
|
16707
|
-
const map = fn(
|
|
16708
|
-
rules,
|
|
16709
|
-
ref,
|
|
16710
|
-
regex,
|
|
16711
|
-
literal,
|
|
16712
|
-
keywords,
|
|
16713
|
-
sequence,
|
|
16714
|
-
choice,
|
|
16715
|
-
dispatch,
|
|
16716
|
-
when,
|
|
16717
|
-
startsWith,
|
|
16718
|
-
endsWith,
|
|
16719
|
-
matches,
|
|
16720
|
-
otherwise,
|
|
16721
|
-
routed,
|
|
16722
|
-
attempt,
|
|
16723
|
-
many,
|
|
16724
|
-
oneOrMore,
|
|
16725
|
-
optional,
|
|
16726
|
-
sepBy,
|
|
16727
|
-
keepSeparator,
|
|
16728
|
-
not,
|
|
16729
|
-
peek,
|
|
16730
|
-
node,
|
|
16731
|
-
parser,
|
|
16732
|
-
scanTo,
|
|
16733
|
-
balanced,
|
|
16734
|
-
token,
|
|
16735
|
-
leaf,
|
|
16736
|
-
transform,
|
|
16737
|
-
trivia,
|
|
16738
|
-
classifiedTrivia,
|
|
16739
|
-
label,
|
|
16740
|
-
field,
|
|
16741
|
-
expect,
|
|
16742
|
-
adjacent,
|
|
16743
|
-
notAdjacent,
|
|
16744
|
-
_tf,
|
|
16745
|
-
_lf,
|
|
16746
|
-
_nd,
|
|
16747
|
-
_gch,
|
|
16748
|
-
_wc
|
|
16749
|
-
);
|
|
16750
|
-
return Object.entries(map);
|
|
16936
|
+
try {
|
|
16937
|
+
return c._def.thunk();
|
|
16938
|
+
} catch {
|
|
16939
|
+
return null;
|
|
16940
|
+
}
|
|
16941
|
+
}
|
|
16942
|
+
var Unserializable = class extends Error {
|
|
16943
|
+
};
|
|
16944
|
+
function repeatOpts(min, max, trailing) {
|
|
16945
|
+
const parts = [];
|
|
16946
|
+
if (min !== 0) parts.push(`min: ${min}`);
|
|
16947
|
+
if (max !== void 0) parts.push(`max: ${max}`);
|
|
16948
|
+
if (trailing !== void 0) parts.push(`trailing: ${JSON.stringify(trailing)}`);
|
|
16949
|
+
return parts.length === 0 ? "" : `, { ${parts.join(", ")} }`;
|
|
16950
|
+
}
|
|
16951
|
+
function projectOpt(project) {
|
|
16952
|
+
if (project === void 0) return void 0;
|
|
16953
|
+
return `project: ${project}`;
|
|
16954
|
+
}
|
|
16955
|
+
function tagsOpt(tags) {
|
|
16956
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
16957
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
16958
|
+
}
|
|
16959
|
+
function matcherExpr(entry) {
|
|
16960
|
+
switch (entry.kind) {
|
|
16961
|
+
case "startsWith":
|
|
16962
|
+
return `startsWith(${JSON.stringify(entry.value)})`;
|
|
16963
|
+
case "endsWith":
|
|
16964
|
+
return `endsWith(${JSON.stringify(entry.value)})`;
|
|
16965
|
+
case "matches":
|
|
16966
|
+
return `matches(${new RegExp(entry.value, entry.flags ?? "").toString()})`;
|
|
16967
|
+
}
|
|
16968
|
+
}
|
|
16969
|
+
function serializeRuleMap(ruleMap, scanSkip) {
|
|
16970
|
+
try {
|
|
16971
|
+
return new Serializer(ruleMap, scanSkip ?? []).run();
|
|
16972
|
+
} catch (e) {
|
|
16973
|
+
if (e instanceof Unserializable) {
|
|
16974
|
+
if (process.env.PARSEMAN_IR_DEBUG) console.error(`[ir] fallback: ${e.message}`);
|
|
16975
|
+
return null;
|
|
16976
|
+
}
|
|
16977
|
+
throw e;
|
|
16978
|
+
}
|
|
16979
|
+
}
|
|
16980
|
+
function serializeCombinator(c) {
|
|
16981
|
+
return serializeRuleMap([], [c]);
|
|
16751
16982
|
}
|
|
16752
16983
|
var Serializer = class {
|
|
16753
16984
|
counts = /* @__PURE__ */ new Map();
|
|
@@ -17011,7 +17242,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17011
17242
|
case "label":
|
|
17012
17243
|
return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
|
|
17013
17244
|
case "field":
|
|
17014
|
-
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
|
|
17245
|
+
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)}${fieldOptionsSrc(def)})`;
|
|
17015
17246
|
case "expect":
|
|
17016
17247
|
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
17017
17248
|
case "scanTo":
|
|
@@ -17074,128 +17305,13 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17074
17305
|
}
|
|
17075
17306
|
}
|
|
17076
17307
|
};
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
function resolveHostMode(ruleMap, explicit) {
|
|
17081
|
-
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
17082
|
-
}
|
|
17083
|
-
function resolveTrackLines(ruleMap, explicit) {
|
|
17084
|
-
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
17085
|
-
}
|
|
17086
|
-
function withAmbient(ruleMap, opts) {
|
|
17087
|
-
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
17088
|
-
const wrappers = /* @__PURE__ */ new Map();
|
|
17089
|
-
return ruleMap.map(([name, rule]) => {
|
|
17090
|
-
if (rule._meta.isTrivia) return [name, rule];
|
|
17091
|
-
const addTrivia = opts.trivia !== void 0 && rule._meta.grammarTrivia === void 0;
|
|
17092
|
-
const addScanSkip = opts.scanSkip !== void 0 && rule._meta.grammarScanSkip === void 0;
|
|
17093
|
-
if (!addTrivia && !addScanSkip) return [name, rule];
|
|
17094
|
-
let wrapped = wrappers.get(rule);
|
|
17095
|
-
if (wrapped === void 0) {
|
|
17096
|
-
wrapped = {
|
|
17097
|
-
...rule,
|
|
17098
|
-
_meta: {
|
|
17099
|
-
...rule._meta,
|
|
17100
|
-
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
17101
|
-
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
17102
|
-
}
|
|
17103
|
-
};
|
|
17104
|
-
wrappers.set(rule, wrapped);
|
|
17105
|
-
}
|
|
17106
|
-
return [name, wrapped];
|
|
17107
|
-
});
|
|
17108
|
-
}
|
|
17109
|
-
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
17110
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
17111
|
-
if (encoded === null) return null;
|
|
17112
|
-
const { prog, hostMode, plan } = encoded;
|
|
17113
|
-
const artifact = closureArtifact(prog);
|
|
17114
|
-
return {
|
|
17115
|
-
keys: ruleMap.map(([key]) => key),
|
|
17116
|
-
hostMode,
|
|
17117
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
17118
|
-
reflection: collectGrammarReflection(ruleMap),
|
|
17119
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
17120
|
-
rules: tableRules(prog),
|
|
17121
|
-
prog: artifact
|
|
17122
|
-
};
|
|
17123
|
-
}
|
|
17124
|
-
function encodeForRun(ruleMap, opts) {
|
|
17125
|
-
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
17126
|
-
const encodeMap = withAmbient(ruleMap, opts);
|
|
17127
|
-
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
17128
|
-
encodeMap.map(([, rule]) => rule),
|
|
17129
|
-
Object.fromEntries(encodeMap.filter(([, rule]) => rule._def.tag !== "lazy"))
|
|
17130
|
-
) : void 0;
|
|
17131
|
-
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
17132
|
-
const settings = {
|
|
17133
|
-
hostMode,
|
|
17134
|
-
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
17135
|
-
...opts.recovery === true ? { recovery: true } : {},
|
|
17136
|
-
...plan === void 0 ? {} : { coverage: plan }
|
|
17137
|
-
};
|
|
17138
|
-
try {
|
|
17139
|
-
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
17140
|
-
return { prog, fnSrcs, hostMode, plan };
|
|
17141
|
-
} catch (e) {
|
|
17142
|
-
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
17143
|
-
return null;
|
|
17144
|
-
}
|
|
17145
|
-
}
|
|
17146
|
-
function compileRuleMap(ruleMap, opts = {}) {
|
|
17147
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
17148
|
-
if (encoded === null) return null;
|
|
17149
|
-
const { prog, fnSrcs, hostMode, plan } = encoded;
|
|
17150
|
-
const artifact = closureArtifact(prog);
|
|
17151
|
-
if (artifact.runtimeOnly !== void 0 && artifact.runtimeOnly.length > 0) {
|
|
17152
|
-
opts.refusals?.push(...artifact.runtimeOnly);
|
|
17153
|
-
return null;
|
|
17154
|
-
}
|
|
17155
|
-
const supplied = opts.fnSources;
|
|
17156
|
-
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? null);
|
|
17157
|
-
if (sources.some((s) => s === null)) {
|
|
17158
|
-
const missing = sources.flatMap((s, i) => s === null ? [i] : []);
|
|
17159
|
-
opts.refusals?.push(
|
|
17160
|
-
`author reducer source missing for prog.fns[${missing.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`
|
|
17161
|
-
);
|
|
17162
|
-
return null;
|
|
17163
|
-
}
|
|
17164
|
-
if (supplied !== void 0 && supplied.length > fnSrcs.length) {
|
|
17165
|
-
throw new Error(
|
|
17166
|
-
`compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
|
|
17167
|
-
);
|
|
17168
|
-
}
|
|
17169
|
-
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
17170
|
-
entry: null,
|
|
17171
|
-
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
17172
|
-
fnSources: sources,
|
|
17173
|
-
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
17174
|
-
...metadataSource === void 0 ? {} : { metadataSource }
|
|
17175
|
-
});
|
|
17176
|
-
const replacement = replacementWithMetadata();
|
|
17177
|
-
return {
|
|
17178
|
-
keys: ruleMap.map(([key]) => key),
|
|
17179
|
-
replacement,
|
|
17180
|
-
replacementWithMetadata,
|
|
17181
|
-
hostMode,
|
|
17182
|
-
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
17183
|
-
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
17184
|
-
// off. `mode === 'ast'` alone over-reports it: an all-STRUCTURAL grammar has no
|
|
17185
|
-
// direct builder, so there was no branch to drop and it stays usable with either
|
|
17186
|
-
// host — the long-standing `node(parser)` contract. Same predicate codegen uses
|
|
17187
|
-
// for its own `hasDirectBuilders` (both read `analysis/commitment.ts`), so the two
|
|
17188
|
-
// lowerings stamp the same artifact rather than disagreeing about it.
|
|
17189
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
17190
|
-
reflection: collectGrammarReflection(ruleMap),
|
|
17191
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
17192
|
-
rules: tableRules(prog),
|
|
17193
|
-
prog: artifact
|
|
17194
|
-
};
|
|
17308
|
+
function fieldOptionsSrc(def) {
|
|
17309
|
+
if (def.leadingTrivia !== true && def.trailingTrivia !== true) return "";
|
|
17310
|
+
return `, { ${[def.leadingTrivia === true ? "leadingTrivia: true" : "", def.trailingTrivia === true ? "trailingTrivia: true" : ""].filter(Boolean).join(", ")} }`;
|
|
17195
17311
|
}
|
|
17196
17312
|
|
|
17197
17313
|
// src/version.ts
|
|
17198
|
-
var PARSEMAN_VERSION = "0.
|
|
17314
|
+
var PARSEMAN_VERSION = "0.54.0";
|
|
17199
17315
|
|
|
17200
17316
|
// src/compiler/compile-linkable-table.ts
|
|
17201
17317
|
function isLocal(rule) {
|
|
@@ -17307,6 +17423,29 @@ function gate(predicate) {
|
|
|
17307
17423
|
};
|
|
17308
17424
|
}
|
|
17309
17425
|
|
|
17426
|
+
// src/combinators/withCtx.ts
|
|
17427
|
+
function withCtx(extra, combinator) {
|
|
17428
|
+
const meta = {
|
|
17429
|
+
firstSet: combinator._meta.firstSet,
|
|
17430
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
17431
|
+
isTrivia: false
|
|
17432
|
+
};
|
|
17433
|
+
return {
|
|
17434
|
+
_tag: "withCtx",
|
|
17435
|
+
_meta: meta,
|
|
17436
|
+
_def: { tag: "withCtx", extra, parser: combinator },
|
|
17437
|
+
parse(input, pos, ctx) {
|
|
17438
|
+
const saved = ctx.state;
|
|
17439
|
+
ctx.state = extra;
|
|
17440
|
+
try {
|
|
17441
|
+
return combinator.parse(input, pos, ctx);
|
|
17442
|
+
} finally {
|
|
17443
|
+
ctx.state = saved;
|
|
17444
|
+
}
|
|
17445
|
+
}
|
|
17446
|
+
};
|
|
17447
|
+
}
|
|
17448
|
+
|
|
17310
17449
|
// src/plugin/direct-builder-static.ts
|
|
17311
17450
|
import { parseSync } from "oxc-parser";
|
|
17312
17451
|
var STATIC_BUILDER_GLOBALS = /* @__PURE__ */ new Set([
|
|
@@ -17592,6 +17731,41 @@ var _builderImports = null;
|
|
|
17592
17731
|
function setBuilderImportResolver(r) {
|
|
17593
17732
|
_builderImports = r;
|
|
17594
17733
|
}
|
|
17734
|
+
var ModuleScope = class _ModuleScope extends Map {
|
|
17735
|
+
tried = /* @__PURE__ */ new Map();
|
|
17736
|
+
resolveFree;
|
|
17737
|
+
unresolved;
|
|
17738
|
+
constructor(resolveFree, unresolved) {
|
|
17739
|
+
super();
|
|
17740
|
+
this.resolveFree = resolveFree;
|
|
17741
|
+
this.unresolved = unresolved;
|
|
17742
|
+
}
|
|
17743
|
+
has(name) {
|
|
17744
|
+
return super.has(name) || this.resolve(name);
|
|
17745
|
+
}
|
|
17746
|
+
get(name) {
|
|
17747
|
+
if (super.has(name) || this.resolve(name)) return super.get(name);
|
|
17748
|
+
const why = this.tried.get(name);
|
|
17749
|
+
if (why !== void 0) this.unresolved.add(`\`${name}\` ${why}`);
|
|
17750
|
+
return void 0;
|
|
17751
|
+
}
|
|
17752
|
+
/** A child scope (a factory body) that keeps resolving this module's free names. */
|
|
17753
|
+
fork() {
|
|
17754
|
+
const child = new _ModuleScope(this.resolveFree, this.unresolved);
|
|
17755
|
+
for (const [k, v] of super.entries()) child.set(k, v);
|
|
17756
|
+
return child;
|
|
17757
|
+
}
|
|
17758
|
+
resolve(name) {
|
|
17759
|
+
if (this.tried.has(name)) return false;
|
|
17760
|
+
const r = this.resolveFree(name);
|
|
17761
|
+
if (r !== null && "value" in r) {
|
|
17762
|
+
super.set(name, r.value);
|
|
17763
|
+
return true;
|
|
17764
|
+
}
|
|
17765
|
+
if (r !== null) this.tried.set(name, r.unresolved);
|
|
17766
|
+
return false;
|
|
17767
|
+
}
|
|
17768
|
+
};
|
|
17595
17769
|
function isWordFactory(v) {
|
|
17596
17770
|
return !!v && typeof v === "object" && v.tag === "wordFactory";
|
|
17597
17771
|
}
|
|
@@ -17651,7 +17825,7 @@ var SUPPORTED = {
|
|
|
17651
17825
|
a[0]
|
|
17652
17826
|
),
|
|
17653
17827
|
label: (...a) => label(a[0], a[1]),
|
|
17654
|
-
field: (...a) => field(a[0], a[1]),
|
|
17828
|
+
field: (...a) => field(a[0], a[1], a[2]),
|
|
17655
17829
|
noTrivia: (...a) => noTrivia(a[0]),
|
|
17656
17830
|
token: (...a) => token(a[0]),
|
|
17657
17831
|
// `routed(fallback)` — the fallback must be forwarded. A zero-arg entry here read
|
|
@@ -17715,7 +17889,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17715
17889
|
if (!keyArg || !parserArg || extraArg !== void 0 || keyArg.type === "SpreadElement" || parserArg.type === "SpreadElement") return null;
|
|
17716
17890
|
const key = anyValue(keyArg, scope, code, mfs);
|
|
17717
17891
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17718
|
-
if (!
|
|
17892
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17719
17893
|
const opts = { caseInsensitive: factory.caseInsensitive };
|
|
17720
17894
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17721
17895
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
@@ -17726,7 +17900,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17726
17900
|
const [parserArg] = node2.arguments;
|
|
17727
17901
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17728
17902
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17729
|
-
if (!
|
|
17903
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17730
17904
|
return otherwise(parserValue);
|
|
17731
17905
|
}
|
|
17732
17906
|
if (callee.name === "when") {
|
|
@@ -17736,24 +17910,24 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17736
17910
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17737
17911
|
const opts = dispatchWhenOptions(optsArg === void 0 ? void 0 : anyValue(optsArg, scope, code, mfs));
|
|
17738
17912
|
if (opts === null) return null;
|
|
17739
|
-
if (!
|
|
17913
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17740
17914
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17741
17915
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
17742
17916
|
if (isDispatchMatcher(key)) return when(key, parserValue, opts);
|
|
17743
17917
|
}
|
|
17744
17918
|
return null;
|
|
17745
17919
|
}
|
|
17746
|
-
function
|
|
17920
|
+
function isCombinator2(v) {
|
|
17747
17921
|
return !!v && typeof v === "object" && "_def" in v;
|
|
17748
17922
|
}
|
|
17749
17923
|
function isDispatchArm(v) {
|
|
17750
17924
|
if (!v || typeof v !== "object") return false;
|
|
17751
17925
|
const rec = v;
|
|
17752
|
-
if (rec.kind === "otherwise") return
|
|
17926
|
+
if (rec.kind === "otherwise") return isCombinator2(rec.parser);
|
|
17753
17927
|
if (rec.kind === "whenMatcher") {
|
|
17754
|
-
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" &&
|
|
17928
|
+
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17755
17929
|
}
|
|
17756
|
-
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" &&
|
|
17930
|
+
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17757
17931
|
}
|
|
17758
17932
|
function isDispatchMatcher(v) {
|
|
17759
17933
|
if (!v || typeof v !== "object") return false;
|
|
@@ -17768,7 +17942,7 @@ function scopeGet(scope, name, mfs) {
|
|
|
17768
17942
|
if (mfs && entry.mfSrcs.length > 0) mfs.push(...entry.mfSrcs);
|
|
17769
17943
|
return entry.combi;
|
|
17770
17944
|
}
|
|
17771
|
-
if (
|
|
17945
|
+
if (isCombinator2(entry)) return entry;
|
|
17772
17946
|
return null;
|
|
17773
17947
|
}
|
|
17774
17948
|
function unwrapStaticExpr(expr) {
|
|
@@ -17820,7 +17994,7 @@ function scopedStaticValue(expr, scope) {
|
|
|
17820
17994
|
return { found: true, value };
|
|
17821
17995
|
}
|
|
17822
17996
|
function staticNodeOptionsFromValue(value) {
|
|
17823
|
-
if (value === null || typeof value !== "object" || Array.isArray(value) ||
|
|
17997
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator2(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
17824
17998
|
const opts = {};
|
|
17825
17999
|
const rec = value;
|
|
17826
18000
|
for (const name of Object.keys(rec)) {
|
|
@@ -17872,6 +18046,13 @@ function staticNodeOptions(expr, scope) {
|
|
|
17872
18046
|
}
|
|
17873
18047
|
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 || opts.buildArity !== void 0 ? opts : void 0;
|
|
17874
18048
|
}
|
|
18049
|
+
var UNKNOWN_OPTIONS = /* @__PURE__ */ Symbol("parseman.unknownOptions");
|
|
18050
|
+
function scanOptions(optsArg, scope, code) {
|
|
18051
|
+
if (optsArg === void 0) return void 0;
|
|
18052
|
+
if (optsArg.type === "SpreadElement") return UNKNOWN_OPTIONS;
|
|
18053
|
+
const opts = anyValue(optsArg, scope, code, []);
|
|
18054
|
+
return isHole(optsArg, opts, scope) ? UNKNOWN_OPTIONS : opts;
|
|
18055
|
+
}
|
|
17875
18056
|
function exprToCombi(node2, scope, code, mfs) {
|
|
17876
18057
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
17877
18058
|
if (node2.type !== "CallExpression") return null;
|
|
@@ -17907,7 +18088,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17907
18088
|
const [parserArg, fnArg] = node2.arguments;
|
|
17908
18089
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17909
18090
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17910
|
-
if (!
|
|
18091
|
+
if (!isCombinator2(inner)) return null;
|
|
17911
18092
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17912
18093
|
mfs.push(fnSrc);
|
|
17913
18094
|
try {
|
|
@@ -17922,7 +18103,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17922
18103
|
const [parserArg, fnArg] = node2.arguments;
|
|
17923
18104
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17924
18105
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17925
|
-
if (!
|
|
18106
|
+
if (!isCombinator2(inner)) return null;
|
|
17926
18107
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17927
18108
|
mfs.push(fnSrc);
|
|
17928
18109
|
try {
|
|
@@ -17943,7 +18124,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17943
18124
|
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
17944
18125
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17945
18126
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17946
|
-
if (!
|
|
18127
|
+
if (!isCombinator2(inner)) return null;
|
|
17947
18128
|
const be = buildArg;
|
|
17948
18129
|
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
17949
18130
|
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
@@ -18017,7 +18198,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18017
18198
|
const opts = anyValue(optsArg, scope, code, []);
|
|
18018
18199
|
if (!opts || typeof opts !== "object") return null;
|
|
18019
18200
|
const root = anyValue(rootArg, scope, code, mfs);
|
|
18020
|
-
if (!
|
|
18201
|
+
if (!isCombinator2(root)) return null;
|
|
18021
18202
|
try {
|
|
18022
18203
|
return parser(opts, root);
|
|
18023
18204
|
} catch {
|
|
@@ -18029,10 +18210,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18029
18210
|
if (!itemArg || !sepArg || itemArg.type === "SpreadElement" || sepArg.type === "SpreadElement") return null;
|
|
18030
18211
|
const itemMfs = [];
|
|
18031
18212
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18032
|
-
if (!
|
|
18213
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18033
18214
|
const sepMfs = [];
|
|
18034
18215
|
const sepCombi = anyValue(sepArg, scope, code, sepMfs);
|
|
18035
|
-
if (!
|
|
18216
|
+
if (!isCombinator2(sepCombi)) return null;
|
|
18036
18217
|
let opts;
|
|
18037
18218
|
if (optsArg) {
|
|
18038
18219
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18052,7 +18233,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18052
18233
|
if (!itemArg || itemArg.type === "SpreadElement") return null;
|
|
18053
18234
|
const itemMfs = [];
|
|
18054
18235
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18055
|
-
if (!
|
|
18236
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18056
18237
|
let opts;
|
|
18057
18238
|
if (optsArg) {
|
|
18058
18239
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18074,7 +18255,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18074
18255
|
const [innerArg] = node2.arguments;
|
|
18075
18256
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18076
18257
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18077
|
-
if (!
|
|
18258
|
+
if (!isCombinator2(inner)) return null;
|
|
18078
18259
|
try {
|
|
18079
18260
|
return not(inner);
|
|
18080
18261
|
} catch {
|
|
@@ -18085,7 +18266,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18085
18266
|
const [innerArg] = node2.arguments;
|
|
18086
18267
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18087
18268
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18088
|
-
if (!
|
|
18269
|
+
if (!isCombinator2(inner)) return null;
|
|
18089
18270
|
try {
|
|
18090
18271
|
return peek(inner);
|
|
18091
18272
|
} catch {
|
|
@@ -18098,7 +18279,8 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18098
18279
|
const open = anyValue(openArg, scope, code, []);
|
|
18099
18280
|
const close = anyValue(closeArg, scope, code, []);
|
|
18100
18281
|
if (typeof open !== "string" || typeof close !== "string") return null;
|
|
18101
|
-
const opts =
|
|
18282
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18283
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18102
18284
|
try {
|
|
18103
18285
|
return balanced(open, close, opts);
|
|
18104
18286
|
} catch {
|
|
@@ -18109,8 +18291,9 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18109
18291
|
const [sentinelArg, optsArg] = node2.arguments;
|
|
18110
18292
|
if (!sentinelArg || sentinelArg.type === "SpreadElement") return null;
|
|
18111
18293
|
const sentinel = anyValue(sentinelArg, scope, code, []);
|
|
18112
|
-
if (!
|
|
18113
|
-
const opts =
|
|
18294
|
+
if (!isCombinator2(sentinel)) return null;
|
|
18295
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18296
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18114
18297
|
try {
|
|
18115
18298
|
return scanTo(sentinel, opts);
|
|
18116
18299
|
} catch {
|
|
@@ -18139,7 +18322,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18139
18322
|
const extraSrc = stripTsFromSource(extraArg, code);
|
|
18140
18323
|
mfs.push(extraSrc);
|
|
18141
18324
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18142
|
-
if (!
|
|
18325
|
+
if (!isCombinator2(inner)) return null;
|
|
18143
18326
|
try {
|
|
18144
18327
|
const evaluated = anyValue(extraArg, scope, code, []);
|
|
18145
18328
|
const usable = typeof evaluated === "object" && evaluated !== null && !Array.isArray(evaluated) && Object.getPrototypeOf(evaluated) === Object.prototype;
|
|
@@ -18155,7 +18338,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18155
18338
|
const [selectorArg, ...armArgs] = node2.arguments;
|
|
18156
18339
|
if (!selectorArg || selectorArg.type === "SpreadElement") return null;
|
|
18157
18340
|
const selector = anyValue(selectorArg, scope, code, mfs);
|
|
18158
|
-
if (!
|
|
18341
|
+
if (!isCombinator2(selector)) return null;
|
|
18159
18342
|
const arms = [];
|
|
18160
18343
|
for (const arg of armArgs) {
|
|
18161
18344
|
if (arg.type === "SpreadElement") return null;
|
|
@@ -18182,12 +18365,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18182
18365
|
const gateSrc = stripTsFromSource(parts.gate, code);
|
|
18183
18366
|
mfs.push(gateSrc);
|
|
18184
18367
|
const combi = anyValue(parts.combinator, scope, code, mfs);
|
|
18185
|
-
if (!
|
|
18368
|
+
if (!isCombinator2(combi)) return null;
|
|
18186
18369
|
arms.push({ gate: () => true, combinator: combi });
|
|
18187
18370
|
gateSrcs.push(gateSrc);
|
|
18188
18371
|
} else {
|
|
18189
18372
|
const combi = anyValue(argNode, scope, code, mfs);
|
|
18190
|
-
if (!
|
|
18373
|
+
if (!isCombinator2(combi)) return null;
|
|
18191
18374
|
arms.push(combi);
|
|
18192
18375
|
gateSrcs.push(null);
|
|
18193
18376
|
}
|
|
@@ -18217,6 +18400,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18217
18400
|
return null;
|
|
18218
18401
|
}
|
|
18219
18402
|
}
|
|
18403
|
+
function isHole(node2, value, scope) {
|
|
18404
|
+
if (value !== null) return false;
|
|
18405
|
+
const n = unwrapStaticExpr(node2);
|
|
18406
|
+
if (n.type === "Identifier") return !scope.has(n.name);
|
|
18407
|
+
return !(n.type === "Literal" && n.value === null) && n.type !== "ArrowFunctionExpression" && n.type !== "FunctionExpression";
|
|
18408
|
+
}
|
|
18220
18409
|
function anyValue(node2, scope, code, mfs) {
|
|
18221
18410
|
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
18222
18411
|
const inner = node2.expression;
|
|
@@ -18237,7 +18426,9 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18237
18426
|
continue;
|
|
18238
18427
|
}
|
|
18239
18428
|
if (el.type === "SpreadElement") return null;
|
|
18240
|
-
|
|
18429
|
+
const v = anyValue(el, scope, code, mfs);
|
|
18430
|
+
if (isHole(el, v, scope)) return null;
|
|
18431
|
+
out.push(v);
|
|
18241
18432
|
}
|
|
18242
18433
|
return out;
|
|
18243
18434
|
}
|
|
@@ -18246,7 +18437,10 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18246
18437
|
for (const prop of node2.properties) {
|
|
18247
18438
|
const key = propName(prop);
|
|
18248
18439
|
if (key === null) return null;
|
|
18249
|
-
|
|
18440
|
+
const valueNode = prop.value;
|
|
18441
|
+
const v = anyValue(valueNode, scope, code, mfs);
|
|
18442
|
+
if (isHole(valueNode, v, scope)) return null;
|
|
18443
|
+
obj[key] = v;
|
|
18250
18444
|
}
|
|
18251
18445
|
return obj;
|
|
18252
18446
|
}
|
|
@@ -18322,10 +18516,9 @@ function evaluateExpr(node2, scope, code, mapFnSources) {
|
|
|
18322
18516
|
return exprToCombi(node2, scope, code, mapFnSources);
|
|
18323
18517
|
}
|
|
18324
18518
|
function evaluateCombinatorArray(node2, scope, code) {
|
|
18325
|
-
if (node2.type !== "ArrayExpression") return null;
|
|
18326
18519
|
const val = anyValue(node2, scope, code, []);
|
|
18327
18520
|
if (!Array.isArray(val) || val.length === 0) return null;
|
|
18328
|
-
if (!val.every(
|
|
18521
|
+
if (!val.every(isCombinator2)) return null;
|
|
18329
18522
|
return val;
|
|
18330
18523
|
}
|
|
18331
18524
|
function collectRuleKeys(retObj) {
|
|
@@ -18403,7 +18596,7 @@ function evalBodyStatements(statements, scope, code, out) {
|
|
|
18403
18596
|
return false;
|
|
18404
18597
|
}
|
|
18405
18598
|
const thisDeclMfSrcs = bodyMfs.slice(before);
|
|
18406
|
-
if (
|
|
18599
|
+
if (isCombinator2(val)) scope.set(name, { combi: val, mfSrcs: thisDeclMfSrcs });
|
|
18407
18600
|
else if (isDispatchArm(val)) scope.set(name, { value: val, mfSrcs: thisDeclMfSrcs });
|
|
18408
18601
|
else scope.set(name, val);
|
|
18409
18602
|
}
|
|
@@ -18448,7 +18641,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18448
18641
|
let built;
|
|
18449
18642
|
try {
|
|
18450
18643
|
built = rules(options ?? {}, (g) => {
|
|
18451
|
-
const localScope = new Map(scope);
|
|
18644
|
+
const localScope = scope instanceof ModuleScope ? scope.fork() : new Map(scope);
|
|
18452
18645
|
localScope.set(proxyName, g);
|
|
18453
18646
|
if (!evalBodyStatements(statements, localScope, code, out)) throw ABORT;
|
|
18454
18647
|
const entries = flattenRuleEntries(retObj, localScope, code);
|
|
@@ -18458,7 +18651,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18458
18651
|
const definitions = {};
|
|
18459
18652
|
for (const [key, e] of finalByKey) {
|
|
18460
18653
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
18461
|
-
if (!
|
|
18654
|
+
if (!isCombinator2(val)) throw ABORT;
|
|
18462
18655
|
definitions[key] = val;
|
|
18463
18656
|
}
|
|
18464
18657
|
return definitions;
|
|
@@ -18473,7 +18666,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18473
18666
|
return map;
|
|
18474
18667
|
}
|
|
18475
18668
|
function isDefinableRef2(v) {
|
|
18476
|
-
return
|
|
18669
|
+
return isCombinator2(v) && typeof v.define === "function" && v._def.tag === "lazy";
|
|
18477
18670
|
}
|
|
18478
18671
|
function evaluateRefDeclaration(init, name, scope) {
|
|
18479
18672
|
if (init.type !== "CallExpression") return null;
|
|
@@ -18493,12 +18686,12 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18493
18686
|
if (mem.property.type !== "Identifier" || mem.property.name !== "define") return false;
|
|
18494
18687
|
if (mem.object.type !== "Identifier" || !mem.object.name) return false;
|
|
18495
18688
|
const target = scope.get(mem.object.name);
|
|
18496
|
-
const refCombi = isScopeEntry(target) ? target.combi :
|
|
18689
|
+
const refCombi = isScopeEntry(target) ? target.combi : isCombinator2(target) ? target : null;
|
|
18497
18690
|
if (!refCombi || !isDefinableRef2(refCombi)) return false;
|
|
18498
18691
|
const args = callExpr.arguments;
|
|
18499
18692
|
if (args.length !== 1 || args[0].type === "SpreadElement") return false;
|
|
18500
18693
|
const inner = anyValue(args[0], scope, code, []);
|
|
18501
|
-
if (!
|
|
18694
|
+
if (!isCombinator2(inner)) return false;
|
|
18502
18695
|
try {
|
|
18503
18696
|
refCombi.define(inner);
|
|
18504
18697
|
} catch {
|
|
@@ -18508,7 +18701,7 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18508
18701
|
}
|
|
18509
18702
|
function referencesAny(node2, names, scope) {
|
|
18510
18703
|
if (node2.type === "Identifier") {
|
|
18511
|
-
return names.has(node2.name) ||
|
|
18704
|
+
return names.has(node2.name) || Map.prototype.has.call(scope, node2.name);
|
|
18512
18705
|
}
|
|
18513
18706
|
for (const key of Object.keys(node2)) {
|
|
18514
18707
|
const child = node2[key];
|
|
@@ -18569,7 +18762,9 @@ function patternNames(pat, out) {
|
|
|
18569
18762
|
}
|
|
18570
18763
|
}
|
|
18571
18764
|
function declare(scope, name, b) {
|
|
18572
|
-
|
|
18765
|
+
const prev = scope.bindings.get(name);
|
|
18766
|
+
if (prev) prev.reassigned = true;
|
|
18767
|
+
else scope.bindings.set(name, b);
|
|
18573
18768
|
}
|
|
18574
18769
|
function functionScope(scope) {
|
|
18575
18770
|
let s = scope;
|
|
@@ -18669,7 +18864,8 @@ function markReassignments(body, root) {
|
|
|
18669
18864
|
}
|
|
18670
18865
|
const node2 = n;
|
|
18671
18866
|
if (typeof node2.type !== "string") return;
|
|
18672
|
-
|
|
18867
|
+
const loopWrite = (node2.type === "ForOfStatement" || node2.type === "ForInStatement") && node2.left?.type !== "VariableDeclaration";
|
|
18868
|
+
if (node2.type === "AssignmentExpression" || node2.type === "UpdateExpression" || loopWrite) {
|
|
18673
18869
|
const target = node2.type === "UpdateExpression" ? node2.argument : node2.left;
|
|
18674
18870
|
const names = [];
|
|
18675
18871
|
if (target) patternNames(target, names);
|
|
@@ -18685,6 +18881,11 @@ function markReassignments(body, root) {
|
|
|
18685
18881
|
};
|
|
18686
18882
|
for (const stmt of body) walk(stmt);
|
|
18687
18883
|
}
|
|
18884
|
+
function topLevelIsStable(body, moduleEnd) {
|
|
18885
|
+
const root = buildScopeTree(body, moduleEnd);
|
|
18886
|
+
markReassignments(body, root);
|
|
18887
|
+
return (name) => root.bindings.get(name)?.reassigned !== true;
|
|
18888
|
+
}
|
|
18688
18889
|
function functionArity(fn) {
|
|
18689
18890
|
const params = fn.params ?? [];
|
|
18690
18891
|
let count = 0;
|
|
@@ -19137,7 +19338,7 @@ function ast(value) {
|
|
|
19137
19338
|
function nodes(value) {
|
|
19138
19339
|
return Array.isArray(value) ? value.filter((v) => ast(v) !== void 0) : [];
|
|
19139
19340
|
}
|
|
19140
|
-
function
|
|
19341
|
+
function nameOf2(node2) {
|
|
19141
19342
|
return node2?.type === "Identifier" && typeof node2.name === "string" ? node2.name : void 0;
|
|
19142
19343
|
}
|
|
19143
19344
|
function range(node2) {
|
|
@@ -19170,7 +19371,7 @@ function isDirectCallUse(call, parent, statement) {
|
|
|
19170
19371
|
return declarations.length === 1 && declarations[0] === parent && parent.init === call;
|
|
19171
19372
|
}
|
|
19172
19373
|
if (parent.type === "AssignmentExpression") {
|
|
19173
|
-
return statement.type === "ExpressionStatement" && statement.expression === parent &&
|
|
19374
|
+
return statement.type === "ExpressionStatement" && statement.expression === parent && nameOf2(ast(parent.left)) !== void 0 && parent.right === call && parent.operator === "=";
|
|
19174
19375
|
}
|
|
19175
19376
|
if (parent.type === "ReturnStatement") return statement === parent && parent.argument === call;
|
|
19176
19377
|
return false;
|
|
@@ -19188,7 +19389,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19188
19389
|
if (node2.type === "Identifier" && node2.name === "arguments") hazard = true;
|
|
19189
19390
|
else if (node2.type === "ThisExpression") hazard = true;
|
|
19190
19391
|
else if (node2.type === "VariableDeclaration" && node2.kind === "var") hazard = true;
|
|
19191
|
-
else if (node2.type === "MetaProperty" &&
|
|
19392
|
+
else if (node2.type === "MetaProperty" && nameOf2(ast(node2.meta)) === "new" && nameOf2(ast(node2.property)) === "target") hazard = true;
|
|
19192
19393
|
else for (const child of children2(node2)) walk(child);
|
|
19193
19394
|
};
|
|
19194
19395
|
walk(fn.body);
|
|
@@ -19196,7 +19397,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19196
19397
|
}
|
|
19197
19398
|
function hasInlineSignature(fn) {
|
|
19198
19399
|
const params = nodes(fn.node.params);
|
|
19199
|
-
return params.length === 3 &&
|
|
19400
|
+
return params.length === 3 && nameOf2(params[0]) === "input" && nameOf2(params[1]) === "pos" && nameOf2(params[2]) === "ctx";
|
|
19200
19401
|
}
|
|
19201
19402
|
function render2(source, start, end, edits) {
|
|
19202
19403
|
const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
@@ -19289,7 +19490,7 @@ function supercompileRuleMapReplacement(prog, replacement) {
|
|
|
19289
19490
|
const call = ast(declarator?.init);
|
|
19290
19491
|
const table = nodes(call?.arguments)[0];
|
|
19291
19492
|
if (declaration?.type !== "VariableDeclaration" || declarator?.type !== "VariableDeclarator" || call?.type !== "CallExpression" || table?.type !== "ObjectExpression") return replacement;
|
|
19292
|
-
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" &&
|
|
19493
|
+
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" && nameOf2(ast(prop.key)) === key);
|
|
19293
19494
|
const assembliesProp = property(table, "a");
|
|
19294
19495
|
const assemblies = nodes(ast(assembliesProp?.value)?.elements);
|
|
19295
19496
|
if (assembliesProp === void 0 || assemblies.length !== 1 || assemblies[0]?.type !== "ObjectExpression") return replacement;
|
|
@@ -19322,7 +19523,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19322
19523
|
const fns = /* @__PURE__ */ new Map();
|
|
19323
19524
|
for (const statement of nodes(wrapperBody.body)) {
|
|
19324
19525
|
if (statement.type !== "FunctionDeclaration") continue;
|
|
19325
|
-
const name =
|
|
19526
|
+
const name = nameOf2(ast(statement.id));
|
|
19326
19527
|
const hit = name === void 0 ? void 0 : PIECE.exec(name);
|
|
19327
19528
|
const body = ast(statement.body);
|
|
19328
19529
|
if (hit !== void 0 && hit !== null && body?.type === "BlockStatement") {
|
|
@@ -19335,7 +19536,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19335
19536
|
const allCalls = [];
|
|
19336
19537
|
const walk = (node2, current, parent, statement, statementParent) => {
|
|
19337
19538
|
if (isFunction(node2) && node2 !== current?.node) {
|
|
19338
|
-
const own = node2.type === "FunctionDeclaration" ?
|
|
19539
|
+
const own = node2.type === "FunctionDeclaration" ? nameOf2(ast(node2.id)) : void 0;
|
|
19339
19540
|
const hit = own === void 0 ? void 0 : PIECE.exec(own);
|
|
19340
19541
|
if (hit !== void 0 && hit !== null) {
|
|
19341
19542
|
const fn = fns.get(Number(hit[1]));
|
|
@@ -19359,12 +19560,12 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19359
19560
|
ownerParent = parent;
|
|
19360
19561
|
}
|
|
19361
19562
|
if (node2.type === "CallExpression") {
|
|
19362
|
-
const calleeName =
|
|
19563
|
+
const calleeName = nameOf2(ast(node2.callee));
|
|
19363
19564
|
const hit = calleeName === void 0 ? void 0 : PIECE.exec(calleeName);
|
|
19364
19565
|
if (hit !== void 0 && hit !== null) {
|
|
19365
19566
|
const callee = Number(hit[1]);
|
|
19366
19567
|
const args = nodes(node2.arguments);
|
|
19367
|
-
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 &&
|
|
19568
|
+
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 && nameOf2(args[0]) === "input" && nameOf2(args[2]) === "ctx" && isDirectCallUse(node2, parent, owner2) && isListStatement(owner2, ownerParent);
|
|
19368
19569
|
if (current === void 0 || owner2 === void 0) externalRefs.add(callee);
|
|
19369
19570
|
else {
|
|
19370
19571
|
const call = { caller: current.ip, callee, node: node2, statement: owner2, args, transformable };
|
|
@@ -19539,7 +19740,7 @@ ${nested}
|
|
|
19539
19740
|
const referenced = /* @__PURE__ */ new Set();
|
|
19540
19741
|
const checkRefs = (node2, parent) => {
|
|
19541
19742
|
if (node2.type === "FunctionDeclaration") {
|
|
19542
|
-
const name =
|
|
19743
|
+
const name = nameOf2(ast(node2.id));
|
|
19543
19744
|
if (name !== void 0 && PIECE.test(name)) declared.add(name);
|
|
19544
19745
|
}
|
|
19545
19746
|
if (node2.type === "Identifier" && typeof node2.name === "string" && PIECE.test(node2.name)) {
|
|
@@ -19548,32 +19749,210 @@ ${nested}
|
|
|
19548
19749
|
}
|
|
19549
19750
|
for (const child of children2(node2)) checkRefs(child, node2);
|
|
19550
19751
|
};
|
|
19551
|
-
checkRefs(checked.program);
|
|
19552
|
-
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19553
|
-
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19554
|
-
}
|
|
19555
|
-
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19556
|
-
const protocolRegions = {
|
|
19557
|
-
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19558
|
-
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19559
|
-
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19752
|
+
checkRefs(checked.program);
|
|
19753
|
+
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19754
|
+
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19755
|
+
}
|
|
19756
|
+
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19757
|
+
const protocolRegions = {
|
|
19758
|
+
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19759
|
+
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19760
|
+
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19761
|
+
};
|
|
19762
|
+
return {
|
|
19763
|
+
...emitted,
|
|
19764
|
+
source: candidate,
|
|
19765
|
+
supercompile: {
|
|
19766
|
+
...before,
|
|
19767
|
+
activated: removed > 0,
|
|
19768
|
+
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19769
|
+
functionsAfter,
|
|
19770
|
+
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19771
|
+
sourceAfter: candidate.length,
|
|
19772
|
+
regions: roots.length,
|
|
19773
|
+
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19774
|
+
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19775
|
+
protocolRegions
|
|
19776
|
+
}
|
|
19777
|
+
};
|
|
19778
|
+
}
|
|
19779
|
+
|
|
19780
|
+
// src/plugin/ir-eval.ts
|
|
19781
|
+
function evalRulesIR(ir) {
|
|
19782
|
+
return evalIR(ir, rules);
|
|
19783
|
+
}
|
|
19784
|
+
function evalCombinatorIR(ir) {
|
|
19785
|
+
const units = evalIR(ir, (opts) => opts.scanSkip);
|
|
19786
|
+
return units?.length === 1 ? units[0] : null;
|
|
19787
|
+
}
|
|
19788
|
+
function evalIR(ir, rulesImpl) {
|
|
19789
|
+
const _tf = (child, src, recognitionOnly = false) => {
|
|
19790
|
+
let fn2;
|
|
19791
|
+
try {
|
|
19792
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19793
|
+
} catch {
|
|
19794
|
+
fn2 = () => {
|
|
19795
|
+
throw new Error("IR transform fn not materialized");
|
|
19796
|
+
};
|
|
19797
|
+
}
|
|
19798
|
+
const t = transform(child, fn2);
|
|
19799
|
+
t._def.fnSrc = src;
|
|
19800
|
+
if (recognitionOnly) t._def.recognitionOnly = true;
|
|
19801
|
+
return t;
|
|
19802
|
+
};
|
|
19803
|
+
const _lf = (child, src, source = false) => {
|
|
19804
|
+
let fn2;
|
|
19805
|
+
try {
|
|
19806
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19807
|
+
} catch {
|
|
19808
|
+
fn2 = () => {
|
|
19809
|
+
throw new Error("IR leaf fn not materialized");
|
|
19810
|
+
};
|
|
19811
|
+
}
|
|
19812
|
+
const l = source ? sourceLeaf(child, fn2) : leaf(child, fn2);
|
|
19813
|
+
l._def.fnSrc = src;
|
|
19814
|
+
return l;
|
|
19815
|
+
};
|
|
19816
|
+
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
19817
|
+
if (staticError !== void 0 && staticError.length > 0) {
|
|
19818
|
+
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
19819
|
+
}
|
|
19820
|
+
const n = node(type, child, (() => {
|
|
19821
|
+
throw new Error("IR node build requires static re-lowering");
|
|
19822
|
+
}), opts);
|
|
19823
|
+
n._def.buildSrc = src;
|
|
19824
|
+
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
19825
|
+
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
19826
|
+
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
19827
|
+
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
19828
|
+
return n;
|
|
19829
|
+
};
|
|
19830
|
+
const _gch = (items) => {
|
|
19831
|
+
const gateSrcs = [];
|
|
19832
|
+
const arms = items.map((it) => {
|
|
19833
|
+
if (Array.isArray(it)) {
|
|
19834
|
+
const [src, comb] = it;
|
|
19835
|
+
gateSrcs.push(src);
|
|
19836
|
+
let gate2;
|
|
19837
|
+
try {
|
|
19838
|
+
gate2 = (0, eval)(`(${src})`);
|
|
19839
|
+
} catch {
|
|
19840
|
+
gate2 = () => {
|
|
19841
|
+
throw new Error("IR gate fn not materialized");
|
|
19842
|
+
};
|
|
19843
|
+
}
|
|
19844
|
+
return { gate: gate2, combinator: comb };
|
|
19845
|
+
}
|
|
19846
|
+
gateSrcs.push(null);
|
|
19847
|
+
return it;
|
|
19848
|
+
});
|
|
19849
|
+
const c = choice(...arms);
|
|
19850
|
+
const gates = c._def.gates;
|
|
19851
|
+
if (gates && gates.length !== gateSrcs.length) {
|
|
19852
|
+
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
19853
|
+
}
|
|
19854
|
+
;
|
|
19855
|
+
c._def.gateSrcs = gateSrcs;
|
|
19856
|
+
return c;
|
|
19560
19857
|
};
|
|
19561
|
-
|
|
19562
|
-
|
|
19563
|
-
|
|
19564
|
-
|
|
19565
|
-
|
|
19566
|
-
|
|
19567
|
-
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19568
|
-
functionsAfter,
|
|
19569
|
-
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19570
|
-
sourceAfter: candidate.length,
|
|
19571
|
-
regions: roots.length,
|
|
19572
|
-
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19573
|
-
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19574
|
-
protocolRegions
|
|
19858
|
+
const _wc = (src, inner) => {
|
|
19859
|
+
let extra;
|
|
19860
|
+
try {
|
|
19861
|
+
extra = (0, eval)(`(${src})`);
|
|
19862
|
+
} catch {
|
|
19863
|
+
extra = void 0;
|
|
19575
19864
|
}
|
|
19865
|
+
const w = withCtx(extra, inner);
|
|
19866
|
+
w._def.extraSrc = src;
|
|
19867
|
+
return w;
|
|
19576
19868
|
};
|
|
19869
|
+
const fn = new Function(
|
|
19870
|
+
"rules",
|
|
19871
|
+
"ref",
|
|
19872
|
+
"regex",
|
|
19873
|
+
"literal",
|
|
19874
|
+
"keywords",
|
|
19875
|
+
"sequence",
|
|
19876
|
+
"choice",
|
|
19877
|
+
"dispatch",
|
|
19878
|
+
"when",
|
|
19879
|
+
"startsWith",
|
|
19880
|
+
"endsWith",
|
|
19881
|
+
"matches",
|
|
19882
|
+
"otherwise",
|
|
19883
|
+
"routed",
|
|
19884
|
+
"attempt",
|
|
19885
|
+
"many",
|
|
19886
|
+
"oneOrMore",
|
|
19887
|
+
"optional",
|
|
19888
|
+
"sepBy",
|
|
19889
|
+
"keepSeparator",
|
|
19890
|
+
"not",
|
|
19891
|
+
"peek",
|
|
19892
|
+
"node",
|
|
19893
|
+
"parser",
|
|
19894
|
+
"scanTo",
|
|
19895
|
+
"balanced",
|
|
19896
|
+
"token",
|
|
19897
|
+
"leaf",
|
|
19898
|
+
"transform",
|
|
19899
|
+
"trivia",
|
|
19900
|
+
"classifiedTrivia",
|
|
19901
|
+
"label",
|
|
19902
|
+
"field",
|
|
19903
|
+
"expect",
|
|
19904
|
+
"adjacent",
|
|
19905
|
+
"notAdjacent",
|
|
19906
|
+
"_tf",
|
|
19907
|
+
"_lf",
|
|
19908
|
+
"_nd",
|
|
19909
|
+
"_gch",
|
|
19910
|
+
"_wc",
|
|
19911
|
+
`return (${ir})`
|
|
19912
|
+
);
|
|
19913
|
+
return fn(
|
|
19914
|
+
rulesImpl,
|
|
19915
|
+
ref,
|
|
19916
|
+
regex,
|
|
19917
|
+
literal,
|
|
19918
|
+
keywords,
|
|
19919
|
+
sequence,
|
|
19920
|
+
choice,
|
|
19921
|
+
dispatch,
|
|
19922
|
+
when,
|
|
19923
|
+
startsWith,
|
|
19924
|
+
endsWith,
|
|
19925
|
+
matches,
|
|
19926
|
+
otherwise,
|
|
19927
|
+
routed,
|
|
19928
|
+
attempt,
|
|
19929
|
+
many,
|
|
19930
|
+
oneOrMore,
|
|
19931
|
+
optional,
|
|
19932
|
+
sepBy,
|
|
19933
|
+
keepSeparator,
|
|
19934
|
+
not,
|
|
19935
|
+
peek,
|
|
19936
|
+
node,
|
|
19937
|
+
parser,
|
|
19938
|
+
scanTo,
|
|
19939
|
+
balanced,
|
|
19940
|
+
token,
|
|
19941
|
+
leaf,
|
|
19942
|
+
transform,
|
|
19943
|
+
trivia,
|
|
19944
|
+
classifiedTrivia,
|
|
19945
|
+
label,
|
|
19946
|
+
field,
|
|
19947
|
+
expect,
|
|
19948
|
+
adjacent,
|
|
19949
|
+
notAdjacent,
|
|
19950
|
+
_tf,
|
|
19951
|
+
_lf,
|
|
19952
|
+
_nd,
|
|
19953
|
+
_gch,
|
|
19954
|
+
_wc
|
|
19955
|
+
);
|
|
19577
19956
|
}
|
|
19578
19957
|
|
|
19579
19958
|
// src/plugin/index.ts
|
|
@@ -19738,13 +20117,30 @@ function topLevelInit(body, name) {
|
|
|
19738
20117
|
}
|
|
19739
20118
|
return null;
|
|
19740
20119
|
}
|
|
19741
|
-
function
|
|
20120
|
+
function isSymbolFor(n, key) {
|
|
19742
20121
|
if (!n || n.type !== "CallExpression") return false;
|
|
19743
20122
|
const callee = n.callee;
|
|
19744
20123
|
const obj = callee?.object?.name;
|
|
19745
20124
|
const prop = callee?.property?.name;
|
|
19746
20125
|
const arg0 = n.arguments?.[0];
|
|
19747
|
-
return obj === "Symbol" && prop === "for" && arg0?.value ===
|
|
20126
|
+
return obj === "Symbol" && prop === "for" && arg0?.value === key;
|
|
20127
|
+
}
|
|
20128
|
+
var isComposedPiecesSymbol = (n) => isSymbolFor(n, "parseman.composedPieces");
|
|
20129
|
+
var COMBINATOR_IR_KEY = "parseman.combinatorIR";
|
|
20130
|
+
function carriedCombinatorIR(init) {
|
|
20131
|
+
let n = init;
|
|
20132
|
+
while (n.type === "ParenthesizedExpression") n = n.expression;
|
|
20133
|
+
if (n.type !== "CallExpression") return null;
|
|
20134
|
+
const callee = n.callee;
|
|
20135
|
+
const args = n.arguments;
|
|
20136
|
+
if (callee.object?.name !== "Object" || callee.property?.name !== "defineProperty" || !isSymbolFor(args[1], COMBINATOR_IR_KEY)) return null;
|
|
20137
|
+
for (const p of args[2]?.properties ?? []) {
|
|
20138
|
+
const v = p.value;
|
|
20139
|
+
if (propName(p) !== "value") continue;
|
|
20140
|
+
if (v?.type === "Literal" && typeof v.value === "string") return v.value;
|
|
20141
|
+
if (v?.type === "TemplateLiteral" && v.expressions?.length === 0) return v.quasis?.[0]?.value.cooked ?? null;
|
|
20142
|
+
}
|
|
20143
|
+
return null;
|
|
19748
20144
|
}
|
|
19749
20145
|
function findCarriedPiecesLiteral(root) {
|
|
19750
20146
|
let found = null;
|
|
@@ -19760,7 +20156,7 @@ function findCarriedPiecesLiteral(root) {
|
|
|
19760
20156
|
const obj = callee?.object?.name;
|
|
19761
20157
|
const prop = callee?.property?.name;
|
|
19762
20158
|
const args = node2.arguments;
|
|
19763
|
-
if (callee?.type === "Identifier" &&
|
|
20159
|
+
if (callee?.type === "Identifier" && args?.[1]?.type === "ObjectExpression") {
|
|
19764
20160
|
for (const p of args[1].properties ?? []) {
|
|
19765
20161
|
if (p.computed && isComposedPiecesSymbol(p.key) && p.value) {
|
|
19766
20162
|
found = { start: p.value.start, end: p.value.end };
|
|
@@ -19860,13 +20256,14 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19860
20256
|
const allNames = /* @__PURE__ */ new Set();
|
|
19861
20257
|
const importBindings = /* @__PURE__ */ new Map();
|
|
19862
20258
|
const ordinaryImports = [];
|
|
20259
|
+
const isMacroImport = (s) => s.attributes.some((a) => {
|
|
20260
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
20261
|
+
return key === "type" && a.value.value === "macro";
|
|
20262
|
+
});
|
|
19863
20263
|
for (const stmt of body) {
|
|
19864
20264
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
19865
20265
|
const s = stmt;
|
|
19866
|
-
const isMacro = moduleAliases.has(s.source.value) && s
|
|
19867
|
-
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
19868
|
-
return key === "type" && a.value.value === "macro";
|
|
19869
|
-
});
|
|
20266
|
+
const isMacro = moduleAliases.has(s.source.value) && isMacroImport(s);
|
|
19870
20267
|
if (!isMacro) {
|
|
19871
20268
|
const specifiers = [];
|
|
19872
20269
|
for (const spec of s.specifiers) {
|
|
@@ -19909,7 +20306,209 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19909
20306
|
}
|
|
19910
20307
|
const reducerResolver = createReducerResolver(id, body, code);
|
|
19911
20308
|
setReducerResolver(reducerResolver, code);
|
|
19912
|
-
|
|
20309
|
+
let builderImports = (name) => importBindings.get(name) ?? null;
|
|
20310
|
+
setBuilderImportResolver((name) => builderImports(name));
|
|
20311
|
+
const ownRoot = nearestPackageRoot(id);
|
|
20312
|
+
let ownDir = path2.dirname(id);
|
|
20313
|
+
try {
|
|
20314
|
+
ownDir = fs2.realpathSync(ownDir);
|
|
20315
|
+
} catch {
|
|
20316
|
+
}
|
|
20317
|
+
const rebaseSpecifier = (from, spec) => {
|
|
20318
|
+
if (!spec.startsWith(".")) return spec;
|
|
20319
|
+
const target = path2.resolve(path2.dirname(from), spec);
|
|
20320
|
+
if (ownRoot === null || nearestPackageRoot(target) !== ownRoot) return null;
|
|
20321
|
+
const rel = path2.relative(ownDir, target).split(path2.sep).join("/");
|
|
20322
|
+
return rel.startsWith("../") ? rel : `./${rel}`;
|
|
20323
|
+
};
|
|
20324
|
+
const unresolvedImports = /* @__PURE__ */ new Set();
|
|
20325
|
+
const valueModules = /* @__PURE__ */ new Map();
|
|
20326
|
+
const OPAQUE_IMPORT = "is a default or namespace import, which the macro does not resolve \u2014 import the binding by name";
|
|
20327
|
+
const opaqueImportsOf = (moduleBody) => {
|
|
20328
|
+
const out = /* @__PURE__ */ new Set();
|
|
20329
|
+
for (const st of moduleBody) {
|
|
20330
|
+
if (st.type !== "ImportDeclaration") continue;
|
|
20331
|
+
for (const sp of st.specifiers) {
|
|
20332
|
+
if (sp.type !== "ImportSpecifier") out.add(sp.local.name);
|
|
20333
|
+
}
|
|
20334
|
+
}
|
|
20335
|
+
return out;
|
|
20336
|
+
};
|
|
20337
|
+
const valueModule = (file) => {
|
|
20338
|
+
if (valueModules.has(file)) return valueModules.get(file);
|
|
20339
|
+
const mod = parseModuleCached(file);
|
|
20340
|
+
let out = null;
|
|
20341
|
+
if (mod) {
|
|
20342
|
+
const consts = /* @__PURE__ */ new Map();
|
|
20343
|
+
let stable;
|
|
20344
|
+
for (const st of mod.body) {
|
|
20345
|
+
const vd = unwrapVd(st);
|
|
20346
|
+
if (!vd) continue;
|
|
20347
|
+
const isConst = vd.kind === "const";
|
|
20348
|
+
for (const d of vd.declarations) {
|
|
20349
|
+
const idn = d.id;
|
|
20350
|
+
if (idn.type !== "Identifier" || !idn.name || !d.init) continue;
|
|
20351
|
+
if (isConst || (stable ??= topLevelIsStable(mod.body, mod.src.length))(idn.name)) consts.set(idn.name, d.init);
|
|
20352
|
+
}
|
|
20353
|
+
}
|
|
20354
|
+
out = {
|
|
20355
|
+
file,
|
|
20356
|
+
src: mod.src,
|
|
20357
|
+
body: mod.body,
|
|
20358
|
+
consts,
|
|
20359
|
+
imports: extractImportBindings(mod.body),
|
|
20360
|
+
opaqueImports: opaqueImportsOf(mod.body)
|
|
20361
|
+
};
|
|
20362
|
+
}
|
|
20363
|
+
valueModules.set(file, out);
|
|
20364
|
+
return out;
|
|
20365
|
+
};
|
|
20366
|
+
const resolveValueFile = (from, specifier) => {
|
|
20367
|
+
const source = resolvePrivateSourceModule(from, specifier);
|
|
20368
|
+
if (source) return source;
|
|
20369
|
+
try {
|
|
20370
|
+
return getCompiledResolver().resolveFileSync(from, specifier).path ?? null;
|
|
20371
|
+
} catch {
|
|
20372
|
+
return null;
|
|
20373
|
+
}
|
|
20374
|
+
};
|
|
20375
|
+
const evaluatingConsts = /* @__PURE__ */ new Set();
|
|
20376
|
+
const rebaseCarriedBuilderImports = (combi, from) => {
|
|
20377
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20378
|
+
const walk = (v) => {
|
|
20379
|
+
if (v === null || typeof v !== "object" || seen.has(v)) return null;
|
|
20380
|
+
seen.add(v);
|
|
20381
|
+
const def = v._def;
|
|
20382
|
+
if (def?.buildImports) {
|
|
20383
|
+
const out = [];
|
|
20384
|
+
for (const bi of def.buildImports) {
|
|
20385
|
+
const source = rebaseSpecifier(from, bi.source);
|
|
20386
|
+
if (source === null) return bi;
|
|
20387
|
+
out.push({ ...bi, source });
|
|
20388
|
+
}
|
|
20389
|
+
def.buildImports = out;
|
|
20390
|
+
}
|
|
20391
|
+
for (const child of Object.values(v)) {
|
|
20392
|
+
for (const c of Array.isArray(child) ? child : [child]) {
|
|
20393
|
+
const stuck = walk(c);
|
|
20394
|
+
if (stuck) return stuck;
|
|
20395
|
+
}
|
|
20396
|
+
}
|
|
20397
|
+
return null;
|
|
20398
|
+
};
|
|
20399
|
+
return walk(combi);
|
|
20400
|
+
};
|
|
20401
|
+
const moduleConstValue = (m, name) => {
|
|
20402
|
+
const key = `${m.file}\0${name}`;
|
|
20403
|
+
if (evaluatingConsts.has(key)) return { unresolved: `is part of a declaration cycle in ${m.file}` };
|
|
20404
|
+
evaluatingConsts.add(key);
|
|
20405
|
+
const outerBuilderImports = builderImports;
|
|
20406
|
+
try {
|
|
20407
|
+
const init = m.consts.get(name);
|
|
20408
|
+
const ir = carriedCombinatorIR(init);
|
|
20409
|
+
if (ir !== null) {
|
|
20410
|
+
let combi2 = null;
|
|
20411
|
+
let why = "";
|
|
20412
|
+
try {
|
|
20413
|
+
combi2 = evalCombinatorIR(ir);
|
|
20414
|
+
} catch (e) {
|
|
20415
|
+
why = `: ${e.message}`;
|
|
20416
|
+
}
|
|
20417
|
+
if (!combi2) return { unresolved: `carries combinator IR that does not evaluate (${m.file})${why}` };
|
|
20418
|
+
const stuck = rebaseCarriedBuilderImports(combi2, m.file);
|
|
20419
|
+
return stuck ? { unresolved: `has a node() builder reading \`${stuck.local}\` from '${stuck.source}' inside ${m.file}, which this module cannot import \u2014 import it there by package name` } : { value: { combi: combi2, mfSrcs: [] } };
|
|
20420
|
+
}
|
|
20421
|
+
const scope2 = moduleValueScope(m);
|
|
20422
|
+
reducerResolver.register(m.file);
|
|
20423
|
+
builderImports = (name2) => {
|
|
20424
|
+
const b = m.imports.get(name2);
|
|
20425
|
+
const source = b ? rebaseSpecifier(m.file, b.source) : null;
|
|
20426
|
+
return b && source !== null ? { source, imported: b.imported } : null;
|
|
20427
|
+
};
|
|
20428
|
+
const mfs = [];
|
|
20429
|
+
const combi = evaluateExpr(init, scope2, m.src, mfs);
|
|
20430
|
+
if (combi) return { value: { combi, mfSrcs: mfs } };
|
|
20431
|
+
const factory = evaluateWordFactory(init, scope2, m.src) ?? evaluateWhenFactory(init, scope2, m.src);
|
|
20432
|
+
if (factory) return { value: factory };
|
|
20433
|
+
const value = evaluateStaticValue(init, scope2, m.src);
|
|
20434
|
+
if (value !== null && value !== void 0 || isStaticNullishExpression(init)) return { value };
|
|
20435
|
+
return {
|
|
20436
|
+
unresolved: /\btableRules\b/.test(m.src.slice(init.start, init.end)) ? `is a compiled parser in ${m.file} that carries no combinator IR \u2014 rebuild that module with parseman v${PARSEMAN_VERSION}` : `is not a statically-known combinator or value (${m.file})`
|
|
20437
|
+
};
|
|
20438
|
+
} finally {
|
|
20439
|
+
evaluatingConsts.delete(key);
|
|
20440
|
+
builderImports = outerBuilderImports;
|
|
20441
|
+
}
|
|
20442
|
+
};
|
|
20443
|
+
const moduleValueScope = (m) => m.scope ??= new ModuleScope((name) => {
|
|
20444
|
+
if (m.consts.has(name)) return moduleConstValue(m, name);
|
|
20445
|
+
const binding = m.imports.get(name);
|
|
20446
|
+
if (binding) return importedValue(m.file, binding);
|
|
20447
|
+
return m.opaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20448
|
+
}, unresolvedImports);
|
|
20449
|
+
const exportedValue = (m, name, depth) => {
|
|
20450
|
+
for (const st of m.body) {
|
|
20451
|
+
if (st.type !== "ExportNamedDeclaration" || !st.source) continue;
|
|
20452
|
+
for (const sp of st.specifiers ?? []) {
|
|
20453
|
+
if (sp.exported.name !== name) continue;
|
|
20454
|
+
const source = st.source.value;
|
|
20455
|
+
const file = depth < 16 ? resolveValueFile(m.file, source) : null;
|
|
20456
|
+
const next = file ? valueModule(file) : null;
|
|
20457
|
+
if (!next) return { unresolved: `is re-exported from '${source}', which does not resolve from ${m.file}` };
|
|
20458
|
+
return exportedValue(next, sp.local.name, depth + 1);
|
|
20459
|
+
}
|
|
20460
|
+
}
|
|
20461
|
+
const local = exportLocalName(m.body, name);
|
|
20462
|
+
if (local === null) {
|
|
20463
|
+
for (const st of m.body) {
|
|
20464
|
+
if (st.type !== "ExportAllDeclaration" || st.exported) continue;
|
|
20465
|
+
const file = depth < 16 ? resolveValueFile(m.file, st.source.value) : null;
|
|
20466
|
+
const next = file ? valueModule(file) : null;
|
|
20467
|
+
if (!next) continue;
|
|
20468
|
+
const r = exportedValue(next, name, depth + 1);
|
|
20469
|
+
if (r !== null && "unresolved" in r && r.unresolved.startsWith("is not exported by ")) continue;
|
|
20470
|
+
return r;
|
|
20471
|
+
}
|
|
20472
|
+
return { unresolved: `is not exported by ${m.file}` };
|
|
20473
|
+
}
|
|
20474
|
+
const scope2 = moduleValueScope(m);
|
|
20475
|
+
if (!scope2.has(local)) {
|
|
20476
|
+
scope2.get(local);
|
|
20477
|
+
return { unresolved: `could not be resolved in ${m.file}` };
|
|
20478
|
+
}
|
|
20479
|
+
return { value: scope2.get(local) };
|
|
20480
|
+
};
|
|
20481
|
+
const importedValue = (from, binding) => {
|
|
20482
|
+
const file = resolveValueFile(from, binding.source);
|
|
20483
|
+
const m = file ? valueModule(file) : null;
|
|
20484
|
+
if (!m) return { unresolved: `is imported from '${binding.source}', which does not resolve from ${from}` };
|
|
20485
|
+
return exportedValue(m, binding.imported, 0);
|
|
20486
|
+
};
|
|
20487
|
+
const deferredLocals = /* @__PURE__ */ new Map();
|
|
20488
|
+
const deferredResults = /* @__PURE__ */ new Map();
|
|
20489
|
+
const mainOpaqueImports = opaqueImportsOf(body);
|
|
20490
|
+
const resolveMainFree = (name) => {
|
|
20491
|
+
const done = deferredResults.get(name);
|
|
20492
|
+
if (done !== void 0) return done;
|
|
20493
|
+
const deferred = deferredLocals.get(name);
|
|
20494
|
+
if (deferred !== void 0) {
|
|
20495
|
+
deferredLocals.delete(name);
|
|
20496
|
+
const outer = [...unresolvedImports];
|
|
20497
|
+
unresolvedImports.clear();
|
|
20498
|
+
const value = evaluateStaticValue(deferred, scope, code);
|
|
20499
|
+
const why = [...unresolvedImports];
|
|
20500
|
+
unresolvedImports.clear();
|
|
20501
|
+
for (const n of outer) unresolvedImports.add(n);
|
|
20502
|
+
const result2 = value !== null && value !== void 0 || isStaticNullishExpression(deferred) ? { value } : why.length > 0 ? { unresolved: `could not be evaluated at build time, because: ${why.join("; ")}` } : null;
|
|
20503
|
+
deferredResults.set(name, result2);
|
|
20504
|
+
return result2;
|
|
20505
|
+
}
|
|
20506
|
+
const binding = importBindings.get(name);
|
|
20507
|
+
if (!binding) return mainOpaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20508
|
+
const resolved = importedValue(id, binding);
|
|
20509
|
+
if (resolved !== null && "value" in resolved) usedImportedFactories.add(name);
|
|
20510
|
+
return resolved;
|
|
20511
|
+
};
|
|
19913
20512
|
const topLevelFunction = (moduleBody, name) => {
|
|
19914
20513
|
for (const st of moduleBody) {
|
|
19915
20514
|
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
@@ -19918,19 +20517,17 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19918
20517
|
}
|
|
19919
20518
|
return null;
|
|
19920
20519
|
};
|
|
19921
|
-
const
|
|
19922
|
-
|
|
19923
|
-
const
|
|
19924
|
-
|
|
19925
|
-
const
|
|
19926
|
-
|
|
19927
|
-
|
|
19928
|
-
|
|
19929
|
-
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
19930
|
-
const out = /* @__PURE__ */ new Map();
|
|
20520
|
+
const sourceScopeUntil = (file, moduleBody, source, until) => {
|
|
20521
|
+
const imports = extractImportBindings(moduleBody);
|
|
20522
|
+
const opaque = opaqueImportsOf(moduleBody);
|
|
20523
|
+
const out = new ModuleScope((name) => {
|
|
20524
|
+
const binding = imports.get(name);
|
|
20525
|
+
if (binding) return importedValue(file, binding);
|
|
20526
|
+
return opaque.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20527
|
+
}, unresolvedImports);
|
|
19931
20528
|
for (const stmt of moduleBody) {
|
|
19932
20529
|
if (stmt.type === "ImportDeclaration") {
|
|
19933
|
-
if (!
|
|
20530
|
+
if (moduleAliases.has(stmt.source.value) && !isMacroImport(stmt)) return null;
|
|
19934
20531
|
continue;
|
|
19935
20532
|
}
|
|
19936
20533
|
if (stmt.type === "FunctionDeclaration") continue;
|
|
@@ -19983,6 +20580,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19983
20580
|
}
|
|
19984
20581
|
return out;
|
|
19985
20582
|
};
|
|
20583
|
+
const factoryFailures = /* @__PURE__ */ new Map();
|
|
19986
20584
|
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
19987
20585
|
const markUsedImportedFactories = (names) => {
|
|
19988
20586
|
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
@@ -19995,8 +20593,13 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19995
20593
|
const localFor = exportLocalName(mod.body, binding.imported);
|
|
19996
20594
|
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
19997
20595
|
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
19998
|
-
|
|
19999
|
-
|
|
20596
|
+
unresolvedImports.clear();
|
|
20597
|
+
const factoryScope = sourceScopeUntil(file, mod.body, mod.src, init.start);
|
|
20598
|
+
if (!factoryScope) {
|
|
20599
|
+
if (unresolvedImports.size > 0) factoryFailures.set(localName, [...unresolvedImports]);
|
|
20600
|
+
unresolvedImports.clear();
|
|
20601
|
+
continue;
|
|
20602
|
+
}
|
|
20000
20603
|
factoryDecls.set(localName, {
|
|
20001
20604
|
fn: init,
|
|
20002
20605
|
declaredAt: -1,
|
|
@@ -20006,7 +20609,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20006
20609
|
});
|
|
20007
20610
|
reducerResolver.register(file);
|
|
20008
20611
|
}
|
|
20009
|
-
const scope =
|
|
20612
|
+
const scope = new ModuleScope(resolveMainFree, unresolvedImports);
|
|
20010
20613
|
const replacements = [];
|
|
20011
20614
|
const warnings = [];
|
|
20012
20615
|
beginDegradationCapture();
|
|
@@ -20026,6 +20629,12 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20026
20629
|
m = /* @__PURE__ */ new Map();
|
|
20027
20630
|
pendingBuilderImports.set(bi.source, m);
|
|
20028
20631
|
}
|
|
20632
|
+
const prev = m.get(bi.local);
|
|
20633
|
+
if (prev !== void 0 && prev !== bi.imported) {
|
|
20634
|
+
throw new Error(
|
|
20635
|
+
`${id} \u2014 parseman will not emit this module: inlined builders read \`${bi.local}\` as both \`${prev}\` and \`${bi.imported}\` from ${JSON.stringify(bi.source)}. The builder source names \`${bi.local}\` verbatim, so one import cannot bind both; import them under different names.`
|
|
20636
|
+
);
|
|
20637
|
+
}
|
|
20029
20638
|
m.set(bi.local, bi.imported);
|
|
20030
20639
|
}
|
|
20031
20640
|
if (def?.tag === "lazy" && v._ruleName === void 0 && typeof def.thunk === "function") {
|
|
@@ -20067,6 +20676,41 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20067
20676
|
anyUnresolved = true;
|
|
20068
20677
|
warnings.push(`${id}:${lineOf(pos)} \u2014 ${msg} (running via the interpreter; add the plugin or simplify the declaration to compile it)`);
|
|
20069
20678
|
};
|
|
20679
|
+
const unevaluable = (pos, what) => {
|
|
20680
|
+
const names = [...unresolvedImports];
|
|
20681
|
+
unresolvedImports.clear();
|
|
20682
|
+
throw new Error(
|
|
20683
|
+
`${id}:${lineOf(pos)} \u2014 ${what} can't be evaluated at build time` + (names.length > 0 ? `; unresolved binding(s):
|
|
20684
|
+
${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/value expression)") + `
|
|
20685
|
+
parseman will not emit this module rather than drop it silently.`
|
|
20686
|
+
);
|
|
20687
|
+
};
|
|
20688
|
+
const requiredOption = (label2, name, value, evaluate) => {
|
|
20689
|
+
if (value === void 0 || isStaticNullishExpression(value)) return void 0;
|
|
20690
|
+
unresolvedImports.clear();
|
|
20691
|
+
const out = evaluate(value);
|
|
20692
|
+
if (out === null) {
|
|
20693
|
+
const id2 = value.type === "Identifier" ? value.name : null;
|
|
20694
|
+
if (id2 !== null && scope.has(id2) && scope.get(id2) == null) return void 0;
|
|
20695
|
+
return unevaluable(value.start, `${label2}: rules({ ${name} })`);
|
|
20696
|
+
}
|
|
20697
|
+
unresolvedImports.clear();
|
|
20698
|
+
return out;
|
|
20699
|
+
};
|
|
20700
|
+
const RULES_OPTIONS = /* @__PURE__ */ new Set(["trivia", "scanSkip", "hostMode", "trackLines"]);
|
|
20701
|
+
const assertPlainOptions = (optExpr, label2) => {
|
|
20702
|
+
for (const p of optExpr?.type === "ObjectExpression" ? optExpr.properties : []) {
|
|
20703
|
+
if (propName(p) !== null) continue;
|
|
20704
|
+
const key = p.type === "Property" ? evaluateStaticValue(p.key, scope, code) : null;
|
|
20705
|
+
if (typeof key !== "string" || RULES_OPTIONS.has(key)) {
|
|
20706
|
+
unevaluable(p.start, `${label2}: an options ${p.type === "Property" ? "computed key" : "spread"}`);
|
|
20707
|
+
}
|
|
20708
|
+
}
|
|
20709
|
+
};
|
|
20710
|
+
const triviaOption = (optExpr, label2) => {
|
|
20711
|
+
assertPlainOptions(optExpr, label2);
|
|
20712
|
+
return requiredOption(label2, "trivia", optionProp(optExpr, "trivia"), (v) => evaluateExpr(v, scope, code, []));
|
|
20713
|
+
};
|
|
20070
20714
|
const evaluateRulesFactory = (init, label2) => {
|
|
20071
20715
|
const args = init.arguments;
|
|
20072
20716
|
const arg0 = args[0];
|
|
@@ -20082,7 +20726,15 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20082
20726
|
const factoryScope = namedFactory?.scope ?? scope;
|
|
20083
20727
|
const factoryCode = namedFactory?.code ?? code;
|
|
20084
20728
|
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
20729
|
+
const failedFactory = factoryArgRaw.type === "Identifier" ? factoryFailures.get(factoryArgRaw.name) : void 0;
|
|
20730
|
+
if (failedFactory) {
|
|
20731
|
+
for (const n of failedFactory) unresolvedImports.add(n);
|
|
20732
|
+
unevaluable(init.start, `${label2}: the imported rules() factory \`${factoryArgRaw.name}\``);
|
|
20733
|
+
}
|
|
20085
20734
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
20735
|
+
if (optionsArg !== void 0 && optionsArg.type !== "ObjectExpression" && !isStaticNullishExpression(optionsArg)) {
|
|
20736
|
+
unevaluable(optionsArg.start, `${label2}: rules() options`);
|
|
20737
|
+
}
|
|
20086
20738
|
const optionValue = (name) => optionProp(optionsArg, name);
|
|
20087
20739
|
const hostModeValue = optionValue("hostMode");
|
|
20088
20740
|
const gHostMode = hostModeValue?.type === "Literal" ? hostModeValue.value : void 0;
|
|
@@ -20096,11 +20748,16 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20096
20748
|
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
20097
20749
|
return null;
|
|
20098
20750
|
}
|
|
20099
|
-
const
|
|
20100
|
-
const
|
|
20101
|
-
|
|
20102
|
-
|
|
20751
|
+
const gTrivia = triviaOption(optionsArg, label2);
|
|
20752
|
+
const scanSkipArray = requiredOption(label2, "scanSkip", optionValue("scanSkip"), (v) => {
|
|
20753
|
+
const units = evaluateCombinatorArray(v, scope, code);
|
|
20754
|
+
if (units) return units;
|
|
20755
|
+
const value = evaluateStaticValue(v, scope, code);
|
|
20756
|
+
return Array.isArray(value) && value.length === 0 ? [] : null;
|
|
20757
|
+
});
|
|
20758
|
+
const gScanSkip = scanSkipArray?.length ? scanSkipArray : void 0;
|
|
20103
20759
|
const why = {};
|
|
20760
|
+
unresolvedImports.clear();
|
|
20104
20761
|
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, [], why, {
|
|
20105
20762
|
...gTrivia ? { trivia: gTrivia } : {},
|
|
20106
20763
|
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
@@ -20108,6 +20765,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20108
20765
|
...gTrackLines === true ? { trackLines: true } : {}
|
|
20109
20766
|
});
|
|
20110
20767
|
if (!ruleMap) {
|
|
20768
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `${label2}: rules(...) factory`);
|
|
20111
20769
|
warn(init.start, why.reason === void 0 ? `${label2}: rules(...) factory isn't statically evaluable` : `${label2}: rules(...) factory isn't statically evaluable \u2014 ${why.reason}`);
|
|
20112
20770
|
return null;
|
|
20113
20771
|
}
|
|
@@ -20124,6 +20782,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20124
20782
|
if (!evaluated) return null;
|
|
20125
20783
|
const refusals = [];
|
|
20126
20784
|
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage, refusals });
|
|
20785
|
+
if (compiled !== null) collectBuilderImports([...evaluated.ruleMap]);
|
|
20127
20786
|
if (compiled !== null) usedTableRuntime = true;
|
|
20128
20787
|
return {
|
|
20129
20788
|
replacement: compiled?.replacement ?? null,
|
|
@@ -20185,49 +20844,63 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20185
20844
|
};
|
|
20186
20845
|
const localComposedCarried = /* @__PURE__ */ new Map();
|
|
20187
20846
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
20188
|
-
const resolveModulePieces = (module, exportName, seen) => {
|
|
20847
|
+
const resolveModulePieces = (module, exportName, seen, unresolved, local = false) => {
|
|
20189
20848
|
const { file } = module;
|
|
20190
20849
|
const mod = module.source ? lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recovery) : parseModuleCached(file);
|
|
20191
20850
|
if (!mod) return null;
|
|
20192
|
-
const localFor = exportLocalName(mod.body, exportName);
|
|
20851
|
+
const localFor = local ? exportName : exportLocalName(mod.body, exportName);
|
|
20193
20852
|
const initNode = localFor ? topLevelInit(mod.body, localFor) : null;
|
|
20194
20853
|
const literalRange = initNode ? findCarriedPiecesLiteral(initNode) : null;
|
|
20195
20854
|
if (!literalRange) return null;
|
|
20196
20855
|
const literal2 = mod.src.slice(literalRange.start, literalRange.end);
|
|
20856
|
+
const fail = (why) => {
|
|
20857
|
+
unresolved.why ??= `${exportName} in ${file}: ${why}`;
|
|
20858
|
+
return null;
|
|
20859
|
+
};
|
|
20197
20860
|
const imports = extractImportBindings(mod.body);
|
|
20198
20861
|
const stubNames = [];
|
|
20199
20862
|
const stubVals = [];
|
|
20200
|
-
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20863
|
+
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*(?:\/\*[^]*?\*\/\s*)*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20201
20864
|
const done = /* @__PURE__ */ new Set();
|
|
20202
20865
|
for (let m; m = spreadRe.exec(literal2); ) {
|
|
20203
|
-
const
|
|
20204
|
-
if (done.has(
|
|
20205
|
-
done.add(
|
|
20206
|
-
const b = imports.get(
|
|
20866
|
+
const local2 = m[1];
|
|
20867
|
+
if (done.has(local2)) continue;
|
|
20868
|
+
done.add(local2);
|
|
20869
|
+
const b = imports.get(local2);
|
|
20207
20870
|
let subPieces = [];
|
|
20208
20871
|
if (b) {
|
|
20209
20872
|
const subModule = resolveGrammarModule(file, b.source);
|
|
20210
|
-
if (subModule
|
|
20211
|
-
|
|
20873
|
+
if (subModule === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', a module that could not be found`);
|
|
20874
|
+
if (!seen.has(subModule.file)) {
|
|
20875
|
+
subPieces = resolveModulePieces(subModule, b.imported, new Set(seen).add(subModule.file), unresolved);
|
|
20876
|
+
if (subPieces === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', which could not be resolved`);
|
|
20212
20877
|
}
|
|
20878
|
+
} else if (topLevelInit(mod.body, local2) !== null && !seen.has(`${file}#${local2}`)) {
|
|
20879
|
+
subPieces = resolveModulePieces(module, local2, new Set(seen).add(`${file}#${local2}`), unresolved, true);
|
|
20880
|
+
if (subPieces === null) return fail(`its carried pieces spread the inlined binding \`${local2}\`, which carries none`);
|
|
20881
|
+
} else {
|
|
20882
|
+
return fail(`its carried pieces spread \`${local2}\`, which is neither an import nor a top-level binding of the module`);
|
|
20213
20883
|
}
|
|
20214
|
-
stubNames.push(
|
|
20884
|
+
stubNames.push(local2);
|
|
20215
20885
|
stubVals.push({ [COMPOSED_PIECES]: subPieces });
|
|
20216
20886
|
}
|
|
20217
20887
|
try {
|
|
20218
20888
|
const list = new Function(...stubNames, `return (${literal2})`)(...stubVals);
|
|
20219
20889
|
return list;
|
|
20220
|
-
} catch {
|
|
20221
|
-
return
|
|
20890
|
+
} catch (e) {
|
|
20891
|
+
return fail(`its carried pieces literal did not evaluate (${e.message})`);
|
|
20222
20892
|
}
|
|
20223
20893
|
};
|
|
20894
|
+
const unresolvedCompiled = /* @__PURE__ */ new Map();
|
|
20224
20895
|
const importedPieces = (localName) => {
|
|
20225
20896
|
if (importedPiecesCache.has(localName)) return importedPiecesCache.get(localName);
|
|
20226
20897
|
let result2 = null;
|
|
20227
20898
|
const binding = importBindings.get(localName);
|
|
20228
20899
|
if (binding) {
|
|
20229
20900
|
const module = resolveGrammarModule(id, binding.source);
|
|
20230
|
-
|
|
20901
|
+
const unresolved = {};
|
|
20902
|
+
result2 = module ? resolveModulePieces(module, binding.imported, /* @__PURE__ */ new Set([module.file]), unresolved) : null;
|
|
20903
|
+
if (result2 === null && unresolved.why !== void 0) unresolvedCompiled.set(localName, unresolved.why);
|
|
20231
20904
|
}
|
|
20232
20905
|
importedPiecesCache.set(localName, result2);
|
|
20233
20906
|
return result2;
|
|
@@ -20238,7 +20911,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20238
20911
|
const add = (item) => {
|
|
20239
20912
|
if (!isIR(item)) return false;
|
|
20240
20913
|
if (item.trackLines === true) trackLines = true;
|
|
20241
|
-
|
|
20914
|
+
const map = evalRulesIR(item.ir);
|
|
20915
|
+
pieces.push({ ns: item.ns, rules: Object.entries(map), recipes: map[RULES_RECIPE] });
|
|
20242
20916
|
return true;
|
|
20243
20917
|
};
|
|
20244
20918
|
for (const item of items) {
|
|
@@ -20265,10 +20939,20 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20265
20939
|
}
|
|
20266
20940
|
return [...winners];
|
|
20267
20941
|
};
|
|
20268
|
-
const mergedCarriedRules = (items) => {
|
|
20942
|
+
const mergedCarriedRules = (items, link) => {
|
|
20269
20943
|
const carriedMaps = carriedRuleMaps(items);
|
|
20270
20944
|
if (carriedMaps === null) return null;
|
|
20271
|
-
|
|
20945
|
+
const linked = linkRules(carriedMaps.pieces.flatMap((p) => p.recipes), link);
|
|
20946
|
+
const rules2 = Object.entries(linked).filter(([, rule]) => {
|
|
20947
|
+
if (rule._def.tag !== "lazy") return true;
|
|
20948
|
+
try {
|
|
20949
|
+
rule._def.thunk();
|
|
20950
|
+
return true;
|
|
20951
|
+
} catch {
|
|
20952
|
+
return false;
|
|
20953
|
+
}
|
|
20954
|
+
});
|
|
20955
|
+
return { rules: rules2, trackLines: carriedMaps.trackLines };
|
|
20272
20956
|
};
|
|
20273
20957
|
const applyComposingTrivia = (ruleMap, composing) => {
|
|
20274
20958
|
for (const [, rule] of ruleMap) {
|
|
@@ -20308,9 +20992,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20308
20992
|
const a0 = rulesArgs[0];
|
|
20309
20993
|
const a1 = rulesArgs[1];
|
|
20310
20994
|
const optExpr = a0?.type === "ObjectExpression" ? a0 : a1?.type === "ObjectExpression" ? a1 : void 0;
|
|
20311
|
-
|
|
20312
|
-
if (!triviaValue) return void 0;
|
|
20313
|
-
return evaluateExpr(triviaValue, scope, code, []) ?? void 0;
|
|
20995
|
+
return triviaOption(optExpr, "compose() element");
|
|
20314
20996
|
};
|
|
20315
20997
|
const composingTrivia = (elements) => {
|
|
20316
20998
|
for (let i = elements.length - 1; i >= 0; i--) {
|
|
@@ -20337,6 +21019,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20337
21019
|
}
|
|
20338
21020
|
const elements = arr.elements;
|
|
20339
21021
|
const cOptions = init.arguments[1];
|
|
21022
|
+
if (cOptions !== void 0 && cOptions.type !== "ObjectExpression") unevaluable(cOptions.start, "compose() options");
|
|
21023
|
+
assertPlainOptions(cOptions, "compose()");
|
|
20340
21024
|
const cHostModeValue = optionProp(cOptions, "hostMode");
|
|
20341
21025
|
const cHostMode = cHostModeValue?.type === "Literal" ? cHostModeValue.value : void 0;
|
|
20342
21026
|
if (cHostModeValue !== void 0 && cHostMode !== "ast" && cHostMode !== "cst") {
|
|
@@ -20349,15 +21033,25 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20349
21033
|
for (let i = 0; i < elements.length; i++) {
|
|
20350
21034
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
20351
21035
|
if (!r) {
|
|
21036
|
+
const el = elements[i];
|
|
21037
|
+
const name = el.type === "Identifier" ? el.name : void 0;
|
|
21038
|
+
const why = name === void 0 ? void 0 : unresolvedCompiled.get(name);
|
|
21039
|
+
if (why !== void 0) {
|
|
21040
|
+
throw new Error(
|
|
21041
|
+
`${id}:${lineOf(init.start)} \u2014 compose(): argument ${i} (\`${name}\` from '${importBindings.get(name)?.source}') is a build-compiled grammar whose carried pieces could not be resolved: ${why}. A runtime compose() cannot link a build-compiled grammar, so this would throw at import. The usual cause is a bundler rewriting the upstream module (inlining or renaming an ancestor grammar it composes, or reprinting its carried-pieces literal); keep upstream grammar packages external to the bundle.`
|
|
21042
|
+
);
|
|
21043
|
+
}
|
|
20352
21044
|
warn(init.start, `compose(): argument ${i} isn't a build-resolvable grammar; falling back to runtime`);
|
|
20353
21045
|
return null;
|
|
20354
21046
|
}
|
|
20355
21047
|
carried.push(...r.carried);
|
|
20356
21048
|
importedFactories.push(...r.importedFactories ?? []);
|
|
20357
21049
|
}
|
|
20358
|
-
const merged = mergedCarriedRules(carried
|
|
21050
|
+
const merged = mergedCarriedRules(carried, {
|
|
21051
|
+
trivia: composing,
|
|
21052
|
+
...cHostMode ? { hostMode: cHostMode } : {}
|
|
21053
|
+
});
|
|
20359
21054
|
if (merged !== null) {
|
|
20360
|
-
if (composing) applyComposingTrivia(merged.rules, composing);
|
|
20361
21055
|
collectBuilderImports(merged.rules);
|
|
20362
21056
|
const refusals = [];
|
|
20363
21057
|
const compiled = compileRuleMap(merged.rules, {
|
|
@@ -20552,11 +21246,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20552
21246
|
if (d.id.type === "Identifier") {
|
|
20553
21247
|
const varName = d.id.name;
|
|
20554
21248
|
if (!referencesAny(init, allNames, scope)) {
|
|
20555
|
-
|
|
20556
|
-
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
20557
|
-
;
|
|
20558
|
-
scope.set(varName, staticValue);
|
|
20559
|
-
}
|
|
21249
|
+
deferredLocals.set(varName, init);
|
|
20560
21250
|
continue;
|
|
20561
21251
|
}
|
|
20562
21252
|
if (refNames.has(varName)) {
|
|
@@ -20643,6 +21333,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20643
21333
|
continue;
|
|
20644
21334
|
}
|
|
20645
21335
|
const mapFnSources = [];
|
|
21336
|
+
unresolvedImports.clear();
|
|
20646
21337
|
const parser2 = evaluateExpr(init, scope, code, mapFnSources);
|
|
20647
21338
|
if (parser2 === null) {
|
|
20648
21339
|
const wordFactory = evaluateWordFactory(init, scope, code);
|
|
@@ -20675,6 +21366,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20675
21366
|
if (exportPrefix) exportedFactories.push({ name: varName, pos: init.start });
|
|
20676
21367
|
continue;
|
|
20677
21368
|
}
|
|
21369
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `"${varName}"`);
|
|
20678
21370
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
20679
21371
|
continue;
|
|
20680
21372
|
}
|
|
@@ -20687,7 +21379,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20687
21379
|
replacements.push({
|
|
20688
21380
|
start: init.start,
|
|
20689
21381
|
end: init.end,
|
|
20690
|
-
replacement: compiled.inlineExpression
|
|
21382
|
+
replacement: compiled.inlineExpression,
|
|
21383
|
+
carry: { name: varName, combi: parser2, exported: exportPrefix !== "" }
|
|
20691
21384
|
});
|
|
20692
21385
|
scope.set(varName, { combi: parser2, mfSrcs: mapFnSources });
|
|
20693
21386
|
} else if (d.id.type === "ObjectPattern") {
|
|
@@ -20754,37 +21447,58 @@ ${which}
|
|
|
20754
21447
|
Drop the \`export\`. The factory is macro-only; \`rules(${exportedFactories[0].name})\` is lowered in place and needs no runtime value.`
|
|
20755
21448
|
);
|
|
20756
21449
|
}
|
|
21450
|
+
const withCombinatorIR = (r) => {
|
|
21451
|
+
if (!r.carry || !r.carry.exported && !referencedNames().live.has(r.carry.name)) return r;
|
|
21452
|
+
let ir = null;
|
|
21453
|
+
try {
|
|
21454
|
+
ir = serializeCombinator(r.carry.combi);
|
|
21455
|
+
} catch {
|
|
21456
|
+
}
|
|
21457
|
+
return ir === null ? r : {
|
|
21458
|
+
...r,
|
|
21459
|
+
replacement: `/* @__PURE__ */ Object.defineProperty(${r.replacement}, Symbol.for('${COMBINATOR_IR_KEY}'), { value: ${JSON.stringify(ir)}, enumerable: false })`
|
|
21460
|
+
};
|
|
21461
|
+
};
|
|
20757
21462
|
const ms = new MagicString(code);
|
|
20758
21463
|
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
20759
21464
|
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
|
|
21465
|
+
let referenced = null;
|
|
21466
|
+
const referencedNames = () => {
|
|
21467
|
+
if (referenced !== null) return referenced;
|
|
21468
|
+
const all = /* @__PURE__ */ new Set();
|
|
21469
|
+
const live = /* @__PURE__ */ new Set();
|
|
21470
|
+
const deadRanges = [...[...factoryDecls.values()].filter((f) => !f.imported).map((f) => f.fn), ...anyUnresolved ? [] : defineRemovals];
|
|
21471
|
+
const walk = (node2, inFactory, parent, parentKey) => {
|
|
21472
|
+
if (!node2 || typeof node2 !== "object") return;
|
|
20763
21473
|
const rec = node2;
|
|
20764
|
-
if (rec.type === "ImportDeclaration") return
|
|
20765
|
-
if (typeof rec.start === "number" && typeof rec.end === "number"
|
|
20766
|
-
|
|
20767
|
-
|
|
20768
|
-
|
|
20769
|
-
|
|
20770
|
-
|
|
21474
|
+
if (rec.type === "ImportDeclaration") return;
|
|
21475
|
+
if (typeof rec.start === "number" && typeof rec.end === "number") {
|
|
21476
|
+
if (isInsideReplacement(rec.start, rec.end)) return;
|
|
21477
|
+
inFactory ||= deadRanges.some((f) => rec.start >= f.start && rec.end <= f.end);
|
|
21478
|
+
}
|
|
21479
|
+
if (rec.type === "Identifier" || rec.type === "BindingIdentifier") {
|
|
21480
|
+
const isKey = parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true;
|
|
21481
|
+
const isMember = parentKey === "property" && (parent?.type === "StaticMemberExpression" || parent?.type === "MemberExpression" && parent.computed !== true);
|
|
21482
|
+
const isDeclared = parentKey === "id" && parent?.type === "VariableDeclarator";
|
|
21483
|
+
if (!isKey && !isMember && !isDeclared) {
|
|
21484
|
+
all.add(rec.name);
|
|
21485
|
+
if (!inFactory) live.add(rec.name);
|
|
21486
|
+
}
|
|
21487
|
+
return;
|
|
20771
21488
|
}
|
|
20772
21489
|
for (const key of Object.keys(rec)) {
|
|
20773
21490
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
20774
21491
|
const value = rec[key];
|
|
20775
|
-
if (Array.isArray(value))
|
|
20776
|
-
|
|
20777
|
-
} else if (walk(value, rec, key)) {
|
|
20778
|
-
return true;
|
|
20779
|
-
}
|
|
21492
|
+
if (Array.isArray(value)) for (const child of value) walk(child, inFactory, rec, key);
|
|
21493
|
+
else walk(value, inFactory, rec, key);
|
|
20780
21494
|
}
|
|
20781
|
-
return false;
|
|
20782
21495
|
};
|
|
20783
|
-
|
|
21496
|
+
for (const stmt of body) walk(stmt, false);
|
|
21497
|
+
return referenced = { all, live };
|
|
20784
21498
|
};
|
|
20785
21499
|
for (const imp of ordinaryImports) {
|
|
20786
21500
|
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
20787
|
-
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !
|
|
21501
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !referencedNames().all.has(spec.local)
|
|
20788
21502
|
)) {
|
|
20789
21503
|
ms.remove(imp.start, imp.end);
|
|
20790
21504
|
}
|
|
@@ -20801,7 +21515,7 @@ ${which}
|
|
|
20801
21515
|
ms.overwrite(imp.start, imp.end, stripped);
|
|
20802
21516
|
}
|
|
20803
21517
|
}
|
|
20804
|
-
const applied = runtimeComposeFallback ? [] : replacements;
|
|
21518
|
+
const applied = runtimeComposeFallback ? [] : replacements.map((r) => withCombinatorIR(r));
|
|
20805
21519
|
for (const { start, end, replacement } of applied.slice().sort((a, b) => b.start - a.start)) {
|
|
20806
21520
|
ms.overwrite(start, end, replacement);
|
|
20807
21521
|
}
|