parseman 0.1.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.
Files changed (60) hide show
  1. package/README.md +510 -0
  2. package/dist/combinators/choice.d.ts +15 -0
  3. package/dist/combinators/choice.d.ts.map +1 -0
  4. package/dist/combinators/first-set.d.ts +8 -0
  5. package/dist/combinators/first-set.d.ts.map +1 -0
  6. package/dist/combinators/grammar.d.ts +8 -0
  7. package/dist/combinators/grammar.d.ts.map +1 -0
  8. package/dist/combinators/guard.d.ts +15 -0
  9. package/dist/combinators/guard.d.ts.map +1 -0
  10. package/dist/combinators/lazy.d.ts +14 -0
  11. package/dist/combinators/lazy.d.ts.map +1 -0
  12. package/dist/combinators/literal.d.ts +6 -0
  13. package/dist/combinators/literal.d.ts.map +1 -0
  14. package/dist/combinators/map.d.ts +8 -0
  15. package/dist/combinators/map.d.ts.map +1 -0
  16. package/dist/combinators/not.d.ts +13 -0
  17. package/dist/combinators/not.d.ts.map +1 -0
  18. package/dist/combinators/parser.d.ts +25 -0
  19. package/dist/combinators/parser.d.ts.map +1 -0
  20. package/dist/combinators/recover.d.ts +20 -0
  21. package/dist/combinators/recover.d.ts.map +1 -0
  22. package/dist/combinators/ref.d.ts +18 -0
  23. package/dist/combinators/ref.d.ts.map +1 -0
  24. package/dist/combinators/regex.d.ts +3 -0
  25. package/dist/combinators/regex.d.ts.map +1 -0
  26. package/dist/combinators/repeat.d.ts +6 -0
  27. package/dist/combinators/repeat.d.ts.map +1 -0
  28. package/dist/combinators/scanTo.d.ts +30 -0
  29. package/dist/combinators/scanTo.d.ts.map +1 -0
  30. package/dist/combinators/sequence.d.ts +7 -0
  31. package/dist/combinators/sequence.d.ts.map +1 -0
  32. package/dist/combinators/withCtx.d.ts +13 -0
  33. package/dist/combinators/withCtx.d.ts.map +1 -0
  34. package/dist/compiler/codegen.d.ts +23 -0
  35. package/dist/compiler/codegen.d.ts.map +1 -0
  36. package/dist/compiler/line-index.d.ts +16 -0
  37. package/dist/compiler/line-index.d.ts.map +1 -0
  38. package/dist/cst/grammar.d.ts +84 -0
  39. package/dist/cst/grammar.d.ts.map +1 -0
  40. package/dist/cst/incremental.d.ts +34 -0
  41. package/dist/cst/incremental.d.ts.map +1 -0
  42. package/dist/cst/types.d.ts +74 -0
  43. package/dist/cst/types.d.ts.map +1 -0
  44. package/dist/index.cjs +1795 -0
  45. package/dist/index.cjs.map +7 -0
  46. package/dist/index.d.ts +26 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +1762 -0
  49. package/dist/index.js.map +7 -0
  50. package/dist/plugin/evaluator.d.ts +15 -0
  51. package/dist/plugin/evaluator.d.ts.map +1 -0
  52. package/dist/plugin/index.cjs +1473 -0
  53. package/dist/plugin/index.cjs.map +7 -0
  54. package/dist/plugin/index.d.ts +12 -0
  55. package/dist/plugin/index.d.ts.map +1 -0
  56. package/dist/plugin/index.js +1442 -0
  57. package/dist/plugin/index.js.map +7 -0
  58. package/dist/types.d.ts +201 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/package.json +67 -0
@@ -0,0 +1,1473 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/plugin/index.ts
31
+ var plugin_exports = {};
32
+ __export(plugin_exports, {
33
+ default: () => plugin_default,
34
+ transformMacro: () => transformMacro
35
+ });
36
+ module.exports = __toCommonJS(plugin_exports);
37
+ var import_unplugin = require("unplugin");
38
+ var import_oxc_parser = require("oxc-parser");
39
+ var import_magic_string = __toESM(require("magic-string"), 1);
40
+
41
+ // src/combinators/first-set.ts
42
+ function union(a, b) {
43
+ if (a.kind === "any" || b.kind === "any") return { kind: "any" };
44
+ if (a.kind === "empty") return b;
45
+ if (b.kind === "empty") return a;
46
+ return { kind: "ranges", ranges: mergeRanges([...a.ranges, ...b.ranges]) };
47
+ }
48
+ function intersects(a, b) {
49
+ if (a.kind === "any" || b.kind === "any") return true;
50
+ if (a.kind === "empty" || b.kind === "empty") return false;
51
+ for (const ra of a.ranges) {
52
+ for (const rb of b.ranges) {
53
+ if (ra.lo <= rb.hi && rb.lo <= ra.hi) return true;
54
+ }
55
+ }
56
+ return false;
57
+ }
58
+ function fromChar(code) {
59
+ return { kind: "ranges", ranges: [{ lo: code, hi: code }] };
60
+ }
61
+ function fromRange(lo, hi) {
62
+ return { kind: "ranges", ranges: [{ lo, hi }] };
63
+ }
64
+ function any() {
65
+ return { kind: "any" };
66
+ }
67
+ function empty() {
68
+ return { kind: "empty" };
69
+ }
70
+ function mergeRanges(ranges) {
71
+ if (ranges.length === 0) return [];
72
+ const sorted = [...ranges].sort((a, b) => a.lo - b.lo);
73
+ const out = [{ lo: sorted[0].lo, hi: sorted[0].hi }];
74
+ for (let i = 1; i < sorted.length; i++) {
75
+ const top = out[out.length - 1];
76
+ const cur = sorted[i];
77
+ if (cur.lo <= top.hi + 1) {
78
+ if (cur.hi > top.hi) top.hi = cur.hi;
79
+ } else {
80
+ out.push({ lo: cur.lo, hi: cur.hi });
81
+ }
82
+ }
83
+ return out;
84
+ }
85
+
86
+ // src/combinators/literal.ts
87
+ var _collatorCache = null;
88
+ function collator() {
89
+ if (_collatorCache === null) {
90
+ _collatorCache = new Intl.Collator(void 0, { sensitivity: "accent" });
91
+ }
92
+ return _collatorCache;
93
+ }
94
+ function literal(value, opts = {}) {
95
+ const caseInsensitive = opts.caseInsensitive ?? false;
96
+ const firstSet = value.length > 0 ? fromChar(value.codePointAt(0)) : empty();
97
+ const meta = {
98
+ firstSet,
99
+ canMatchNewline: value.includes("\n"),
100
+ isTrivia: false
101
+ };
102
+ if (caseInsensitive) {
103
+ const upper = value.toUpperCase();
104
+ const lower = value.toLowerCase();
105
+ const firstUpper = upper.codePointAt(0);
106
+ const firstLower = lower.codePointAt(0);
107
+ meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? { kind: "ranges", ranges: [
108
+ { lo: Math.min(firstLower, firstUpper), hi: Math.max(firstLower, firstUpper) }
109
+ ] } : firstSet;
110
+ }
111
+ return {
112
+ _tag: "literal",
113
+ _meta: meta,
114
+ _def: { tag: "literal", value, caseInsensitive },
115
+ parse(input, pos, _ctx) {
116
+ const end = pos + value.length;
117
+ if (end > input.length) {
118
+ return { ok: false, expected: [JSON.stringify(value)], span: { start: pos, end: pos } };
119
+ }
120
+ const slice = input.slice(pos, end);
121
+ const matched = caseInsensitive ? collator().compare(slice, value) === 0 : slice === value;
122
+ if (matched) {
123
+ const span = { start: pos, end };
124
+ const leaf = { _tag: "leaf", value: slice, span };
125
+ if (_ctx._cstLeaves) _ctx._cstLeaves.push(leaf);
126
+ if (_ctx._cstRawChildren) _ctx._cstRawChildren.push(leaf);
127
+ return { ok: true, value: slice, span };
128
+ }
129
+ return { ok: false, expected: [JSON.stringify(value)], span: { start: pos, end: pos } };
130
+ }
131
+ };
132
+ }
133
+
134
+ // src/combinators/regex.ts
135
+ var import_regexp_tree = __toESM(require("regexp-tree"), 1);
136
+ function firstSetFromRegex(pattern) {
137
+ try {
138
+ const ast = import_regexp_tree.default.parse(`/${pattern}/`);
139
+ return extractFirstSet(ast.body);
140
+ } catch {
141
+ return { firstSet: any(), canMatchNewline: true };
142
+ }
143
+ }
144
+ function canBeEmpty(node) {
145
+ if (!node) return true;
146
+ switch (node.type) {
147
+ case "Repetition": {
148
+ const q = node.quantifier;
149
+ return q.kind === "*" || q.kind === "?" || q.kind === "Range" && (q.from ?? 1) === 0;
150
+ }
151
+ case "Alternative": {
152
+ const exprs = node.expressions;
153
+ return !exprs || exprs.length === 0 || exprs.every((e) => canBeEmpty(e));
154
+ }
155
+ case "Group":
156
+ return canBeEmpty(node.expression);
157
+ case "Disjunction":
158
+ return canBeEmpty(node.left) || canBeEmpty(node.right);
159
+ default:
160
+ return false;
161
+ }
162
+ }
163
+ function extractFirstSet(node) {
164
+ if (!node) return { firstSet: empty(), canMatchNewline: false };
165
+ switch (node.type) {
166
+ case "Disjunction": {
167
+ const left = extractFirstSet(node.left);
168
+ const right = extractFirstSet(node.right);
169
+ return {
170
+ firstSet: union(left.firstSet, right.firstSet),
171
+ canMatchNewline: left.canMatchNewline || right.canMatchNewline
172
+ };
173
+ }
174
+ case "Alternative": {
175
+ const exprs = node.expressions;
176
+ if (!exprs || exprs.length === 0) return { firstSet: empty(), canMatchNewline: false };
177
+ let fs = empty();
178
+ let canNL = false;
179
+ for (const expr of exprs) {
180
+ const r = extractFirstSet(expr);
181
+ fs = union(fs, r.firstSet);
182
+ canNL = canNL || r.canMatchNewline;
183
+ if (!canBeEmpty(expr)) break;
184
+ }
185
+ return { firstSet: fs, canMatchNewline: canNL };
186
+ }
187
+ case "Char": {
188
+ const kind = node.kind;
189
+ if (kind === "simple") {
190
+ const code = node.codePoint ?? node.value.codePointAt(0) ?? 0;
191
+ return { firstSet: fromRange(code, code), canMatchNewline: code === 10 };
192
+ }
193
+ if (kind === "meta") {
194
+ const val = node.value;
195
+ if (val === ".") return { firstSet: any(), canMatchNewline: false };
196
+ if (val === "d") return { firstSet: fromRange(48, 57), canMatchNewline: false };
197
+ if (val === "D") return { firstSet: any(), canMatchNewline: true };
198
+ if (val === "w") return {
199
+ firstSet: union(
200
+ union(fromRange(48, 57), fromRange(65, 90)),
201
+ union(fromRange(97, 122), fromRange(95, 95))
202
+ ),
203
+ canMatchNewline: false
204
+ };
205
+ if (val === "s") return { firstSet: fromRange(9, 13), canMatchNewline: true };
206
+ if (val === "n") return { firstSet: fromRange(10, 10), canMatchNewline: true };
207
+ }
208
+ return { firstSet: any(), canMatchNewline: true };
209
+ }
210
+ case "CharacterClass": {
211
+ const expressions = node.expressions;
212
+ let fs = empty();
213
+ let canNL = false;
214
+ for (const expr of expressions) {
215
+ if (expr.type === "ClassRange") {
216
+ const from = expr.from.codePoint;
217
+ const to = expr.to.codePoint;
218
+ fs = union(fs, fromRange(from, to));
219
+ if (from <= 10 && 10 <= to) canNL = true;
220
+ } else if (expr.type === "Char") {
221
+ const r = extractFirstSet(expr);
222
+ fs = union(fs, r.firstSet);
223
+ canNL = canNL || r.canMatchNewline;
224
+ }
225
+ }
226
+ if (node.negative) return { firstSet: any(), canMatchNewline: true };
227
+ return { firstSet: fs, canMatchNewline: canNL };
228
+ }
229
+ case "Repetition": {
230
+ return extractFirstSet(node.expression);
231
+ }
232
+ case "Group": {
233
+ return extractFirstSet(node.expression);
234
+ }
235
+ default:
236
+ return { firstSet: any(), canMatchNewline: true };
237
+ }
238
+ }
239
+ function optimizeRegex(source, flags) {
240
+ try {
241
+ const result = import_regexp_tree.default.optimize(`/${source}/${flags}`);
242
+ const str = result.toString();
243
+ const lastSlash = str.lastIndexOf("/");
244
+ return str.slice(1, lastSlash);
245
+ } catch {
246
+ return source;
247
+ }
248
+ }
249
+ function regex(pattern, flags = "") {
250
+ const source = typeof pattern === "string" ? pattern : pattern.source;
251
+ const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
252
+ const optimizedSource = optimizeRegex(source, resolvedFlags);
253
+ const anchored = new RegExp(optimizedSource, "y" + resolvedFlags.replace(/[gy]/g, ""));
254
+ const { firstSet, canMatchNewline } = firstSetFromRegex(source);
255
+ const meta = { firstSet, canMatchNewline, isTrivia: false };
256
+ return {
257
+ _tag: "regex",
258
+ _meta: meta,
259
+ _def: { tag: "regex", source, flags: resolvedFlags, optimizedSource },
260
+ parse(input, pos, ctx) {
261
+ anchored.lastIndex = pos;
262
+ const m = anchored.exec(input);
263
+ if (m === null) {
264
+ return { ok: false, expected: [`/${source}/`], span: { start: pos, end: pos } };
265
+ }
266
+ const span = { start: pos, end: pos + m[0].length };
267
+ const leaf = { _tag: "leaf", value: m[0], span };
268
+ if (ctx._cstLeaves) ctx._cstLeaves.push(leaf);
269
+ if (ctx._cstRawChildren) ctx._cstRawChildren.push(leaf);
270
+ return { ok: true, value: m[0], span };
271
+ }
272
+ };
273
+ }
274
+
275
+ // src/combinators/sequence.ts
276
+ function sequence(...parsers) {
277
+ const meta = {
278
+ firstSet: parsers[0]?._meta.firstSet ?? empty(),
279
+ canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
280
+ isTrivia: false
281
+ };
282
+ return {
283
+ _tag: "sequence",
284
+ _meta: meta,
285
+ _def: { tag: "sequence", parsers },
286
+ parse(input, pos, ctx) {
287
+ const values = [];
288
+ let cur = pos;
289
+ for (let i = 0; i < parsers.length; i++) {
290
+ if (ctx.trivia && i > 0) {
291
+ const tr = ctx.trivia.parse(input, cur, { trivia: ctx.trivia, trackLines: ctx.trackLines, user: ctx.user });
292
+ if (tr.ok) {
293
+ if (ctx._cstRawChildren && tr.span.end > tr.span.start)
294
+ ctx._cstRawChildren.push({ _tag: "trivia", value: input.slice(tr.span.start, tr.span.end), span: tr.span });
295
+ cur = tr.span.end;
296
+ }
297
+ }
298
+ const result = parsers[i].parse(input, cur, ctx);
299
+ if (!result.ok) return result;
300
+ values.push(result.value);
301
+ cur = result.span.end;
302
+ }
303
+ return {
304
+ ok: true,
305
+ value: values,
306
+ span: { start: pos, end: cur }
307
+ };
308
+ }
309
+ };
310
+ }
311
+
312
+ // src/combinators/choice.ts
313
+ function choice(...args) {
314
+ const parsers = args.map((a) => "gate" in a ? a.parser : a);
315
+ const gates = args.map((a) => "gate" in a ? a.gate : null);
316
+ const hasGates = gates.some((g) => g !== null);
317
+ const disjoint = !hasGates && areDisjoint(parsers.map((p) => p._meta.firstSet));
318
+ let combined = { kind: "empty" };
319
+ for (const p of parsers) combined = union(combined, p._meta.firstSet);
320
+ const meta = {
321
+ firstSet: combined,
322
+ canMatchNewline: parsers.some((p) => p._meta.canMatchNewline),
323
+ isTrivia: false,
324
+ disjoint
325
+ };
326
+ const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
327
+ const autoNot = !disjoint && !hasGates && strategy?.tag === "firstMatch" ? computeAutoNot(parsers) : parsers.map(() => null);
328
+ let greedyRe = null;
329
+ let greedyLitMap = null;
330
+ let sortedParsers = null;
331
+ if (strategy?.tag === "greedyClassify") {
332
+ const regexDef = getCoreRegexDef(parsers[strategy.superIndex]);
333
+ const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
334
+ greedyRe = new RegExp(regexDef.source, flags);
335
+ greedyLitMap = /* @__PURE__ */ new Map();
336
+ for (let i = 0; i < parsers.length; i++) {
337
+ if (i === strategy.superIndex) continue;
338
+ const litVal = getCoreLiteralValue(parsers[i]);
339
+ if (litVal !== null) greedyLitMap.set(litVal, i);
340
+ }
341
+ } else if (strategy?.tag === "literalsLongestFirst") {
342
+ sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
343
+ }
344
+ return {
345
+ _tag: "choice",
346
+ _meta: meta,
347
+ _def: {
348
+ tag: "choice",
349
+ parsers,
350
+ gates,
351
+ disjoint,
352
+ strategy: strategy ?? { tag: "firstMatch" },
353
+ autoNot
354
+ },
355
+ parse(input, pos, ctx) {
356
+ const expected = [];
357
+ if (disjoint && pos < input.length) {
358
+ const code = input.codePointAt(pos);
359
+ for (const parser2 of parsers) {
360
+ if (inFirstSet(code, parser2._meta.firstSet)) {
361
+ const result = parser2.parse(input, pos, ctx);
362
+ if (result.ok) return result;
363
+ expected.push(...result.expected);
364
+ return { ok: false, expected, span: { start: pos, end: pos } };
365
+ }
366
+ }
367
+ return {
368
+ ok: false,
369
+ expected: parsers.flatMap((p) => {
370
+ const r = p.parse(input, pos, ctx);
371
+ return r.ok ? [] : r.expected;
372
+ }),
373
+ span: { start: pos, end: pos }
374
+ };
375
+ }
376
+ if (strategy?.tag === "greedyClassify") {
377
+ const superResult = parsers[strategy.superIndex].parse(input, pos, ctx);
378
+ if (!superResult.ok) return superResult;
379
+ const end = superResult.span.end;
380
+ const litIdx = greedyLitMap.get(input.slice(pos, end));
381
+ if (litIdx !== void 0) {
382
+ const litVal = getCoreLiteralValue(parsers[litIdx]);
383
+ const value = applyTransforms(parsers[litIdx], litVal, { start: pos, end });
384
+ return { ok: true, value, span: { start: pos, end } };
385
+ }
386
+ return superResult;
387
+ }
388
+ if (strategy?.tag === "literalsLongestFirst") {
389
+ for (const p of sortedParsers) {
390
+ const r = p.parse(input, pos, ctx);
391
+ if (r.ok) return r;
392
+ expected.push(...r.expected);
393
+ }
394
+ return { ok: false, expected, span: { start: pos, end: pos } };
395
+ }
396
+ for (let i = 0; i < parsers.length; i++) {
397
+ if (gates[i] && !gates[i](ctx.user)) continue;
398
+ const result = parsers[i].parse(input, pos, ctx);
399
+ if (!result.ok) {
400
+ expected.push(...result.expected);
401
+ continue;
402
+ }
403
+ const checks = autoNot[i];
404
+ if (checks && autoNotFires(input, result.span.end, checks)) continue;
405
+ return result;
406
+ }
407
+ return { ok: false, expected, span: { start: pos, end: pos } };
408
+ }
409
+ };
410
+ }
411
+ function detectStrategy(parsers) {
412
+ const regexIndices = [];
413
+ const literalIndices = [];
414
+ for (let i = 0; i < parsers.length; i++) {
415
+ if (getCoreRegexDef(parsers[i]) !== null) regexIndices.push(i);
416
+ else if (getCoreLiteralValue(parsers[i]) !== null) literalIndices.push(i);
417
+ }
418
+ if (regexIndices.length === 1 && literalIndices.length === parsers.length - 1 && literalIndices.length > 0) {
419
+ const superIndex = regexIndices[0];
420
+ const regexDef = getCoreRegexDef(parsers[superIndex]);
421
+ const flags = "y" + regexDef.flags.replace(/[gy]/g, "");
422
+ const re = new RegExp(regexDef.source, flags);
423
+ const allSubsumed = literalIndices.every((i) => {
424
+ const litVal = getCoreLiteralValue(parsers[i]);
425
+ re.lastIndex = 0;
426
+ const m = re.exec(litVal);
427
+ return m !== null && m[0] === litVal;
428
+ });
429
+ if (allSubsumed) return { tag: "greedyClassify", superIndex };
430
+ }
431
+ if (parsers.length === literalIndices.length) {
432
+ const sortedIndices = [...literalIndices].sort(
433
+ (a, b) => getCoreLiteralValue(parsers[b]).length - getCoreLiteralValue(parsers[a]).length
434
+ );
435
+ return { tag: "literalsLongestFirst", sortedIndices };
436
+ }
437
+ return { tag: "firstMatch" };
438
+ }
439
+ function computeAutoNot(parsers) {
440
+ return parsers.map((p, i) => {
441
+ const litVal = getCoreLiteralValue(p);
442
+ if (litVal === null) return null;
443
+ const checks = [];
444
+ for (let j = i + 1; j < parsers.length; j++) {
445
+ const other = parsers[j];
446
+ const otherLit = getCoreLiteralValue(other);
447
+ if (otherLit !== null && otherLit.startsWith(litVal) && otherLit.length > litVal.length) {
448
+ checks.push({ kind: "startsWith", value: otherLit.slice(litVal.length) });
449
+ continue;
450
+ }
451
+ const regexDef = getCoreRegexDef(other);
452
+ if (regexDef !== null) {
453
+ const contSet = continuationFirstSet(litVal, regexDef.source, regexDef.flags);
454
+ if (contSet !== null) checks.push({ kind: "firstSet", set: contSet });
455
+ }
456
+ }
457
+ return checks.length > 0 ? checks : null;
458
+ });
459
+ }
460
+ function autoNotFires(input, end, checks) {
461
+ for (const check of checks) {
462
+ if (check.kind === "firstSet") {
463
+ const code = end < input.length ? input.codePointAt(end) ?? -1 : -1;
464
+ if (inFirstSet(code, check.set)) return true;
465
+ } else {
466
+ if (input.startsWith(check.value, end)) return true;
467
+ }
468
+ }
469
+ return false;
470
+ }
471
+ function getCoreLiteralValue(p) {
472
+ const def = p._def;
473
+ if (def.tag === "literal" && !def.caseInsensitive) return def.value;
474
+ if (def.tag === "transform") return getCoreLiteralValue(def.parser);
475
+ return null;
476
+ }
477
+ function getCoreRegexDef(p) {
478
+ const def = p._def;
479
+ if (def.tag === "regex") return { source: def.source, flags: def.flags };
480
+ if (def.tag === "transform") return getCoreRegexDef(def.parser);
481
+ return null;
482
+ }
483
+ function applyTransforms(p, value, span) {
484
+ const def = p._def;
485
+ if (def.tag === "transform") {
486
+ const inner = applyTransforms(def.parser, value, span);
487
+ return def.fn(inner, span);
488
+ }
489
+ return value;
490
+ }
491
+ function continuationFirstSet(lit, source, flags) {
492
+ const re = new RegExp(source, "y" + flags.replace(/[gy]/g, ""));
493
+ re.lastIndex = 0;
494
+ const base = re.exec(lit);
495
+ if (!base || base[0] !== lit) return null;
496
+ const contCodes = [];
497
+ for (let code = 1; code < 128; code++) {
498
+ re.lastIndex = 0;
499
+ const m = re.exec(lit + String.fromCharCode(code));
500
+ if (m && m[0].length > lit.length) contCodes.push(code);
501
+ }
502
+ if (contCodes.length === 0) return null;
503
+ return codesToFirstSet(contCodes);
504
+ }
505
+ function codesToFirstSet(codes) {
506
+ codes.sort((a, b) => a - b);
507
+ const ranges = [];
508
+ let lo = codes[0], hi = codes[0];
509
+ for (let i = 1; i < codes.length; i++) {
510
+ if (codes[i] === hi + 1) {
511
+ hi = codes[i];
512
+ } else {
513
+ ranges.push({ lo, hi });
514
+ lo = hi = codes[i];
515
+ }
516
+ }
517
+ ranges.push({ lo, hi });
518
+ return { kind: "ranges", ranges };
519
+ }
520
+ function inFirstSet(code, fs) {
521
+ if (fs.kind === "any") return true;
522
+ if (fs.kind === "empty") return false;
523
+ for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
524
+ return false;
525
+ }
526
+ function areDisjoint(sets) {
527
+ if (sets.some((s) => s.kind === "any")) return false;
528
+ for (let i = 0; i < sets.length; i++)
529
+ for (let j = i + 1; j < sets.length; j++)
530
+ if (intersects(sets[i], sets[j])) return false;
531
+ return true;
532
+ }
533
+
534
+ // src/combinators/repeat.ts
535
+ function many(parser2) {
536
+ const meta = {
537
+ firstSet: parser2._meta.firstSet,
538
+ canMatchNewline: parser2._meta.canMatchNewline,
539
+ isTrivia: false
540
+ };
541
+ return {
542
+ _tag: "many",
543
+ _meta: meta,
544
+ _def: { tag: "many", parser: parser2, min: 0 },
545
+ parse(input, pos, ctx) {
546
+ const values = [];
547
+ let cur = pos;
548
+ while (cur < input.length) {
549
+ const result = parser2.parse(input, cur, ctx);
550
+ if (!result.ok) break;
551
+ if (result.span.end === cur) break;
552
+ values.push(result.value);
553
+ cur = result.span.end;
554
+ }
555
+ return { ok: true, value: values, span: { start: pos, end: cur } };
556
+ }
557
+ };
558
+ }
559
+ function oneOrMore(parser2) {
560
+ const meta = {
561
+ firstSet: parser2._meta.firstSet,
562
+ canMatchNewline: parser2._meta.canMatchNewline,
563
+ isTrivia: false
564
+ };
565
+ return {
566
+ _tag: "oneOrMore",
567
+ _meta: meta,
568
+ _def: { tag: "oneOrMore", parser: parser2, min: 1 },
569
+ parse(input, pos, ctx) {
570
+ const first = parser2.parse(input, pos, ctx);
571
+ if (!first.ok) return first;
572
+ const values = [first.value];
573
+ let cur = first.span.end;
574
+ while (cur < input.length) {
575
+ const result = parser2.parse(input, cur, ctx);
576
+ if (!result.ok) break;
577
+ if (result.span.end === cur) break;
578
+ values.push(result.value);
579
+ cur = result.span.end;
580
+ }
581
+ return { ok: true, value: values, span: { start: pos, end: cur } };
582
+ }
583
+ };
584
+ }
585
+ function optional(parser2) {
586
+ const meta = {
587
+ firstSet: parser2._meta.firstSet,
588
+ canMatchNewline: parser2._meta.canMatchNewline,
589
+ isTrivia: false
590
+ };
591
+ return {
592
+ _tag: "optional",
593
+ _meta: meta,
594
+ _def: { tag: "optional", parser: parser2 },
595
+ parse(input, pos, ctx) {
596
+ const result = parser2.parse(input, pos, ctx);
597
+ if (result.ok) return result;
598
+ return { ok: true, value: null, span: { start: pos, end: pos } };
599
+ }
600
+ };
601
+ }
602
+ function sepBy(parser2, separator) {
603
+ const meta = {
604
+ firstSet: parser2._meta.firstSet,
605
+ canMatchNewline: parser2._meta.canMatchNewline || separator._meta.canMatchNewline,
606
+ isTrivia: false
607
+ };
608
+ return {
609
+ _tag: "sepBy",
610
+ _meta: meta,
611
+ _def: { tag: "sepBy", parser: parser2, separator },
612
+ parse(input, pos, ctx) {
613
+ const first = parser2.parse(input, pos, ctx);
614
+ if (!first.ok) return { ok: true, value: [], span: { start: pos, end: pos } };
615
+ const values = [first.value];
616
+ let cur = first.span.end;
617
+ while (cur < input.length) {
618
+ let sepPos = cur;
619
+ if (ctx.trivia) {
620
+ const triviaCtx = { trivia: ctx.trivia, trackLines: ctx.trackLines, user: ctx.user };
621
+ const tr = ctx.trivia.parse(input, sepPos, triviaCtx);
622
+ if (tr.ok) {
623
+ if (ctx._cstRawChildren && tr.span.end > tr.span.start) ctx._cstRawChildren.push({ _tag: "trivia", value: input.slice(tr.span.start, tr.span.end), span: tr.span });
624
+ sepPos = tr.span.end;
625
+ }
626
+ }
627
+ const sep = separator.parse(input, sepPos, ctx);
628
+ if (!sep.ok) break;
629
+ let nextPos = sep.span.end;
630
+ if (ctx.trivia) {
631
+ const triviaCtx = { trivia: ctx.trivia, trackLines: ctx.trackLines, user: ctx.user };
632
+ const tr = ctx.trivia.parse(input, nextPos, triviaCtx);
633
+ if (tr.ok) {
634
+ if (ctx._cstRawChildren && tr.span.end > tr.span.start) ctx._cstRawChildren.push({ _tag: "trivia", value: input.slice(tr.span.start, tr.span.end), span: tr.span });
635
+ nextPos = tr.span.end;
636
+ }
637
+ }
638
+ const next = parser2.parse(input, nextPos, ctx);
639
+ if (!next.ok) break;
640
+ values.push(next.value);
641
+ cur = next.span.end;
642
+ }
643
+ return { ok: true, value: values, span: { start: pos, end: cur } };
644
+ }
645
+ };
646
+ }
647
+
648
+ // src/compiler/codegen.ts
649
+ function v(ctx, prefix = "_v") {
650
+ return `${prefix}${ctx.vars++}`;
651
+ }
652
+ function ind(ctx) {
653
+ return " ".repeat(ctx.indent);
654
+ }
655
+ function failStmt(ctx, expected, posExpr) {
656
+ return `${ind(ctx)}return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
657
+ }
658
+ function firstSetCond(codeVar, fs) {
659
+ if (fs.kind === "any") return "true";
660
+ if (fs.kind === "empty") return "false";
661
+ return fs.ranges.map(
662
+ (r) => r.lo === r.hi ? `${codeVar} === ${r.lo}` : `(${codeVar} >= ${r.lo} && ${codeVar} <= ${r.hi})`
663
+ ).join(" || ");
664
+ }
665
+ function asIIFE(stmts, valueVar, endVar, startPos, indent) {
666
+ return [
667
+ `(() => {`,
668
+ ...stmts,
669
+ `${indent} return { ok: true, value: ${valueVar}, span: { start: ${startPos}, end: ${endVar} } }`,
670
+ `${indent}})()`
671
+ ].join("\n");
672
+ }
673
+ function emitLit(def, ctx, pos) {
674
+ const { value, caseInsensitive } = def;
675
+ const len = value.length;
676
+ const vv = v(ctx);
677
+ const expectedStr = JSON.stringify(JSON.stringify(value));
678
+ const stmts = [];
679
+ if (caseInsensitive) {
680
+ ctx.needsCollator = true;
681
+ stmts.push(
682
+ `${ind(ctx)}if (${pos} + ${len} > input.length) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
683
+ `${ind(ctx)}const ${vv}_s = input.slice(${pos}, ${pos} + ${len})`,
684
+ `${ind(ctx)}if (_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
685
+ `${ind(ctx)}const ${vv} = ${vv}_s`
686
+ );
687
+ } else if (len === 0) {
688
+ stmts.push(`${ind(ctx)}const ${vv} = ''`);
689
+ } else if (len === 1) {
690
+ const code = value.codePointAt(0);
691
+ stmts.push(
692
+ `${ind(ctx)}if (${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
693
+ `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
694
+ );
695
+ } else if (len <= 4) {
696
+ const checks = Array.from(
697
+ { length: len },
698
+ (_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
699
+ ).join(" || ");
700
+ stmts.push(
701
+ `${ind(ctx)}if (${pos} + ${len} > input.length || ${checks}) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
702
+ `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
703
+ );
704
+ } else {
705
+ stmts.push(
706
+ `${ind(ctx)}if (!input.startsWith(${JSON.stringify(value)}, ${pos})) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
707
+ `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
708
+ );
709
+ }
710
+ return { stmts, valueVar: vv, endVar: len === 0 ? pos : `${pos} + ${len}` };
711
+ }
712
+ function emitRegex(def, ctx, pos) {
713
+ const flags = "y" + def.flags.replace(/[gy]/g, "");
714
+ const rName = `_re${ctx.regexDecls.length}`;
715
+ ctx.regexDecls.push(`const ${rName} = /${def.optimizedSource}/${flags}`);
716
+ const mv = v(ctx, "_m");
717
+ const vv = v(ctx);
718
+ const expectedStr = JSON.stringify(`/${def.source}/`);
719
+ const stmts = [
720
+ `${ind(ctx)}${rName}.lastIndex = ${pos}`,
721
+ `${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
722
+ `${ind(ctx)}if (${mv} === null) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
723
+ `${ind(ctx)}const ${vv} = ${mv}[0]`
724
+ ];
725
+ return { stmts, valueVar: vv, endVar: `${pos} + ${vv}.length` };
726
+ }
727
+ function ensureTriviaFn(ctx) {
728
+ const trivia2 = ctx.activeTrivia;
729
+ if (!ctx.namedParsers.has(trivia2)) {
730
+ const fnName = `_pf${ctx.namedParsers.size}`;
731
+ ctx.namedParsers.set(trivia2, fnName);
732
+ const savedIndent = ctx.indent;
733
+ ctx.indent = 1;
734
+ const r = emit(trivia2, ctx, "_pos");
735
+ ctx.indent = savedIndent;
736
+ ctx.namedFnDecls.push([
737
+ `function ${fnName}(input, _pos, _ctx) {`,
738
+ ...r.stmts,
739
+ ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
740
+ `}`
741
+ ].join("\n"));
742
+ }
743
+ return ctx.namedParsers.get(trivia2);
744
+ }
745
+ function emitSeq(def, ctx, pos) {
746
+ const startV = v(ctx, "_start");
747
+ const curV = v(ctx, "_cur");
748
+ const stmts = [
749
+ `${ind(ctx)}const ${startV} = ${pos}`,
750
+ `${ind(ctx)}let ${curV} = ${pos}`
751
+ ];
752
+ const valueVars = [];
753
+ for (let i = 0; i < def.parsers.length; i++) {
754
+ if (i > 0 && ctx.activeTrivia) {
755
+ const trivFn = ensureTriviaFn(ctx);
756
+ const tmp = v(ctx, "_trv");
757
+ stmts.push(
758
+ `${ind(ctx)}const ${tmp} = ${trivFn}(input, ${curV}, _ctx)`,
759
+ `${ind(ctx)}if (${tmp}.ok) ${curV} = ${tmp}.span.end`
760
+ );
761
+ }
762
+ const r = emit(def.parsers[i], ctx, curV);
763
+ stmts.push(...r.stmts, `${ind(ctx)}${curV} = ${r.endVar}`);
764
+ valueVars.push(r.valueVar);
765
+ }
766
+ const arrV = v(ctx, "_arr");
767
+ stmts.push(`${ind(ctx)}const ${arrV} = [${valueVars.join(", ")}]`);
768
+ return { stmts, valueVar: arrV, endVar: curV };
769
+ }
770
+ function emitChoice(def, ctx, pos) {
771
+ const allExpected = JSON.stringify(
772
+ def.parsers.map((p) => {
773
+ const d = p._def;
774
+ if (d.tag === "literal") return JSON.stringify(d.value);
775
+ if (d.tag === "regex") return `/${d.source}/`;
776
+ return p._tag;
777
+ })
778
+ );
779
+ if (def.disjoint) {
780
+ const codeV = v(ctx, "_code");
781
+ const valV = v(ctx, "_chv");
782
+ const endV = v(ctx, "_che");
783
+ const stmts = [
784
+ `${ind(ctx)}const ${codeV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
785
+ `${ind(ctx)}let ${valV}, ${endV} = ${pos}`
786
+ ];
787
+ let first = true;
788
+ for (const p of def.parsers) {
789
+ const cond = firstSetCond(codeV, p._meta.firstSet);
790
+ const kw = first ? "if" : "else if";
791
+ first = false;
792
+ stmts.push(`${ind(ctx)}${kw} (${cond}) {`);
793
+ ctx.indent++;
794
+ const r = emit(p, ctx, pos);
795
+ stmts.push(...r.stmts);
796
+ stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}; ${endV} = ${r.endVar}`);
797
+ ctx.indent--;
798
+ stmts.push(`${ind(ctx)}}`);
799
+ }
800
+ stmts.push(
801
+ `${ind(ctx)}else return { ok: false, expected: ${allExpected}, span: { start: ${pos}, end: ${pos} } }`
802
+ );
803
+ return { stmts, valueVar: valV, endVar: endV };
804
+ }
805
+ return emitNonDisjoint(def, def.strategy, allExpected, ctx, pos);
806
+ }
807
+ function emitGreedyClassify(def, superIndex, allExpected, ctx, pos) {
808
+ const superParser = def.parsers[superIndex];
809
+ const regexDef = getCoreRegexDef(superParser);
810
+ const reIdx = ctx.regexDecls.length;
811
+ const reVar = `_re${reIdx}`;
812
+ const cleanFlags = "y" + regexDef.flags.replace(/[gy]/g, "");
813
+ ctx.regexDecls.push(`const ${reVar} = /${regexDef.source}/${cleanFlags}`);
814
+ const matchV = v(ctx, "_gm");
815
+ const wordV = v(ctx, "_gw");
816
+ const endV = v(ctx, "_ge");
817
+ const stmts = [
818
+ `${ind(ctx)}${reVar}.lastIndex = ${pos}`,
819
+ `${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
820
+ `${ind(ctx)}if (${matchV} === null) return { ok: false, expected: ${allExpected}, span: { start: ${pos}, end: ${pos} } }`,
821
+ `${ind(ctx)}const ${wordV} = ${matchV}[0]`,
822
+ `${ind(ctx)}const ${endV} = ${pos} + ${wordV}.length`
823
+ ];
824
+ for (let i = 0; i < def.parsers.length; i++) {
825
+ if (i === superIndex) continue;
826
+ const p = def.parsers[i];
827
+ const litVal = getCoreLiteralValue(p);
828
+ if (litVal === null) continue;
829
+ stmts.push(`${ind(ctx)}if (${wordV} === ${JSON.stringify(litVal)}) {`);
830
+ ctx.indent++;
831
+ const tR = emitTransformChain(p, JSON.stringify(litVal), endV, pos, ctx);
832
+ stmts.push(...tR.stmts);
833
+ stmts.push(`${ind(ctx)}return { ok: true, value: ${tR.valueVar}, span: { start: ${pos}, end: ${endV} } }`);
834
+ ctx.indent--;
835
+ stmts.push(`${ind(ctx)}}`);
836
+ }
837
+ const rR = emitTransformChain(superParser, wordV, endV, pos, ctx);
838
+ stmts.push(...rR.stmts);
839
+ return { stmts, valueVar: rR.valueVar, endVar: endV };
840
+ }
841
+ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos) {
842
+ const valV = v(ctx, "_llv");
843
+ const endV = v(ctx, "_lle");
844
+ const stmts = [`${ind(ctx)}let ${valV}, ${endV} = ${pos}`];
845
+ let first = true;
846
+ for (const idx of sortedIndices) {
847
+ const p = def.parsers[idx];
848
+ const litVal = getCoreLiteralValue(p);
849
+ const litLen = litVal.length;
850
+ const litCond = emitLiteralCondition(litVal, pos);
851
+ const kw = first ? "if" : "else if";
852
+ first = false;
853
+ stmts.push(`${ind(ctx)}${kw} (${litCond}) {`);
854
+ ctx.indent++;
855
+ const tR = emitTransformChain(p, JSON.stringify(litVal), `${pos} + ${litLen}`, pos, ctx);
856
+ stmts.push(...tR.stmts, `${ind(ctx)}${valV} = ${tR.valueVar}; ${endV} = ${pos} + ${litLen}`);
857
+ ctx.indent--;
858
+ stmts.push(`${ind(ctx)}}`);
859
+ }
860
+ stmts.push(`${ind(ctx)}else return { ok: false, expected: ${allExpected}, span: { start: ${pos}, end: ${pos} } }`);
861
+ return { stmts, valueVar: valV, endVar: endV };
862
+ }
863
+ function emitFirstMatch(def, allExpected, ctx, pos) {
864
+ const resV = v(ctx, "_cr");
865
+ const stmts = [`${ind(ctx)}let ${resV}`];
866
+ for (let i = 0; i < def.parsers.length; i++) {
867
+ const p = def.parsers[i];
868
+ const gate = def.gates[i];
869
+ const autoNot = def.autoNot[i];
870
+ const savedIndent = ctx.indent;
871
+ ctx.indent = 0;
872
+ const r = emit(p, ctx, pos);
873
+ ctx.indent = savedIndent;
874
+ const iife = asIIFE(r.stmts, r.valueVar, r.endVar, pos, ind(ctx));
875
+ let gateCond = null;
876
+ if (gate) {
877
+ const gateIdx = ctx.mapFns.length;
878
+ ctx.mapFns.push(gate);
879
+ gateCond = `_mf[${gateIdx}](_ctx.user)`;
880
+ }
881
+ const skipCond = gateCond ? `!${resV}?.ok && ${gateCond}` : `!${resV}?.ok`;
882
+ if (autoNot && autoNot.length > 0) {
883
+ const tmp = v(ctx, "_ct");
884
+ const anCode = v(ctx, "_anc");
885
+ const rejectCond = autoNot.map(
886
+ (check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${tmp}.span.end)`
887
+ ).join(" || ");
888
+ stmts.push(
889
+ `${ind(ctx)}if (${skipCond}) { const ${tmp} = (() => { try { return ${iife} } catch {} })(); if (${tmp}?.ok) { const ${anCode} = ${tmp}.span.end < input.length ? input.charCodeAt(${tmp}.span.end) : -1; if (!(${rejectCond})) ${resV} = ${tmp} } }`
890
+ );
891
+ } else {
892
+ stmts.push(`${ind(ctx)}if (${skipCond}) { try { ${resV} = ${iife} } catch {} }`);
893
+ }
894
+ }
895
+ stmts.push(
896
+ `${ind(ctx)}if (!${resV}?.ok) return { ok: false, expected: ${allExpected}, span: { start: ${pos}, end: ${pos} } }`
897
+ );
898
+ return { stmts, valueVar: `${resV}.value`, endVar: `${resV}.span.end` };
899
+ }
900
+ function emitNonDisjoint(def, strategy, allExpected, ctx, pos) {
901
+ if (strategy.tag === "greedyClassify")
902
+ return emitGreedyClassify(def, strategy.superIndex, allExpected, ctx, pos);
903
+ if (strategy.tag === "literalsLongestFirst")
904
+ return emitLiteralsLongestFirst(def, strategy.sortedIndices, allExpected, ctx, pos);
905
+ return emitFirstMatch(def, allExpected, ctx, pos);
906
+ }
907
+ function emitTransformChain(p, baseValue, endV, startPos, ctx) {
908
+ const def = p._def;
909
+ if (def.tag === "transform") {
910
+ const innerR = emitTransformChain(def.parser, baseValue, endV, startPos, ctx);
911
+ const fnIdx = ctx.mapFns.length;
912
+ ctx.mapFns.push(def.fn);
913
+ const vv = v(ctx);
914
+ return {
915
+ stmts: [...innerR.stmts, `${ind(ctx)}const ${vv} = _mf[${fnIdx}](${innerR.valueVar}, { start: ${startPos}, end: ${endV} })`],
916
+ valueVar: vv,
917
+ endVar: endV
918
+ };
919
+ }
920
+ return { stmts: [], valueVar: baseValue, endVar: endV };
921
+ }
922
+ function emitLiteralCondition(litVal, pos) {
923
+ const len = litVal.length;
924
+ if (len === 0) return "true";
925
+ if (len > 4) return `input.startsWith(${JSON.stringify(litVal)}, ${pos})`;
926
+ const checks = [`${pos} + ${len} <= input.length`];
927
+ for (let i = 0; i < len; i++) {
928
+ const code = litVal.codePointAt(i);
929
+ checks.push(`input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) === ${code}`);
930
+ }
931
+ return checks.join(" && ");
932
+ }
933
+ function emitMany(def, ctx, pos) {
934
+ const arrV = v(ctx, "_arr");
935
+ const curV = v(ctx, "_cur");
936
+ const stmts = [
937
+ `${ind(ctx)}const ${arrV} = []`,
938
+ `${ind(ctx)}let ${curV} = ${pos}`
939
+ ];
940
+ const emitInnerIIFE = () => {
941
+ const savedIndent = ctx.indent;
942
+ ctx.indent = 0;
943
+ const r = emit(def.parser, ctx, curV);
944
+ ctx.indent = savedIndent;
945
+ return asIIFE(r.stmts, r.valueVar, r.endVar, curV, ind(ctx) + " ");
946
+ };
947
+ if (def.min === 1) {
948
+ const firstR = emit(def.parser, ctx, curV);
949
+ stmts.push(...firstR.stmts);
950
+ stmts.push(
951
+ `${ind(ctx)}${arrV}.push(${firstR.valueVar})`,
952
+ `${ind(ctx)}${curV} = ${firstR.endVar}`
953
+ );
954
+ }
955
+ stmts.push(`${ind(ctx)}while (${curV} < input.length) {`);
956
+ ctx.indent++;
957
+ stmts.push(
958
+ `${ind(ctx)}const _iter = (() => { try { return ${emitInnerIIFE()} } catch { return null } })()`,
959
+ `${ind(ctx)}if (!_iter?.ok || _iter.span.end === ${curV}) break`,
960
+ `${ind(ctx)}${arrV}.push(_iter.value)`,
961
+ `${ind(ctx)}${curV} = _iter.span.end`
962
+ );
963
+ ctx.indent--;
964
+ stmts.push(`${ind(ctx)}}`);
965
+ return { stmts, valueVar: arrV, endVar: curV };
966
+ }
967
+ function emitOptional(def, ctx, pos) {
968
+ const valV = v(ctx, "_opt");
969
+ const endV = v(ctx, "_opte");
970
+ const savedIndent = ctx.indent;
971
+ ctx.indent = 0;
972
+ const r = emit(def.parser, ctx, pos);
973
+ ctx.indent = savedIndent;
974
+ const iife = asIIFE(r.stmts, r.valueVar, r.endVar, pos, ind(ctx));
975
+ const resV = v(ctx, "_optr");
976
+ const stmts = [
977
+ `${ind(ctx)}const ${resV} = (() => { try { return ${iife} } catch { return null } })()`,
978
+ `${ind(ctx)}const ${valV} = ${resV}?.ok ? ${resV}.value : null`,
979
+ `${ind(ctx)}const ${endV} = ${resV}?.ok ? ${resV}.span.end : ${pos}`
980
+ ];
981
+ return { stmts, valueVar: valV, endVar: endV };
982
+ }
983
+ function emitSepBy(_p, def, ctx, pos) {
984
+ const arrV = v(ctx, "_arr");
985
+ const curV = v(ctx, "_cur");
986
+ const iife = (inner, posExpr) => {
987
+ const saved = ctx.indent;
988
+ ctx.indent = 0;
989
+ const r = emit(inner, ctx, posExpr);
990
+ ctx.indent = saved;
991
+ return asIIFE(r.stmts, r.valueVar, r.endVar, posExpr, ind(ctx));
992
+ };
993
+ const firstR_saved = ctx.indent;
994
+ ctx.indent = 0;
995
+ const firstR = emit(def.parser, ctx, pos);
996
+ ctx.indent = firstR_saved;
997
+ const firstV = v(ctx, "_sb0");
998
+ const sepV = v(ctx, "_sbs");
999
+ const nextV = v(ctx, "_sbn");
1000
+ const stmts = [
1001
+ `${ind(ctx)}const ${arrV} = []`,
1002
+ `${ind(ctx)}let ${curV} = ${pos}`,
1003
+ `${ind(ctx)}const ${firstV} = (() => { try { return ${asIIFE(firstR.stmts, firstR.valueVar, firstR.endVar, pos, ind(ctx))} } catch { return null } })()`,
1004
+ `${ind(ctx)}if (${firstV}?.ok) {`
1005
+ ];
1006
+ ctx.indent++;
1007
+ stmts.push(
1008
+ `${ind(ctx)}${arrV}.push(${firstV}.value)`,
1009
+ `${ind(ctx)}${curV} = ${firstV}.span.end`,
1010
+ `${ind(ctx)}while (${curV} < input.length) {`
1011
+ );
1012
+ ctx.indent++;
1013
+ stmts.push(
1014
+ `${ind(ctx)}const ${sepV} = (() => { try { return ${iife(def.separator, curV)} } catch { return null } })()`,
1015
+ `${ind(ctx)}if (!${sepV}?.ok) break`,
1016
+ `${ind(ctx)}const ${nextV} = (() => { try { return ${iife(def.parser, `${sepV}.span.end`)} } catch { return null } })()`,
1017
+ `${ind(ctx)}if (!${nextV}?.ok) break`,
1018
+ `${ind(ctx)}${arrV}.push(${nextV}.value)`,
1019
+ `${ind(ctx)}${curV} = ${nextV}.span.end`
1020
+ );
1021
+ ctx.indent--;
1022
+ stmts.push(`${ind(ctx)}}`);
1023
+ ctx.indent--;
1024
+ stmts.push(`${ind(ctx)}}`);
1025
+ return { stmts, valueVar: arrV, endVar: curV };
1026
+ }
1027
+ function emitScanTo(def, ctx, pos) {
1028
+ const safeIIFE = (inner, posExpr) => {
1029
+ const saved = ctx.indent;
1030
+ ctx.indent = 0;
1031
+ const r = emit(inner, ctx, posExpr);
1032
+ ctx.indent = saved;
1033
+ return `(() => { try { return ${asIIFE(r.stmts, r.valueVar, r.endVar, posExpr, ind(ctx))} } catch { return null } })()`;
1034
+ };
1035
+ const curV = v(ctx, "_stcur");
1036
+ const foundV = v(ctx, "_stfnd");
1037
+ const stmts = [
1038
+ `${ind(ctx)}let ${curV} = ${pos}`,
1039
+ `${ind(ctx)}let ${foundV} = false`,
1040
+ `${ind(ctx)}while (${curV} < input.length) {`
1041
+ ];
1042
+ ctx.indent++;
1043
+ const sentV = v(ctx, "_sts");
1044
+ stmts.push(
1045
+ `${ind(ctx)}const ${sentV} = ${safeIIFE(def.sentinel, curV)}`,
1046
+ `${ind(ctx)}if (${sentV}?.ok) { ${foundV} = true; break }`
1047
+ );
1048
+ if (def.skip.length > 0) {
1049
+ const advV = v(ctx, "_stadv");
1050
+ stmts.push(`${ind(ctx)}let ${advV} = false`);
1051
+ for (const skipper of def.skip) {
1052
+ const skV = v(ctx, "_sk");
1053
+ stmts.push(
1054
+ `${ind(ctx)}if (!${advV}) { const ${skV} = ${safeIIFE(skipper, curV)}; if (${skV}?.ok && ${skV}.span.end > ${curV}) { ${curV} = ${skV}.span.end; ${advV} = true } }`
1055
+ );
1056
+ }
1057
+ stmts.push(`${ind(ctx)}if (!${advV}) ${curV}++`);
1058
+ } else {
1059
+ stmts.push(`${ind(ctx)}${curV}++`);
1060
+ }
1061
+ ctx.indent--;
1062
+ stmts.push(`${ind(ctx)}}`);
1063
+ if (!def.orEOF) {
1064
+ const sentDef = def.sentinel._def;
1065
+ const expectedStr = sentDef.tag === "literal" ? JSON.stringify([JSON.stringify(sentDef.value)]) : `["sentinel"]`;
1066
+ stmts.push(
1067
+ `${ind(ctx)}if (!${foundV}) return { ok: false, expected: ${expectedStr}, span: { start: ${pos}, end: ${curV} } }`
1068
+ );
1069
+ }
1070
+ const valV = v(ctx);
1071
+ stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
1072
+ return { stmts, valueVar: valV, endVar: curV };
1073
+ }
1074
+ function emitRuntimeFallback(parser2, ctx, pos) {
1075
+ const idx = ctx.runtimeParsers.length;
1076
+ ctx.runtimeParsers.push(parser2);
1077
+ const rv = v(ctx, "_rt");
1078
+ const vv = v(ctx, "_rtv");
1079
+ const ev = v(ctx, "_rte");
1080
+ const stmts = [
1081
+ `${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
1082
+ `${ind(ctx)}if (!${rv}.ok) return ${rv}`,
1083
+ `${ind(ctx)}const ${vv} = ${rv}.value`,
1084
+ `${ind(ctx)}const ${ev} = ${rv}.span.end`
1085
+ ];
1086
+ return { stmts, valueVar: vv, endVar: ev };
1087
+ }
1088
+ function emitLazy(p, def, ctx, pos) {
1089
+ if (!ctx.namedParsers.has(p)) {
1090
+ const fnName2 = `_pf${ctx.namedParsers.size}`;
1091
+ ctx.namedParsers.set(p, fnName2);
1092
+ let resolved;
1093
+ try {
1094
+ resolved = def.thunk();
1095
+ } catch {
1096
+ ctx.namedParsers.delete(p);
1097
+ return emitRuntimeFallback(p, ctx, pos);
1098
+ }
1099
+ const savedIndent = ctx.indent;
1100
+ ctx.indent = 1;
1101
+ const r = emit(resolved, ctx, "_pos");
1102
+ ctx.indent = savedIndent;
1103
+ ctx.namedFnDecls.push([
1104
+ `function ${fnName2}(input, _pos, _ctx) {`,
1105
+ ...r.stmts,
1106
+ ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
1107
+ `}`
1108
+ ].join("\n"));
1109
+ }
1110
+ const fnName = ctx.namedParsers.get(p);
1111
+ const rv = v(ctx, "_pfr");
1112
+ const vv = v(ctx, "_pfv");
1113
+ const ev = v(ctx, "_pfe");
1114
+ return {
1115
+ stmts: [
1116
+ `${ind(ctx)}const ${rv} = ${fnName}(input, ${pos}, _ctx)`,
1117
+ `${ind(ctx)}if (!${rv}.ok) return ${rv}`,
1118
+ `${ind(ctx)}const ${vv} = ${rv}.value`,
1119
+ `${ind(ctx)}const ${ev} = ${rv}.span.end`
1120
+ ],
1121
+ valueVar: vv,
1122
+ endVar: ev
1123
+ };
1124
+ }
1125
+ function emit(p, ctx, pos) {
1126
+ const def = p._def;
1127
+ switch (def.tag) {
1128
+ case "literal":
1129
+ return emitLit(def, ctx, pos);
1130
+ case "regex":
1131
+ return emitRegex(def, ctx, pos);
1132
+ case "sequence":
1133
+ return emitSeq(def, ctx, pos);
1134
+ case "choice":
1135
+ return emitChoice(def, ctx, pos);
1136
+ case "many":
1137
+ case "oneOrMore":
1138
+ return emitMany(def, ctx, pos);
1139
+ case "optional":
1140
+ return emitOptional(def, ctx, pos);
1141
+ case "sepBy":
1142
+ return emitSepBy(p, def, ctx, pos);
1143
+ case "transform": {
1144
+ const inner = emit(def.parser, ctx, pos);
1145
+ const fnIdx = ctx.mapFns.length;
1146
+ ctx.mapFns.push(def.fn);
1147
+ const mv = v(ctx, "_mapped");
1148
+ return {
1149
+ stmts: [
1150
+ ...inner.stmts,
1151
+ `${ind(ctx)}const ${mv} = _mf[${fnIdx}](${inner.valueVar}, { start: ${pos}, end: ${inner.endVar} })`
1152
+ ],
1153
+ valueVar: mv,
1154
+ endVar: inner.endVar
1155
+ };
1156
+ }
1157
+ case "skip": {
1158
+ const mainR = emit(def.main, ctx, pos);
1159
+ const skipR = emit(def.skipped, ctx, mainR.endVar);
1160
+ const endV = v(ctx, "_skipe");
1161
+ return {
1162
+ stmts: [
1163
+ ...mainR.stmts,
1164
+ // try skipped; if fails, keep main end
1165
+ `${ind(ctx)}let ${endV} = ${mainR.endVar}`,
1166
+ `${ind(ctx)}try {`,
1167
+ ...skipR.stmts.map((s) => " " + s),
1168
+ `${ind(ctx)} ${endV} = ${skipR.endVar}`,
1169
+ `${ind(ctx)}} catch {}`
1170
+ ],
1171
+ valueVar: mainR.valueVar,
1172
+ endVar: endV
1173
+ };
1174
+ }
1175
+ case "lazy":
1176
+ return emitLazy(p, def, ctx, pos);
1177
+ case "trivia":
1178
+ return emit(def.parser, ctx, pos);
1179
+ case "grammar": {
1180
+ const savedTrivia = ctx.activeTrivia;
1181
+ if (def.triviaParser) ctx.activeTrivia = def.triviaParser;
1182
+ const r = emit(def.parser, ctx, pos);
1183
+ if (savedTrivia === void 0) delete ctx.activeTrivia;
1184
+ else ctx.activeTrivia = savedTrivia;
1185
+ return r;
1186
+ }
1187
+ case "scanTo":
1188
+ return emitScanTo(def, ctx, pos);
1189
+ case "guard": {
1190
+ const fnIdx = ctx.mapFns.length;
1191
+ ctx.mapFns.push(def.predicate);
1192
+ const vv = v(ctx);
1193
+ return {
1194
+ stmts: [
1195
+ `${ind(ctx)}if (!_mf[${fnIdx}](_ctx.user)) ${failStmt({ ...ctx, indent: 0 }, '"gate"', pos).trim()}`,
1196
+ `${ind(ctx)}const ${vv} = null`
1197
+ ],
1198
+ valueVar: vv,
1199
+ endVar: pos
1200
+ };
1201
+ }
1202
+ case "withCtx": {
1203
+ const evIdx = ctx.mapFns.length;
1204
+ const extra = def.extra;
1205
+ ctx.mapFns.push((() => extra));
1206
+ const innerParser = def.parser;
1207
+ if (!ctx.namedParsers.has(innerParser)) {
1208
+ const fnName = `_wcf${ctx.namedParsers.size}`;
1209
+ ctx.namedParsers.set(innerParser, fnName);
1210
+ const savedIndent = ctx.indent;
1211
+ ctx.indent = 1;
1212
+ const innerR = emit(innerParser, ctx, "_pos");
1213
+ ctx.indent = savedIndent;
1214
+ ctx.namedFnDecls.push([
1215
+ `function ${fnName}(input, _pos, _ctx) {`,
1216
+ ...innerR.stmts,
1217
+ ` return { ok: true, value: ${innerR.valueVar}, span: { start: _pos, end: ${innerR.endVar} } }`,
1218
+ `}`
1219
+ ].join("\n"));
1220
+ }
1221
+ const fn = ctx.namedParsers.get(innerParser);
1222
+ const rv = v(ctx, "_wcr");
1223
+ const vv = v(ctx);
1224
+ const ev = v(ctx, "_wce");
1225
+ return {
1226
+ stmts: [
1227
+ `${ind(ctx)}const ${rv} = ${fn}(input, ${pos}, { ..._ctx, user: _mf[${evIdx}]() })`,
1228
+ `${ind(ctx)}if (!${rv}.ok) return ${rv}`,
1229
+ `${ind(ctx)}const ${vv} = ${rv}.value`,
1230
+ `${ind(ctx)}const ${ev} = ${rv}.span.end`
1231
+ ],
1232
+ valueVar: vv,
1233
+ endVar: ev
1234
+ };
1235
+ }
1236
+ default:
1237
+ return emitRuntimeFallback(p, ctx, pos);
1238
+ }
1239
+ }
1240
+ function compile(parser2) {
1241
+ const ctx = {
1242
+ vars: 0,
1243
+ indent: 1,
1244
+ regexDecls: [],
1245
+ mapFns: [],
1246
+ runtimeParsers: [],
1247
+ needsCollator: false,
1248
+ namedParsers: /* @__PURE__ */ new Map(),
1249
+ namedFnDecls: []
1250
+ };
1251
+ const r = emit(parser2, ctx, "_pos");
1252
+ const collatorDecl = ctx.needsCollator ? `const _collator = new Intl.Collator(undefined, { sensitivity: 'accent' })
1253
+ ` : "";
1254
+ const source = [
1255
+ ...ctx.regexDecls,
1256
+ "",
1257
+ ...ctx.namedFnDecls,
1258
+ `${collatorDecl}function _parse(input, _pos, _rp, _mf, _ctx) {`,
1259
+ ` let pos = _pos`,
1260
+ ...r.stmts,
1261
+ ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`,
1262
+ `}`
1263
+ ].join("\n");
1264
+ const fn = new Function("input", "_pos", "_rp", "_mf", "_ctx", [
1265
+ ...ctx.regexDecls,
1266
+ collatorDecl,
1267
+ ...ctx.namedFnDecls,
1268
+ `let pos = _pos`,
1269
+ ...r.stmts,
1270
+ `return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
1271
+ ].join("\n"));
1272
+ const defaultCtx = { trackLines: false };
1273
+ const canInline = ctx.runtimeParsers.length === 0 && ctx.mapFns.length === 0;
1274
+ const inlineExpression = canInline ? buildInlineExpression(ctx, r, collatorDecl) : null;
1275
+ return {
1276
+ source,
1277
+ inlineExpression,
1278
+ parse(input, pos = 0) {
1279
+ return fn(input, pos, ctx.runtimeParsers, ctx.mapFns, defaultCtx);
1280
+ }
1281
+ };
1282
+ }
1283
+ function buildInlineExpression(ctx, r, collatorDecl) {
1284
+ const bodyLines = [
1285
+ ` let pos = _pos`,
1286
+ ...r.stmts.map((s) => ` ${s}`),
1287
+ ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
1288
+ ];
1289
+ const innerFn = [
1290
+ `function(input, _pos, _ctx) {`,
1291
+ ...bodyLines,
1292
+ `}`
1293
+ ].join("\n");
1294
+ const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0;
1295
+ if (!needsWrapper) {
1296
+ return innerFn;
1297
+ }
1298
+ return [
1299
+ `/* @__PURE__ */ (() => {`,
1300
+ ...ctx.regexDecls.map((d) => ` ${d}`),
1301
+ collatorDecl ? ` ${collatorDecl.trim()}` : "",
1302
+ ...ctx.namedFnDecls.flatMap((f) => f.split("\n").map((l) => ` ${l}`)),
1303
+ ` return ${innerFn}`,
1304
+ `})()`
1305
+ ].filter(Boolean).join("\n");
1306
+ }
1307
+
1308
+ // src/plugin/evaluator.ts
1309
+ var SUPPORTED = {
1310
+ literal: (...a) => literal(a[0], a[1]),
1311
+ regex: (...a) => regex(a[0], a[1]),
1312
+ sequence: (...a) => sequence(...a),
1313
+ choice: (...a) => choice(...a),
1314
+ many: (...a) => many(a[0]),
1315
+ oneOrMore: (...a) => oneOrMore(a[0]),
1316
+ optional: (...a) => optional(a[0]),
1317
+ sepBy: (...a) => sepBy(a[0], a[1])
1318
+ // transform / grammar intentionally omitted — take user closures that can't be serialized
1319
+ };
1320
+ function evaluateExpr(node, scope) {
1321
+ if (node.type === "Identifier") return scope.get(node.name) ?? null;
1322
+ if (node.type !== "CallExpression") return null;
1323
+ const callee = node.callee;
1324
+ if (callee.type !== "Identifier") return null;
1325
+ const factory = SUPPORTED[callee.name];
1326
+ if (!factory) return null;
1327
+ const args = node.arguments.map((arg) => {
1328
+ if (arg.type === "SpreadElement") return null;
1329
+ return evaluateArg(arg, scope);
1330
+ });
1331
+ if (args.some((a) => a === null)) return null;
1332
+ try {
1333
+ return factory(...args);
1334
+ } catch {
1335
+ return null;
1336
+ }
1337
+ }
1338
+ function evaluateArg(node, scope) {
1339
+ if (node.type === "Literal") {
1340
+ if ("regex" in node && node.regex !== null && node.regex !== void 0) {
1341
+ return new RegExp(node.regex.pattern, node.regex.flags);
1342
+ }
1343
+ return node.value;
1344
+ }
1345
+ if (node.type === "ObjectExpression") {
1346
+ const obj = {};
1347
+ for (const prop of node.properties) {
1348
+ if (prop.type !== "Property") return null;
1349
+ if (prop.computed) return null;
1350
+ const key = prop.key.type === "Identifier" ? prop.key.name : prop.key.type === "Literal" ? String(prop.key.value) : null;
1351
+ if (key === null) return null;
1352
+ obj[key] = evaluateArg(prop.value, scope);
1353
+ }
1354
+ return obj;
1355
+ }
1356
+ if (node.type === "Identifier") {
1357
+ if (node.name === "undefined") return void 0;
1358
+ return scope.get(node.name) ?? null;
1359
+ }
1360
+ if (node.type === "CallExpression") return evaluateExpr(node, scope);
1361
+ return null;
1362
+ }
1363
+ function referencesAny(node, names, scope) {
1364
+ if (node.type === "Identifier") {
1365
+ return names.has(node.name) || scope.has(node.name);
1366
+ }
1367
+ for (const key of Object.keys(node)) {
1368
+ const child = node[key];
1369
+ if (!child || typeof child !== "object") continue;
1370
+ if (Array.isArray(child)) {
1371
+ if (child.some((c) => c && typeof c === "object" && "type" in c && referencesAny(c, names, scope))) return true;
1372
+ } else if ("type" in child) {
1373
+ if (referencesAny(child, names, scope)) return true;
1374
+ }
1375
+ }
1376
+ return false;
1377
+ }
1378
+
1379
+ // src/plugin/index.ts
1380
+ var PARSEMAN_MODULE = "parseman";
1381
+ var plugin_default = (0, import_unplugin.createUnplugin)((opts = {}) => ({
1382
+ name: "parseman",
1383
+ transformInclude(id) {
1384
+ return /\.[jt]sx?$/.test(id) && !id.includes("node_modules");
1385
+ },
1386
+ transform(code, id) {
1387
+ if (!code.includes("parseman")) return null;
1388
+ if (!code.includes("macro")) return null;
1389
+ const moduleAliases = /* @__PURE__ */ new Set([PARSEMAN_MODULE, ...opts.moduleAliases ?? []]);
1390
+ return transformMacro(code, id, moduleAliases);
1391
+ }
1392
+ }));
1393
+ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSEMAN_MODULE])) {
1394
+ let result;
1395
+ try {
1396
+ result = (0, import_oxc_parser.parseSync)(id, code);
1397
+ } catch {
1398
+ return null;
1399
+ }
1400
+ if (result.errors.length > 0) return null;
1401
+ const body = result.program.body;
1402
+ const macroImports = [];
1403
+ const allNames = /* @__PURE__ */ new Set();
1404
+ for (const stmt of body) {
1405
+ if (stmt.type !== "ImportDeclaration") continue;
1406
+ const s = stmt;
1407
+ if (!moduleAliases.has(s.source.value)) continue;
1408
+ const isMacro = s.attributes.some((a) => {
1409
+ const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
1410
+ return key === "type" && a.value.value === "macro";
1411
+ });
1412
+ if (!isMacro) continue;
1413
+ const names = /* @__PURE__ */ new Set();
1414
+ for (const spec of s.specifiers) {
1415
+ if (spec.type === "ImportSpecifier") names.add(spec.local.name);
1416
+ }
1417
+ macroImports.push({ start: s.start, end: s.end, names, fullyResolved: false });
1418
+ for (const n of names) allNames.add(n);
1419
+ }
1420
+ if (macroImports.length === 0) return null;
1421
+ const scope = /* @__PURE__ */ new Map();
1422
+ const replacements = [];
1423
+ let anyUnresolved = false;
1424
+ for (const stmt of body) {
1425
+ if (stmt.type !== "VariableDeclaration") continue;
1426
+ for (const decl of stmt.declarations) {
1427
+ const d = decl;
1428
+ if (!d.init) continue;
1429
+ if (d.id.type !== "Identifier") continue;
1430
+ const varName = d.id.name;
1431
+ const init = d.init;
1432
+ if (!referencesAny(init, allNames, scope)) continue;
1433
+ const parser2 = evaluateExpr(init, scope);
1434
+ if (parser2 === null) {
1435
+ anyUnresolved = true;
1436
+ continue;
1437
+ }
1438
+ const compiled = compile(parser2);
1439
+ if (compiled.inlineExpression === null) {
1440
+ anyUnresolved = true;
1441
+ continue;
1442
+ }
1443
+ replacements.push({
1444
+ start: init.start,
1445
+ end: init.end,
1446
+ replacement: compiled.inlineExpression
1447
+ });
1448
+ scope.set(varName, parser2);
1449
+ }
1450
+ }
1451
+ if (replacements.length === 0) return null;
1452
+ for (const imp of macroImports) {
1453
+ imp.fullyResolved = !anyUnresolved;
1454
+ }
1455
+ const ms = new import_magic_string.default(code);
1456
+ for (const imp of macroImports) {
1457
+ if (imp.fullyResolved) {
1458
+ ms.remove(imp.start, imp.end);
1459
+ } else {
1460
+ const original = code.slice(imp.start, imp.end);
1461
+ const stripped = original.replace(/\s+with\s*\{[^}]*\}/gs, "").replace(/\s+assert\s*\{[^}]*\}/gs, "");
1462
+ ms.overwrite(imp.start, imp.end, stripped);
1463
+ }
1464
+ }
1465
+ for (const { start, end, replacement } of [...replacements].sort((a, b) => b.start - a.start)) {
1466
+ ms.overwrite(start, end, replacement);
1467
+ }
1468
+ return {
1469
+ code: ms.toString(),
1470
+ map: ms.generateMap({ hires: true })
1471
+ };
1472
+ }
1473
+ //# sourceMappingURL=index.cjs.map