parseman 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -551
- package/dist/combinators/node.d.ts +15 -1
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +26 -0
- package/dist/compiler/build-arity.d.ts.map +1 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/index.cjs +102 -12
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +102 -12
- package/dist/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +89 -13
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +89 -13
- package/dist/plugin/index.js.map +3 -3
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -1
|
@@ -19,5 +19,19 @@ export type BuildNode<N> = (children: ReadonlyArray<unknown>, rawChildren: Reado
|
|
|
19
19
|
start: number;
|
|
20
20
|
end: number;
|
|
21
21
|
}, triviaLog: readonly number[], state: unknown) => N;
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Options for `node()`.
|
|
24
|
+
* - `collapse` — a structural wrapper rule (a selector list, an
|
|
25
|
+
* expression-precedence level, …) that IS its single child when it captured
|
|
26
|
+
* exactly one. With `collapse: true`, a one-child match returns that child
|
|
27
|
+
* directly (a leaf unwrapped to its string value, a sub-node as-is) and
|
|
28
|
+
* `build` is NOT called; zero or two-plus children go through `build`
|
|
29
|
+
* normally. Lets a grammar keep readable layered rules without paying a build
|
|
30
|
+
* call per collapsing layer — and without hand-writing
|
|
31
|
+
* `if (children.length === 1) return children[0]` in every wrapper builder.
|
|
32
|
+
*/
|
|
33
|
+
export type NodeOptions = {
|
|
34
|
+
collapse?: boolean;
|
|
35
|
+
};
|
|
36
|
+
export declare function node<N>(type: string, combinator: Combinator<unknown>, build: BuildNode<N>, opts?: NodeOptions): Combinator<N>;
|
|
23
37
|
//# sourceMappingURL=node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/combinators/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/combinators/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAoD,MAAM,aAAa,CAAA;AAI/F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CACzB,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAChC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,EACnC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,KAAK,EAAE,OAAO,KACX,CAAC,CAAA;AAEN;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAShD,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CA8C7H"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ParserDef } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Per-node CST-trivia (4th build arg) and state-clone (5th build arg) capture is
|
|
4
|
+
* dead work when the build never declares those formal params. This module derives
|
|
5
|
+
* a build's *confirmed* formal-parameter arity so all three eval paths (interpreter,
|
|
6
|
+
* compiler, macro) can elide that capture identically.
|
|
7
|
+
*
|
|
8
|
+
* Conservative by construction: any source we can't confidently parse — rest params,
|
|
9
|
+
* destructuring, `arguments`, an unrecognized shape — yields `null` (arity unknown),
|
|
10
|
+
* and callers KEEP full capture. We only ever return a number when the parameter list
|
|
11
|
+
* is a plain comma-separated list of simple identifiers.
|
|
12
|
+
*/
|
|
13
|
+
type NodeDef = Extract<ParserDef, {
|
|
14
|
+
tag: 'node';
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Confirmed count of simple formal parameters the build declares, or `null` when the
|
|
18
|
+
* source can't be parsed into a plain identifier list (→ caller keeps full capture).
|
|
19
|
+
*/
|
|
20
|
+
export declare function confirmedBuildArity(src: string): number | null;
|
|
21
|
+
/** Build reads the 4th (triviaLog) arg? Unknown/unparseable → true (keep capture). */
|
|
22
|
+
export declare function buildReadsTrivia(def: NodeDef): boolean;
|
|
23
|
+
/** Build reads the 5th (state) arg? Unknown/unparseable → true (keep state clone). */
|
|
24
|
+
export declare function buildReadsState(def: NodeDef): boolean;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=build-arity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-arity.d.ts","sourceRoot":"","sources":["../../src/compiler/build-arity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;;;;;;;;;GAUG;AAEH,KAAK,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAkBlD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuB9D;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKtD;AAED,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAKrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAuB,WAAW,EAAE,YAAY,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAuB,WAAW,EAAE,YAAY,EAAE,UAAU,EAAkB,MAAM,aAAa,CAAA;AA4jDzH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;IAC9B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAClD,kGAAkG;IAClG,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IAChF;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,UAAU,EAAE,CAAA;KAAE,CAAA;IACvF,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;OAMG;IACH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChC,CAAA;AAoJD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC,CAyGhG;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6EhD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../src/functional/doc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAElE,qFAAqF;AACrF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,CAAA;AAEzF,gFAAgF;AAChF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,QAAQ,IAAI;IACrD,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;CAC1E,CAAA;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ;IAC/C,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;CACtE;
|
|
1
|
+
{"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../src/functional/doc.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAElE,qFAAqF;AACrF,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,CAAA;AAEzF,gFAAgF;AAChF,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;AAEnD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,QAAQ,IAAI;IACrD,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;CAC1E,CAAA;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,QAAQ;IAC/C,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAA;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAAA;CACtE;AA0KD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,QAAQ,EAClD,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,EACrB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,oBAAoB,CAAC,CAAC,CAAM,GACjC,aAAa,CAAC,CAAC,CAAC,CASlB"}
|
package/dist/index.cjs
CHANGED
|
@@ -1200,24 +1200,70 @@ function not(combinator) {
|
|
|
1200
1200
|
};
|
|
1201
1201
|
}
|
|
1202
1202
|
|
|
1203
|
+
// src/compiler/build-arity.ts
|
|
1204
|
+
var PARAM_LIST_RE = (
|
|
1205
|
+
// (params) => ... | function name?(params) ... | single-ident arrow `x => ...`
|
|
1206
|
+
/^(?:function\b[^(]*\(([^)]*)\)|\(([^)]*)\)\s*=>|([A-Za-z_$][\w$]*)\s*=>)/
|
|
1207
|
+
);
|
|
1208
|
+
var CONFIRMABLE_PARAM_RE = /^[A-Za-z_$][\w$]*\s*\??\s*(?::[^,=]+)?$/;
|
|
1209
|
+
function confirmedBuildArity(src) {
|
|
1210
|
+
const s = src.trim();
|
|
1211
|
+
const m = PARAM_LIST_RE.exec(s);
|
|
1212
|
+
if (!m) return null;
|
|
1213
|
+
if (m[3] !== void 0) return 1;
|
|
1214
|
+
const inner = (m[1] ?? m[2] ?? "").trim();
|
|
1215
|
+
if (inner === "") return 0;
|
|
1216
|
+
const parts = inner.split(",");
|
|
1217
|
+
for (const part of parts) {
|
|
1218
|
+
if (!CONFIRMABLE_PARAM_RE.test(part.trim())) return null;
|
|
1219
|
+
}
|
|
1220
|
+
if (/\barguments\b/.test(s)) return null;
|
|
1221
|
+
return parts.length;
|
|
1222
|
+
}
|
|
1223
|
+
function buildReadsTrivia(def) {
|
|
1224
|
+
const src = def.buildSrc ?? def.build.toString();
|
|
1225
|
+
const arity = confirmedBuildArity(src);
|
|
1226
|
+
if (arity === null) return true;
|
|
1227
|
+
return arity >= 4;
|
|
1228
|
+
}
|
|
1229
|
+
function buildReadsState(def) {
|
|
1230
|
+
const src = def.buildSrc ?? def.build.toString();
|
|
1231
|
+
const arity = confirmedBuildArity(src);
|
|
1232
|
+
if (arity === null) return true;
|
|
1233
|
+
return arity >= 5;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1203
1236
|
// src/combinators/node.ts
|
|
1204
|
-
function
|
|
1237
|
+
function collapseChild(child) {
|
|
1238
|
+
return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
|
|
1239
|
+
}
|
|
1240
|
+
function node(type, combinator, build, opts) {
|
|
1205
1241
|
const meta = {
|
|
1206
1242
|
firstSet: combinator._meta.firstSet,
|
|
1207
1243
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
1208
1244
|
isTrivia: false
|
|
1209
1245
|
};
|
|
1246
|
+
const collapse = opts?.collapse === true;
|
|
1247
|
+
const def = collapse ? { tag: "node", type, parser: combinator, build, collapse: true } : { tag: "node", type, parser: combinator, build };
|
|
1248
|
+
const capturesTrivia = buildReadsTrivia(def);
|
|
1249
|
+
const clonesState = buildReadsState(def);
|
|
1210
1250
|
return {
|
|
1211
1251
|
_tag: "node",
|
|
1212
1252
|
_meta: meta,
|
|
1213
|
-
_def:
|
|
1253
|
+
_def: def,
|
|
1214
1254
|
parse(input, pos, ctx) {
|
|
1215
1255
|
const saved = beginCstNodeCapture(ctx);
|
|
1256
|
+
if (!capturesTrivia) ctx.captureTrivia = false;
|
|
1216
1257
|
const r = combinator.parse(input, pos, ctx);
|
|
1217
1258
|
const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
|
|
1218
1259
|
if (!r.ok) return r;
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1260
|
+
const built = collapse && children.length === 1 ? collapseChild(children[0]) : build(
|
|
1261
|
+
children,
|
|
1262
|
+
rawChildren,
|
|
1263
|
+
r.span,
|
|
1264
|
+
triviaLog,
|
|
1265
|
+
clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0
|
|
1266
|
+
);
|
|
1221
1267
|
const isNodeLike = typeof built === "object" && built !== null && built._tag === "node";
|
|
1222
1268
|
const rawEntry = isNodeLike ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
|
|
1223
1269
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
@@ -2652,25 +2698,34 @@ function emitNode(def, ctx, pos) {
|
|
|
2652
2698
|
ctx.buildSrcs.push(def.buildSrc ?? null);
|
|
2653
2699
|
}
|
|
2654
2700
|
const i = ind(ctx);
|
|
2701
|
+
const capturesTrivia = mkType !== null || buildReadsTrivia(def);
|
|
2702
|
+
const clonesState = buildReadsState(def);
|
|
2655
2703
|
const chV = v(ctx, "_ch");
|
|
2656
2704
|
const rawV = v(ctx, "_raw");
|
|
2657
|
-
const tlV = v(ctx, "_tl");
|
|
2705
|
+
const tlV = capturesTrivia ? v(ctx, "_tl") : "_EMPTY_TL";
|
|
2706
|
+
if (!capturesTrivia) ctx.needsEmptyTl = true;
|
|
2658
2707
|
const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
|
|
2708
|
+
const allocStmt = capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
|
|
2709
|
+
const innerTl = capturesTrivia ? tlV : "undefined";
|
|
2659
2710
|
const stmts = [
|
|
2660
|
-
|
|
2711
|
+
allocStmt,
|
|
2661
2712
|
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
|
|
2662
|
-
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${
|
|
2713
|
+
`${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
|
|
2663
2714
|
];
|
|
2664
2715
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
2665
2716
|
stmts.push(...innerStmts);
|
|
2666
2717
|
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
|
|
2667
2718
|
stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
|
|
2668
|
-
|
|
2669
|
-
|
|
2719
|
+
let stV = "undefined";
|
|
2720
|
+
if (clonesState) {
|
|
2721
|
+
stV = v(ctx, "_nst");
|
|
2722
|
+
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
2723
|
+
}
|
|
2670
2724
|
const ndV = v(ctx, "_nd");
|
|
2671
2725
|
const ndExpr = mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `_build[${buildIdx}](${chV}, ${rawV}, { start: ${pos}, end: ${endVar} }, ${tlV}, ${stV})`;
|
|
2726
|
+
const finalExpr = def.collapse ? `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})` : ndExpr;
|
|
2672
2727
|
stmts.push(
|
|
2673
|
-
`${i}const ${ndV} = ${
|
|
2728
|
+
`${i}const ${ndV} = ${finalExpr}`,
|
|
2674
2729
|
`${i}if (${sc}) ${sc}.push(${ndV})`,
|
|
2675
2730
|
`${i}if (${sr}) ${sr}.push((typeof ${ndV} === 'object' && ${ndV} !== null && ${ndV}._tag === 'node') ? ${ndV} : { _tag: 'leaf', value: typeof ${ndV} === 'string' ? ${ndV} : '', span: { start: ${pos}, end: ${endVar} } })`
|
|
2676
2731
|
);
|
|
@@ -3062,7 +3117,9 @@ function compile(combinator, mapFnSources) {
|
|
|
3062
3117
|
const collatorDecl = ctx.needsCollator ? `const _collator = new Intl.Collator(undefined, { sensitivity: 'accent' })
|
|
3063
3118
|
` : "";
|
|
3064
3119
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
|
|
3120
|
+
const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
|
|
3065
3121
|
const source = [
|
|
3122
|
+
...emptyTlDecls,
|
|
3066
3123
|
...ctx.regexDecls,
|
|
3067
3124
|
"",
|
|
3068
3125
|
...namedPrelude,
|
|
@@ -3074,6 +3131,7 @@ function compile(combinator, mapFnSources) {
|
|
|
3074
3131
|
`}`
|
|
3075
3132
|
].join("\n");
|
|
3076
3133
|
const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
|
|
3134
|
+
...emptyTlDecls,
|
|
3077
3135
|
...ctx.regexDecls,
|
|
3078
3136
|
collatorDecl,
|
|
3079
3137
|
...namedPrelude,
|
|
@@ -3127,10 +3185,12 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
|
|
|
3127
3185
|
].join("\n");
|
|
3128
3186
|
const mfDecl = mapFnSources?.length ? ` const _mf = [${mapFnSources.join(", ")}]` : "";
|
|
3129
3187
|
const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
|
|
3130
|
-
const
|
|
3188
|
+
const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
|
|
3189
|
+
const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl;
|
|
3131
3190
|
if (!needsWrapper) return innerFn;
|
|
3132
3191
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
3133
3192
|
const hoistedDecls = [
|
|
3193
|
+
emptyTlDecl,
|
|
3134
3194
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
3135
3195
|
collatorDecl ? ` ${collatorDecl.trim()}` : "",
|
|
3136
3196
|
mfDecl,
|
|
@@ -3415,6 +3475,31 @@ function replaceAtPath(rebuild, root, path, newNode) {
|
|
|
3415
3475
|
function defaultRebuild(node2, children) {
|
|
3416
3476
|
return { ...node2, children };
|
|
3417
3477
|
}
|
|
3478
|
+
function shiftSpans(child, delta) {
|
|
3479
|
+
const c = child;
|
|
3480
|
+
const span = { start: c.span.start + delta, end: c.span.end + delta };
|
|
3481
|
+
if (Array.isArray(c.children)) {
|
|
3482
|
+
return { ...c, span, children: c.children.map((g) => shiftSpans(g, delta)) };
|
|
3483
|
+
}
|
|
3484
|
+
return { ...c, span };
|
|
3485
|
+
}
|
|
3486
|
+
function graftAndShift(root, path, newNode, delta) {
|
|
3487
|
+
if (path.length === 0) return newNode;
|
|
3488
|
+
const [idx, ...rest] = path;
|
|
3489
|
+
const oldChildren = root.children;
|
|
3490
|
+
const newChildren = oldChildren.map((child, i) => {
|
|
3491
|
+
if (i < idx) return child;
|
|
3492
|
+
if (i === idx) {
|
|
3493
|
+
return rest.length === 0 ? newNode : graftAndShift(child, rest, newNode, delta);
|
|
3494
|
+
}
|
|
3495
|
+
return shiftSpans(child, delta);
|
|
3496
|
+
});
|
|
3497
|
+
return {
|
|
3498
|
+
...root,
|
|
3499
|
+
span: { start: root.span.start, end: root.span.end + delta },
|
|
3500
|
+
children: newChildren
|
|
3501
|
+
};
|
|
3502
|
+
}
|
|
3418
3503
|
var FunctionalDocImpl = class _FunctionalDocImpl {
|
|
3419
3504
|
_registry;
|
|
3420
3505
|
_rootRule;
|
|
@@ -3452,7 +3537,12 @@ var FunctionalDocImpl = class _FunctionalDocImpl {
|
|
|
3452
3537
|
const r = ruleFn(newInput, node2.span.start, ctx);
|
|
3453
3538
|
if (!r.ok) continue;
|
|
3454
3539
|
if (r.span.end === node2.span.end + delta) {
|
|
3455
|
-
|
|
3540
|
+
if (delta === 0) {
|
|
3541
|
+
const newTree2 = replaceAtPath(rebuild, this.tree, path, r.value);
|
|
3542
|
+
return new _FunctionalDocImpl(this._registry, this._rootRule, this._opts, newTree2, [], newInput);
|
|
3543
|
+
}
|
|
3544
|
+
if (this._opts.rebuild) return reparse();
|
|
3545
|
+
const newTree = graftAndShift(this.tree, path, r.value, delta);
|
|
3456
3546
|
return new _FunctionalDocImpl(this._registry, this._rootRule, this._opts, newTree, [], newInput);
|
|
3457
3547
|
}
|
|
3458
3548
|
}
|