parseman 0.22.0 → 0.23.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/compiler/codegen.d.ts +3 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +7 -2
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/index.cjs +273 -36
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +273 -36
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +128 -27
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +128 -27
- package/dist/plugin/index.js.map +3 -3
- package/package.json +1 -1
package/dist/plugin/index.cjs
CHANGED
|
@@ -5539,9 +5539,10 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
5539
5539
|
].join("\n");
|
|
5540
5540
|
return { keys: perEntry.map((e) => e.key), replacement };
|
|
5541
5541
|
}
|
|
5542
|
-
function compileLinkable(ruleMapArg, ns) {
|
|
5542
|
+
function compileLinkable(ruleMapArg, ns, opts) {
|
|
5543
5543
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5544
5544
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
5545
|
+
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
5545
5546
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
5546
5547
|
const d = val._def;
|
|
5547
5548
|
if (d.tag !== "lazy") return true;
|
|
@@ -5572,7 +5573,8 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5572
5573
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
5573
5574
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
5574
5575
|
ns,
|
|
5575
|
-
deferFirstSetRefs: true
|
|
5576
|
+
deferFirstSetRefs: true,
|
|
5577
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5576
5578
|
};
|
|
5577
5579
|
const seen = /* @__PURE__ */ new Map();
|
|
5578
5580
|
const ruleNames = /* @__PURE__ */ new Map();
|
|
@@ -5635,7 +5637,10 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5635
5637
|
ctx.indent = 1;
|
|
5636
5638
|
ctx.failLabel = "_pfail";
|
|
5637
5639
|
ctx.recordFail = true;
|
|
5640
|
+
const savedTrivia = ctx.activeTrivia;
|
|
5641
|
+
if (rule._meta.isTrivia) ctx.activeTrivia = void 0;
|
|
5638
5642
|
const body = emit(resolved, ctx, "_pos");
|
|
5643
|
+
ctx.activeTrivia = savedTrivia;
|
|
5639
5644
|
ctx.indent = savedIndent;
|
|
5640
5645
|
ctx.failLabel = savedFail;
|
|
5641
5646
|
ctx.recordFail = savedRec;
|
|
@@ -6129,6 +6134,23 @@ ${body}
|
|
|
6129
6134
|
};
|
|
6130
6135
|
|
|
6131
6136
|
// src/compiler/linker.ts
|
|
6137
|
+
function pickPieces(pieces, names) {
|
|
6138
|
+
const winner = /* @__PURE__ */ new Map();
|
|
6139
|
+
for (const pc of pieces) for (const k of pc.keys) winner.set(k, pc);
|
|
6140
|
+
for (const n of names) {
|
|
6141
|
+
if (!winner.has(n)) throw new Error(`pick: rule "${n}" is not in this grammar (available: ${[...winner.keys()].join(", ")})`);
|
|
6142
|
+
}
|
|
6143
|
+
const keep = /* @__PURE__ */ new Set();
|
|
6144
|
+
const visit = (n) => {
|
|
6145
|
+
const w = winner.get(n);
|
|
6146
|
+
if (keep.has(n) || !w) return;
|
|
6147
|
+
keep.add(n);
|
|
6148
|
+
for (const d of w.deps.get(n) ?? []) visit(d);
|
|
6149
|
+
};
|
|
6150
|
+
for (const n of names) visit(n);
|
|
6151
|
+
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
6152
|
+
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc) })).filter((pc) => pc.keys.length > 0);
|
|
6153
|
+
}
|
|
6132
6154
|
function fusedBody(pieces) {
|
|
6133
6155
|
const winner = /* @__PURE__ */ new Map();
|
|
6134
6156
|
for (const p of pieces) for (const k of p.keys) winner.set(k, p);
|
|
@@ -6148,7 +6170,7 @@ function fusedBody(pieces) {
|
|
|
6148
6170
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
6149
6171
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
6150
6172
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
6151
|
-
...
|
|
6173
|
+
...new Set(contributingPieces.flatMap((p) => p.prelude)),
|
|
6152
6174
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
6153
6175
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
6154
6176
|
];
|
|
@@ -6189,9 +6211,9 @@ ${body}
|
|
|
6189
6211
|
function isIRPiece(p) {
|
|
6190
6212
|
return !!p && typeof p === "object" && typeof p.ir === "string" && typeof p.ns === "string" && !("ruleFns" in p);
|
|
6191
6213
|
}
|
|
6192
|
-
function materializePiece(p) {
|
|
6214
|
+
function materializePiece(p, trivia2) {
|
|
6193
6215
|
if (!isIRPiece(p)) return p;
|
|
6194
|
-
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns);
|
|
6216
|
+
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, trivia2 ? { trivia: trivia2 } : void 0);
|
|
6195
6217
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
6196
6218
|
return pieces;
|
|
6197
6219
|
}
|
|
@@ -6897,11 +6919,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6897
6919
|
warn(init.start, `${label2}: rule map couldn't be inlined`);
|
|
6898
6920
|
return null;
|
|
6899
6921
|
}
|
|
6900
|
-
return { replacement: compiled.replacement, ruleMap };
|
|
6922
|
+
return { replacement: compiled.replacement, ruleMap, ...gTrivia ? { trivia: gTrivia } : {} };
|
|
6901
6923
|
};
|
|
6902
6924
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
6903
6925
|
const isComposeCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "compose";
|
|
6926
|
+
const isPickCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "pick";
|
|
6904
6927
|
const localRuleMaps = /* @__PURE__ */ new Map();
|
|
6928
|
+
const localGrammarTrivia = /* @__PURE__ */ new Map();
|
|
6905
6929
|
const nsFor = (label2) => `_${(0, import_node_crypto.createHash)("sha1").update(`${id}#${label2}`).digest("hex").slice(0, 8)}_`;
|
|
6906
6930
|
const stripIndent = (s) => s.replace(/\n[ \t]+/g, "\n");
|
|
6907
6931
|
const serializePieces = (p) => {
|
|
@@ -6915,7 +6939,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6915
6939
|
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)} }` : serializePieces(it);
|
|
6916
6940
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
6917
6941
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
6918
|
-
const
|
|
6942
|
+
const localComposedCarried = /* @__PURE__ */ new Map();
|
|
6943
|
+
const localComposedTrivia = /* @__PURE__ */ new Map();
|
|
6919
6944
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
6920
6945
|
const resolveModulePieces = (file, exportName, seen) => {
|
|
6921
6946
|
const mod = parseModuleCached(file);
|
|
@@ -6949,7 +6974,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6949
6974
|
}
|
|
6950
6975
|
try {
|
|
6951
6976
|
const list = new Function(...stubNames, `return (${literal2})`)(...stubVals);
|
|
6952
|
-
return list
|
|
6977
|
+
return list;
|
|
6953
6978
|
} catch {
|
|
6954
6979
|
return null;
|
|
6955
6980
|
}
|
|
@@ -6969,32 +6994,108 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6969
6994
|
importedPiecesCache.set(localName, result2);
|
|
6970
6995
|
return result2;
|
|
6971
6996
|
};
|
|
6972
|
-
const
|
|
6997
|
+
const materializeCarried = (items, composing) => {
|
|
6998
|
+
const out = [];
|
|
6999
|
+
for (const it of items) {
|
|
7000
|
+
if (isSpread(it)) {
|
|
7001
|
+
for (const p of importedPieces(it.__spreadLocal) ?? []) out.push(materializePiece(p, composing));
|
|
7002
|
+
} else if (isIR(it)) {
|
|
7003
|
+
out.push(materializePiece(it, composing));
|
|
7004
|
+
} else {
|
|
7005
|
+
out.push(it);
|
|
7006
|
+
}
|
|
7007
|
+
}
|
|
7008
|
+
return out;
|
|
7009
|
+
};
|
|
7010
|
+
const localCarried = (rm, label2, composing) => {
|
|
6973
7011
|
const entries = [...rm];
|
|
6974
7012
|
const ns = nsFor(label2);
|
|
6975
|
-
const p = compileLinkable(entries, ns);
|
|
6976
|
-
if (!p) return null;
|
|
6977
7013
|
const ir = serializeRuleMap(entries);
|
|
6978
|
-
|
|
7014
|
+
if (ir) return { carried: [{ ns, ir }] };
|
|
7015
|
+
const p = compileLinkable(entries, ns, composing ? { trivia: composing } : void 0);
|
|
7016
|
+
return p ? { carried: [p] } : null;
|
|
6979
7017
|
};
|
|
6980
|
-
const argPieces = (arg, label2) => {
|
|
7018
|
+
const argPieces = (arg, label2, composing) => {
|
|
7019
|
+
if (isPickCall(arg)) {
|
|
7020
|
+
const pargs = arg.arguments;
|
|
7021
|
+
const inner = pargs[0];
|
|
7022
|
+
const namesArg = pargs[1];
|
|
7023
|
+
if (!inner || namesArg?.type !== "ArrayExpression") return null;
|
|
7024
|
+
const names = [];
|
|
7025
|
+
for (const el of namesArg.elements ?? []) {
|
|
7026
|
+
const v2 = el?.value;
|
|
7027
|
+
if ((el?.type === "Literal" || el?.type === "StringLiteral") && typeof v2 === "string") names.push(v2);
|
|
7028
|
+
else return null;
|
|
7029
|
+
}
|
|
7030
|
+
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
7031
|
+
if (!innerArg) return null;
|
|
7032
|
+
try {
|
|
7033
|
+
return { carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names) };
|
|
7034
|
+
} catch (e) {
|
|
7035
|
+
warn(arg.start, `pick(): ${e.message}`);
|
|
7036
|
+
return null;
|
|
7037
|
+
}
|
|
7038
|
+
}
|
|
6981
7039
|
if (isRulesCall(arg)) {
|
|
6982
|
-
const
|
|
7040
|
+
const rulesArgs = arg.arguments;
|
|
7041
|
+
const a0 = rulesArgs[0];
|
|
7042
|
+
const a1 = rulesArgs[1];
|
|
7043
|
+
const optionsFirst = a0?.type === "ObjectExpression";
|
|
7044
|
+
const factory = optionsFirst ? a1 : a0;
|
|
6983
7045
|
const rm = factory ? evaluateParserFactory(factory, scope, code, []) : null;
|
|
6984
|
-
return rm ?
|
|
7046
|
+
return rm ? localCarried(rm, label2, composing) : null;
|
|
6985
7047
|
}
|
|
6986
7048
|
if (arg.type === "Identifier") {
|
|
6987
7049
|
const name = arg.name;
|
|
6988
7050
|
const rm = localRuleMaps.get(name);
|
|
6989
|
-
if (rm) return
|
|
6990
|
-
const composed =
|
|
6991
|
-
if (composed) return {
|
|
7051
|
+
if (rm) return localCarried(rm, label2, composing);
|
|
7052
|
+
const composed = localComposedCarried.get(name);
|
|
7053
|
+
if (composed) return { carried: composed };
|
|
6992
7054
|
const pieces = importedPieces(name);
|
|
6993
7055
|
if (!pieces) return null;
|
|
6994
|
-
return importBindings.has(name) ? {
|
|
7056
|
+
return { carried: importBindings.has(name) ? [{ __spreadLocal: name }] : [...pieces] };
|
|
6995
7057
|
}
|
|
6996
7058
|
return null;
|
|
6997
7059
|
};
|
|
7060
|
+
const rulesCallTrivia = (el) => {
|
|
7061
|
+
const rulesArgs = el.arguments;
|
|
7062
|
+
const a0 = rulesArgs[0];
|
|
7063
|
+
const a1 = rulesArgs[1];
|
|
7064
|
+
const optExpr = a0?.type === "ObjectExpression" ? a0 : a1?.type === "ObjectExpression" ? a1 : void 0;
|
|
7065
|
+
const triviaProp = (optExpr?.properties ?? []).find(
|
|
7066
|
+
(p) => p.key?.name === "trivia"
|
|
7067
|
+
);
|
|
7068
|
+
if (!triviaProp?.value) return void 0;
|
|
7069
|
+
return evaluateExpr(triviaProp.value, scope, code, []) ?? void 0;
|
|
7070
|
+
};
|
|
7071
|
+
const composingTrivia = (elements) => {
|
|
7072
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
7073
|
+
const el = elements[i];
|
|
7074
|
+
if (!el) continue;
|
|
7075
|
+
if (isRulesCall(el)) {
|
|
7076
|
+
const t = rulesCallTrivia(el);
|
|
7077
|
+
if (t) return t;
|
|
7078
|
+
continue;
|
|
7079
|
+
}
|
|
7080
|
+
if (el.type === "Identifier") {
|
|
7081
|
+
const t = localGrammarTrivia.get(el.name);
|
|
7082
|
+
if (t) return t;
|
|
7083
|
+
}
|
|
7084
|
+
}
|
|
7085
|
+
return void 0;
|
|
7086
|
+
};
|
|
7087
|
+
const ownTrivia = (arg) => {
|
|
7088
|
+
if (isRulesCall(arg)) return rulesCallTrivia(arg);
|
|
7089
|
+
if (isPickCall(arg)) {
|
|
7090
|
+
const inner = arg.arguments[0];
|
|
7091
|
+
return inner ? ownTrivia(inner) : void 0;
|
|
7092
|
+
}
|
|
7093
|
+
if (arg.type === "Identifier") {
|
|
7094
|
+
const name = arg.name;
|
|
7095
|
+
return localGrammarTrivia.get(name) ?? localComposedTrivia.get(name);
|
|
7096
|
+
}
|
|
7097
|
+
return void 0;
|
|
7098
|
+
};
|
|
6998
7099
|
const compileComposeCall = (init) => {
|
|
6999
7100
|
const args = init.arguments;
|
|
7000
7101
|
const arr = args[0];
|
|
@@ -7003,21 +7104,19 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
7003
7104
|
return null;
|
|
7004
7105
|
}
|
|
7005
7106
|
const elements = arr.elements;
|
|
7006
|
-
const
|
|
7107
|
+
const composing = composingTrivia(elements);
|
|
7007
7108
|
const carried = [];
|
|
7008
7109
|
for (let i = 0; i < elements.length; i++) {
|
|
7009
|
-
const r = argPieces(elements[i], `compose${init.start}_${i}
|
|
7110
|
+
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
7010
7111
|
if (!r) {
|
|
7011
7112
|
warn(init.start, `compose(): argument ${i} isn't a build-resolvable grammar; falling back to runtime`);
|
|
7012
7113
|
return null;
|
|
7013
7114
|
}
|
|
7014
|
-
|
|
7015
|
-
if (r.spreadLocal) carried.push({ __spreadLocal: r.spreadLocal });
|
|
7016
|
-
else if (r.ir) carried.push(r.ir);
|
|
7017
|
-
else carried.push(...r.pieces);
|
|
7115
|
+
carried.push(...r.carried);
|
|
7018
7116
|
}
|
|
7117
|
+
const pieces = materializeCarried(carried, composing);
|
|
7019
7118
|
try {
|
|
7020
|
-
return { replacement: emitFusedSource(pieces),
|
|
7119
|
+
return { replacement: emitFusedSource(pieces), carried, ...composing ? { trivia: composing } : {} };
|
|
7021
7120
|
} catch (e) {
|
|
7022
7121
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
7023
7122
|
return null;
|
|
@@ -7102,6 +7201,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
7102
7201
|
const compiledRules = compileRulesFactory(init, varName);
|
|
7103
7202
|
if (!compiledRules) continue;
|
|
7104
7203
|
localRuleMaps.set(varName, compiledRules.ruleMap);
|
|
7204
|
+
if (compiledRules.trivia) localGrammarTrivia.set(varName, compiledRules.trivia);
|
|
7105
7205
|
let replacement = compiledRules.replacement;
|
|
7106
7206
|
if (exportPrefix) {
|
|
7107
7207
|
const ns = nsFor(varName);
|
|
@@ -7117,7 +7217,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
7117
7217
|
if (isComposeCall(init)) {
|
|
7118
7218
|
const fused = compileComposeCall(init);
|
|
7119
7219
|
if (!fused) continue;
|
|
7120
|
-
|
|
7220
|
+
localComposedCarried.set(varName, fused.carried);
|
|
7221
|
+
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
7121
7222
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
7122
7223
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
7123
7224
|
continue;
|