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.
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA+ThE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAuGzC;AAED,oEAAoE;AACpE,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AAQlF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAoBT;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAqVhE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAuGzC;AAED,oEAAoE;AACpE,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AAQlF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAoBT;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
@@ -1134,24 +1134,70 @@ function not(combinator) {
1134
1134
  };
1135
1135
  }
1136
1136
 
1137
+ // src/compiler/build-arity.ts
1138
+ var PARAM_LIST_RE = (
1139
+ // (params) => ... | function name?(params) ... | single-ident arrow `x => ...`
1140
+ /^(?:function\b[^(]*\(([^)]*)\)|\(([^)]*)\)\s*=>|([A-Za-z_$][\w$]*)\s*=>)/
1141
+ );
1142
+ var CONFIRMABLE_PARAM_RE = /^[A-Za-z_$][\w$]*\s*\??\s*(?::[^,=]+)?$/;
1143
+ function confirmedBuildArity(src) {
1144
+ const s = src.trim();
1145
+ const m = PARAM_LIST_RE.exec(s);
1146
+ if (!m) return null;
1147
+ if (m[3] !== void 0) return 1;
1148
+ const inner = (m[1] ?? m[2] ?? "").trim();
1149
+ if (inner === "") return 0;
1150
+ const parts = inner.split(",");
1151
+ for (const part of parts) {
1152
+ if (!CONFIRMABLE_PARAM_RE.test(part.trim())) return null;
1153
+ }
1154
+ if (/\barguments\b/.test(s)) return null;
1155
+ return parts.length;
1156
+ }
1157
+ function buildReadsTrivia(def) {
1158
+ const src = def.buildSrc ?? def.build.toString();
1159
+ const arity = confirmedBuildArity(src);
1160
+ if (arity === null) return true;
1161
+ return arity >= 4;
1162
+ }
1163
+ function buildReadsState(def) {
1164
+ const src = def.buildSrc ?? def.build.toString();
1165
+ const arity = confirmedBuildArity(src);
1166
+ if (arity === null) return true;
1167
+ return arity >= 5;
1168
+ }
1169
+
1137
1170
  // src/combinators/node.ts
1138
- function node(type, combinator, build) {
1171
+ function collapseChild(child) {
1172
+ return child !== null && typeof child === "object" && child._tag === "leaf" ? child.value : child;
1173
+ }
1174
+ function node(type, combinator, build, opts) {
1139
1175
  const meta = {
1140
1176
  firstSet: combinator._meta.firstSet,
1141
1177
  canMatchNewline: combinator._meta.canMatchNewline,
1142
1178
  isTrivia: false
1143
1179
  };
1180
+ const collapse = opts?.collapse === true;
1181
+ const def = collapse ? { tag: "node", type, parser: combinator, build, collapse: true } : { tag: "node", type, parser: combinator, build };
1182
+ const capturesTrivia = buildReadsTrivia(def);
1183
+ const clonesState = buildReadsState(def);
1144
1184
  return {
1145
1185
  _tag: "node",
1146
1186
  _meta: meta,
1147
- _def: { tag: "node", type, parser: combinator, build },
1187
+ _def: def,
1148
1188
  parse(input, pos, ctx) {
1149
1189
  const saved = beginCstNodeCapture(ctx);
1190
+ if (!capturesTrivia) ctx.captureTrivia = false;
1150
1191
  const r = combinator.parse(input, pos, ctx);
1151
1192
  const { children, rawChildren, triviaLog } = endCstNodeCapture(ctx, saved);
1152
1193
  if (!r.ok) return r;
1153
- const state = ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
1154
- const built = build(children, rawChildren, r.span, triviaLog, state);
1194
+ const built = collapse && children.length === 1 ? collapseChild(children[0]) : build(
1195
+ children,
1196
+ rawChildren,
1197
+ r.span,
1198
+ triviaLog,
1199
+ clonesState && ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0
1200
+ );
1155
1201
  const isNodeLike = typeof built === "object" && built !== null && built._tag === "node";
1156
1202
  const rawEntry = isNodeLike ? built : { _tag: "leaf", value: typeof built === "string" ? built : "", span: r.span };
1157
1203
  if (saved.buf !== void 0 || saved.ch !== void 0) {
@@ -2554,25 +2600,34 @@ function emitNode(def, ctx, pos) {
2554
2600
  ctx.buildSrcs.push(def.buildSrc ?? null);
2555
2601
  }
2556
2602
  const i = ind(ctx);
2603
+ const capturesTrivia = mkType !== null || buildReadsTrivia(def);
2604
+ const clonesState = buildReadsState(def);
2557
2605
  const chV = v(ctx, "_ch");
2558
2606
  const rawV = v(ctx, "_raw");
2559
- const tlV = v(ctx, "_tl");
2607
+ const tlV = capturesTrivia ? v(ctx, "_tl") : "_EMPTY_TL";
2608
+ if (!capturesTrivia) ctx.needsEmptyTl = true;
2560
2609
  const sc = v(ctx, "_sc"), sl = v(ctx, "_sl"), sr = v(ctx, "_sr"), st = v(ctx, "_st"), stl = v(ctx, "_stl");
2610
+ const allocStmt = capturesTrivia ? `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []` : `${i}const ${chV} = [], ${rawV} = []`;
2611
+ const innerTl = capturesTrivia ? tlV : "undefined";
2561
2612
  const stmts = [
2562
- `${i}const ${chV} = [], ${rawV} = [], ${tlV} = []`,
2613
+ allocStmt,
2563
2614
  `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog`,
2564
- `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${tlV}`
2615
+ `${i}_ctx._cstChildren = ${chV}; _ctx._cstLeaves = ${chV}; _ctx._cstRawChildren = ${rawV}; _ctx.captureTrivia = true; _ctx._cstTriviaLog = ${innerTl}`
2565
2616
  ];
2566
2617
  const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
2567
2618
  stmts.push(...innerStmts);
2568
2619
  stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
2569
2620
  stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
2570
- const stV = v(ctx, "_nst");
2571
- stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
2621
+ let stV = "undefined";
2622
+ if (clonesState) {
2623
+ stV = v(ctx, "_nst");
2624
+ stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
2625
+ }
2572
2626
  const ndV = v(ctx, "_nd");
2573
2627
  const ndExpr = mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, pos, endVar, tlV) : `_build[${buildIdx}](${chV}, ${rawV}, { start: ${pos}, end: ${endVar} }, ${tlV}, ${stV})`;
2628
+ 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;
2574
2629
  stmts.push(
2575
- `${i}const ${ndV} = ${ndExpr}`,
2630
+ `${i}const ${ndV} = ${finalExpr}`,
2576
2631
  `${i}if (${sc}) ${sc}.push(${ndV})`,
2577
2632
  `${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} } })`
2578
2633
  );
@@ -2964,7 +3019,9 @@ function compile(combinator, mapFnSources) {
2964
3019
  const collatorDecl = ctx.needsCollator ? `const _collator = new Intl.Collator(undefined, { sensitivity: 'accent' })
2965
3020
  ` : "";
2966
3021
  const namedPrelude = ctx.namedFnDecls.length > 0 ? [...namedFnPrelude(), ""] : [];
3022
+ const emptyTlDecls = ctx.needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [];
2967
3023
  const source = [
3024
+ ...emptyTlDecls,
2968
3025
  ...ctx.regexDecls,
2969
3026
  "",
2970
3027
  ...namedPrelude,
@@ -2976,6 +3033,7 @@ function compile(combinator, mapFnSources) {
2976
3033
  `}`
2977
3034
  ].join("\n");
2978
3035
  const fn = new Function("input", "_pos", "_rp", "_mf", "_build", "_ctx", [
3036
+ ...emptyTlDecls,
2979
3037
  ...ctx.regexDecls,
2980
3038
  collatorDecl,
2981
3039
  ...namedPrelude,
@@ -3048,6 +3106,7 @@ function compileRuleMap(ruleMap) {
3048
3106
  const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
3049
3107
  const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
3050
3108
  const hoistedDecls = [
3109
+ ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "",
3051
3110
  ...ctx.regexDecls.map((d) => ` ${d}`),
3052
3111
  collatorDecl ? ` ${collatorDecl.trim()}` : "",
3053
3112
  mfDecl,
@@ -3089,10 +3148,12 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
3089
3148
  ].join("\n");
3090
3149
  const mfDecl = mapFnSources?.length ? ` const _mf = [${mapFnSources.join(", ")}]` : "";
3091
3150
  const buildDecl = buildSources?.length ? ` const _build = [${buildSources.join(", ")}]` : "";
3092
- const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
3151
+ const emptyTlDecl = ctx.needsEmptyTl ? ` const _EMPTY_TL = Object.freeze([])` : "";
3152
+ const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl || !!emptyTlDecl;
3093
3153
  if (!needsWrapper) return innerFn;
3094
3154
  const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
3095
3155
  const hoistedDecls = [
3156
+ emptyTlDecl,
3096
3157
  ...ctx.regexDecls.map((d) => ` ${d}`),
3097
3158
  collatorDecl ? ` ${collatorDecl.trim()}` : "",
3098
3159
  mfDecl,
@@ -3293,6 +3354,20 @@ function scopeGet(scope, name, mfs) {
3293
3354
  if (isCombinator(entry)) return entry;
3294
3355
  return null;
3295
3356
  }
3357
+ function staticCollapseOption(expr) {
3358
+ if (expr.type !== "ObjectExpression") return false;
3359
+ for (const prop of expr.properties) {
3360
+ const p = prop;
3361
+ if (p.computed) continue;
3362
+ const key = p.key;
3363
+ const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
3364
+ if (name === "collapse") {
3365
+ const val = p.value;
3366
+ return (val.type === "Literal" || val.type === "BooleanLiteral") && val.value === true;
3367
+ }
3368
+ }
3369
+ return false;
3370
+ }
3296
3371
  function exprToCombi(node2, scope, code, mfs) {
3297
3372
  if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
3298
3373
  if (node2.type !== "CallExpression") return null;
@@ -3341,15 +3416,16 @@ function exprToCombi(node2, scope, code, mfs) {
3341
3416
  }
3342
3417
  }
3343
3418
  if (callee.name === "node" && code !== void 0) {
3344
- const [typeArg, parserArg, buildArg] = node2.arguments;
3419
+ const [typeArg, parserArg, buildArg, optsArg] = node2.arguments;
3345
3420
  if (!typeArg || !parserArg || !buildArg || typeArg.type === "SpreadElement" || parserArg.type === "SpreadElement" || buildArg.type === "SpreadElement") return null;
3346
3421
  const typeVal = anyValue(typeArg, scope, code);
3347
3422
  if (typeof typeVal !== "string") return null;
3348
3423
  const inner = anyValue(parserArg, scope, code, mfs);
3349
3424
  if (!isCombinator(inner)) return null;
3350
3425
  const buildSrc = code.slice(buildArg.start, buildArg.end);
3426
+ const collapse = optsArg !== void 0 && optsArg.type !== "SpreadElement" ? staticCollapseOption(optsArg) : false;
3351
3427
  try {
3352
- const combi = node(typeVal, inner, () => null);
3428
+ const combi = node(typeVal, inner, () => null, collapse ? { collapse: true } : void 0);
3353
3429
  if (combi._def.tag === "node") combi._def.buildSrc = buildSrc;
3354
3430
  return combi;
3355
3431
  } catch {