parseman 0.52.0 → 0.53.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 +358 -8
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +5929 -6172
- package/dist/cli/index.js.map +3 -3
- 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/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/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/index.js +416 -704
- 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 +1073 -523
- 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/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/index.js +235 -87
- package/dist/table/index.js.map +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/parser.ts +133 -67
- package/src/combinators/ref.ts +10 -1
- package/src/compiler/borrowed-rules.ts +88 -0
- package/src/compiler/compile-linkable-table.ts +1 -1
- package/src/compiler/grammar-coverage-ids.ts +35 -6
- package/src/compiler/ir-serialize.ts +12 -118
- package/src/compiler/linker.ts +190 -666
- package/src/coverage.ts +6 -4
- package/src/cst/reflection.ts +6 -1
- package/src/plugin/evaluator.ts +113 -13
- 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/compile-rule-map.ts +18 -8
- package/src/table/compile.ts +61 -0
- 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
|
},
|
|
@@ -1810,6 +1811,7 @@ function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
|
1810
1811
|
function collectGrammarReflection(ruleMap, opts) {
|
|
1811
1812
|
const byType = /* @__PURE__ */ new Map();
|
|
1812
1813
|
const followLazy = opts?.followLazy !== false;
|
|
1814
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1813
1815
|
for (const [, rule] of ruleMap) {
|
|
1814
1816
|
if (!followLazy && rule._def.tag === "lazy") {
|
|
1815
1817
|
try {
|
|
@@ -1819,7 +1821,7 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
1819
1821
|
}
|
|
1820
1822
|
continue;
|
|
1821
1823
|
}
|
|
1822
|
-
collectFromCombinator(rule, byType,
|
|
1824
|
+
collectFromCombinator(rule, byType, seen, followLazy);
|
|
1823
1825
|
}
|
|
1824
1826
|
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
1825
1827
|
}
|
|
@@ -1850,9 +1852,26 @@ function isNamedRuleRefForAnotherRule(r, key) {
|
|
|
1850
1852
|
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1851
1853
|
return name !== void 0 && name !== key;
|
|
1852
1854
|
}
|
|
1855
|
+
var claimedRules = /* @__PURE__ */ new WeakSet();
|
|
1856
|
+
function ownRule(p, copies) {
|
|
1857
|
+
if (!claimedRules.has(p) || p._meta.isTrivia) return p;
|
|
1858
|
+
let own = copies.get(p);
|
|
1859
|
+
if (own === void 0) {
|
|
1860
|
+
const { grammarTrivia: _t, grammarScanSkip: _s, grammarHostMode: _h, grammarTrackLines: _l, ...meta } = p._meta;
|
|
1861
|
+
copies.set(p, own = { ...p, _meta: meta });
|
|
1862
|
+
}
|
|
1863
|
+
return own;
|
|
1864
|
+
}
|
|
1853
1865
|
function rules(a, b) {
|
|
1854
1866
|
const factory = typeof a === "function" ? a : b;
|
|
1855
1867
|
const options = typeof a === "function" ? b : a;
|
|
1868
|
+
const recipe = { factory, options };
|
|
1869
|
+
const map = linkRules([recipe]);
|
|
1870
|
+
Object.defineProperty(map, RULES_RECIPE, { value: [recipe], enumerable: false });
|
|
1871
|
+
return map;
|
|
1872
|
+
}
|
|
1873
|
+
var RULES_RECIPE = /* @__PURE__ */ Symbol.for("parseman.rulesRecipe");
|
|
1874
|
+
function linkRules(recipes, link) {
|
|
1856
1875
|
const cache = {};
|
|
1857
1876
|
const proxy = new Proxy(cache, {
|
|
1858
1877
|
get(target, key) {
|
|
@@ -1866,10 +1885,18 @@ function rules(a, b) {
|
|
|
1866
1885
|
return record[key];
|
|
1867
1886
|
}
|
|
1868
1887
|
});
|
|
1869
|
-
const
|
|
1870
|
-
for (const
|
|
1888
|
+
const winners = /* @__PURE__ */ new Map();
|
|
1889
|
+
for (const recipe of recipes) {
|
|
1890
|
+
const definitions = recipe.factory(proxy);
|
|
1891
|
+
for (const key of Object.keys(definitions)) {
|
|
1892
|
+
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
const keys = [...winners.keys()];
|
|
1896
|
+
const copies = /* @__PURE__ */ new Map();
|
|
1897
|
+
for (const [key, { parser: defined }] of winners) {
|
|
1871
1898
|
const placeholder = cache[key];
|
|
1872
|
-
const parser2 =
|
|
1899
|
+
const parser2 = ownRule(defined, copies);
|
|
1873
1900
|
if (placeholder === parser2) {
|
|
1874
1901
|
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1875
1902
|
}
|
|
@@ -1878,7 +1905,8 @@ function rules(a, b) {
|
|
|
1878
1905
|
placeholder.define(parser2);
|
|
1879
1906
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1880
1907
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1881
|
-
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1908
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key) || link !== void 0) {
|
|
1909
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1882
1910
|
const alias = ref();
|
|
1883
1911
|
tagRule(alias, key);
|
|
1884
1912
|
alias.define(parser2);
|
|
@@ -1890,48 +1918,34 @@ function rules(a, b) {
|
|
|
1890
1918
|
cache[key] = parser2;
|
|
1891
1919
|
}
|
|
1892
1920
|
}
|
|
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;
|
|
1921
|
+
for (const key of keys) {
|
|
1922
|
+
const options = winners.get(key).options;
|
|
1923
|
+
let rule = cache[key];
|
|
1924
|
+
if (!rule._meta.isTrivia) {
|
|
1925
|
+
const meta = rule._meta;
|
|
1926
|
+
const trivia2 = link !== void 0 ? link.trivia : options?.trivia;
|
|
1927
|
+
if (trivia2 != null) meta.grammarTrivia = trivia2;
|
|
1928
|
+
if (options?.scanSkip != null) meta.grammarScanSkip = options.scanSkip;
|
|
1929
|
+
if ((link?.hostMode ?? options?.hostMode) === "cst") meta.grammarHostMode = "cst";
|
|
1930
|
+
if (options?.trackLines === true) {
|
|
1931
|
+
meta.grammarTrackLines = true;
|
|
1932
|
+
if (rule._def.tag !== "grammar") {
|
|
1933
|
+
rule = parser({ trackLines: true }, rule);
|
|
1934
|
+
tagRule(rule, key);
|
|
1935
|
+
rule._meta.grammarTrackLines = true;
|
|
1936
|
+
cache[key] = rule;
|
|
1937
|
+
}
|
|
1923
1938
|
}
|
|
1924
1939
|
}
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
markUnusedValues(cache[key]);
|
|
1940
|
+
markUnusedValues(rule);
|
|
1941
|
+
claimedRules.add(winners.get(key).parser).add(rule);
|
|
1928
1942
|
}
|
|
1929
1943
|
Object.defineProperty(cache, RULE_ORDER, {
|
|
1930
|
-
value:
|
|
1944
|
+
value: keys,
|
|
1931
1945
|
enumerable: false,
|
|
1932
1946
|
configurable: true
|
|
1933
1947
|
});
|
|
1934
|
-
attachGrammarReflection(cache, collectGrammarReflection(
|
|
1948
|
+
attachGrammarReflection(cache, collectGrammarReflection(keys.map((key) => [key, cache[key]])));
|
|
1935
1949
|
return cache;
|
|
1936
1950
|
}
|
|
1937
1951
|
|
|
@@ -15020,7 +15034,8 @@ function children(def, winners) {
|
|
|
15020
15034
|
return [];
|
|
15021
15035
|
}
|
|
15022
15036
|
const name = resolved._ruleName;
|
|
15023
|
-
|
|
15037
|
+
const winner = name ? winners?.[name] : void 0;
|
|
15038
|
+
return winner !== void 0 && winner._def !== def ? [winner] : [resolved];
|
|
15024
15039
|
}
|
|
15025
15040
|
default:
|
|
15026
15041
|
return [];
|
|
@@ -15045,16 +15060,39 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15045
15060
|
}
|
|
15046
15061
|
}
|
|
15047
15062
|
}
|
|
15063
|
+
const selfWinnerBody = (parser2) => {
|
|
15064
|
+
if (parser2._def.tag !== "lazy" || winners === void 0) return void 0;
|
|
15065
|
+
const name = winnerNames.get(parser2);
|
|
15066
|
+
if (name === void 0 || winners[name] !== parser2) return void 0;
|
|
15067
|
+
try {
|
|
15068
|
+
return parser2._def.thunk();
|
|
15069
|
+
} catch {
|
|
15070
|
+
return void 0;
|
|
15071
|
+
}
|
|
15072
|
+
};
|
|
15073
|
+
const slotsPerBody = /* @__PURE__ */ new Map();
|
|
15074
|
+
if (winners) {
|
|
15075
|
+
for (const winner of Object.values(winners)) {
|
|
15076
|
+
const body = selfWinnerBody(winner);
|
|
15077
|
+
if (body !== void 0) slotsPerBody.set(body, (slotsPerBody.get(body) ?? 0) + 1);
|
|
15078
|
+
}
|
|
15079
|
+
}
|
|
15080
|
+
const sharedBody = (parser2) => (slotsPerBody.get(parser2) ?? 0) > 1;
|
|
15081
|
+
const ownRule2 = (parser2, rule) => {
|
|
15082
|
+
const id = `rule:${rule}`;
|
|
15083
|
+
definitions.set(id, { id, kind: "rule" });
|
|
15084
|
+
rules2.set(parser2, id);
|
|
15085
|
+
};
|
|
15048
15086
|
const seen = /* @__PURE__ */ new Set();
|
|
15049
15087
|
const visit = (parser2, path3) => {
|
|
15050
15088
|
if (seen.has(parser2)) return;
|
|
15051
15089
|
seen.add(parser2);
|
|
15052
15090
|
const rule = winnerNames.get(parser2) ?? parser2._ruleName;
|
|
15053
|
-
|
|
15054
|
-
|
|
15055
|
-
|
|
15056
|
-
rules2.set(parser2, id);
|
|
15091
|
+
const body = selfWinnerBody(parser2);
|
|
15092
|
+
if (rule && body === void 0 && !sharedBody(parser2) && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
15093
|
+
ownRule2(parser2, rule);
|
|
15057
15094
|
}
|
|
15095
|
+
if (rule && body !== void 0 && sharedBody(body)) ownRule2(parser2, rule);
|
|
15058
15096
|
if (parser2._def.tag === "choice") {
|
|
15059
15097
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path3}/arm:${index}`);
|
|
15060
15098
|
choices.set(parser2, ids);
|
|
@@ -15075,7 +15113,13 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15075
15113
|
};
|
|
15076
15114
|
const roots = Array.isArray(entry) ? entry : [entry];
|
|
15077
15115
|
for (const root of roots) {
|
|
15078
|
-
|
|
15116
|
+
const name = winnerNames.get(root) ?? root._ruleName ?? "entry";
|
|
15117
|
+
const body = selfWinnerBody(root);
|
|
15118
|
+
if (body !== void 0 && sharedBody(body) && !seen.has(root)) {
|
|
15119
|
+
seen.add(root);
|
|
15120
|
+
ownRule2(root, name);
|
|
15121
|
+
}
|
|
15122
|
+
visit(body ?? root, name);
|
|
15079
15123
|
}
|
|
15080
15124
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
15081
15125
|
}
|
|
@@ -16381,6 +16425,183 @@ function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
|
16381
16425
|
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16382
16426
|
}
|
|
16383
16427
|
|
|
16428
|
+
// src/table/compile-rule-map.ts
|
|
16429
|
+
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
16430
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
16431
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16432
|
+
}
|
|
16433
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
16434
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16435
|
+
}
|
|
16436
|
+
function withAmbient(ruleMap, opts) {
|
|
16437
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16438
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
16439
|
+
return ruleMap.map(([name, rule]) => {
|
|
16440
|
+
if (rule._meta.isTrivia) return [name, rule];
|
|
16441
|
+
const addTrivia = opts.trivia !== void 0 && rule._meta.grammarTrivia === void 0;
|
|
16442
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule._meta.grammarScanSkip === void 0;
|
|
16443
|
+
if (!addTrivia && !addScanSkip) return [name, rule];
|
|
16444
|
+
let wrapped = wrappers.get(rule);
|
|
16445
|
+
if (wrapped === void 0) {
|
|
16446
|
+
wrapped = {
|
|
16447
|
+
...rule,
|
|
16448
|
+
_meta: {
|
|
16449
|
+
...rule._meta,
|
|
16450
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16451
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16452
|
+
}
|
|
16453
|
+
};
|
|
16454
|
+
wrappers.set(rule, wrapped);
|
|
16455
|
+
}
|
|
16456
|
+
return [name, wrapped];
|
|
16457
|
+
});
|
|
16458
|
+
}
|
|
16459
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16460
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16461
|
+
if (encoded === null) return null;
|
|
16462
|
+
const { prog, hostMode, plan } = encoded;
|
|
16463
|
+
const artifact = closureArtifact(prog);
|
|
16464
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
16465
|
+
return {
|
|
16466
|
+
keys: ruleMap.map(([key]) => key),
|
|
16467
|
+
hostMode,
|
|
16468
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16469
|
+
reflection,
|
|
16470
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16471
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16472
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
16473
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16474
|
+
prog: artifact
|
|
16475
|
+
};
|
|
16476
|
+
}
|
|
16477
|
+
function encodeForRun(ruleMap, opts) {
|
|
16478
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16479
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
16480
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16481
|
+
encodeMap.map(([, rule]) => rule),
|
|
16482
|
+
Object.fromEntries(encodeMap.filter(([, rule]) => rule._def.tag !== "lazy"))
|
|
16483
|
+
) : void 0;
|
|
16484
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16485
|
+
const settings = {
|
|
16486
|
+
hostMode,
|
|
16487
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16488
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
16489
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
16490
|
+
};
|
|
16491
|
+
try {
|
|
16492
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16493
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
16494
|
+
} catch (e) {
|
|
16495
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16496
|
+
return null;
|
|
16497
|
+
}
|
|
16498
|
+
}
|
|
16499
|
+
function compileRuleMap(ruleMap, opts = {}) {
|
|
16500
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16501
|
+
if (encoded === null) return null;
|
|
16502
|
+
const { prog, fnSrcs, hostMode, plan } = encoded;
|
|
16503
|
+
const artifact = closureArtifact(prog);
|
|
16504
|
+
if (artifact.runtimeOnly !== void 0 && artifact.runtimeOnly.length > 0) {
|
|
16505
|
+
opts.refusals?.push(...artifact.runtimeOnly);
|
|
16506
|
+
return null;
|
|
16507
|
+
}
|
|
16508
|
+
const supplied = opts.fnSources;
|
|
16509
|
+
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? null);
|
|
16510
|
+
if (sources.some((s) => s === null)) {
|
|
16511
|
+
const missing = sources.flatMap((s, i) => s === null ? [i] : []);
|
|
16512
|
+
opts.refusals?.push(
|
|
16513
|
+
`author reducer source missing for prog.fns[${missing.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`
|
|
16514
|
+
);
|
|
16515
|
+
return null;
|
|
16516
|
+
}
|
|
16517
|
+
if (supplied !== void 0 && supplied.length > fnSrcs.length) {
|
|
16518
|
+
throw new Error(
|
|
16519
|
+
`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.`
|
|
16520
|
+
);
|
|
16521
|
+
}
|
|
16522
|
+
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
16523
|
+
entry: null,
|
|
16524
|
+
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
16525
|
+
fnSources: sources,
|
|
16526
|
+
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
16527
|
+
...metadataSource === void 0 ? {} : { metadataSource }
|
|
16528
|
+
});
|
|
16529
|
+
const replacement = replacementWithMetadata();
|
|
16530
|
+
return {
|
|
16531
|
+
keys: ruleMap.map(([key]) => key),
|
|
16532
|
+
replacement,
|
|
16533
|
+
replacementWithMetadata,
|
|
16534
|
+
hostMode,
|
|
16535
|
+
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
16536
|
+
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
16537
|
+
// off. `mode === 'ast'` alone over-reports it: an all-STRUCTURAL grammar has no
|
|
16538
|
+
// direct builder, so there was no branch to drop and it stays usable with either
|
|
16539
|
+
// host — the long-standing `node(parser)` contract. Same predicate codegen uses
|
|
16540
|
+
// for its own `hasDirectBuilders` (both read `analysis/commitment.ts`), so the two
|
|
16541
|
+
// lowerings stamp the same artifact rather than disagreeing about it.
|
|
16542
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16543
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
16544
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16545
|
+
rules: tableRules(artifact),
|
|
16546
|
+
prog: artifact
|
|
16547
|
+
};
|
|
16548
|
+
}
|
|
16549
|
+
|
|
16550
|
+
// src/compiler/borrowed-rules.ts
|
|
16551
|
+
var nameOf = (c) => c._ruleName;
|
|
16552
|
+
function deref(c) {
|
|
16553
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16554
|
+
let current = c;
|
|
16555
|
+
while (current._def.tag === "lazy" && !seen.has(current)) {
|
|
16556
|
+
seen.add(current);
|
|
16557
|
+
try {
|
|
16558
|
+
current = current._def.thunk();
|
|
16559
|
+
} catch {
|
|
16560
|
+
return void 0;
|
|
16561
|
+
}
|
|
16562
|
+
}
|
|
16563
|
+
return current;
|
|
16564
|
+
}
|
|
16565
|
+
function borrowedRuleReference(map) {
|
|
16566
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16567
|
+
for (const [rule, self] of Object.entries(map)) {
|
|
16568
|
+
let found;
|
|
16569
|
+
const visit = (c) => {
|
|
16570
|
+
if (found !== void 0) return;
|
|
16571
|
+
if (c._def.tag === "lazy") {
|
|
16572
|
+
if (!winnerWrapsReference(self, c)) {
|
|
16573
|
+
const name = nameOf(c);
|
|
16574
|
+
const winner = name !== void 0 && Object.hasOwn(map, name) ? map[name] : void 0;
|
|
16575
|
+
if (winner !== void 0) {
|
|
16576
|
+
if (winnerWrapsReference(winner, c) || deref(c) === deref(winner)) return;
|
|
16577
|
+
found = name;
|
|
16578
|
+
return;
|
|
16579
|
+
}
|
|
16580
|
+
}
|
|
16581
|
+
if (seen.has(c)) return;
|
|
16582
|
+
seen.add(c);
|
|
16583
|
+
let body;
|
|
16584
|
+
try {
|
|
16585
|
+
body = c._def.thunk();
|
|
16586
|
+
} catch {
|
|
16587
|
+
return;
|
|
16588
|
+
}
|
|
16589
|
+
visit(body);
|
|
16590
|
+
return;
|
|
16591
|
+
}
|
|
16592
|
+
if (seen.has(c)) return;
|
|
16593
|
+
seen.add(c);
|
|
16594
|
+
for (const child of childrenOf2(c._def)) visit(child);
|
|
16595
|
+
};
|
|
16596
|
+
visit(self);
|
|
16597
|
+
if (found !== void 0) return { rule, reference: found };
|
|
16598
|
+
}
|
|
16599
|
+
return void 0;
|
|
16600
|
+
}
|
|
16601
|
+
function borrowedRuleMessage(api, hit) {
|
|
16602
|
+
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.`;
|
|
16603
|
+
}
|
|
16604
|
+
|
|
16384
16605
|
// src/table/compile.ts
|
|
16385
16606
|
var ENTRY = "Entry";
|
|
16386
16607
|
function ownSource(fn) {
|
|
@@ -16390,7 +16611,47 @@ function ownSource(fn) {
|
|
|
16390
16611
|
const name = fn.name;
|
|
16391
16612
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
16392
16613
|
}
|
|
16393
|
-
function compile(
|
|
16614
|
+
function compile(target, second, third) {
|
|
16615
|
+
if (!isCombinator(target)) return compileMap(target, second);
|
|
16616
|
+
return compileRoot(target, second, third);
|
|
16617
|
+
}
|
|
16618
|
+
function isCombinator(x) {
|
|
16619
|
+
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
16620
|
+
}
|
|
16621
|
+
function compileMap(grammar, opts = {}) {
|
|
16622
|
+
const entries = [];
|
|
16623
|
+
for (const [key, value] of Object.entries(grammar)) {
|
|
16624
|
+
if (!isCombinator(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
16625
|
+
if (value._def.tag === "lazy") {
|
|
16626
|
+
try {
|
|
16627
|
+
value._def.thunk();
|
|
16628
|
+
} catch {
|
|
16629
|
+
continue;
|
|
16630
|
+
}
|
|
16631
|
+
}
|
|
16632
|
+
entries.push([key, value]);
|
|
16633
|
+
}
|
|
16634
|
+
const borrowed = borrowedRuleReference(Object.fromEntries(entries));
|
|
16635
|
+
if (borrowed !== void 0) throw new Error(borrowedRuleMessage("compile", borrowed));
|
|
16636
|
+
const drain = beginCompileDegradationDrain();
|
|
16637
|
+
let done = false;
|
|
16638
|
+
try {
|
|
16639
|
+
const refusals = [];
|
|
16640
|
+
const compiled = compileRuleMapRunnable(entries, {
|
|
16641
|
+
...opts.hostMode ? { hostMode: opts.hostMode } : {},
|
|
16642
|
+
refusals,
|
|
16643
|
+
specialise: true
|
|
16644
|
+
});
|
|
16645
|
+
if (compiled === null) {
|
|
16646
|
+
throw new Error(`compile: this grammar could not be encoded to a table${refusals.length ? ` \u2014 ${refusals.join("; ")}` : ""}`);
|
|
16647
|
+
}
|
|
16648
|
+
done = true;
|
|
16649
|
+
return compiled.rules;
|
|
16650
|
+
} finally {
|
|
16651
|
+
drain(done);
|
|
16652
|
+
}
|
|
16653
|
+
}
|
|
16654
|
+
function compileRoot(combinator, mapFnSources, opts = {}) {
|
|
16394
16655
|
runDuplicationDiagnostic(combinator, opts.duplication);
|
|
16395
16656
|
const drain = beginCompileDegradationDrain();
|
|
16396
16657
|
let compiled = false;
|
|
@@ -16460,29 +16721,6 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
16460
16721
|
};
|
|
16461
16722
|
}
|
|
16462
16723
|
|
|
16463
|
-
// src/combinators/withCtx.ts
|
|
16464
|
-
function withCtx(extra, combinator) {
|
|
16465
|
-
const meta = {
|
|
16466
|
-
firstSet: combinator._meta.firstSet,
|
|
16467
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
16468
|
-
isTrivia: false
|
|
16469
|
-
};
|
|
16470
|
-
return {
|
|
16471
|
-
_tag: "withCtx",
|
|
16472
|
-
_meta: meta,
|
|
16473
|
-
_def: { tag: "withCtx", extra, parser: combinator },
|
|
16474
|
-
parse(input, pos, ctx) {
|
|
16475
|
-
const saved = ctx.state;
|
|
16476
|
-
ctx.state = extra;
|
|
16477
|
-
try {
|
|
16478
|
-
return combinator.parse(input, pos, ctx);
|
|
16479
|
-
} finally {
|
|
16480
|
-
ctx.state = saved;
|
|
16481
|
-
}
|
|
16482
|
-
}
|
|
16483
|
-
};
|
|
16484
|
-
}
|
|
16485
|
-
|
|
16486
16724
|
// src/compiler/ir-serialize.ts
|
|
16487
16725
|
function childrenOf3(def) {
|
|
16488
16726
|
switch (def.tag) {
|
|
@@ -16579,195 +16817,28 @@ function serializeRuleMap(ruleMap, scanSkip) {
|
|
|
16579
16817
|
throw e;
|
|
16580
16818
|
}
|
|
16581
16819
|
}
|
|
16582
|
-
function
|
|
16583
|
-
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
|
|
16587
|
-
|
|
16588
|
-
|
|
16589
|
-
|
|
16590
|
-
|
|
16591
|
-
|
|
16592
|
-
|
|
16593
|
-
|
|
16594
|
-
|
|
16595
|
-
|
|
16596
|
-
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
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);
|
|
16751
|
-
}
|
|
16752
|
-
var Serializer = class {
|
|
16753
|
-
counts = /* @__PURE__ */ new Map();
|
|
16754
|
-
selfRef = /* @__PURE__ */ new Set();
|
|
16755
|
-
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
16756
|
-
cycleInterior = /* @__PURE__ */ new Set();
|
|
16757
|
-
// combinators lying ON a self-reference cycle (strictly below its target)
|
|
16758
|
-
constName = /* @__PURE__ */ new Map();
|
|
16759
|
-
emitted = /* @__PURE__ */ new Set();
|
|
16760
|
-
decls = [];
|
|
16761
|
-
ruleValues = /* @__PURE__ */ new Set();
|
|
16762
|
-
localRuleNames = /* @__PURE__ */ new Map();
|
|
16763
|
-
ruleMap;
|
|
16764
|
-
scanSkip;
|
|
16765
|
-
constructor(ruleMap, scanSkip = []) {
|
|
16766
|
-
this.ruleMap = ruleMap;
|
|
16767
|
-
this.scanSkip = scanSkip;
|
|
16768
|
-
for (const [name, c] of ruleMap) {
|
|
16769
|
-
this.localRuleNames.set(c, name);
|
|
16770
|
-
this.ruleValues.add(this.body(c));
|
|
16820
|
+
function serializeCombinator(c) {
|
|
16821
|
+
return serializeRuleMap([], [c]);
|
|
16822
|
+
}
|
|
16823
|
+
var Serializer = class {
|
|
16824
|
+
counts = /* @__PURE__ */ new Map();
|
|
16825
|
+
selfRef = /* @__PURE__ */ new Set();
|
|
16826
|
+
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
16827
|
+
cycleInterior = /* @__PURE__ */ new Set();
|
|
16828
|
+
// combinators lying ON a self-reference cycle (strictly below its target)
|
|
16829
|
+
constName = /* @__PURE__ */ new Map();
|
|
16830
|
+
emitted = /* @__PURE__ */ new Set();
|
|
16831
|
+
decls = [];
|
|
16832
|
+
ruleValues = /* @__PURE__ */ new Set();
|
|
16833
|
+
localRuleNames = /* @__PURE__ */ new Map();
|
|
16834
|
+
ruleMap;
|
|
16835
|
+
scanSkip;
|
|
16836
|
+
constructor(ruleMap, scanSkip = []) {
|
|
16837
|
+
this.ruleMap = ruleMap;
|
|
16838
|
+
this.scanSkip = scanSkip;
|
|
16839
|
+
for (const [name, c] of ruleMap) {
|
|
16840
|
+
this.localRuleNames.set(c, name);
|
|
16841
|
+
this.ruleValues.add(this.body(c));
|
|
16771
16842
|
}
|
|
16772
16843
|
}
|
|
16773
16844
|
/** A grammar-level `scanSkip` unit is an opaque TERMINAL (a string, a balanced
|
|
@@ -17075,127 +17146,8 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17075
17146
|
}
|
|
17076
17147
|
};
|
|
17077
17148
|
|
|
17078
|
-
// src/table/compile-rule-map.ts
|
|
17079
|
-
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
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
|
-
};
|
|
17195
|
-
}
|
|
17196
|
-
|
|
17197
17149
|
// src/version.ts
|
|
17198
|
-
var PARSEMAN_VERSION = "0.
|
|
17150
|
+
var PARSEMAN_VERSION = "0.53.0";
|
|
17199
17151
|
|
|
17200
17152
|
// src/compiler/compile-linkable-table.ts
|
|
17201
17153
|
function isLocal(rule) {
|
|
@@ -17307,6 +17259,29 @@ function gate(predicate) {
|
|
|
17307
17259
|
};
|
|
17308
17260
|
}
|
|
17309
17261
|
|
|
17262
|
+
// src/combinators/withCtx.ts
|
|
17263
|
+
function withCtx(extra, combinator) {
|
|
17264
|
+
const meta = {
|
|
17265
|
+
firstSet: combinator._meta.firstSet,
|
|
17266
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
17267
|
+
isTrivia: false
|
|
17268
|
+
};
|
|
17269
|
+
return {
|
|
17270
|
+
_tag: "withCtx",
|
|
17271
|
+
_meta: meta,
|
|
17272
|
+
_def: { tag: "withCtx", extra, parser: combinator },
|
|
17273
|
+
parse(input, pos, ctx) {
|
|
17274
|
+
const saved = ctx.state;
|
|
17275
|
+
ctx.state = extra;
|
|
17276
|
+
try {
|
|
17277
|
+
return combinator.parse(input, pos, ctx);
|
|
17278
|
+
} finally {
|
|
17279
|
+
ctx.state = saved;
|
|
17280
|
+
}
|
|
17281
|
+
}
|
|
17282
|
+
};
|
|
17283
|
+
}
|
|
17284
|
+
|
|
17310
17285
|
// src/plugin/direct-builder-static.ts
|
|
17311
17286
|
import { parseSync } from "oxc-parser";
|
|
17312
17287
|
var STATIC_BUILDER_GLOBALS = /* @__PURE__ */ new Set([
|
|
@@ -17592,6 +17567,41 @@ var _builderImports = null;
|
|
|
17592
17567
|
function setBuilderImportResolver(r) {
|
|
17593
17568
|
_builderImports = r;
|
|
17594
17569
|
}
|
|
17570
|
+
var ModuleScope = class _ModuleScope extends Map {
|
|
17571
|
+
tried = /* @__PURE__ */ new Map();
|
|
17572
|
+
resolveFree;
|
|
17573
|
+
unresolved;
|
|
17574
|
+
constructor(resolveFree, unresolved) {
|
|
17575
|
+
super();
|
|
17576
|
+
this.resolveFree = resolveFree;
|
|
17577
|
+
this.unresolved = unresolved;
|
|
17578
|
+
}
|
|
17579
|
+
has(name) {
|
|
17580
|
+
return super.has(name) || this.resolve(name);
|
|
17581
|
+
}
|
|
17582
|
+
get(name) {
|
|
17583
|
+
if (super.has(name) || this.resolve(name)) return super.get(name);
|
|
17584
|
+
const why = this.tried.get(name);
|
|
17585
|
+
if (why !== void 0) this.unresolved.add(`\`${name}\` ${why}`);
|
|
17586
|
+
return void 0;
|
|
17587
|
+
}
|
|
17588
|
+
/** A child scope (a factory body) that keeps resolving this module's free names. */
|
|
17589
|
+
fork() {
|
|
17590
|
+
const child = new _ModuleScope(this.resolveFree, this.unresolved);
|
|
17591
|
+
for (const [k, v] of super.entries()) child.set(k, v);
|
|
17592
|
+
return child;
|
|
17593
|
+
}
|
|
17594
|
+
resolve(name) {
|
|
17595
|
+
if (this.tried.has(name)) return false;
|
|
17596
|
+
const r = this.resolveFree(name);
|
|
17597
|
+
if (r !== null && "value" in r) {
|
|
17598
|
+
super.set(name, r.value);
|
|
17599
|
+
return true;
|
|
17600
|
+
}
|
|
17601
|
+
if (r !== null) this.tried.set(name, r.unresolved);
|
|
17602
|
+
return false;
|
|
17603
|
+
}
|
|
17604
|
+
};
|
|
17595
17605
|
function isWordFactory(v) {
|
|
17596
17606
|
return !!v && typeof v === "object" && v.tag === "wordFactory";
|
|
17597
17607
|
}
|
|
@@ -17715,7 +17725,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17715
17725
|
if (!keyArg || !parserArg || extraArg !== void 0 || keyArg.type === "SpreadElement" || parserArg.type === "SpreadElement") return null;
|
|
17716
17726
|
const key = anyValue(keyArg, scope, code, mfs);
|
|
17717
17727
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17718
|
-
if (!
|
|
17728
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17719
17729
|
const opts = { caseInsensitive: factory.caseInsensitive };
|
|
17720
17730
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17721
17731
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
@@ -17726,7 +17736,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17726
17736
|
const [parserArg] = node2.arguments;
|
|
17727
17737
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17728
17738
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17729
|
-
if (!
|
|
17739
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17730
17740
|
return otherwise(parserValue);
|
|
17731
17741
|
}
|
|
17732
17742
|
if (callee.name === "when") {
|
|
@@ -17736,24 +17746,24 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17736
17746
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17737
17747
|
const opts = dispatchWhenOptions(optsArg === void 0 ? void 0 : anyValue(optsArg, scope, code, mfs));
|
|
17738
17748
|
if (opts === null) return null;
|
|
17739
|
-
if (!
|
|
17749
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17740
17750
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17741
17751
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
17742
17752
|
if (isDispatchMatcher(key)) return when(key, parserValue, opts);
|
|
17743
17753
|
}
|
|
17744
17754
|
return null;
|
|
17745
17755
|
}
|
|
17746
|
-
function
|
|
17756
|
+
function isCombinator2(v) {
|
|
17747
17757
|
return !!v && typeof v === "object" && "_def" in v;
|
|
17748
17758
|
}
|
|
17749
17759
|
function isDispatchArm(v) {
|
|
17750
17760
|
if (!v || typeof v !== "object") return false;
|
|
17751
17761
|
const rec = v;
|
|
17752
|
-
if (rec.kind === "otherwise") return
|
|
17762
|
+
if (rec.kind === "otherwise") return isCombinator2(rec.parser);
|
|
17753
17763
|
if (rec.kind === "whenMatcher") {
|
|
17754
|
-
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" &&
|
|
17764
|
+
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17755
17765
|
}
|
|
17756
|
-
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" &&
|
|
17766
|
+
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17757
17767
|
}
|
|
17758
17768
|
function isDispatchMatcher(v) {
|
|
17759
17769
|
if (!v || typeof v !== "object") return false;
|
|
@@ -17768,7 +17778,7 @@ function scopeGet(scope, name, mfs) {
|
|
|
17768
17778
|
if (mfs && entry.mfSrcs.length > 0) mfs.push(...entry.mfSrcs);
|
|
17769
17779
|
return entry.combi;
|
|
17770
17780
|
}
|
|
17771
|
-
if (
|
|
17781
|
+
if (isCombinator2(entry)) return entry;
|
|
17772
17782
|
return null;
|
|
17773
17783
|
}
|
|
17774
17784
|
function unwrapStaticExpr(expr) {
|
|
@@ -17820,7 +17830,7 @@ function scopedStaticValue(expr, scope) {
|
|
|
17820
17830
|
return { found: true, value };
|
|
17821
17831
|
}
|
|
17822
17832
|
function staticNodeOptionsFromValue(value) {
|
|
17823
|
-
if (value === null || typeof value !== "object" || Array.isArray(value) ||
|
|
17833
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator2(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
17824
17834
|
const opts = {};
|
|
17825
17835
|
const rec = value;
|
|
17826
17836
|
for (const name of Object.keys(rec)) {
|
|
@@ -17872,6 +17882,13 @@ function staticNodeOptions(expr, scope) {
|
|
|
17872
17882
|
}
|
|
17873
17883
|
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
17884
|
}
|
|
17885
|
+
var UNKNOWN_OPTIONS = /* @__PURE__ */ Symbol("parseman.unknownOptions");
|
|
17886
|
+
function scanOptions(optsArg, scope, code) {
|
|
17887
|
+
if (optsArg === void 0) return void 0;
|
|
17888
|
+
if (optsArg.type === "SpreadElement") return UNKNOWN_OPTIONS;
|
|
17889
|
+
const opts = anyValue(optsArg, scope, code, []);
|
|
17890
|
+
return isHole(optsArg, opts, scope) ? UNKNOWN_OPTIONS : opts;
|
|
17891
|
+
}
|
|
17875
17892
|
function exprToCombi(node2, scope, code, mfs) {
|
|
17876
17893
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
17877
17894
|
if (node2.type !== "CallExpression") return null;
|
|
@@ -17907,7 +17924,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17907
17924
|
const [parserArg, fnArg] = node2.arguments;
|
|
17908
17925
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17909
17926
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17910
|
-
if (!
|
|
17927
|
+
if (!isCombinator2(inner)) return null;
|
|
17911
17928
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17912
17929
|
mfs.push(fnSrc);
|
|
17913
17930
|
try {
|
|
@@ -17922,7 +17939,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17922
17939
|
const [parserArg, fnArg] = node2.arguments;
|
|
17923
17940
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17924
17941
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17925
|
-
if (!
|
|
17942
|
+
if (!isCombinator2(inner)) return null;
|
|
17926
17943
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17927
17944
|
mfs.push(fnSrc);
|
|
17928
17945
|
try {
|
|
@@ -17943,7 +17960,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17943
17960
|
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
17944
17961
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17945
17962
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17946
|
-
if (!
|
|
17963
|
+
if (!isCombinator2(inner)) return null;
|
|
17947
17964
|
const be = buildArg;
|
|
17948
17965
|
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
17949
17966
|
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
@@ -18017,7 +18034,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18017
18034
|
const opts = anyValue(optsArg, scope, code, []);
|
|
18018
18035
|
if (!opts || typeof opts !== "object") return null;
|
|
18019
18036
|
const root = anyValue(rootArg, scope, code, mfs);
|
|
18020
|
-
if (!
|
|
18037
|
+
if (!isCombinator2(root)) return null;
|
|
18021
18038
|
try {
|
|
18022
18039
|
return parser(opts, root);
|
|
18023
18040
|
} catch {
|
|
@@ -18029,10 +18046,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18029
18046
|
if (!itemArg || !sepArg || itemArg.type === "SpreadElement" || sepArg.type === "SpreadElement") return null;
|
|
18030
18047
|
const itemMfs = [];
|
|
18031
18048
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18032
|
-
if (!
|
|
18049
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18033
18050
|
const sepMfs = [];
|
|
18034
18051
|
const sepCombi = anyValue(sepArg, scope, code, sepMfs);
|
|
18035
|
-
if (!
|
|
18052
|
+
if (!isCombinator2(sepCombi)) return null;
|
|
18036
18053
|
let opts;
|
|
18037
18054
|
if (optsArg) {
|
|
18038
18055
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18052,7 +18069,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18052
18069
|
if (!itemArg || itemArg.type === "SpreadElement") return null;
|
|
18053
18070
|
const itemMfs = [];
|
|
18054
18071
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18055
|
-
if (!
|
|
18072
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18056
18073
|
let opts;
|
|
18057
18074
|
if (optsArg) {
|
|
18058
18075
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18074,7 +18091,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18074
18091
|
const [innerArg] = node2.arguments;
|
|
18075
18092
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18076
18093
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18077
|
-
if (!
|
|
18094
|
+
if (!isCombinator2(inner)) return null;
|
|
18078
18095
|
try {
|
|
18079
18096
|
return not(inner);
|
|
18080
18097
|
} catch {
|
|
@@ -18085,7 +18102,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18085
18102
|
const [innerArg] = node2.arguments;
|
|
18086
18103
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18087
18104
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18088
|
-
if (!
|
|
18105
|
+
if (!isCombinator2(inner)) return null;
|
|
18089
18106
|
try {
|
|
18090
18107
|
return peek(inner);
|
|
18091
18108
|
} catch {
|
|
@@ -18098,7 +18115,8 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18098
18115
|
const open = anyValue(openArg, scope, code, []);
|
|
18099
18116
|
const close = anyValue(closeArg, scope, code, []);
|
|
18100
18117
|
if (typeof open !== "string" || typeof close !== "string") return null;
|
|
18101
|
-
const opts =
|
|
18118
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18119
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18102
18120
|
try {
|
|
18103
18121
|
return balanced(open, close, opts);
|
|
18104
18122
|
} catch {
|
|
@@ -18109,8 +18127,9 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18109
18127
|
const [sentinelArg, optsArg] = node2.arguments;
|
|
18110
18128
|
if (!sentinelArg || sentinelArg.type === "SpreadElement") return null;
|
|
18111
18129
|
const sentinel = anyValue(sentinelArg, scope, code, []);
|
|
18112
|
-
if (!
|
|
18113
|
-
const opts =
|
|
18130
|
+
if (!isCombinator2(sentinel)) return null;
|
|
18131
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18132
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18114
18133
|
try {
|
|
18115
18134
|
return scanTo(sentinel, opts);
|
|
18116
18135
|
} catch {
|
|
@@ -18139,7 +18158,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18139
18158
|
const extraSrc = stripTsFromSource(extraArg, code);
|
|
18140
18159
|
mfs.push(extraSrc);
|
|
18141
18160
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18142
|
-
if (!
|
|
18161
|
+
if (!isCombinator2(inner)) return null;
|
|
18143
18162
|
try {
|
|
18144
18163
|
const evaluated = anyValue(extraArg, scope, code, []);
|
|
18145
18164
|
const usable = typeof evaluated === "object" && evaluated !== null && !Array.isArray(evaluated) && Object.getPrototypeOf(evaluated) === Object.prototype;
|
|
@@ -18155,7 +18174,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18155
18174
|
const [selectorArg, ...armArgs] = node2.arguments;
|
|
18156
18175
|
if (!selectorArg || selectorArg.type === "SpreadElement") return null;
|
|
18157
18176
|
const selector = anyValue(selectorArg, scope, code, mfs);
|
|
18158
|
-
if (!
|
|
18177
|
+
if (!isCombinator2(selector)) return null;
|
|
18159
18178
|
const arms = [];
|
|
18160
18179
|
for (const arg of armArgs) {
|
|
18161
18180
|
if (arg.type === "SpreadElement") return null;
|
|
@@ -18182,12 +18201,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18182
18201
|
const gateSrc = stripTsFromSource(parts.gate, code);
|
|
18183
18202
|
mfs.push(gateSrc);
|
|
18184
18203
|
const combi = anyValue(parts.combinator, scope, code, mfs);
|
|
18185
|
-
if (!
|
|
18204
|
+
if (!isCombinator2(combi)) return null;
|
|
18186
18205
|
arms.push({ gate: () => true, combinator: combi });
|
|
18187
18206
|
gateSrcs.push(gateSrc);
|
|
18188
18207
|
} else {
|
|
18189
18208
|
const combi = anyValue(argNode, scope, code, mfs);
|
|
18190
|
-
if (!
|
|
18209
|
+
if (!isCombinator2(combi)) return null;
|
|
18191
18210
|
arms.push(combi);
|
|
18192
18211
|
gateSrcs.push(null);
|
|
18193
18212
|
}
|
|
@@ -18217,6 +18236,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18217
18236
|
return null;
|
|
18218
18237
|
}
|
|
18219
18238
|
}
|
|
18239
|
+
function isHole(node2, value, scope) {
|
|
18240
|
+
if (value !== null) return false;
|
|
18241
|
+
const n = unwrapStaticExpr(node2);
|
|
18242
|
+
if (n.type === "Identifier") return !scope.has(n.name);
|
|
18243
|
+
return !(n.type === "Literal" && n.value === null) && n.type !== "ArrowFunctionExpression" && n.type !== "FunctionExpression";
|
|
18244
|
+
}
|
|
18220
18245
|
function anyValue(node2, scope, code, mfs) {
|
|
18221
18246
|
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
18222
18247
|
const inner = node2.expression;
|
|
@@ -18237,7 +18262,9 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18237
18262
|
continue;
|
|
18238
18263
|
}
|
|
18239
18264
|
if (el.type === "SpreadElement") return null;
|
|
18240
|
-
|
|
18265
|
+
const v = anyValue(el, scope, code, mfs);
|
|
18266
|
+
if (isHole(el, v, scope)) return null;
|
|
18267
|
+
out.push(v);
|
|
18241
18268
|
}
|
|
18242
18269
|
return out;
|
|
18243
18270
|
}
|
|
@@ -18246,7 +18273,10 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18246
18273
|
for (const prop of node2.properties) {
|
|
18247
18274
|
const key = propName(prop);
|
|
18248
18275
|
if (key === null) return null;
|
|
18249
|
-
|
|
18276
|
+
const valueNode = prop.value;
|
|
18277
|
+
const v = anyValue(valueNode, scope, code, mfs);
|
|
18278
|
+
if (isHole(valueNode, v, scope)) return null;
|
|
18279
|
+
obj[key] = v;
|
|
18250
18280
|
}
|
|
18251
18281
|
return obj;
|
|
18252
18282
|
}
|
|
@@ -18322,10 +18352,9 @@ function evaluateExpr(node2, scope, code, mapFnSources) {
|
|
|
18322
18352
|
return exprToCombi(node2, scope, code, mapFnSources);
|
|
18323
18353
|
}
|
|
18324
18354
|
function evaluateCombinatorArray(node2, scope, code) {
|
|
18325
|
-
if (node2.type !== "ArrayExpression") return null;
|
|
18326
18355
|
const val = anyValue(node2, scope, code, []);
|
|
18327
18356
|
if (!Array.isArray(val) || val.length === 0) return null;
|
|
18328
|
-
if (!val.every(
|
|
18357
|
+
if (!val.every(isCombinator2)) return null;
|
|
18329
18358
|
return val;
|
|
18330
18359
|
}
|
|
18331
18360
|
function collectRuleKeys(retObj) {
|
|
@@ -18403,7 +18432,7 @@ function evalBodyStatements(statements, scope, code, out) {
|
|
|
18403
18432
|
return false;
|
|
18404
18433
|
}
|
|
18405
18434
|
const thisDeclMfSrcs = bodyMfs.slice(before);
|
|
18406
|
-
if (
|
|
18435
|
+
if (isCombinator2(val)) scope.set(name, { combi: val, mfSrcs: thisDeclMfSrcs });
|
|
18407
18436
|
else if (isDispatchArm(val)) scope.set(name, { value: val, mfSrcs: thisDeclMfSrcs });
|
|
18408
18437
|
else scope.set(name, val);
|
|
18409
18438
|
}
|
|
@@ -18448,7 +18477,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18448
18477
|
let built;
|
|
18449
18478
|
try {
|
|
18450
18479
|
built = rules(options ?? {}, (g) => {
|
|
18451
|
-
const localScope = new Map(scope);
|
|
18480
|
+
const localScope = scope instanceof ModuleScope ? scope.fork() : new Map(scope);
|
|
18452
18481
|
localScope.set(proxyName, g);
|
|
18453
18482
|
if (!evalBodyStatements(statements, localScope, code, out)) throw ABORT;
|
|
18454
18483
|
const entries = flattenRuleEntries(retObj, localScope, code);
|
|
@@ -18458,7 +18487,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18458
18487
|
const definitions = {};
|
|
18459
18488
|
for (const [key, e] of finalByKey) {
|
|
18460
18489
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
18461
|
-
if (!
|
|
18490
|
+
if (!isCombinator2(val)) throw ABORT;
|
|
18462
18491
|
definitions[key] = val;
|
|
18463
18492
|
}
|
|
18464
18493
|
return definitions;
|
|
@@ -18473,7 +18502,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18473
18502
|
return map;
|
|
18474
18503
|
}
|
|
18475
18504
|
function isDefinableRef2(v) {
|
|
18476
|
-
return
|
|
18505
|
+
return isCombinator2(v) && typeof v.define === "function" && v._def.tag === "lazy";
|
|
18477
18506
|
}
|
|
18478
18507
|
function evaluateRefDeclaration(init, name, scope) {
|
|
18479
18508
|
if (init.type !== "CallExpression") return null;
|
|
@@ -18493,12 +18522,12 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18493
18522
|
if (mem.property.type !== "Identifier" || mem.property.name !== "define") return false;
|
|
18494
18523
|
if (mem.object.type !== "Identifier" || !mem.object.name) return false;
|
|
18495
18524
|
const target = scope.get(mem.object.name);
|
|
18496
|
-
const refCombi = isScopeEntry(target) ? target.combi :
|
|
18525
|
+
const refCombi = isScopeEntry(target) ? target.combi : isCombinator2(target) ? target : null;
|
|
18497
18526
|
if (!refCombi || !isDefinableRef2(refCombi)) return false;
|
|
18498
18527
|
const args = callExpr.arguments;
|
|
18499
18528
|
if (args.length !== 1 || args[0].type === "SpreadElement") return false;
|
|
18500
18529
|
const inner = anyValue(args[0], scope, code, []);
|
|
18501
|
-
if (!
|
|
18530
|
+
if (!isCombinator2(inner)) return false;
|
|
18502
18531
|
try {
|
|
18503
18532
|
refCombi.define(inner);
|
|
18504
18533
|
} catch {
|
|
@@ -18508,7 +18537,7 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18508
18537
|
}
|
|
18509
18538
|
function referencesAny(node2, names, scope) {
|
|
18510
18539
|
if (node2.type === "Identifier") {
|
|
18511
|
-
return names.has(node2.name) ||
|
|
18540
|
+
return names.has(node2.name) || Map.prototype.has.call(scope, node2.name);
|
|
18512
18541
|
}
|
|
18513
18542
|
for (const key of Object.keys(node2)) {
|
|
18514
18543
|
const child = node2[key];
|
|
@@ -18569,7 +18598,9 @@ function patternNames(pat, out) {
|
|
|
18569
18598
|
}
|
|
18570
18599
|
}
|
|
18571
18600
|
function declare(scope, name, b) {
|
|
18572
|
-
|
|
18601
|
+
const prev = scope.bindings.get(name);
|
|
18602
|
+
if (prev) prev.reassigned = true;
|
|
18603
|
+
else scope.bindings.set(name, b);
|
|
18573
18604
|
}
|
|
18574
18605
|
function functionScope(scope) {
|
|
18575
18606
|
let s = scope;
|
|
@@ -18669,7 +18700,8 @@ function markReassignments(body, root) {
|
|
|
18669
18700
|
}
|
|
18670
18701
|
const node2 = n;
|
|
18671
18702
|
if (typeof node2.type !== "string") return;
|
|
18672
|
-
|
|
18703
|
+
const loopWrite = (node2.type === "ForOfStatement" || node2.type === "ForInStatement") && node2.left?.type !== "VariableDeclaration";
|
|
18704
|
+
if (node2.type === "AssignmentExpression" || node2.type === "UpdateExpression" || loopWrite) {
|
|
18673
18705
|
const target = node2.type === "UpdateExpression" ? node2.argument : node2.left;
|
|
18674
18706
|
const names = [];
|
|
18675
18707
|
if (target) patternNames(target, names);
|
|
@@ -18685,6 +18717,11 @@ function markReassignments(body, root) {
|
|
|
18685
18717
|
};
|
|
18686
18718
|
for (const stmt of body) walk(stmt);
|
|
18687
18719
|
}
|
|
18720
|
+
function topLevelIsStable(body, moduleEnd) {
|
|
18721
|
+
const root = buildScopeTree(body, moduleEnd);
|
|
18722
|
+
markReassignments(body, root);
|
|
18723
|
+
return (name) => root.bindings.get(name)?.reassigned !== true;
|
|
18724
|
+
}
|
|
18688
18725
|
function functionArity(fn) {
|
|
18689
18726
|
const params = fn.params ?? [];
|
|
18690
18727
|
let count = 0;
|
|
@@ -19137,7 +19174,7 @@ function ast(value) {
|
|
|
19137
19174
|
function nodes(value) {
|
|
19138
19175
|
return Array.isArray(value) ? value.filter((v) => ast(v) !== void 0) : [];
|
|
19139
19176
|
}
|
|
19140
|
-
function
|
|
19177
|
+
function nameOf2(node2) {
|
|
19141
19178
|
return node2?.type === "Identifier" && typeof node2.name === "string" ? node2.name : void 0;
|
|
19142
19179
|
}
|
|
19143
19180
|
function range(node2) {
|
|
@@ -19170,7 +19207,7 @@ function isDirectCallUse(call, parent, statement) {
|
|
|
19170
19207
|
return declarations.length === 1 && declarations[0] === parent && parent.init === call;
|
|
19171
19208
|
}
|
|
19172
19209
|
if (parent.type === "AssignmentExpression") {
|
|
19173
|
-
return statement.type === "ExpressionStatement" && statement.expression === parent &&
|
|
19210
|
+
return statement.type === "ExpressionStatement" && statement.expression === parent && nameOf2(ast(parent.left)) !== void 0 && parent.right === call && parent.operator === "=";
|
|
19174
19211
|
}
|
|
19175
19212
|
if (parent.type === "ReturnStatement") return statement === parent && parent.argument === call;
|
|
19176
19213
|
return false;
|
|
@@ -19188,7 +19225,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19188
19225
|
if (node2.type === "Identifier" && node2.name === "arguments") hazard = true;
|
|
19189
19226
|
else if (node2.type === "ThisExpression") hazard = true;
|
|
19190
19227
|
else if (node2.type === "VariableDeclaration" && node2.kind === "var") hazard = true;
|
|
19191
|
-
else if (node2.type === "MetaProperty" &&
|
|
19228
|
+
else if (node2.type === "MetaProperty" && nameOf2(ast(node2.meta)) === "new" && nameOf2(ast(node2.property)) === "target") hazard = true;
|
|
19192
19229
|
else for (const child of children2(node2)) walk(child);
|
|
19193
19230
|
};
|
|
19194
19231
|
walk(fn.body);
|
|
@@ -19196,7 +19233,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19196
19233
|
}
|
|
19197
19234
|
function hasInlineSignature(fn) {
|
|
19198
19235
|
const params = nodes(fn.node.params);
|
|
19199
|
-
return params.length === 3 &&
|
|
19236
|
+
return params.length === 3 && nameOf2(params[0]) === "input" && nameOf2(params[1]) === "pos" && nameOf2(params[2]) === "ctx";
|
|
19200
19237
|
}
|
|
19201
19238
|
function render2(source, start, end, edits) {
|
|
19202
19239
|
const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
@@ -19289,7 +19326,7 @@ function supercompileRuleMapReplacement(prog, replacement) {
|
|
|
19289
19326
|
const call = ast(declarator?.init);
|
|
19290
19327
|
const table = nodes(call?.arguments)[0];
|
|
19291
19328
|
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" &&
|
|
19329
|
+
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" && nameOf2(ast(prop.key)) === key);
|
|
19293
19330
|
const assembliesProp = property(table, "a");
|
|
19294
19331
|
const assemblies = nodes(ast(assembliesProp?.value)?.elements);
|
|
19295
19332
|
if (assembliesProp === void 0 || assemblies.length !== 1 || assemblies[0]?.type !== "ObjectExpression") return replacement;
|
|
@@ -19322,7 +19359,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19322
19359
|
const fns = /* @__PURE__ */ new Map();
|
|
19323
19360
|
for (const statement of nodes(wrapperBody.body)) {
|
|
19324
19361
|
if (statement.type !== "FunctionDeclaration") continue;
|
|
19325
|
-
const name =
|
|
19362
|
+
const name = nameOf2(ast(statement.id));
|
|
19326
19363
|
const hit = name === void 0 ? void 0 : PIECE.exec(name);
|
|
19327
19364
|
const body = ast(statement.body);
|
|
19328
19365
|
if (hit !== void 0 && hit !== null && body?.type === "BlockStatement") {
|
|
@@ -19335,7 +19372,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19335
19372
|
const allCalls = [];
|
|
19336
19373
|
const walk = (node2, current, parent, statement, statementParent) => {
|
|
19337
19374
|
if (isFunction(node2) && node2 !== current?.node) {
|
|
19338
|
-
const own = node2.type === "FunctionDeclaration" ?
|
|
19375
|
+
const own = node2.type === "FunctionDeclaration" ? nameOf2(ast(node2.id)) : void 0;
|
|
19339
19376
|
const hit = own === void 0 ? void 0 : PIECE.exec(own);
|
|
19340
19377
|
if (hit !== void 0 && hit !== null) {
|
|
19341
19378
|
const fn = fns.get(Number(hit[1]));
|
|
@@ -19359,12 +19396,12 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19359
19396
|
ownerParent = parent;
|
|
19360
19397
|
}
|
|
19361
19398
|
if (node2.type === "CallExpression") {
|
|
19362
|
-
const calleeName =
|
|
19399
|
+
const calleeName = nameOf2(ast(node2.callee));
|
|
19363
19400
|
const hit = calleeName === void 0 ? void 0 : PIECE.exec(calleeName);
|
|
19364
19401
|
if (hit !== void 0 && hit !== null) {
|
|
19365
19402
|
const callee = Number(hit[1]);
|
|
19366
19403
|
const args = nodes(node2.arguments);
|
|
19367
|
-
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 &&
|
|
19404
|
+
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
19405
|
if (current === void 0 || owner2 === void 0) externalRefs.add(callee);
|
|
19369
19406
|
else {
|
|
19370
19407
|
const call = { caller: current.ip, callee, node: node2, statement: owner2, args, transformable };
|
|
@@ -19539,7 +19576,7 @@ ${nested}
|
|
|
19539
19576
|
const referenced = /* @__PURE__ */ new Set();
|
|
19540
19577
|
const checkRefs = (node2, parent) => {
|
|
19541
19578
|
if (node2.type === "FunctionDeclaration") {
|
|
19542
|
-
const name =
|
|
19579
|
+
const name = nameOf2(ast(node2.id));
|
|
19543
19580
|
if (name !== void 0 && PIECE.test(name)) declared.add(name);
|
|
19544
19581
|
}
|
|
19545
19582
|
if (node2.type === "Identifier" && typeof node2.name === "string" && PIECE.test(node2.name)) {
|
|
@@ -19548,32 +19585,210 @@ ${nested}
|
|
|
19548
19585
|
}
|
|
19549
19586
|
for (const child of children2(node2)) checkRefs(child, node2);
|
|
19550
19587
|
};
|
|
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
|
|
19588
|
+
checkRefs(checked.program);
|
|
19589
|
+
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19590
|
+
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19591
|
+
}
|
|
19592
|
+
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19593
|
+
const protocolRegions = {
|
|
19594
|
+
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19595
|
+
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19596
|
+
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19597
|
+
};
|
|
19598
|
+
return {
|
|
19599
|
+
...emitted,
|
|
19600
|
+
source: candidate,
|
|
19601
|
+
supercompile: {
|
|
19602
|
+
...before,
|
|
19603
|
+
activated: removed > 0,
|
|
19604
|
+
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19605
|
+
functionsAfter,
|
|
19606
|
+
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19607
|
+
sourceAfter: candidate.length,
|
|
19608
|
+
regions: roots.length,
|
|
19609
|
+
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19610
|
+
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19611
|
+
protocolRegions
|
|
19612
|
+
}
|
|
19613
|
+
};
|
|
19614
|
+
}
|
|
19615
|
+
|
|
19616
|
+
// src/plugin/ir-eval.ts
|
|
19617
|
+
function evalRulesIR(ir) {
|
|
19618
|
+
return evalIR(ir, rules);
|
|
19619
|
+
}
|
|
19620
|
+
function evalCombinatorIR(ir) {
|
|
19621
|
+
const units = evalIR(ir, (opts) => opts.scanSkip);
|
|
19622
|
+
return units?.length === 1 ? units[0] : null;
|
|
19623
|
+
}
|
|
19624
|
+
function evalIR(ir, rulesImpl) {
|
|
19625
|
+
const _tf = (child, src, recognitionOnly = false) => {
|
|
19626
|
+
let fn2;
|
|
19627
|
+
try {
|
|
19628
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19629
|
+
} catch {
|
|
19630
|
+
fn2 = () => {
|
|
19631
|
+
throw new Error("IR transform fn not materialized");
|
|
19632
|
+
};
|
|
19633
|
+
}
|
|
19634
|
+
const t = transform(child, fn2);
|
|
19635
|
+
t._def.fnSrc = src;
|
|
19636
|
+
if (recognitionOnly) t._def.recognitionOnly = true;
|
|
19637
|
+
return t;
|
|
19638
|
+
};
|
|
19639
|
+
const _lf = (child, src, source = false) => {
|
|
19640
|
+
let fn2;
|
|
19641
|
+
try {
|
|
19642
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19643
|
+
} catch {
|
|
19644
|
+
fn2 = () => {
|
|
19645
|
+
throw new Error("IR leaf fn not materialized");
|
|
19646
|
+
};
|
|
19647
|
+
}
|
|
19648
|
+
const l = source ? sourceLeaf(child, fn2) : leaf(child, fn2);
|
|
19649
|
+
l._def.fnSrc = src;
|
|
19650
|
+
return l;
|
|
19651
|
+
};
|
|
19652
|
+
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
19653
|
+
if (staticError !== void 0 && staticError.length > 0) {
|
|
19654
|
+
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
19655
|
+
}
|
|
19656
|
+
const n = node(type, child, (() => {
|
|
19657
|
+
throw new Error("IR node build requires static re-lowering");
|
|
19658
|
+
}), opts);
|
|
19659
|
+
n._def.buildSrc = src;
|
|
19660
|
+
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
19661
|
+
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
19662
|
+
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
19663
|
+
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
19664
|
+
return n;
|
|
19665
|
+
};
|
|
19666
|
+
const _gch = (items) => {
|
|
19667
|
+
const gateSrcs = [];
|
|
19668
|
+
const arms = items.map((it) => {
|
|
19669
|
+
if (Array.isArray(it)) {
|
|
19670
|
+
const [src, comb] = it;
|
|
19671
|
+
gateSrcs.push(src);
|
|
19672
|
+
let gate2;
|
|
19673
|
+
try {
|
|
19674
|
+
gate2 = (0, eval)(`(${src})`);
|
|
19675
|
+
} catch {
|
|
19676
|
+
gate2 = () => {
|
|
19677
|
+
throw new Error("IR gate fn not materialized");
|
|
19678
|
+
};
|
|
19679
|
+
}
|
|
19680
|
+
return { gate: gate2, combinator: comb };
|
|
19681
|
+
}
|
|
19682
|
+
gateSrcs.push(null);
|
|
19683
|
+
return it;
|
|
19684
|
+
});
|
|
19685
|
+
const c = choice(...arms);
|
|
19686
|
+
const gates = c._def.gates;
|
|
19687
|
+
if (gates && gates.length !== gateSrcs.length) {
|
|
19688
|
+
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
19689
|
+
}
|
|
19690
|
+
;
|
|
19691
|
+
c._def.gateSrcs = gateSrcs;
|
|
19692
|
+
return c;
|
|
19560
19693
|
};
|
|
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
|
|
19694
|
+
const _wc = (src, inner) => {
|
|
19695
|
+
let extra;
|
|
19696
|
+
try {
|
|
19697
|
+
extra = (0, eval)(`(${src})`);
|
|
19698
|
+
} catch {
|
|
19699
|
+
extra = void 0;
|
|
19575
19700
|
}
|
|
19701
|
+
const w = withCtx(extra, inner);
|
|
19702
|
+
w._def.extraSrc = src;
|
|
19703
|
+
return w;
|
|
19576
19704
|
};
|
|
19705
|
+
const fn = new Function(
|
|
19706
|
+
"rules",
|
|
19707
|
+
"ref",
|
|
19708
|
+
"regex",
|
|
19709
|
+
"literal",
|
|
19710
|
+
"keywords",
|
|
19711
|
+
"sequence",
|
|
19712
|
+
"choice",
|
|
19713
|
+
"dispatch",
|
|
19714
|
+
"when",
|
|
19715
|
+
"startsWith",
|
|
19716
|
+
"endsWith",
|
|
19717
|
+
"matches",
|
|
19718
|
+
"otherwise",
|
|
19719
|
+
"routed",
|
|
19720
|
+
"attempt",
|
|
19721
|
+
"many",
|
|
19722
|
+
"oneOrMore",
|
|
19723
|
+
"optional",
|
|
19724
|
+
"sepBy",
|
|
19725
|
+
"keepSeparator",
|
|
19726
|
+
"not",
|
|
19727
|
+
"peek",
|
|
19728
|
+
"node",
|
|
19729
|
+
"parser",
|
|
19730
|
+
"scanTo",
|
|
19731
|
+
"balanced",
|
|
19732
|
+
"token",
|
|
19733
|
+
"leaf",
|
|
19734
|
+
"transform",
|
|
19735
|
+
"trivia",
|
|
19736
|
+
"classifiedTrivia",
|
|
19737
|
+
"label",
|
|
19738
|
+
"field",
|
|
19739
|
+
"expect",
|
|
19740
|
+
"adjacent",
|
|
19741
|
+
"notAdjacent",
|
|
19742
|
+
"_tf",
|
|
19743
|
+
"_lf",
|
|
19744
|
+
"_nd",
|
|
19745
|
+
"_gch",
|
|
19746
|
+
"_wc",
|
|
19747
|
+
`return (${ir})`
|
|
19748
|
+
);
|
|
19749
|
+
return fn(
|
|
19750
|
+
rulesImpl,
|
|
19751
|
+
ref,
|
|
19752
|
+
regex,
|
|
19753
|
+
literal,
|
|
19754
|
+
keywords,
|
|
19755
|
+
sequence,
|
|
19756
|
+
choice,
|
|
19757
|
+
dispatch,
|
|
19758
|
+
when,
|
|
19759
|
+
startsWith,
|
|
19760
|
+
endsWith,
|
|
19761
|
+
matches,
|
|
19762
|
+
otherwise,
|
|
19763
|
+
routed,
|
|
19764
|
+
attempt,
|
|
19765
|
+
many,
|
|
19766
|
+
oneOrMore,
|
|
19767
|
+
optional,
|
|
19768
|
+
sepBy,
|
|
19769
|
+
keepSeparator,
|
|
19770
|
+
not,
|
|
19771
|
+
peek,
|
|
19772
|
+
node,
|
|
19773
|
+
parser,
|
|
19774
|
+
scanTo,
|
|
19775
|
+
balanced,
|
|
19776
|
+
token,
|
|
19777
|
+
leaf,
|
|
19778
|
+
transform,
|
|
19779
|
+
trivia,
|
|
19780
|
+
classifiedTrivia,
|
|
19781
|
+
label,
|
|
19782
|
+
field,
|
|
19783
|
+
expect,
|
|
19784
|
+
adjacent,
|
|
19785
|
+
notAdjacent,
|
|
19786
|
+
_tf,
|
|
19787
|
+
_lf,
|
|
19788
|
+
_nd,
|
|
19789
|
+
_gch,
|
|
19790
|
+
_wc
|
|
19791
|
+
);
|
|
19577
19792
|
}
|
|
19578
19793
|
|
|
19579
19794
|
// src/plugin/index.ts
|
|
@@ -19738,13 +19953,30 @@ function topLevelInit(body, name) {
|
|
|
19738
19953
|
}
|
|
19739
19954
|
return null;
|
|
19740
19955
|
}
|
|
19741
|
-
function
|
|
19956
|
+
function isSymbolFor(n, key) {
|
|
19742
19957
|
if (!n || n.type !== "CallExpression") return false;
|
|
19743
19958
|
const callee = n.callee;
|
|
19744
19959
|
const obj = callee?.object?.name;
|
|
19745
19960
|
const prop = callee?.property?.name;
|
|
19746
19961
|
const arg0 = n.arguments?.[0];
|
|
19747
|
-
return obj === "Symbol" && prop === "for" && arg0?.value ===
|
|
19962
|
+
return obj === "Symbol" && prop === "for" && arg0?.value === key;
|
|
19963
|
+
}
|
|
19964
|
+
var isComposedPiecesSymbol = (n) => isSymbolFor(n, "parseman.composedPieces");
|
|
19965
|
+
var COMBINATOR_IR_KEY = "parseman.combinatorIR";
|
|
19966
|
+
function carriedCombinatorIR(init) {
|
|
19967
|
+
let n = init;
|
|
19968
|
+
while (n.type === "ParenthesizedExpression") n = n.expression;
|
|
19969
|
+
if (n.type !== "CallExpression") return null;
|
|
19970
|
+
const callee = n.callee;
|
|
19971
|
+
const args = n.arguments;
|
|
19972
|
+
if (callee.object?.name !== "Object" || callee.property?.name !== "defineProperty" || !isSymbolFor(args[1], COMBINATOR_IR_KEY)) return null;
|
|
19973
|
+
for (const p of args[2]?.properties ?? []) {
|
|
19974
|
+
const v = p.value;
|
|
19975
|
+
if (propName(p) !== "value") continue;
|
|
19976
|
+
if (v?.type === "Literal" && typeof v.value === "string") return v.value;
|
|
19977
|
+
if (v?.type === "TemplateLiteral" && v.expressions?.length === 0) return v.quasis?.[0]?.value.cooked ?? null;
|
|
19978
|
+
}
|
|
19979
|
+
return null;
|
|
19748
19980
|
}
|
|
19749
19981
|
function findCarriedPiecesLiteral(root) {
|
|
19750
19982
|
let found = null;
|
|
@@ -19760,7 +19992,7 @@ function findCarriedPiecesLiteral(root) {
|
|
|
19760
19992
|
const obj = callee?.object?.name;
|
|
19761
19993
|
const prop = callee?.property?.name;
|
|
19762
19994
|
const args = node2.arguments;
|
|
19763
|
-
if (callee?.type === "Identifier" &&
|
|
19995
|
+
if (callee?.type === "Identifier" && args?.[1]?.type === "ObjectExpression") {
|
|
19764
19996
|
for (const p of args[1].properties ?? []) {
|
|
19765
19997
|
if (p.computed && isComposedPiecesSymbol(p.key) && p.value) {
|
|
19766
19998
|
found = { start: p.value.start, end: p.value.end };
|
|
@@ -19860,13 +20092,14 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19860
20092
|
const allNames = /* @__PURE__ */ new Set();
|
|
19861
20093
|
const importBindings = /* @__PURE__ */ new Map();
|
|
19862
20094
|
const ordinaryImports = [];
|
|
20095
|
+
const isMacroImport = (s) => s.attributes.some((a) => {
|
|
20096
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
20097
|
+
return key === "type" && a.value.value === "macro";
|
|
20098
|
+
});
|
|
19863
20099
|
for (const stmt of body) {
|
|
19864
20100
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
19865
20101
|
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
|
-
});
|
|
20102
|
+
const isMacro = moduleAliases.has(s.source.value) && isMacroImport(s);
|
|
19870
20103
|
if (!isMacro) {
|
|
19871
20104
|
const specifiers = [];
|
|
19872
20105
|
for (const spec of s.specifiers) {
|
|
@@ -19909,7 +20142,209 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19909
20142
|
}
|
|
19910
20143
|
const reducerResolver = createReducerResolver(id, body, code);
|
|
19911
20144
|
setReducerResolver(reducerResolver, code);
|
|
19912
|
-
|
|
20145
|
+
let builderImports = (name) => importBindings.get(name) ?? null;
|
|
20146
|
+
setBuilderImportResolver((name) => builderImports(name));
|
|
20147
|
+
const ownRoot = nearestPackageRoot(id);
|
|
20148
|
+
let ownDir = path2.dirname(id);
|
|
20149
|
+
try {
|
|
20150
|
+
ownDir = fs2.realpathSync(ownDir);
|
|
20151
|
+
} catch {
|
|
20152
|
+
}
|
|
20153
|
+
const rebaseSpecifier = (from, spec) => {
|
|
20154
|
+
if (!spec.startsWith(".")) return spec;
|
|
20155
|
+
const target = path2.resolve(path2.dirname(from), spec);
|
|
20156
|
+
if (ownRoot === null || nearestPackageRoot(target) !== ownRoot) return null;
|
|
20157
|
+
const rel = path2.relative(ownDir, target).split(path2.sep).join("/");
|
|
20158
|
+
return rel.startsWith("../") ? rel : `./${rel}`;
|
|
20159
|
+
};
|
|
20160
|
+
const unresolvedImports = /* @__PURE__ */ new Set();
|
|
20161
|
+
const valueModules = /* @__PURE__ */ new Map();
|
|
20162
|
+
const OPAQUE_IMPORT = "is a default or namespace import, which the macro does not resolve \u2014 import the binding by name";
|
|
20163
|
+
const opaqueImportsOf = (moduleBody) => {
|
|
20164
|
+
const out = /* @__PURE__ */ new Set();
|
|
20165
|
+
for (const st of moduleBody) {
|
|
20166
|
+
if (st.type !== "ImportDeclaration") continue;
|
|
20167
|
+
for (const sp of st.specifiers) {
|
|
20168
|
+
if (sp.type !== "ImportSpecifier") out.add(sp.local.name);
|
|
20169
|
+
}
|
|
20170
|
+
}
|
|
20171
|
+
return out;
|
|
20172
|
+
};
|
|
20173
|
+
const valueModule = (file) => {
|
|
20174
|
+
if (valueModules.has(file)) return valueModules.get(file);
|
|
20175
|
+
const mod = parseModuleCached(file);
|
|
20176
|
+
let out = null;
|
|
20177
|
+
if (mod) {
|
|
20178
|
+
const consts = /* @__PURE__ */ new Map();
|
|
20179
|
+
let stable;
|
|
20180
|
+
for (const st of mod.body) {
|
|
20181
|
+
const vd = unwrapVd(st);
|
|
20182
|
+
if (!vd) continue;
|
|
20183
|
+
const isConst = vd.kind === "const";
|
|
20184
|
+
for (const d of vd.declarations) {
|
|
20185
|
+
const idn = d.id;
|
|
20186
|
+
if (idn.type !== "Identifier" || !idn.name || !d.init) continue;
|
|
20187
|
+
if (isConst || (stable ??= topLevelIsStable(mod.body, mod.src.length))(idn.name)) consts.set(idn.name, d.init);
|
|
20188
|
+
}
|
|
20189
|
+
}
|
|
20190
|
+
out = {
|
|
20191
|
+
file,
|
|
20192
|
+
src: mod.src,
|
|
20193
|
+
body: mod.body,
|
|
20194
|
+
consts,
|
|
20195
|
+
imports: extractImportBindings(mod.body),
|
|
20196
|
+
opaqueImports: opaqueImportsOf(mod.body)
|
|
20197
|
+
};
|
|
20198
|
+
}
|
|
20199
|
+
valueModules.set(file, out);
|
|
20200
|
+
return out;
|
|
20201
|
+
};
|
|
20202
|
+
const resolveValueFile = (from, specifier) => {
|
|
20203
|
+
const source = resolvePrivateSourceModule(from, specifier);
|
|
20204
|
+
if (source) return source;
|
|
20205
|
+
try {
|
|
20206
|
+
return getCompiledResolver().resolveFileSync(from, specifier).path ?? null;
|
|
20207
|
+
} catch {
|
|
20208
|
+
return null;
|
|
20209
|
+
}
|
|
20210
|
+
};
|
|
20211
|
+
const evaluatingConsts = /* @__PURE__ */ new Set();
|
|
20212
|
+
const rebaseCarriedBuilderImports = (combi, from) => {
|
|
20213
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20214
|
+
const walk = (v) => {
|
|
20215
|
+
if (v === null || typeof v !== "object" || seen.has(v)) return null;
|
|
20216
|
+
seen.add(v);
|
|
20217
|
+
const def = v._def;
|
|
20218
|
+
if (def?.buildImports) {
|
|
20219
|
+
const out = [];
|
|
20220
|
+
for (const bi of def.buildImports) {
|
|
20221
|
+
const source = rebaseSpecifier(from, bi.source);
|
|
20222
|
+
if (source === null) return bi;
|
|
20223
|
+
out.push({ ...bi, source });
|
|
20224
|
+
}
|
|
20225
|
+
def.buildImports = out;
|
|
20226
|
+
}
|
|
20227
|
+
for (const child of Object.values(v)) {
|
|
20228
|
+
for (const c of Array.isArray(child) ? child : [child]) {
|
|
20229
|
+
const stuck = walk(c);
|
|
20230
|
+
if (stuck) return stuck;
|
|
20231
|
+
}
|
|
20232
|
+
}
|
|
20233
|
+
return null;
|
|
20234
|
+
};
|
|
20235
|
+
return walk(combi);
|
|
20236
|
+
};
|
|
20237
|
+
const moduleConstValue = (m, name) => {
|
|
20238
|
+
const key = `${m.file}\0${name}`;
|
|
20239
|
+
if (evaluatingConsts.has(key)) return { unresolved: `is part of a declaration cycle in ${m.file}` };
|
|
20240
|
+
evaluatingConsts.add(key);
|
|
20241
|
+
const outerBuilderImports = builderImports;
|
|
20242
|
+
try {
|
|
20243
|
+
const init = m.consts.get(name);
|
|
20244
|
+
const ir = carriedCombinatorIR(init);
|
|
20245
|
+
if (ir !== null) {
|
|
20246
|
+
let combi2 = null;
|
|
20247
|
+
let why = "";
|
|
20248
|
+
try {
|
|
20249
|
+
combi2 = evalCombinatorIR(ir);
|
|
20250
|
+
} catch (e) {
|
|
20251
|
+
why = `: ${e.message}`;
|
|
20252
|
+
}
|
|
20253
|
+
if (!combi2) return { unresolved: `carries combinator IR that does not evaluate (${m.file})${why}` };
|
|
20254
|
+
const stuck = rebaseCarriedBuilderImports(combi2, m.file);
|
|
20255
|
+
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: [] } };
|
|
20256
|
+
}
|
|
20257
|
+
const scope2 = moduleValueScope(m);
|
|
20258
|
+
reducerResolver.register(m.file);
|
|
20259
|
+
builderImports = (name2) => {
|
|
20260
|
+
const b = m.imports.get(name2);
|
|
20261
|
+
const source = b ? rebaseSpecifier(m.file, b.source) : null;
|
|
20262
|
+
return b && source !== null ? { source, imported: b.imported } : null;
|
|
20263
|
+
};
|
|
20264
|
+
const mfs = [];
|
|
20265
|
+
const combi = evaluateExpr(init, scope2, m.src, mfs);
|
|
20266
|
+
if (combi) return { value: { combi, mfSrcs: mfs } };
|
|
20267
|
+
const factory = evaluateWordFactory(init, scope2, m.src) ?? evaluateWhenFactory(init, scope2, m.src);
|
|
20268
|
+
if (factory) return { value: factory };
|
|
20269
|
+
const value = evaluateStaticValue(init, scope2, m.src);
|
|
20270
|
+
if (value !== null && value !== void 0 || isStaticNullishExpression(init)) return { value };
|
|
20271
|
+
return {
|
|
20272
|
+
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})`
|
|
20273
|
+
};
|
|
20274
|
+
} finally {
|
|
20275
|
+
evaluatingConsts.delete(key);
|
|
20276
|
+
builderImports = outerBuilderImports;
|
|
20277
|
+
}
|
|
20278
|
+
};
|
|
20279
|
+
const moduleValueScope = (m) => m.scope ??= new ModuleScope((name) => {
|
|
20280
|
+
if (m.consts.has(name)) return moduleConstValue(m, name);
|
|
20281
|
+
const binding = m.imports.get(name);
|
|
20282
|
+
if (binding) return importedValue(m.file, binding);
|
|
20283
|
+
return m.opaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20284
|
+
}, unresolvedImports);
|
|
20285
|
+
const exportedValue = (m, name, depth) => {
|
|
20286
|
+
for (const st of m.body) {
|
|
20287
|
+
if (st.type !== "ExportNamedDeclaration" || !st.source) continue;
|
|
20288
|
+
for (const sp of st.specifiers ?? []) {
|
|
20289
|
+
if (sp.exported.name !== name) continue;
|
|
20290
|
+
const source = st.source.value;
|
|
20291
|
+
const file = depth < 16 ? resolveValueFile(m.file, source) : null;
|
|
20292
|
+
const next = file ? valueModule(file) : null;
|
|
20293
|
+
if (!next) return { unresolved: `is re-exported from '${source}', which does not resolve from ${m.file}` };
|
|
20294
|
+
return exportedValue(next, sp.local.name, depth + 1);
|
|
20295
|
+
}
|
|
20296
|
+
}
|
|
20297
|
+
const local = exportLocalName(m.body, name);
|
|
20298
|
+
if (local === null) {
|
|
20299
|
+
for (const st of m.body) {
|
|
20300
|
+
if (st.type !== "ExportAllDeclaration" || st.exported) continue;
|
|
20301
|
+
const file = depth < 16 ? resolveValueFile(m.file, st.source.value) : null;
|
|
20302
|
+
const next = file ? valueModule(file) : null;
|
|
20303
|
+
if (!next) continue;
|
|
20304
|
+
const r = exportedValue(next, name, depth + 1);
|
|
20305
|
+
if (r !== null && "unresolved" in r && r.unresolved.startsWith("is not exported by ")) continue;
|
|
20306
|
+
return r;
|
|
20307
|
+
}
|
|
20308
|
+
return { unresolved: `is not exported by ${m.file}` };
|
|
20309
|
+
}
|
|
20310
|
+
const scope2 = moduleValueScope(m);
|
|
20311
|
+
if (!scope2.has(local)) {
|
|
20312
|
+
scope2.get(local);
|
|
20313
|
+
return { unresolved: `could not be resolved in ${m.file}` };
|
|
20314
|
+
}
|
|
20315
|
+
return { value: scope2.get(local) };
|
|
20316
|
+
};
|
|
20317
|
+
const importedValue = (from, binding) => {
|
|
20318
|
+
const file = resolveValueFile(from, binding.source);
|
|
20319
|
+
const m = file ? valueModule(file) : null;
|
|
20320
|
+
if (!m) return { unresolved: `is imported from '${binding.source}', which does not resolve from ${from}` };
|
|
20321
|
+
return exportedValue(m, binding.imported, 0);
|
|
20322
|
+
};
|
|
20323
|
+
const deferredLocals = /* @__PURE__ */ new Map();
|
|
20324
|
+
const deferredResults = /* @__PURE__ */ new Map();
|
|
20325
|
+
const mainOpaqueImports = opaqueImportsOf(body);
|
|
20326
|
+
const resolveMainFree = (name) => {
|
|
20327
|
+
const done = deferredResults.get(name);
|
|
20328
|
+
if (done !== void 0) return done;
|
|
20329
|
+
const deferred = deferredLocals.get(name);
|
|
20330
|
+
if (deferred !== void 0) {
|
|
20331
|
+
deferredLocals.delete(name);
|
|
20332
|
+
const outer = [...unresolvedImports];
|
|
20333
|
+
unresolvedImports.clear();
|
|
20334
|
+
const value = evaluateStaticValue(deferred, scope, code);
|
|
20335
|
+
const why = [...unresolvedImports];
|
|
20336
|
+
unresolvedImports.clear();
|
|
20337
|
+
for (const n of outer) unresolvedImports.add(n);
|
|
20338
|
+
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;
|
|
20339
|
+
deferredResults.set(name, result2);
|
|
20340
|
+
return result2;
|
|
20341
|
+
}
|
|
20342
|
+
const binding = importBindings.get(name);
|
|
20343
|
+
if (!binding) return mainOpaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20344
|
+
const resolved = importedValue(id, binding);
|
|
20345
|
+
if (resolved !== null && "value" in resolved) usedImportedFactories.add(name);
|
|
20346
|
+
return resolved;
|
|
20347
|
+
};
|
|
19913
20348
|
const topLevelFunction = (moduleBody, name) => {
|
|
19914
20349
|
for (const st of moduleBody) {
|
|
19915
20350
|
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
@@ -19918,19 +20353,17 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19918
20353
|
}
|
|
19919
20354
|
return null;
|
|
19920
20355
|
};
|
|
19921
|
-
const
|
|
19922
|
-
|
|
19923
|
-
const
|
|
19924
|
-
|
|
19925
|
-
const
|
|
19926
|
-
|
|
19927
|
-
|
|
19928
|
-
|
|
19929
|
-
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
19930
|
-
const out = /* @__PURE__ */ new Map();
|
|
20356
|
+
const sourceScopeUntil = (file, moduleBody, source, until) => {
|
|
20357
|
+
const imports = extractImportBindings(moduleBody);
|
|
20358
|
+
const opaque = opaqueImportsOf(moduleBody);
|
|
20359
|
+
const out = new ModuleScope((name) => {
|
|
20360
|
+
const binding = imports.get(name);
|
|
20361
|
+
if (binding) return importedValue(file, binding);
|
|
20362
|
+
return opaque.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20363
|
+
}, unresolvedImports);
|
|
19931
20364
|
for (const stmt of moduleBody) {
|
|
19932
20365
|
if (stmt.type === "ImportDeclaration") {
|
|
19933
|
-
if (!
|
|
20366
|
+
if (moduleAliases.has(stmt.source.value) && !isMacroImport(stmt)) return null;
|
|
19934
20367
|
continue;
|
|
19935
20368
|
}
|
|
19936
20369
|
if (stmt.type === "FunctionDeclaration") continue;
|
|
@@ -19983,6 +20416,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19983
20416
|
}
|
|
19984
20417
|
return out;
|
|
19985
20418
|
};
|
|
20419
|
+
const factoryFailures = /* @__PURE__ */ new Map();
|
|
19986
20420
|
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
19987
20421
|
const markUsedImportedFactories = (names) => {
|
|
19988
20422
|
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
@@ -19995,8 +20429,13 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19995
20429
|
const localFor = exportLocalName(mod.body, binding.imported);
|
|
19996
20430
|
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
19997
20431
|
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
19998
|
-
|
|
19999
|
-
|
|
20432
|
+
unresolvedImports.clear();
|
|
20433
|
+
const factoryScope = sourceScopeUntil(file, mod.body, mod.src, init.start);
|
|
20434
|
+
if (!factoryScope) {
|
|
20435
|
+
if (unresolvedImports.size > 0) factoryFailures.set(localName, [...unresolvedImports]);
|
|
20436
|
+
unresolvedImports.clear();
|
|
20437
|
+
continue;
|
|
20438
|
+
}
|
|
20000
20439
|
factoryDecls.set(localName, {
|
|
20001
20440
|
fn: init,
|
|
20002
20441
|
declaredAt: -1,
|
|
@@ -20006,7 +20445,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20006
20445
|
});
|
|
20007
20446
|
reducerResolver.register(file);
|
|
20008
20447
|
}
|
|
20009
|
-
const scope =
|
|
20448
|
+
const scope = new ModuleScope(resolveMainFree, unresolvedImports);
|
|
20010
20449
|
const replacements = [];
|
|
20011
20450
|
const warnings = [];
|
|
20012
20451
|
beginDegradationCapture();
|
|
@@ -20026,6 +20465,12 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20026
20465
|
m = /* @__PURE__ */ new Map();
|
|
20027
20466
|
pendingBuilderImports.set(bi.source, m);
|
|
20028
20467
|
}
|
|
20468
|
+
const prev = m.get(bi.local);
|
|
20469
|
+
if (prev !== void 0 && prev !== bi.imported) {
|
|
20470
|
+
throw new Error(
|
|
20471
|
+
`${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.`
|
|
20472
|
+
);
|
|
20473
|
+
}
|
|
20029
20474
|
m.set(bi.local, bi.imported);
|
|
20030
20475
|
}
|
|
20031
20476
|
if (def?.tag === "lazy" && v._ruleName === void 0 && typeof def.thunk === "function") {
|
|
@@ -20067,6 +20512,41 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20067
20512
|
anyUnresolved = true;
|
|
20068
20513
|
warnings.push(`${id}:${lineOf(pos)} \u2014 ${msg} (running via the interpreter; add the plugin or simplify the declaration to compile it)`);
|
|
20069
20514
|
};
|
|
20515
|
+
const unevaluable = (pos, what) => {
|
|
20516
|
+
const names = [...unresolvedImports];
|
|
20517
|
+
unresolvedImports.clear();
|
|
20518
|
+
throw new Error(
|
|
20519
|
+
`${id}:${lineOf(pos)} \u2014 ${what} can't be evaluated at build time` + (names.length > 0 ? `; unresolved binding(s):
|
|
20520
|
+
${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/value expression)") + `
|
|
20521
|
+
parseman will not emit this module rather than drop it silently.`
|
|
20522
|
+
);
|
|
20523
|
+
};
|
|
20524
|
+
const requiredOption = (label2, name, value, evaluate) => {
|
|
20525
|
+
if (value === void 0 || isStaticNullishExpression(value)) return void 0;
|
|
20526
|
+
unresolvedImports.clear();
|
|
20527
|
+
const out = evaluate(value);
|
|
20528
|
+
if (out === null) {
|
|
20529
|
+
const id2 = value.type === "Identifier" ? value.name : null;
|
|
20530
|
+
if (id2 !== null && scope.has(id2) && scope.get(id2) == null) return void 0;
|
|
20531
|
+
return unevaluable(value.start, `${label2}: rules({ ${name} })`);
|
|
20532
|
+
}
|
|
20533
|
+
unresolvedImports.clear();
|
|
20534
|
+
return out;
|
|
20535
|
+
};
|
|
20536
|
+
const RULES_OPTIONS = /* @__PURE__ */ new Set(["trivia", "scanSkip", "hostMode", "trackLines"]);
|
|
20537
|
+
const assertPlainOptions = (optExpr, label2) => {
|
|
20538
|
+
for (const p of optExpr?.type === "ObjectExpression" ? optExpr.properties : []) {
|
|
20539
|
+
if (propName(p) !== null) continue;
|
|
20540
|
+
const key = p.type === "Property" ? evaluateStaticValue(p.key, scope, code) : null;
|
|
20541
|
+
if (typeof key !== "string" || RULES_OPTIONS.has(key)) {
|
|
20542
|
+
unevaluable(p.start, `${label2}: an options ${p.type === "Property" ? "computed key" : "spread"}`);
|
|
20543
|
+
}
|
|
20544
|
+
}
|
|
20545
|
+
};
|
|
20546
|
+
const triviaOption = (optExpr, label2) => {
|
|
20547
|
+
assertPlainOptions(optExpr, label2);
|
|
20548
|
+
return requiredOption(label2, "trivia", optionProp(optExpr, "trivia"), (v) => evaluateExpr(v, scope, code, []));
|
|
20549
|
+
};
|
|
20070
20550
|
const evaluateRulesFactory = (init, label2) => {
|
|
20071
20551
|
const args = init.arguments;
|
|
20072
20552
|
const arg0 = args[0];
|
|
@@ -20082,7 +20562,15 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20082
20562
|
const factoryScope = namedFactory?.scope ?? scope;
|
|
20083
20563
|
const factoryCode = namedFactory?.code ?? code;
|
|
20084
20564
|
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
20565
|
+
const failedFactory = factoryArgRaw.type === "Identifier" ? factoryFailures.get(factoryArgRaw.name) : void 0;
|
|
20566
|
+
if (failedFactory) {
|
|
20567
|
+
for (const n of failedFactory) unresolvedImports.add(n);
|
|
20568
|
+
unevaluable(init.start, `${label2}: the imported rules() factory \`${factoryArgRaw.name}\``);
|
|
20569
|
+
}
|
|
20085
20570
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
20571
|
+
if (optionsArg !== void 0 && optionsArg.type !== "ObjectExpression" && !isStaticNullishExpression(optionsArg)) {
|
|
20572
|
+
unevaluable(optionsArg.start, `${label2}: rules() options`);
|
|
20573
|
+
}
|
|
20086
20574
|
const optionValue = (name) => optionProp(optionsArg, name);
|
|
20087
20575
|
const hostModeValue = optionValue("hostMode");
|
|
20088
20576
|
const gHostMode = hostModeValue?.type === "Literal" ? hostModeValue.value : void 0;
|
|
@@ -20096,11 +20584,16 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20096
20584
|
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
20097
20585
|
return null;
|
|
20098
20586
|
}
|
|
20099
|
-
const
|
|
20100
|
-
const
|
|
20101
|
-
|
|
20102
|
-
|
|
20587
|
+
const gTrivia = triviaOption(optionsArg, label2);
|
|
20588
|
+
const scanSkipArray = requiredOption(label2, "scanSkip", optionValue("scanSkip"), (v) => {
|
|
20589
|
+
const units = evaluateCombinatorArray(v, scope, code);
|
|
20590
|
+
if (units) return units;
|
|
20591
|
+
const value = evaluateStaticValue(v, scope, code);
|
|
20592
|
+
return Array.isArray(value) && value.length === 0 ? [] : null;
|
|
20593
|
+
});
|
|
20594
|
+
const gScanSkip = scanSkipArray?.length ? scanSkipArray : void 0;
|
|
20103
20595
|
const why = {};
|
|
20596
|
+
unresolvedImports.clear();
|
|
20104
20597
|
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, [], why, {
|
|
20105
20598
|
...gTrivia ? { trivia: gTrivia } : {},
|
|
20106
20599
|
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
@@ -20108,6 +20601,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20108
20601
|
...gTrackLines === true ? { trackLines: true } : {}
|
|
20109
20602
|
});
|
|
20110
20603
|
if (!ruleMap) {
|
|
20604
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `${label2}: rules(...) factory`);
|
|
20111
20605
|
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
20606
|
return null;
|
|
20113
20607
|
}
|
|
@@ -20124,6 +20618,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20124
20618
|
if (!evaluated) return null;
|
|
20125
20619
|
const refusals = [];
|
|
20126
20620
|
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage, refusals });
|
|
20621
|
+
if (compiled !== null) collectBuilderImports([...evaluated.ruleMap]);
|
|
20127
20622
|
if (compiled !== null) usedTableRuntime = true;
|
|
20128
20623
|
return {
|
|
20129
20624
|
replacement: compiled?.replacement ?? null,
|
|
@@ -20185,49 +20680,63 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20185
20680
|
};
|
|
20186
20681
|
const localComposedCarried = /* @__PURE__ */ new Map();
|
|
20187
20682
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
20188
|
-
const resolveModulePieces = (module, exportName, seen) => {
|
|
20683
|
+
const resolveModulePieces = (module, exportName, seen, unresolved, local = false) => {
|
|
20189
20684
|
const { file } = module;
|
|
20190
20685
|
const mod = module.source ? lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recovery) : parseModuleCached(file);
|
|
20191
20686
|
if (!mod) return null;
|
|
20192
|
-
const localFor = exportLocalName(mod.body, exportName);
|
|
20687
|
+
const localFor = local ? exportName : exportLocalName(mod.body, exportName);
|
|
20193
20688
|
const initNode = localFor ? topLevelInit(mod.body, localFor) : null;
|
|
20194
20689
|
const literalRange = initNode ? findCarriedPiecesLiteral(initNode) : null;
|
|
20195
20690
|
if (!literalRange) return null;
|
|
20196
20691
|
const literal2 = mod.src.slice(literalRange.start, literalRange.end);
|
|
20692
|
+
const fail = (why) => {
|
|
20693
|
+
unresolved.why ??= `${exportName} in ${file}: ${why}`;
|
|
20694
|
+
return null;
|
|
20695
|
+
};
|
|
20197
20696
|
const imports = extractImportBindings(mod.body);
|
|
20198
20697
|
const stubNames = [];
|
|
20199
20698
|
const stubVals = [];
|
|
20200
|
-
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20699
|
+
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*(?:\/\*[^]*?\*\/\s*)*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20201
20700
|
const done = /* @__PURE__ */ new Set();
|
|
20202
20701
|
for (let m; m = spreadRe.exec(literal2); ) {
|
|
20203
|
-
const
|
|
20204
|
-
if (done.has(
|
|
20205
|
-
done.add(
|
|
20206
|
-
const b = imports.get(
|
|
20702
|
+
const local2 = m[1];
|
|
20703
|
+
if (done.has(local2)) continue;
|
|
20704
|
+
done.add(local2);
|
|
20705
|
+
const b = imports.get(local2);
|
|
20207
20706
|
let subPieces = [];
|
|
20208
20707
|
if (b) {
|
|
20209
20708
|
const subModule = resolveGrammarModule(file, b.source);
|
|
20210
|
-
if (subModule
|
|
20211
|
-
|
|
20709
|
+
if (subModule === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', a module that could not be found`);
|
|
20710
|
+
if (!seen.has(subModule.file)) {
|
|
20711
|
+
subPieces = resolveModulePieces(subModule, b.imported, new Set(seen).add(subModule.file), unresolved);
|
|
20712
|
+
if (subPieces === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', which could not be resolved`);
|
|
20212
20713
|
}
|
|
20714
|
+
} else if (topLevelInit(mod.body, local2) !== null && !seen.has(`${file}#${local2}`)) {
|
|
20715
|
+
subPieces = resolveModulePieces(module, local2, new Set(seen).add(`${file}#${local2}`), unresolved, true);
|
|
20716
|
+
if (subPieces === null) return fail(`its carried pieces spread the inlined binding \`${local2}\`, which carries none`);
|
|
20717
|
+
} else {
|
|
20718
|
+
return fail(`its carried pieces spread \`${local2}\`, which is neither an import nor a top-level binding of the module`);
|
|
20213
20719
|
}
|
|
20214
|
-
stubNames.push(
|
|
20720
|
+
stubNames.push(local2);
|
|
20215
20721
|
stubVals.push({ [COMPOSED_PIECES]: subPieces });
|
|
20216
20722
|
}
|
|
20217
20723
|
try {
|
|
20218
20724
|
const list = new Function(...stubNames, `return (${literal2})`)(...stubVals);
|
|
20219
20725
|
return list;
|
|
20220
|
-
} catch {
|
|
20221
|
-
return
|
|
20726
|
+
} catch (e) {
|
|
20727
|
+
return fail(`its carried pieces literal did not evaluate (${e.message})`);
|
|
20222
20728
|
}
|
|
20223
20729
|
};
|
|
20730
|
+
const unresolvedCompiled = /* @__PURE__ */ new Map();
|
|
20224
20731
|
const importedPieces = (localName) => {
|
|
20225
20732
|
if (importedPiecesCache.has(localName)) return importedPiecesCache.get(localName);
|
|
20226
20733
|
let result2 = null;
|
|
20227
20734
|
const binding = importBindings.get(localName);
|
|
20228
20735
|
if (binding) {
|
|
20229
20736
|
const module = resolveGrammarModule(id, binding.source);
|
|
20230
|
-
|
|
20737
|
+
const unresolved = {};
|
|
20738
|
+
result2 = module ? resolveModulePieces(module, binding.imported, /* @__PURE__ */ new Set([module.file]), unresolved) : null;
|
|
20739
|
+
if (result2 === null && unresolved.why !== void 0) unresolvedCompiled.set(localName, unresolved.why);
|
|
20231
20740
|
}
|
|
20232
20741
|
importedPiecesCache.set(localName, result2);
|
|
20233
20742
|
return result2;
|
|
@@ -20238,7 +20747,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20238
20747
|
const add = (item) => {
|
|
20239
20748
|
if (!isIR(item)) return false;
|
|
20240
20749
|
if (item.trackLines === true) trackLines = true;
|
|
20241
|
-
|
|
20750
|
+
const map = evalRulesIR(item.ir);
|
|
20751
|
+
pieces.push({ ns: item.ns, rules: Object.entries(map), recipes: map[RULES_RECIPE] });
|
|
20242
20752
|
return true;
|
|
20243
20753
|
};
|
|
20244
20754
|
for (const item of items) {
|
|
@@ -20265,10 +20775,20 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20265
20775
|
}
|
|
20266
20776
|
return [...winners];
|
|
20267
20777
|
};
|
|
20268
|
-
const mergedCarriedRules = (items) => {
|
|
20778
|
+
const mergedCarriedRules = (items, link) => {
|
|
20269
20779
|
const carriedMaps = carriedRuleMaps(items);
|
|
20270
20780
|
if (carriedMaps === null) return null;
|
|
20271
|
-
|
|
20781
|
+
const linked = linkRules(carriedMaps.pieces.flatMap((p) => p.recipes), link);
|
|
20782
|
+
const rules2 = Object.entries(linked).filter(([, rule]) => {
|
|
20783
|
+
if (rule._def.tag !== "lazy") return true;
|
|
20784
|
+
try {
|
|
20785
|
+
rule._def.thunk();
|
|
20786
|
+
return true;
|
|
20787
|
+
} catch {
|
|
20788
|
+
return false;
|
|
20789
|
+
}
|
|
20790
|
+
});
|
|
20791
|
+
return { rules: rules2, trackLines: carriedMaps.trackLines };
|
|
20272
20792
|
};
|
|
20273
20793
|
const applyComposingTrivia = (ruleMap, composing) => {
|
|
20274
20794
|
for (const [, rule] of ruleMap) {
|
|
@@ -20308,9 +20828,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20308
20828
|
const a0 = rulesArgs[0];
|
|
20309
20829
|
const a1 = rulesArgs[1];
|
|
20310
20830
|
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;
|
|
20831
|
+
return triviaOption(optExpr, "compose() element");
|
|
20314
20832
|
};
|
|
20315
20833
|
const composingTrivia = (elements) => {
|
|
20316
20834
|
for (let i = elements.length - 1; i >= 0; i--) {
|
|
@@ -20337,6 +20855,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20337
20855
|
}
|
|
20338
20856
|
const elements = arr.elements;
|
|
20339
20857
|
const cOptions = init.arguments[1];
|
|
20858
|
+
if (cOptions !== void 0 && cOptions.type !== "ObjectExpression") unevaluable(cOptions.start, "compose() options");
|
|
20859
|
+
assertPlainOptions(cOptions, "compose()");
|
|
20340
20860
|
const cHostModeValue = optionProp(cOptions, "hostMode");
|
|
20341
20861
|
const cHostMode = cHostModeValue?.type === "Literal" ? cHostModeValue.value : void 0;
|
|
20342
20862
|
if (cHostModeValue !== void 0 && cHostMode !== "ast" && cHostMode !== "cst") {
|
|
@@ -20349,15 +20869,25 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20349
20869
|
for (let i = 0; i < elements.length; i++) {
|
|
20350
20870
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
20351
20871
|
if (!r) {
|
|
20872
|
+
const el = elements[i];
|
|
20873
|
+
const name = el.type === "Identifier" ? el.name : void 0;
|
|
20874
|
+
const why = name === void 0 ? void 0 : unresolvedCompiled.get(name);
|
|
20875
|
+
if (why !== void 0) {
|
|
20876
|
+
throw new Error(
|
|
20877
|
+
`${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.`
|
|
20878
|
+
);
|
|
20879
|
+
}
|
|
20352
20880
|
warn(init.start, `compose(): argument ${i} isn't a build-resolvable grammar; falling back to runtime`);
|
|
20353
20881
|
return null;
|
|
20354
20882
|
}
|
|
20355
20883
|
carried.push(...r.carried);
|
|
20356
20884
|
importedFactories.push(...r.importedFactories ?? []);
|
|
20357
20885
|
}
|
|
20358
|
-
const merged = mergedCarriedRules(carried
|
|
20886
|
+
const merged = mergedCarriedRules(carried, {
|
|
20887
|
+
trivia: composing,
|
|
20888
|
+
...cHostMode ? { hostMode: cHostMode } : {}
|
|
20889
|
+
});
|
|
20359
20890
|
if (merged !== null) {
|
|
20360
|
-
if (composing) applyComposingTrivia(merged.rules, composing);
|
|
20361
20891
|
collectBuilderImports(merged.rules);
|
|
20362
20892
|
const refusals = [];
|
|
20363
20893
|
const compiled = compileRuleMap(merged.rules, {
|
|
@@ -20552,11 +21082,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20552
21082
|
if (d.id.type === "Identifier") {
|
|
20553
21083
|
const varName = d.id.name;
|
|
20554
21084
|
if (!referencesAny(init, allNames, scope)) {
|
|
20555
|
-
|
|
20556
|
-
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
20557
|
-
;
|
|
20558
|
-
scope.set(varName, staticValue);
|
|
20559
|
-
}
|
|
21085
|
+
deferredLocals.set(varName, init);
|
|
20560
21086
|
continue;
|
|
20561
21087
|
}
|
|
20562
21088
|
if (refNames.has(varName)) {
|
|
@@ -20643,6 +21169,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20643
21169
|
continue;
|
|
20644
21170
|
}
|
|
20645
21171
|
const mapFnSources = [];
|
|
21172
|
+
unresolvedImports.clear();
|
|
20646
21173
|
const parser2 = evaluateExpr(init, scope, code, mapFnSources);
|
|
20647
21174
|
if (parser2 === null) {
|
|
20648
21175
|
const wordFactory = evaluateWordFactory(init, scope, code);
|
|
@@ -20675,6 +21202,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20675
21202
|
if (exportPrefix) exportedFactories.push({ name: varName, pos: init.start });
|
|
20676
21203
|
continue;
|
|
20677
21204
|
}
|
|
21205
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `"${varName}"`);
|
|
20678
21206
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
20679
21207
|
continue;
|
|
20680
21208
|
}
|
|
@@ -20687,7 +21215,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20687
21215
|
replacements.push({
|
|
20688
21216
|
start: init.start,
|
|
20689
21217
|
end: init.end,
|
|
20690
|
-
replacement: compiled.inlineExpression
|
|
21218
|
+
replacement: compiled.inlineExpression,
|
|
21219
|
+
carry: { name: varName, combi: parser2, exported: exportPrefix !== "" }
|
|
20691
21220
|
});
|
|
20692
21221
|
scope.set(varName, { combi: parser2, mfSrcs: mapFnSources });
|
|
20693
21222
|
} else if (d.id.type === "ObjectPattern") {
|
|
@@ -20754,37 +21283,58 @@ ${which}
|
|
|
20754
21283
|
Drop the \`export\`. The factory is macro-only; \`rules(${exportedFactories[0].name})\` is lowered in place and needs no runtime value.`
|
|
20755
21284
|
);
|
|
20756
21285
|
}
|
|
21286
|
+
const withCombinatorIR = (r) => {
|
|
21287
|
+
if (!r.carry || !r.carry.exported && !referencedNames().live.has(r.carry.name)) return r;
|
|
21288
|
+
let ir = null;
|
|
21289
|
+
try {
|
|
21290
|
+
ir = serializeCombinator(r.carry.combi);
|
|
21291
|
+
} catch {
|
|
21292
|
+
}
|
|
21293
|
+
return ir === null ? r : {
|
|
21294
|
+
...r,
|
|
21295
|
+
replacement: `/* @__PURE__ */ Object.defineProperty(${r.replacement}, Symbol.for('${COMBINATOR_IR_KEY}'), { value: ${JSON.stringify(ir)}, enumerable: false })`
|
|
21296
|
+
};
|
|
21297
|
+
};
|
|
20757
21298
|
const ms = new MagicString(code);
|
|
20758
21299
|
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
20759
21300
|
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
|
|
21301
|
+
let referenced = null;
|
|
21302
|
+
const referencedNames = () => {
|
|
21303
|
+
if (referenced !== null) return referenced;
|
|
21304
|
+
const all = /* @__PURE__ */ new Set();
|
|
21305
|
+
const live = /* @__PURE__ */ new Set();
|
|
21306
|
+
const deadRanges = [...[...factoryDecls.values()].filter((f) => !f.imported).map((f) => f.fn), ...anyUnresolved ? [] : defineRemovals];
|
|
21307
|
+
const walk = (node2, inFactory, parent, parentKey) => {
|
|
21308
|
+
if (!node2 || typeof node2 !== "object") return;
|
|
20763
21309
|
const rec = node2;
|
|
20764
|
-
if (rec.type === "ImportDeclaration") return
|
|
20765
|
-
if (typeof rec.start === "number" && typeof rec.end === "number"
|
|
20766
|
-
|
|
20767
|
-
|
|
20768
|
-
|
|
20769
|
-
|
|
20770
|
-
|
|
21310
|
+
if (rec.type === "ImportDeclaration") return;
|
|
21311
|
+
if (typeof rec.start === "number" && typeof rec.end === "number") {
|
|
21312
|
+
if (isInsideReplacement(rec.start, rec.end)) return;
|
|
21313
|
+
inFactory ||= deadRanges.some((f) => rec.start >= f.start && rec.end <= f.end);
|
|
21314
|
+
}
|
|
21315
|
+
if (rec.type === "Identifier" || rec.type === "BindingIdentifier") {
|
|
21316
|
+
const isKey = parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true;
|
|
21317
|
+
const isMember = parentKey === "property" && (parent?.type === "StaticMemberExpression" || parent?.type === "MemberExpression" && parent.computed !== true);
|
|
21318
|
+
const isDeclared = parentKey === "id" && parent?.type === "VariableDeclarator";
|
|
21319
|
+
if (!isKey && !isMember && !isDeclared) {
|
|
21320
|
+
all.add(rec.name);
|
|
21321
|
+
if (!inFactory) live.add(rec.name);
|
|
21322
|
+
}
|
|
21323
|
+
return;
|
|
20771
21324
|
}
|
|
20772
21325
|
for (const key of Object.keys(rec)) {
|
|
20773
21326
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
20774
21327
|
const value = rec[key];
|
|
20775
|
-
if (Array.isArray(value))
|
|
20776
|
-
|
|
20777
|
-
} else if (walk(value, rec, key)) {
|
|
20778
|
-
return true;
|
|
20779
|
-
}
|
|
21328
|
+
if (Array.isArray(value)) for (const child of value) walk(child, inFactory, rec, key);
|
|
21329
|
+
else walk(value, inFactory, rec, key);
|
|
20780
21330
|
}
|
|
20781
|
-
return false;
|
|
20782
21331
|
};
|
|
20783
|
-
|
|
21332
|
+
for (const stmt of body) walk(stmt, false);
|
|
21333
|
+
return referenced = { all, live };
|
|
20784
21334
|
};
|
|
20785
21335
|
for (const imp of ordinaryImports) {
|
|
20786
21336
|
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
20787
|
-
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !
|
|
21337
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !referencedNames().all.has(spec.local)
|
|
20788
21338
|
)) {
|
|
20789
21339
|
ms.remove(imp.start, imp.end);
|
|
20790
21340
|
}
|
|
@@ -20801,7 +21351,7 @@ ${which}
|
|
|
20801
21351
|
ms.overwrite(imp.start, imp.end, stripped);
|
|
20802
21352
|
}
|
|
20803
21353
|
}
|
|
20804
|
-
const applied = runtimeComposeFallback ? [] : replacements;
|
|
21354
|
+
const applied = runtimeComposeFallback ? [] : replacements.map((r) => withCombinatorIR(r));
|
|
20805
21355
|
for (const { start, end, replacement } of applied.slice().sort((a, b) => b.start - a.start)) {
|
|
20806
21356
|
ms.overwrite(start, end, replacement);
|
|
20807
21357
|
}
|