@thomasfosterau/effect-parse 0.4.1 → 0.6.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 (157) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +56 -14
  3. package/dist/Ascii.d.ts +11 -4
  4. package/dist/Ascii.d.ts.map +1 -1
  5. package/dist/Ascii.js +12 -4
  6. package/dist/Ascii.js.map +1 -1
  7. package/dist/Binary.d.ts +5 -2
  8. package/dist/Binary.d.ts.map +1 -1
  9. package/dist/Binary.js +83 -37
  10. package/dist/Binary.js.map +1 -1
  11. package/dist/Bits.d.ts.map +1 -1
  12. package/dist/Bits.js +11 -4
  13. package/dist/Bits.js.map +1 -1
  14. package/dist/Compiler.d.ts +74 -2
  15. package/dist/Compiler.d.ts.map +1 -1
  16. package/dist/Compiler.js +78 -1
  17. package/dist/Compiler.js.map +1 -1
  18. package/dist/Expression.d.ts.map +1 -1
  19. package/dist/Expression.js +86 -74
  20. package/dist/Expression.js.map +1 -1
  21. package/dist/Input.d.ts +56 -5
  22. package/dist/Input.d.ts.map +1 -1
  23. package/dist/Input.js +70 -1
  24. package/dist/Input.js.map +1 -1
  25. package/dist/Nom.d.ts +5 -15
  26. package/dist/Nom.d.ts.map +1 -1
  27. package/dist/Nom.js.map +1 -1
  28. package/dist/ParseError.d.ts +69 -11
  29. package/dist/ParseError.d.ts.map +1 -1
  30. package/dist/ParseError.js +129 -28
  31. package/dist/ParseError.js.map +1 -1
  32. package/dist/Parser.d.ts +375 -29
  33. package/dist/Parser.d.ts.map +1 -1
  34. package/dist/Parser.js +394 -37
  35. package/dist/Parser.js.map +1 -1
  36. package/dist/ParserSchema.d.ts.map +1 -1
  37. package/dist/ParserSchema.js +2 -3
  38. package/dist/ParserSchema.js.map +1 -1
  39. package/dist/ParserStream.d.ts +122 -14
  40. package/dist/ParserStream.d.ts.map +1 -1
  41. package/dist/ParserStream.js +293 -62
  42. package/dist/ParserStream.js.map +1 -1
  43. package/dist/Syntax.d.ts +23 -5
  44. package/dist/Syntax.d.ts.map +1 -1
  45. package/dist/Syntax.js +1 -1
  46. package/dist/Syntax.js.map +1 -1
  47. package/dist/Text.d.ts.map +1 -1
  48. package/dist/Text.js +21 -15
  49. package/dist/Text.js.map +1 -1
  50. package/dist/Token.d.ts +65 -11
  51. package/dist/Token.d.ts.map +1 -1
  52. package/dist/Token.js +73 -26
  53. package/dist/Token.js.map +1 -1
  54. package/dist/internal/compiler/closure.d.ts +1 -1
  55. package/dist/internal/compiler/closure.d.ts.map +1 -1
  56. package/dist/internal/compiler/closure.js +263 -113
  57. package/dist/internal/compiler/closure.js.map +1 -1
  58. package/dist/internal/compiler/entries.d.ts +3 -1
  59. package/dist/internal/compiler/entries.d.ts.map +1 -1
  60. package/dist/internal/compiler/entries.js +3 -2
  61. package/dist/internal/compiler/entries.js.map +1 -1
  62. package/dist/internal/compiler/first.d.ts.map +1 -1
  63. package/dist/internal/compiler/first.js +9 -2
  64. package/dist/internal/compiler/first.js.map +1 -1
  65. package/dist/internal/compiler/graph.d.ts +39 -0
  66. package/dist/internal/compiler/graph.d.ts.map +1 -0
  67. package/dist/internal/compiler/graph.js +78 -0
  68. package/dist/internal/compiler/graph.js.map +1 -0
  69. package/dist/internal/compiler/jit.d.ts +5 -0
  70. package/dist/internal/compiler/jit.d.ts.map +1 -1
  71. package/dist/internal/compiler/jit.js +208 -106
  72. package/dist/internal/compiler/jit.js.map +1 -1
  73. package/dist/internal/compiler/registry.d.ts +11 -3
  74. package/dist/internal/compiler/registry.d.ts.map +1 -1
  75. package/dist/internal/compiler/registry.js.map +1 -1
  76. package/dist/internal/compiler/search.d.ts +32 -0
  77. package/dist/internal/compiler/search.d.ts.map +1 -0
  78. package/dist/internal/compiler/search.js +68 -0
  79. package/dist/internal/compiler/search.js.map +1 -0
  80. package/dist/internal/compiler/sets.d.ts.map +1 -1
  81. package/dist/internal/compiler/sets.js +1 -1
  82. package/dist/internal/compiler/sets.js.map +1 -1
  83. package/dist/internal/compiler/wasm.d.ts +8 -0
  84. package/dist/internal/compiler/wasm.d.ts.map +1 -0
  85. package/dist/internal/compiler/wasm.js +2840 -0
  86. package/dist/internal/compiler/wasm.js.map +1 -0
  87. package/dist/internal/compiler/wasmAsm.d.ts +199 -0
  88. package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
  89. package/dist/internal/compiler/wasmAsm.js +427 -0
  90. package/dist/internal/compiler/wasmAsm.js.map +1 -0
  91. package/dist/internal/entries.d.ts +3 -1
  92. package/dist/internal/entries.d.ts.map +1 -1
  93. package/dist/internal/entries.js.map +1 -1
  94. package/dist/internal/node.d.ts +77 -3
  95. package/dist/internal/node.d.ts.map +1 -1
  96. package/dist/internal/node.js +54 -10
  97. package/dist/internal/node.js.map +1 -1
  98. package/dist/internal/numbers.d.ts.map +1 -1
  99. package/dist/internal/numbers.js.map +1 -1
  100. package/dist/internal/run.d.ts +14 -0
  101. package/dist/internal/run.d.ts.map +1 -1
  102. package/dist/internal/run.js +53 -11
  103. package/dist/internal/run.js.map +1 -1
  104. package/dist/internal/stack.d.ts +14 -0
  105. package/dist/internal/stack.d.ts.map +1 -1
  106. package/dist/internal/stack.js +24 -2
  107. package/dist/internal/stack.js.map +1 -1
  108. package/dist/internal/syntax.d.ts +4 -4
  109. package/dist/internal/syntax.d.ts.map +1 -1
  110. package/dist/internal/syntax.js +18 -10
  111. package/dist/internal/syntax.js.map +1 -1
  112. package/dist/internal/text.d.ts +32 -0
  113. package/dist/internal/text.d.ts.map +1 -1
  114. package/dist/internal/text.js +68 -14
  115. package/dist/internal/text.js.map +1 -1
  116. package/dist/internal/tokens.d.ts +20 -0
  117. package/dist/internal/tokens.d.ts.map +1 -1
  118. package/dist/internal/tokens.js +72 -39
  119. package/dist/internal/tokens.js.map +1 -1
  120. package/dist/internal/tuple.d.ts +6 -0
  121. package/dist/internal/tuple.d.ts.map +1 -0
  122. package/dist/internal/tuple.js +170 -0
  123. package/dist/internal/tuple.js.map +1 -0
  124. package/package.json +18 -10
  125. package/src/Ascii.ts +47 -12
  126. package/src/Binary.ts +174 -73
  127. package/src/Bits.ts +16 -6
  128. package/src/Compiler.ts +101 -10
  129. package/src/Expression.ts +94 -81
  130. package/src/Input.ts +99 -7
  131. package/src/Nom.ts +15 -5
  132. package/src/ParseError.ts +209 -52
  133. package/src/Parser.ts +684 -143
  134. package/src/ParserSchema.ts +1 -2
  135. package/src/ParserStream.ts +361 -68
  136. package/src/Syntax.ts +60 -36
  137. package/src/Text.ts +32 -27
  138. package/src/Token.ts +152 -34
  139. package/src/internal/compiler/closure.ts +371 -153
  140. package/src/internal/compiler/entries.ts +4 -2
  141. package/src/internal/compiler/first.ts +16 -0
  142. package/src/internal/compiler/graph.ts +96 -0
  143. package/src/internal/compiler/jit.ts +319 -169
  144. package/src/internal/compiler/registry.ts +10 -2
  145. package/src/internal/compiler/search.ts +68 -0
  146. package/src/internal/compiler/sets.ts +7 -3
  147. package/src/internal/compiler/wasm.ts +3276 -0
  148. package/src/internal/compiler/wasmAsm.ts +484 -0
  149. package/src/internal/entries.ts +8 -2
  150. package/src/internal/node.ts +103 -7
  151. package/src/internal/numbers.ts +3 -1
  152. package/src/internal/run.ts +73 -12
  153. package/src/internal/stack.ts +25 -1
  154. package/src/internal/syntax.ts +39 -18
  155. package/src/internal/text.ts +97 -9
  156. package/src/internal/tokens.ts +106 -14
  157. package/src/internal/tuple.ts +141 -0
@@ -2,7 +2,7 @@ import * as Predicate from "effect/Predicate";
2
2
  import * as Result from "effect/Result";
3
3
  import { charOf, firstCodePoint } from "./text.js";
4
4
  // src/internal/tokens.ts
5
- const isRange = (u) => Predicate.isObjectOrArray(u) && u._tag === "TokenRange";
5
+ const isRange = (u) => Predicate.isObjectOrArray(u) && Predicate.isTagged(u, "TokenRange");
6
6
  const toCode = (u) => Predicate.isNumber(u) ? u : firstCodePoint(u);
7
7
  /** @internal */
8
8
  const describeChar = (s) => JSON.stringify(s);
@@ -89,8 +89,9 @@ const PredicateRanges = /*#__PURE__*/ Symbol.for("effect-parse/PredicateRanges")
89
89
  */
90
90
  const codePointPredicate = (name, f, ranges) => {
91
91
  Object.defineProperty(f, "name", { value: name });
92
- f[CodePointPredicate] = true;
93
- if (ranges !== void 0) f[PredicateRanges] = ranges;
92
+ const marked = f;
93
+ marked[CodePointPredicate] = true;
94
+ if (ranges !== void 0) marked[PredicateRanges] = ranges;
94
95
  return f;
95
96
  };
96
97
  /**
@@ -202,10 +203,29 @@ const nextIf = (state, m, negate) => {
202
203
  }
203
204
  }
204
205
  };
206
+ /** The one record {@link scan} fills; see there. */
207
+ var ScanResult = class {
208
+ offset = 0;
209
+ count = 0;
210
+ hitEnd = false;
211
+ };
212
+ const scanned = /*#__PURE__*/ new ScanResult();
213
+ /** Fills {@link scanned} and returns it. */
214
+ const scannedAt = (offset, count, hitEnd) => {
215
+ scanned.offset = offset;
216
+ scanned.count = count;
217
+ scanned.hitEnd = hitEnd;
218
+ return scanned;
219
+ };
205
220
  /**
206
221
  * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`
207
222
  * tokens. Returns the offset reached, the number of tokens matched, and
208
223
  * whether the end of input was hit before `max` tokens.
224
+ *
225
+ * The result is one shared record, overwritten by the next scan: read it
226
+ * before running anything else. Allocating one per call cost the
227
+ * interpreter a record per token, since `scan` (shared by every `takeWhile`)
228
+ * is too polymorphic for V8 to inline and remove it.
209
229
  */
210
230
  const scan = (state, m, negate, max) => {
211
231
  let i = state.pos;
@@ -216,70 +236,42 @@ const scan = (state, m, negate, max) => {
216
236
  const s = state.input;
217
237
  const test = m.forString.code;
218
238
  while (count < max) {
219
- if (i >= end) return {
220
- offset: i,
221
- count,
222
- hitEnd: true
223
- };
239
+ if (i >= end) return scannedAt(i, count, true);
224
240
  const c = s.charCodeAt(i);
225
241
  if (c < 55296 || c > 56319) {
226
242
  if (test(c) === negate) break;
227
243
  i++;
228
244
  } else {
229
- if (splitSurrogate(state, i)) return {
230
- offset: i,
231
- count,
232
- hitEnd: true
233
- };
245
+ if (splitSurrogate(state, i)) return scannedAt(i, count, true);
234
246
  const cp = codePointAt(s, i);
235
247
  if (test(cp) === negate) break;
236
248
  i += cp > 65535 ? 2 : 1;
237
249
  }
238
250
  count++;
239
251
  }
240
- return {
241
- offset: i,
242
- count,
243
- hitEnd: false
244
- };
252
+ return scannedAt(i, count, false);
245
253
  }
246
254
  case 1: {
247
255
  const bytes = state.input;
248
256
  const test = m.forCode.code;
249
257
  while (count < max) {
250
- if (i >= end) return {
251
- offset: i,
252
- count,
253
- hitEnd: true
254
- };
258
+ if (i >= end) return scannedAt(i, count, true);
255
259
  if (test(bytes[i]) === negate) break;
256
260
  i++;
257
261
  count++;
258
262
  }
259
- return {
260
- offset: i,
261
- count,
262
- hitEnd: false
263
- };
263
+ return scannedAt(i, count, false);
264
264
  }
265
265
  default: {
266
266
  const arr = state.input;
267
267
  const test = m.forCode.token;
268
268
  while (count < max) {
269
- if (i >= end) return {
270
- offset: i,
271
- count,
272
- hitEnd: true
273
- };
269
+ if (i >= end) return scannedAt(i, count, true);
274
270
  if (test(arr[i]) === negate) break;
275
271
  i++;
276
272
  count++;
277
273
  }
278
- return {
279
- offset: i,
280
- count,
281
- hitEnd: false
282
- };
274
+ return scannedAt(i, count, false);
283
275
  }
284
276
  }
285
277
  };
@@ -318,6 +310,47 @@ const countTokens = (state, start, end) => {
318
310
  }
319
311
  return count;
320
312
  };
313
+ /**
314
+ * The first index at or after `from` of any of `needles` within
315
+ * `[from, state.end)`, or -1. The state remembers, under `needles`, where
316
+ * each one next occurs (`[from, at, end]` at `3 * i`), so successive
317
+ * searches forwards over one input search each needle once per occurrence
318
+ * rather than once per call (as `nextStop` does for `takeTill`).
319
+ *
320
+ * A remembered answer is used only where it still holds: an occurrence, when
321
+ * the search starts between where it was searched from and where it was
322
+ * found, and it still fits before the end; "not found", when the search
323
+ * starts no earlier and the end is no further than the end that search ran
324
+ * to (a parser may narrow `state.end` for a while, and `reset` widens it
325
+ * again, so a miss within a narrower end says nothing about a wider one).
326
+ */
327
+ const indexOfAny = (state, needles, from) => {
328
+ const searches = state.searches ??= /* @__PURE__ */ new Map();
329
+ let memo = searches.get(needles);
330
+ if (memo === void 0) {
331
+ memo = needles.flatMap(() => [
332
+ -1,
333
+ -1,
334
+ -1
335
+ ]);
336
+ searches.set(needles, memo);
337
+ }
338
+ let best = -1;
339
+ for (let i = 0; i < needles.length; i++) {
340
+ const known = memo[3 * i] ?? -1;
341
+ let at = memo[3 * i + 1] ?? -1;
342
+ const searchedTo = memo[3 * i + 2] ?? -1;
343
+ const needle = needles[i] ?? "";
344
+ if (known < 0 || from < known || (at >= 0 ? at < from || at > state.end - needle.length : state.end > searchedTo)) {
345
+ at = indexOf(state, needle, from);
346
+ memo[3 * i] = from;
347
+ memo[3 * i + 1] = at;
348
+ memo[3 * i + 2] = state.end;
349
+ }
350
+ if (at >= 0 && (best < 0 || at < best)) best = at;
351
+ }
352
+ return best;
353
+ };
321
354
  /** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
322
355
  const indexOf = (state, needle, from) => {
323
356
  const last = state.end - needle.length;
@@ -397,6 +430,6 @@ const match = (state, lit, caseless) => {
397
430
  }
398
431
  };
399
432
  const lowerAscii = (c) => c >= 65 && c <= 90 ? c + 32 : c;
400
- export { End, NoMatch, PredicateRanges, advance, codePointPredicate, compile, compileAny, countTokens, describeChar, describeLiteral, indexOf, matchLiteral, nextIf, scan, splitSurrogate };
433
+ export { End, NoMatch, PredicateRanges, advance, codePointPredicate, compile, compileAny, countTokens, describeChar, describeLiteral, indexOf, indexOfAny, matchLiteral, nextIf, scan, splitSurrogate };
401
434
 
402
435
  //# sourceMappingURL=tokens.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","names":[],"sources":["../../src/internal/tokens.ts"],"sourcesContent":["// fallow-ignore-file duplicate-export -- `End` and `scan` here are the token-set versions of the text\n// helpers in ./text.ts; both are internal modules, imported by path, never re-exported from one barrel.\nimport * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport type { Input, State } from \"../Input.js\"\nimport { charOf, firstCodePoint } from \"./text.js\"\n\n/** A compiled token set. */\nexport interface Matcher {\n /** Tests a code point (string input) or a byte (Uint8Array input). */\n readonly code: (code: number) => boolean\n /** Tests an element of an array input. */\n readonly token: (token: unknown) => boolean\n /** Human readable description, used in error messages. */\n readonly description: string\n}\n\n/** @internal */\nexport interface TokenRangeLike {\n readonly _tag: \"TokenRange\"\n readonly from: string | number\n readonly to: string | number\n}\n\nconst isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && (u as any)._tag === \"TokenRange\"\n\nconst toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))\n\n/** @internal */\nexport const describeChar = (s: string): string => JSON.stringify(s)\n\nconst describeSet = (u: unknown): string => {\n if (Predicate.isString(u)) {\n const chars = Array.from(u)\n return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`\n }\n if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, \"0\")}`\n if (Predicate.isFunction(u)) return u.name ? u.name : \"a matching token\"\n if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`\n if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`\n if (Array.isArray(u)) return u.map(describeSet).join(\" or \")\n return JSON.stringify(u)\n}\n\n/** Renders bytes as a Rust-style byte string literal: b\"GET\\r\\n\". */\nconst describeBytes = (bytes: Uint8Array): string => {\n let out = 'b\"'\n for (const b of bytes) {\n if (b === 0x22) out += '\\\\\"'\n else if (b === 0x5c) out += \"\\\\\\\\\"\n else if (b === 0x0a) out += \"\\\\n\"\n else if (b === 0x0d) out += \"\\\\r\"\n else if (b === 0x09) out += \"\\\\t\"\n else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b)\n else out += `\\\\x${b.toString(16).padStart(2, \"0\")}`\n }\n return out + '\"'\n}\n\nconst compileCode = (u: unknown): ((code: number) => boolean) => {\n if (Predicate.isString(u)) {\n const codes = Array.from(u, firstCodePoint)\n if (codes.length === 1) {\n const c = codes[0]\n return (x) => x === c\n }\n return bitmap(codes)\n }\n if (Predicate.isNumber(u)) return (x) => x === u\n if (Predicate.isFunction(u)) return u as (code: number) => boolean\n if (u instanceof Uint8Array) return bitmap(Array.from(u))\n if (isRange(u)) {\n const from = toCode(u.from)\n const to = toCode(u.to)\n return (x) => x >= from && x <= to\n }\n if (Array.isArray(u)) {\n const tests = u.map(compileCode)\n if (tests.length === 1) return tests[0]\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n throw new TypeError(`invalid token set: ${String(u)}`)\n}\n\nconst bitmap = (codes: ReadonlyArray<number>): ((code: number) => boolean) => {\n const ascii = new Uint8Array(256)\n let other: Set<number> | undefined\n for (const c of codes) {\n if (c < 256) ascii[c] = 1\n else (other ??= new Set()).add(c)\n }\n if (other === undefined) return (x) => x < 256 && ascii[x] === 1\n const set = other\n return (x) => (x < 256 ? ascii[x] === 1 : set.has(x))\n}\n\nconst compileToken = (u: unknown): ((token: unknown) => boolean) => {\n if (Predicate.isFunction(u)) return u as (token: unknown) => boolean\n if (Array.isArray(u)) {\n const set = new Set(u)\n return (t) => set.has(t)\n }\n return (t) => t === u\n}\n\n/**\n * Marks a predicate over characters that also accepts a code point (a\n * number), so string inputs can call it without allocating a string per\n * character.\n */\nconst CodePointPredicate: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/CodePointPredicate\")\n\n/**\n * The code points accepted by a predicate, as sorted, disjoint, inclusive\n * ranges, when they are known. The compiler turns such predicates into\n * comparisons or tables.\n */\nexport const PredicateRanges: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/PredicateRanges\")\n\n/**\n * Marks `f` as a {@link CodePointPredicate} named `name` (used in error\n * messages), optionally recording the code point ranges it accepts.\n */\nexport const codePointPredicate = <F extends (c: never) => boolean>(\n name: string,\n f: F,\n ranges?: ReadonlyArray<readonly [number, number]>\n): F => {\n Object.defineProperty(f, \"name\", { value: name })\n ;(f as any)[CodePointPredicate] = true\n if (ranges !== undefined) (f as any)[PredicateRanges] = ranges\n return f\n}\n\n/**\n * Compiles a token set. Predicates for string inputs receive the token as a\n * string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,\n * which is several times slower, for the Basic Multilingual Plane.\n */\nexport const compile = (set: unknown, kind: \"string\" | \"code\" = \"code\"): Matcher => {\n const description = describeSet(set)\n let code: (code: number) => boolean\n if (Predicate.isFunction(set) && kind === \"string\" && !(CodePointPredicate in set)) {\n const pred = set as (c: string) => boolean\n code = (x) => pred(charOf(x))\n } else {\n code = compileCodeSafe(set, kind)\n }\n return { code, token: compileToken(set), description }\n}\n\nconst compileCodeSafe = (set: unknown, kind: \"string\" | \"code\"): ((code: number) => boolean) => {\n if (Array.isArray(set) && kind === \"string\") {\n // Predicates nested in arrays also take strings\n const tests = set.map((s) => compile(s, kind).code)\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n return Result.getOrElse(\n Result.try(() => compileCode(set)),\n (): ((code: number) => boolean) => () => false\n )\n}\n\n/**\n * A matcher that works for every input kind. String predicates receive the\n * token as a string, byte predicates receive numbers.\n */\nexport interface AnyMatcher {\n readonly forString: Matcher\n readonly forCode: Matcher\n readonly description: string\n}\n\n/**\n * A small cache keyed by value, for the parts of a parser that are costly to\n * build and depend only on a string (compiled sets, descriptions). Parsers\n * built inside `Parser.gen` bodies are rebuilt on every run, usually from the\n * same few strings. Dynamic strings could grow it without bound, so it is\n * cleared when full.\n */\nconst cached = <A>(cache: Map<string, A>, key: string, build: (key: string) => A): A => {\n let a = cache.get(key)\n if (a === undefined) {\n if (cache.size >= 1024) cache.clear()\n a = build(key)\n cache.set(key, a)\n }\n return a\n}\n\nconst literalDescriptions = /*#__PURE__*/ new Map<string, string>()\n\n/** Describes a literal for error messages: `\"abc\"`, `b\"abc\"` or `[\"a\", 1]`. */\nexport const describeLiteral = (lit: Input): string =>\n Predicate.isString(lit)\n ? cached(literalDescriptions, lit, describeChar)\n : lit instanceof Uint8Array\n ? describeBytes(lit)\n : `[${lit.map((t) => JSON.stringify(t)).join(\", \")}]`\n\nconst stringMatchers = /*#__PURE__*/ new Map<string, AnyMatcher>()\n\nexport const compileAny = (set: unknown): AnyMatcher =>\n // Matchers for strings are pure functions of the string, so they're shared\n Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set)\n\nconst compileAnyImpl = (set: unknown): AnyMatcher => {\n const forCode = compile(set, \"code\")\n const needsString = Predicate.isFunction(set) || Array.isArray(set)\n return {\n forString: needsString ? compile(set, \"string\") : forCode,\n forCode,\n description: forCode.description\n }\n}\n\n/**\n * Whether the string token at `i` is a high surrogate at the very end of a\n * partial input, i.e. the first half of a code point whose second half has\n * not arrived yet.\n */\nexport const splitSurrogate = (state: State<Input>, i: number): boolean => {\n if (!state.partial || i !== state.end - 1) return false\n const c = (state.input as string).charCodeAt(i)\n return c >= 0xd800 && c <= 0xdbff\n}\n\n/** Reads the code point at `i` of a string. */\nconst codePointAt = (s: string, i: number): number => {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {\n const d = s.charCodeAt(i + 1)\n if (d >= 0xdc00 && d <= 0xdfff) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return c\n}\n\n/**\n * Tests the token at the current position. Returns the token (as the input's\n * token type) and advances, or returns `NoMatch`/`End`.\n */\nexport const NoMatch: unique symbol = /*#__PURE__*/ Symbol(\"NoMatch\")\nexport const End: unique symbol = /*#__PURE__*/ Symbol(\"End\")\n\nexport const nextIf = (state: State<Input>, m: AnyMatcher, negate: boolean): unknown => {\n const pos = state.pos\n if (pos >= state.end) return End\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n if (splitSurrogate(state, pos)) return End\n const cp = codePointAt(s, pos)\n if (m.forString.code(cp) === negate) return NoMatch\n const len = cp > 0xffff ? 2 : 1\n state.pos = pos + len\n return len === 1 ? s[pos] : s.slice(pos, pos + 2)\n }\n case 1: {\n const b = (state.input as Uint8Array)[pos]\n if (m.forCode.code(b) === negate) return NoMatch\n state.pos = pos + 1\n return b\n }\n default: {\n const t = (state.input as ReadonlyArray<unknown>)[pos]\n if (m.forCode.token(t) === negate) return NoMatch\n state.pos = pos + 1\n return t\n }\n }\n}\n\n/** How far a {@link scan} got. */\nexport interface Scanned extends Advanced {\n /** Whether the end of input was hit before `max` tokens. */\n readonly hitEnd: boolean\n}\n\n/**\n * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`\n * tokens. Returns the offset reached, the number of tokens matched, and\n * whether the end of input was hit before `max` tokens.\n */\nexport const scan = (state: State<Input>, m: AnyMatcher, negate: boolean, max: number): Scanned => {\n let i = state.pos\n const end = state.end\n let count = 0\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n const test = m.forString.code\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n const c = s.charCodeAt(i)\n if (c < 0xd800 || c > 0xdbff) {\n if (test(c) === negate) break\n i++\n } else {\n if (splitSurrogate(state, i)) return { offset: i, count, hitEnd: true }\n const cp = codePointAt(s, i)\n if (test(cp) === negate) break\n i += cp > 0xffff ? 2 : 1\n }\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n case 1: {\n const bytes = state.input as Uint8Array\n const test = m.forCode.code\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n if (test(bytes[i]) === negate) break\n i++\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n default: {\n const arr = state.input as ReadonlyArray<unknown>\n const test = m.forCode.token\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n if (test(arr[i]) === negate) break\n i++\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n }\n}\n\n/** The offset reached and the number of tokens passed. */\nexport interface Advanced {\n readonly offset: number\n readonly count: number\n}\n\n/** Advances `n` tokens from `start`, returning the offset reached and the count. */\nexport const advance = (state: State<Input>, start: number, n: number): Advanced => {\n if (state.inputKind !== 0) {\n const offset = Math.min(state.end, start + n)\n return { offset, count: offset - start }\n }\n const s = state.input as string\n let i = start\n let count = 0\n while (count < n && i < state.end) {\n if (splitSurrogate(state, i)) break\n const c = s.charCodeAt(i)\n i += c >= 0xd800 && c <= 0xdbff && i + 1 < s.length && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00 ? 2 : 1\n count++\n }\n return { offset: i, count }\n}\n\n/** Counts tokens between two offsets. */\nexport const countTokens = (state: State<Input>, start: number, end: number): number => {\n if (state.inputKind !== 0) return end - start\n const s = state.input as string\n let count = 0\n for (let i = start; i < end; i++) {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < end && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00) i++\n count++\n }\n return count\n}\n\n/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */\nexport const indexOf = (state: State<Input>, needle: Input, from: number): number => {\n // The whole needle must lie before `state.end`, which may narrow the input\n const last = state.end - needle.length\n if (from > last) return -1\n switch (state.inputKind) {\n case 0: {\n const i = (state.input as string).indexOf(needle as string, from)\n return i <= last ? i : -1\n }\n case 1: {\n const hay = state.input as Uint8Array\n const n = needle as Uint8Array\n if (n.byteLength === 0) return from\n const first = n[0]\n let i = hay.indexOf(first, from)\n while (i !== -1 && i <= last) {\n let j = 1\n while (j < n.length && hay[i + j] === n[j]) j++\n if (j === n.length) return i\n i = hay.indexOf(first, i + 1)\n }\n return -1\n }\n default: {\n const hay = state.input as ReadonlyArray<unknown>\n const n = needle as ReadonlyArray<unknown>\n outer: for (let i = from; i <= last; i++) {\n for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer\n return i\n }\n return -1\n }\n }\n}\n\n/**\n * Compares the input at the current position with a literal. Returns the\n * number of matching units if the literal matches completely (its length),\n * -1 on mismatch, or -2 when the input ends while matching a prefix.\n */\nexport const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const r = match(state, lit, caseless)\n // A failed match may have read up to its length past where it fails (see `Syntax`)\n if (r < 0 && state.syntax !== undefined) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos))\n return r\n}\n\nconst match = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const pos = state.pos\n const len = lit.length\n const avail = state.end - pos\n const n = Math.min(len, avail)\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n const l = lit as string\n if (!caseless) {\n if (avail >= len) return s.startsWith(l, pos) ? len : -1\n return l.startsWith(s.slice(pos)) ? -2 : -1\n }\n for (let i = 0; i < n; i++) {\n if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i))) return -1\n }\n return n === len ? len : -2\n }\n case 1: {\n const b = state.input as Uint8Array\n const l = lit as Uint8Array\n for (let i = 0; i < n; i++) {\n const x = b[pos + i]\n const y = l[i]\n if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1\n }\n return n === len ? len : -2\n }\n default: {\n const a = state.input as ReadonlyArray<unknown>\n const l = lit as ReadonlyArray<unknown>\n for (let i = 0; i < n; i++) if (a[pos + i] !== l[i]) return -1\n return n === len ? len : -2\n }\n }\n}\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\n"],"mappings":";;;;AAwBA,MAAM,WAAW,MAAoC,UAAU,gBAAgB,CAAC,KAAM,EAAU,SAAS;AAEzG,MAAM,UAAU,MAAgC,UAAU,SAAS,CAAC,IAAI,IAAI,eAAe,CAAC;;AAG5F,MAAa,gBAAgB,MAAsB,KAAK,UAAU,CAAC;AAEnE,MAAM,eAAe,MAAuB;CAC1C,IAAI,UAAU,SAAS,CAAC,GAEtB,OADc,MAAM,KAAK,CACd,CAAC,CAAC,WAAW,IAAI,aAAa,CAAC,IAAI,UAAU,KAAK,UAAU,CAAC;CAE1E,IAAI,UAAU,SAAS,CAAC,GAAG,OAAO,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CACrE,IAAI,UAAU,WAAW,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO;CACtD,IAAI,aAAa,YAAY,OAAO,UAAU,cAAc,CAAC;CAC7D,IAAI,QAAQ,CAAC,GAAG,OAAO,GAAG,YAAY,EAAE,IAAI,EAAE,KAAK,YAAY,EAAE,EAAE;CACnE,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,IAAI,WAAW,CAAC,CAAC,KAAK,MAAM;CAC3D,OAAO,KAAK,UAAU,CAAC;AACzB;;AAGA,MAAM,iBAAiB,UAA8B;CACnD,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,OACd,IAAI,MAAM,IAAM,OAAO;MAClB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,GAAM,OAAO;MACvB,IAAI,KAAK,MAAQ,IAAI,KAAM,OAAO,OAAO,aAAa,CAAC;MACvD,OAAO,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAElD,OAAO,MAAM;AACf;AAEA,MAAM,eAAe,MAA4C;CAC/D,IAAI,UAAU,SAAS,CAAC,GAAG;EACzB,MAAM,QAAQ,MAAM,KAAK,GAAG,cAAc;EAC1C,IAAI,MAAM,WAAW,GAAG;GACtB,MAAM,IAAI,MAAM;GAChB,QAAQ,MAAM,MAAM;EACtB;EACA,OAAO,OAAO,KAAK;CACrB;CACA,IAAI,UAAU,SAAS,CAAC,GAAG,QAAQ,MAAM,MAAM;CAC/C,IAAI,UAAU,WAAW,CAAC,GAAG,OAAO;CACpC,IAAI,aAAa,YAAY,OAAO,OAAO,MAAM,KAAK,CAAC,CAAC;CACxD,IAAI,QAAQ,CAAC,GAAG;EACd,MAAM,OAAO,OAAO,EAAE,IAAI;EAC1B,MAAM,KAAK,OAAO,EAAE,EAAE;EACtB,QAAQ,MAAM,KAAK,QAAQ,KAAK;CAClC;CACA,IAAI,MAAM,QAAQ,CAAC,GAAG;EACpB,MAAM,QAAQ,EAAE,IAAI,WAAW;EAC/B,IAAI,MAAM,WAAW,GAAG,OAAO,MAAM;EACrC,QAAQ,MAAM;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO;GAC/D,OAAO;EACT;CACF;CACA,MAAM,IAAI,UAAU,sBAAsB,OAAO,CAAC,GAAG;AACvD;AAEA,MAAM,UAAU,UAA8D;CAC5E,MAAM,wBAAQ,IAAI,WAAW,GAAG;CAChC,IAAI;CACJ,KAAK,MAAM,KAAK,OACd,IAAI,IAAI,KAAK,MAAM,KAAK;MACnB,CAAC,0BAAU,IAAI,IAAI,EAAA,CAAG,IAAI,CAAC;CAElC,IAAI,UAAU,KAAA,GAAW,QAAQ,MAAM,IAAI,OAAO,MAAM,OAAO;CAC/D,MAAM,MAAM;CACZ,QAAQ,MAAO,IAAI,MAAM,MAAM,OAAO,IAAI,IAAI,IAAI,CAAC;AACrD;AAEA,MAAM,gBAAgB,MAA8C;CAClE,IAAI,UAAU,WAAW,CAAC,GAAG,OAAO;CACpC,IAAI,MAAM,QAAQ,CAAC,GAAG;EACpB,MAAM,MAAM,IAAI,IAAI,CAAC;EACrB,QAAQ,MAAM,IAAI,IAAI,CAAC;CACzB;CACA,QAAQ,MAAM,MAAM;AACtB;;;;;;AAOA,MAAM,qBAAkD,qBAAO,IAAI,iCAAiC;;;;;;AAOpG,MAAa,kBAA+C,qBAAO,IAAI,8BAA8B;;;;;AAMrG,MAAa,sBACX,MACA,GACA,WACM;CACN,OAAO,eAAe,GAAG,QAAQ,EAAE,OAAO,KAAK,CAAC;CAC/C,EAAW,sBAAsB;CAClC,IAAI,WAAW,KAAA,GAAW,EAAW,mBAAmB;CACxD,OAAO;AACT;;;;;;AAOA,MAAa,WAAW,KAAc,OAA0B,WAAoB;CAClF,MAAM,cAAc,YAAY,GAAG;CACnC,IAAI;CACJ,IAAI,UAAU,WAAW,GAAG,KAAK,SAAS,YAAY,EAAE,sBAAsB,MAAM;EAClF,MAAM,OAAO;EACb,QAAQ,MAAM,KAAK,OAAO,CAAC,CAAC;CAC9B,OACE,OAAO,gBAAgB,KAAK,IAAI;CAElC,OAAO;EAAE;EAAM,OAAO,aAAa,GAAG;EAAG;CAAY;AACvD;AAEA,MAAM,mBAAmB,KAAc,SAAyD;CAC9F,IAAI,MAAM,QAAQ,GAAG,KAAK,SAAS,UAAU;EAE3C,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,IAAI;EAClD,QAAQ,MAAM;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO;GAC/D,OAAO;EACT;CACF;CACA,OAAO,OAAO,UACZ,OAAO,UAAU,YAAY,GAAG,CAAC,eACQ,KAC3C;AACF;;;;;;;;AAmBA,MAAM,UAAa,OAAuB,KAAa,UAAiC;CACtF,IAAI,IAAI,MAAM,IAAI,GAAG;CACrB,IAAI,MAAM,KAAA,GAAW;EACnB,IAAI,MAAM,QAAQ,MAAM,MAAM,MAAM;EACpC,IAAI,MAAM,GAAG;EACb,MAAM,IAAI,KAAK,CAAC;CAClB;CACA,OAAO;AACT;AAEA,MAAM,oCAAoC,IAAI,IAAoB;;AAGlE,MAAa,mBAAmB,QAC9B,UAAU,SAAS,GAAG,IAClB,OAAO,qBAAqB,KAAK,YAAY,IAC7C,eAAe,aACb,cAAc,GAAG,IACjB,IAAI,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;AAEzD,MAAM,+BAA+B,IAAI,IAAwB;AAEjE,MAAa,cAAc,QAEzB,UAAU,SAAS,GAAG,IAAI,OAAO,gBAAgB,KAAK,cAAc,IAAI,eAAe,GAAG;AAE5F,MAAM,kBAAkB,QAA6B;CACnD,MAAM,UAAU,QAAQ,KAAK,MAAM;CAEnC,OAAO;EACL,WAFkB,UAAU,WAAW,GAAG,KAAK,MAAM,QAAQ,GAAG,IAEvC,QAAQ,KAAK,QAAQ,IAAI;EAClD;EACA,aAAa,QAAQ;CACvB;AACF;;;;;;AAOA,MAAa,kBAAkB,OAAqB,MAAuB;CACzE,IAAI,CAAC,MAAM,WAAW,MAAM,MAAM,MAAM,GAAG,OAAO;CAClD,MAAM,IAAK,MAAM,MAAiB,WAAW,CAAC;CAC9C,OAAO,KAAK,SAAU,KAAK;AAC7B;;AAGA,MAAM,eAAe,GAAW,MAAsB;CACpD,MAAM,IAAI,EAAE,WAAW,CAAC;CACxB,IAAI,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,EAAE,QAAQ;EAClD,MAAM,IAAI,EAAE,WAAW,IAAI,CAAC;EAC5B,IAAI,KAAK,SAAU,KAAK,OAAQ,QAAS,IAAI,SAAW,OAAO,IAAI,SAAU;CAC/E;CACA,OAAO;AACT;;;;;AAMA,MAAa,UAAuC,qBAAO,SAAS;AACpE,MAAa,MAAmC,qBAAO,KAAK;AAE5D,MAAa,UAAU,OAAqB,GAAe,WAA6B;CACtF,MAAM,MAAM,MAAM;CAClB,IAAI,OAAO,MAAM,KAAK,OAAO;CAC7B,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GACN,MAAM,IAAI,MAAM;GAChB,IAAI,eAAe,OAAO,GAAG,GAAG,OAAO;GACvC,MAAM,KAAK,YAAY,GAAG,GAAG;GAC7B,IAAI,EAAE,UAAU,KAAK,EAAE,MAAM,QAAQ,OAAO;GAC5C,MAAM,MAAM,KAAK,QAAS,IAAI;GAC9B,MAAM,MAAM,MAAM;GAClB,OAAO,QAAQ,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;EAClD;EACA,KAAK,GAAG;GACN,MAAM,IAAK,MAAM,MAAqB;GACtC,IAAI,EAAE,QAAQ,KAAK,CAAC,MAAM,QAAQ,OAAO;GACzC,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;EACA,SAAS;GACP,MAAM,IAAK,MAAM,MAAiC;GAClD,IAAI,EAAE,QAAQ,MAAM,CAAC,MAAM,QAAQ,OAAO;GAC1C,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;CACF;AACF;;;;;;AAaA,MAAa,QAAQ,OAAqB,GAAe,QAAiB,QAAyB;CACjG,IAAI,IAAI,MAAM;CACd,MAAM,MAAM,MAAM;CAClB,IAAI,QAAQ;CACZ,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GACN,MAAM,IAAI,MAAM;GAChB,MAAM,OAAO,EAAE,UAAU;GACzB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO;KAAE,QAAQ;KAAG;KAAO,QAAQ;IAAK;IACtD,MAAM,IAAI,EAAE,WAAW,CAAC;IACxB,IAAI,IAAI,SAAU,IAAI,OAAQ;KAC5B,IAAI,KAAK,CAAC,MAAM,QAAQ;KACxB;IACF,OAAO;KACL,IAAI,eAAe,OAAO,CAAC,GAAG,OAAO;MAAE,QAAQ;MAAG;MAAO,QAAQ;KAAK;KACtE,MAAM,KAAK,YAAY,GAAG,CAAC;KAC3B,IAAI,KAAK,EAAE,MAAM,QAAQ;KACzB,KAAK,KAAK,QAAS,IAAI;IACzB;IACA;GACF;GACA,OAAO;IAAE,QAAQ;IAAG;IAAO,QAAQ;GAAM;EAC3C;EACA,KAAK,GAAG;GACN,MAAM,QAAQ,MAAM;GACpB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO;KAAE,QAAQ;KAAG;KAAO,QAAQ;IAAK;IACtD,IAAI,KAAK,MAAM,EAAE,MAAM,QAAQ;IAC/B;IACA;GACF;GACA,OAAO;IAAE,QAAQ;IAAG;IAAO,QAAQ;GAAM;EAC3C;EACA,SAAS;GACP,MAAM,MAAM,MAAM;GAClB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO;KAAE,QAAQ;KAAG;KAAO,QAAQ;IAAK;IACtD,IAAI,KAAK,IAAI,EAAE,MAAM,QAAQ;IAC7B;IACA;GACF;GACA,OAAO;IAAE,QAAQ;IAAG;IAAO,QAAQ;GAAM;EAC3C;CACF;AACF;;AASA,MAAa,WAAW,OAAqB,OAAe,MAAwB;CAClF,IAAI,MAAM,cAAc,GAAG;EACzB,MAAM,SAAS,KAAK,IAAI,MAAM,KAAK,QAAQ,CAAC;EAC5C,OAAO;GAAE;GAAQ,OAAO,SAAS;EAAM;CACzC;CACA,MAAM,IAAI,MAAM;CAChB,IAAI,IAAI;CACR,IAAI,QAAQ;CACZ,OAAO,QAAQ,KAAK,IAAI,MAAM,KAAK;EACjC,IAAI,eAAe,OAAO,CAAC,GAAG;EAC9B,MAAM,IAAI,EAAE,WAAW,CAAC;EACxB,KAAK,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,EAAE,WAAW,EAAE,WAAW,IAAI,CAAC,IAAI,WAAY,QAAS,IAAI;EACvG;CACF;CACA,OAAO;EAAE,QAAQ;EAAG;CAAM;AAC5B;;AAGA,MAAa,eAAe,OAAqB,OAAe,QAAwB;CACtF,IAAI,MAAM,cAAc,GAAG,OAAO,MAAM;CACxC,MAAM,IAAI,MAAM;CAChB,IAAI,QAAQ;CACZ,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAAK;EAChC,MAAM,IAAI,EAAE,WAAW,CAAC;EACxB,IAAI,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,QAAQ,EAAE,WAAW,IAAI,CAAC,IAAI,WAAY,OAAQ;EAC5F;CACF;CACA,OAAO;AACT;;AAGA,MAAa,WAAW,OAAqB,QAAe,SAAyB;CAEnF,MAAM,OAAO,MAAM,MAAM,OAAO;CAChC,IAAI,OAAO,MAAM,OAAO;CACxB,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GACN,MAAM,IAAK,MAAM,MAAiB,QAAQ,QAAkB,IAAI;GAChE,OAAO,KAAK,OAAO,IAAI;EACzB;EACA,KAAK,GAAG;GACN,MAAM,MAAM,MAAM;GAClB,MAAM,IAAI;GACV,IAAI,EAAE,eAAe,GAAG,OAAO;GAC/B,MAAM,QAAQ,EAAE;GAChB,IAAI,IAAI,IAAI,QAAQ,OAAO,IAAI;GAC/B,OAAO,MAAM,MAAM,KAAK,MAAM;IAC5B,IAAI,IAAI;IACR,OAAO,IAAI,EAAE,UAAU,IAAI,IAAI,OAAO,EAAE,IAAI;IAC5C,IAAI,MAAM,EAAE,QAAQ,OAAO;IAC3B,IAAI,IAAI,QAAQ,OAAO,IAAI,CAAC;GAC9B;GACA,OAAO;EACT;EACA,SAAS;GACP,MAAM,MAAM,MAAM;GAClB,MAAM,IAAI;GACV,OAAO,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM,KAAK;IACxC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,SAAS;IACrE,OAAO;GACT;GACA,OAAO;EACT;CACF;AACF;;;;;;AAOA,MAAa,gBAAgB,OAAqB,KAAY,aAA8B;CAC1F,MAAM,IAAI,MAAM,OAAO,KAAK,QAAQ;CAEpC,IAAI,IAAI,KAAK,MAAM,WAAW,KAAA,GAAW,MAAM,OAAO,KAAK,MAAM,MAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,MAAM,MAAM,GAAG,CAAC;CAClH,OAAO;AACT;AAEA,MAAM,SAAS,OAAqB,KAAY,aAA8B;CAC5E,MAAM,MAAM,MAAM;CAClB,MAAM,MAAM,IAAI;CAChB,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK;CAC7B,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GACN,MAAM,IAAI,MAAM;GAChB,MAAM,IAAI;GACV,IAAI,CAAC,UAAU;IACb,IAAI,SAAS,KAAK,OAAO,EAAE,WAAW,GAAG,GAAG,IAAI,MAAM;IACtD,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,CAAC,IAAI,KAAK;GAC3C;GACA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,WAAW,EAAE,WAAW,MAAM,CAAC,CAAC,MAAM,WAAW,EAAE,WAAW,CAAC,CAAC,GAAG,OAAO;GAEhF,OAAO,MAAM,MAAM,MAAM;EAC3B;EACA,KAAK,GAAG;GACN,MAAM,IAAI,MAAM;GAChB,MAAM,IAAI;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,EAAE,MAAM;IAClB,MAAM,IAAI,EAAE;IACZ,IAAI,WAAW,WAAW,CAAC,MAAM,WAAW,CAAC,IAAI,MAAM,GAAG,OAAO;GACnE;GACA,OAAO,MAAM,MAAM,MAAM;EAC3B;EACA,SAAS;GACP,MAAM,IAAI,MAAM;GAChB,MAAM,IAAI;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,EAAE,MAAM,OAAO,EAAE,IAAI,OAAO;GAC5D,OAAO,MAAM,MAAM,MAAM;EAC3B;CACF;AACF;AAEA,MAAM,cAAc,MAAuB,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK"}
1
+ {"version":3,"file":"tokens.js","names":[],"sources":["../../src/internal/tokens.ts"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport type { Input, State } from \"../Input.js\"\nimport { charOf, firstCodePoint } from \"./text.js\"\n\n/** A compiled token set. */\nexport interface Matcher {\n /** Tests a code point (string input) or a byte (Uint8Array input). */\n readonly code: (code: number) => boolean\n /** Tests an element of an array input. */\n readonly token: (token: unknown) => boolean\n /** Human readable description, used in error messages. */\n readonly description: string\n}\n\n/** @internal */\nexport interface TokenRangeLike {\n readonly _tag: \"TokenRange\"\n readonly from: string | number\n readonly to: string | number\n}\n\nconst isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && Predicate.isTagged(u, \"TokenRange\")\n\nconst toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))\n\n/** @internal */\nexport const describeChar = (s: string): string => JSON.stringify(s)\n\nconst describeSet = (u: unknown): string => {\n if (Predicate.isString(u)) {\n const chars = Array.from(u)\n return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`\n }\n if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, \"0\")}`\n if (Predicate.isFunction(u)) return u.name ? u.name : \"a matching token\"\n if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`\n if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`\n if (Array.isArray(u)) return u.map(describeSet).join(\" or \")\n return JSON.stringify(u)\n}\n\n/** Renders bytes as a Rust-style byte string literal: b\"GET\\r\\n\". */\nconst describeBytes = (bytes: Uint8Array): string => {\n let out = 'b\"'\n for (const b of bytes) {\n if (b === 0x22) out += '\\\\\"'\n else if (b === 0x5c) out += \"\\\\\\\\\"\n else if (b === 0x0a) out += \"\\\\n\"\n else if (b === 0x0d) out += \"\\\\r\"\n else if (b === 0x09) out += \"\\\\t\"\n else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b)\n else out += `\\\\x${b.toString(16).padStart(2, \"0\")}`\n }\n return out + '\"'\n}\n\nconst compileCode = (u: unknown): ((code: number) => boolean) => {\n if (Predicate.isString(u)) {\n const codes = Array.from(u, firstCodePoint)\n if (codes.length === 1) {\n const c = codes[0]\n return (x) => x === c\n }\n return bitmap(codes)\n }\n if (Predicate.isNumber(u)) return (x) => x === u\n if (Predicate.isFunction(u)) {\n // SAFETY: a predicate compiled for codes is a byte, code point or `codePoints` predicate (`compile` wraps string predicates first)\n return u as (code: number) => boolean\n }\n if (u instanceof Uint8Array) return bitmap(Array.from(u))\n if (isRange(u)) {\n const from = toCode(u.from)\n const to = toCode(u.to)\n return (x) => x >= from && x <= to\n }\n if (Array.isArray(u)) {\n const tests = u.map(compileCode)\n if (tests.length === 1) return tests[0]\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n throw new TypeError(`invalid token set: ${String(u)}`)\n}\n\nconst bitmap = (codes: ReadonlyArray<number>): ((code: number) => boolean) => {\n const ascii = new Uint8Array(256)\n let other: Set<number> | undefined\n for (const c of codes) {\n if (c < 256) ascii[c] = 1\n else (other ??= new Set()).add(c)\n }\n if (other === undefined) return (x) => x < 256 && ascii[x] === 1\n const set = other\n return (x) => (x < 256 ? ascii[x] === 1 : set.has(x))\n}\n\nconst compileToken = (u: unknown): ((token: unknown) => boolean) => {\n if (Predicate.isFunction(u)) {\n // SAFETY: a predicate in an array input's token set takes the array's elements, the tokens tested here\n return u as (token: unknown) => boolean\n }\n if (Array.isArray(u)) {\n const set = new Set(u)\n return (t) => set.has(t)\n }\n return (t) => t === u\n}\n\n/**\n * Marks a predicate over characters that also accepts a code point (a\n * number), so string inputs can call it without allocating a string per\n * character.\n */\nconst CodePointPredicate: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/CodePointPredicate\")\n\n/**\n * The code points accepted by a predicate, as sorted, disjoint, inclusive\n * ranges, when they are known. The compiler turns such predicates into\n * comparisons or tables.\n */\nexport const PredicateRanges: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/PredicateRanges\")\n\n/**\n * Marks `f` as a {@link CodePointPredicate} named `name` (used in error\n * messages), optionally recording the code point ranges it accepts.\n */\nexport const codePointPredicate = <F extends (c: never) => boolean>(\n name: string,\n f: F,\n ranges?: ReadonlyArray<readonly [number, number]>\n): F => {\n Object.defineProperty(f, \"name\", { value: name })\n // SAFETY: `f` is a function object, which takes new properties; the intersection only names the two markers set here\n const marked = f as F & {\n [CodePointPredicate]?: true\n [PredicateRanges]?: ReadonlyArray<readonly [number, number]>\n }\n marked[CodePointPredicate] = true\n if (ranges !== undefined) marked[PredicateRanges] = ranges\n return f\n}\n\n/**\n * Compiles a token set. Predicates for string inputs receive the token as a\n * string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,\n * which is several times slower, for the Basic Multilingual Plane.\n */\nexport const compile = (set: unknown, kind: \"string\" | \"code\" = \"code\"): Matcher => {\n const description = describeSet(set)\n let code: (code: number) => boolean\n if (Predicate.isFunction(set) && kind === \"string\" && !(CodePointPredicate in set)) {\n // SAFETY: an unmarked predicate in a string token set takes each character as a string (`StringTokenSet`)\n const pred = set as (c: string) => boolean\n code = (x) => pred(charOf(x))\n } else {\n code = compileCodeSafe(set, kind)\n }\n return { code, token: compileToken(set), description }\n}\n\nconst compileCodeSafe = (set: unknown, kind: \"string\" | \"code\"): ((code: number) => boolean) => {\n if (Array.isArray(set) && kind === \"string\") {\n // Predicates nested in arrays also take strings\n const tests = set.map((s) => compile(s, kind).code)\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n return Result.getOrElse(\n Result.try(() => compileCode(set)),\n (): ((code: number) => boolean) => () => false\n )\n}\n\n/**\n * A matcher that works for every input kind. String predicates receive the\n * token as a string, byte predicates receive numbers.\n */\nexport interface AnyMatcher {\n readonly forString: Matcher\n readonly forCode: Matcher\n readonly description: string\n}\n\n/**\n * A small cache keyed by value, for the parts of a parser that are costly to\n * build and depend only on a string (compiled sets, descriptions). Parsers\n * built inside `Parser.gen` bodies are rebuilt on every run, usually from the\n * same few strings. Dynamic strings could grow it without bound, so it is\n * cleared when full.\n */\nconst cached = <A>(cache: Map<string, A>, key: string, build: (key: string) => A): A => {\n let a = cache.get(key)\n if (a === undefined) {\n if (cache.size >= 1024) cache.clear()\n a = build(key)\n cache.set(key, a)\n }\n return a\n}\n\nconst literalDescriptions = /*#__PURE__*/ new Map<string, string>()\n\n/** Describes a literal for error messages: `\"abc\"`, `b\"abc\"` or `[\"a\", 1]`. */\nexport const describeLiteral = (lit: Input): string =>\n Predicate.isString(lit)\n ? cached(literalDescriptions, lit, describeChar)\n : lit instanceof Uint8Array\n ? describeBytes(lit)\n : `[${lit.map((t) => JSON.stringify(t)).join(\", \")}]`\n\nconst stringMatchers = /*#__PURE__*/ new Map<string, AnyMatcher>()\n\nexport const compileAny = (set: unknown): AnyMatcher =>\n // Matchers for strings are pure functions of the string, so they're shared\n Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set)\n\nconst compileAnyImpl = (set: unknown): AnyMatcher => {\n const forCode = compile(set, \"code\")\n const needsString = Predicate.isFunction(set) || Array.isArray(set)\n return {\n forString: needsString ? compile(set, \"string\") : forCode,\n forCode,\n description: forCode.description\n }\n}\n\n/**\n * Whether the string token at `i` is a high surrogate at the very end of a\n * partial input, i.e. the first half of a code point whose second half has\n * not arrived yet.\n */\nexport const splitSurrogate = (state: State<Input>, i: number): boolean => {\n if (!state.partial || i !== state.end - 1) return false\n // SAFETY: called only on string input (the `inputKind === 0` paths of `nextIf`, `scan`, `advance` and `Token.any`)\n const c = (state.input as string).charCodeAt(i)\n return c >= 0xd800 && c <= 0xdbff\n}\n\n/** Reads the code point at `i` of a string. */\nconst codePointAt = (s: string, i: number): number => {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {\n const d = s.charCodeAt(i + 1)\n if (d >= 0xdc00 && d <= 0xdfff) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return c\n}\n\n/**\n * Tests the token at the current position. Returns the token (as the input's\n * token type) and advances, or returns `NoMatch`/`End`.\n */\nexport const NoMatch: unique symbol = /*#__PURE__*/ Symbol(\"NoMatch\")\nexport const End: unique symbol = /*#__PURE__*/ Symbol(\"End\")\n\nexport const nextIf = (state: State<Input>, m: AnyMatcher, negate: boolean): unknown => {\n const pos = state.pos\n if (pos >= state.end) return End\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n if (splitSurrogate(state, pos)) return End\n const cp = codePointAt(s, pos)\n if (m.forString.code(cp) === negate) return NoMatch\n const len = cp > 0xffff ? 2 : 1\n state.pos = pos + len\n return len === 1 ? s[pos] : s.slice(pos, pos + 2)\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const b = (state.input as Uint8Array)[pos]\n if (m.forCode.code(b) === negate) return NoMatch\n state.pos = pos + 1\n return b\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const t = (state.input as ReadonlyArray<unknown>)[pos]\n if (m.forCode.token(t) === negate) return NoMatch\n state.pos = pos + 1\n return t\n }\n }\n}\n\n/** How far a {@link scan} got. */\nexport interface Scanned extends Advanced {\n /** Whether the end of input was hit before `max` tokens. */\n readonly hitEnd: boolean\n}\n\n/** The one record {@link scan} fills; see there. */\nclass ScanResult implements Scanned {\n offset = 0\n count = 0\n hitEnd = false\n}\n\nconst scanned = /*#__PURE__*/ new ScanResult()\n\n/** Fills {@link scanned} and returns it. */\nconst scannedAt = (offset: number, count: number, hitEnd: boolean): Scanned => {\n scanned.offset = offset\n scanned.count = count\n scanned.hitEnd = hitEnd\n return scanned\n}\n\n/**\n * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`\n * tokens. Returns the offset reached, the number of tokens matched, and\n * whether the end of input was hit before `max` tokens.\n *\n * The result is one shared record, overwritten by the next scan: read it\n * before running anything else. Allocating one per call cost the\n * interpreter a record per token, since `scan` (shared by every `takeWhile`)\n * is too polymorphic for V8 to inline and remove it.\n */\nexport const scan = (state: State<Input>, m: AnyMatcher, negate: boolean, max: number): Scanned => {\n let i = state.pos\n const end = state.end\n let count = 0\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n const test = m.forString.code\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n const c = s.charCodeAt(i)\n if (c < 0xd800 || c > 0xdbff) {\n if (test(c) === negate) break\n i++\n } else {\n if (splitSurrogate(state, i)) return scannedAt(i, count, true)\n const cp = codePointAt(s, i)\n if (test(cp) === negate) break\n i += cp > 0xffff ? 2 : 1\n }\n count++\n }\n return scannedAt(i, count, false)\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const bytes = state.input as Uint8Array\n const test = m.forCode.code\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n if (test(bytes[i]) === negate) break\n i++\n count++\n }\n return scannedAt(i, count, false)\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const arr = state.input as ReadonlyArray<unknown>\n const test = m.forCode.token\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n if (test(arr[i]) === negate) break\n i++\n count++\n }\n return scannedAt(i, count, false)\n }\n }\n}\n\n/** The offset reached and the number of tokens passed. */\nexport interface Advanced {\n readonly offset: number\n readonly count: number\n}\n\n/** Advances `n` tokens from `start`, returning the offset reached and the count. */\nexport const advance = (state: State<Input>, start: number, n: number): Advanced => {\n if (state.inputKind !== 0) {\n const offset = Math.min(state.end, start + n)\n return { offset, count: offset - start }\n }\n // SAFETY: the other input kinds returned above, and `inputKind` 0 is set only for a string input\n const s = state.input as string\n let i = start\n let count = 0\n while (count < n && i < state.end) {\n if (splitSurrogate(state, i)) break\n const c = s.charCodeAt(i)\n i += c >= 0xd800 && c <= 0xdbff && i + 1 < s.length && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00 ? 2 : 1\n count++\n }\n return { offset: i, count }\n}\n\n/** Counts tokens between two offsets. */\nexport const countTokens = (state: State<Input>, start: number, end: number): number => {\n if (state.inputKind !== 0) return end - start\n // SAFETY: the other input kinds returned above, and `inputKind` 0 is set only for a string input\n const s = state.input as string\n let count = 0\n for (let i = start; i < end; i++) {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < end && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00) i++\n count++\n }\n return count\n}\n\n/**\n * The first index at or after `from` of any of `needles` within\n * `[from, state.end)`, or -1. The state remembers, under `needles`, where\n * each one next occurs (`[from, at, end]` at `3 * i`), so successive\n * searches forwards over one input search each needle once per occurrence\n * rather than once per call (as `nextStop` does for `takeTill`).\n *\n * A remembered answer is used only where it still holds: an occurrence, when\n * the search starts between where it was searched from and where it was\n * found, and it still fits before the end; \"not found\", when the search\n * starts no earlier and the end is no further than the end that search ran\n * to (a parser may narrow `state.end` for a while, and `reset` widens it\n * again, so a miss within a narrower end says nothing about a wider one).\n */\nexport const indexOfAny = (state: State<Input>, needles: ReadonlyArray<Input>, from: number): number => {\n const searches = (state.searches ??= new Map())\n let memo = searches.get(needles)\n if (memo === undefined) {\n memo = needles.flatMap(() => [-1, -1, -1])\n searches.set(needles, memo)\n }\n let best = -1\n for (let i = 0; i < needles.length; i++) {\n const known = memo[3 * i] ?? -1\n let at = memo[3 * i + 1] ?? -1\n const searchedTo = memo[3 * i + 2] ?? -1\n const needle = needles[i] ?? \"\"\n const stale =\n known < 0 || from < known || (at >= 0 ? at < from || at > state.end - needle.length : state.end > searchedTo)\n if (stale) {\n at = indexOf(state, needle, from)\n memo[3 * i] = from\n memo[3 * i + 1] = at\n memo[3 * i + 2] = state.end\n }\n if (at >= 0 && (best < 0 || at < best)) best = at\n }\n return best\n}\n\n/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */\nexport const indexOf = (state: State<Input>, needle: Input, from: number): number => {\n // The whole needle must lie before `state.end`, which may narrow the input\n const last = state.end - needle.length\n if (from > last) return -1\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input, and the callers' types give the needle the input's kind\n const i = (state.input as string).indexOf(needle as string, from)\n return i <= last ? i : -1\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const hay = state.input as Uint8Array\n // SAFETY: the callers' types give the needle the input's kind (`Text` encodes it for byte input)\n const n = needle as Uint8Array\n if (n.byteLength === 0) return from\n const first = n[0]\n let i = hay.indexOf(first, from)\n while (i !== -1 && i <= last) {\n let j = 1\n while (j < n.length && hay[i + j] === n[j]) j++\n if (j === n.length) return i\n i = hay.indexOf(first, i + 1)\n }\n return -1\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const hay = state.input as ReadonlyArray<unknown>\n // SAFETY: the callers' types give the needle the input's kind, an array of the same element type\n const n = needle as ReadonlyArray<unknown>\n outer: for (let i = from; i <= last; i++) {\n for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer\n return i\n }\n return -1\n }\n }\n}\n\n/**\n * Compares the input at the current position with a literal. Returns the\n * number of matching units if the literal matches completely (its length),\n * -1 on mismatch, or -2 when the input ends while matching a prefix.\n */\nexport const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const r = match(state, lit, caseless)\n // A failed match may have read up to its length past where it fails (see `Syntax`)\n if (r < 0 && state.syntax !== undefined) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos))\n return r\n}\n\nconst match = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const pos = state.pos\n const len = lit.length\n const avail = state.end - pos\n const n = Math.min(len, avail)\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n // SAFETY: the callers' types give the literal the input's kind (`Token.literal` encodes a string literal for byte input)\n const l = lit as string\n if (!caseless) {\n if (avail >= len) return s.startsWith(l, pos) ? len : -1\n return l.startsWith(s.slice(pos)) ? -2 : -1\n }\n for (let i = 0; i < n; i++) {\n if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i))) return -1\n }\n return n === len ? len : -2\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const b = state.input as Uint8Array\n // SAFETY: the callers' types give the literal the input's kind (`Token.literal` and `Text` encode string literals for byte input)\n const l = lit as Uint8Array\n for (let i = 0; i < n; i++) {\n const x = b[pos + i]\n const y = l[i]\n if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1\n }\n return n === len ? len : -2\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const a = state.input as ReadonlyArray<unknown>\n // SAFETY: the callers' types give the literal the input's kind, an array of the same element type\n const l = lit as ReadonlyArray<unknown>\n for (let i = 0; i < n; i++) if (a[pos + i] !== l[i]) return -1\n return n === len ? len : -2\n }\n }\n}\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\n"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Fail, State } from "../Input.js";
2
+ type Step = (state: State<any>) => unknown;
3
+ /** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */
4
+ export declare const tupleStep: (steps: ReadonlyArray<Step>) => ((state: State<any>) => Array<unknown> | Fail);
5
+ export {};
6
+ //# sourceMappingURL=tuple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tuple.d.ts","names":[],"sources":["../../src/internal/tuple.ts"],"mappings":";KAcK,QAAQ,OAAO;;qBAMP,YAAa,OAAO,cAAc,YAAU,OAAO,eAAe,iBAAiB"}
@@ -0,0 +1,170 @@
1
+ import { Fail } from "../Input.js";
2
+ // src/internal/tuple.ts
3
+ /**
4
+ * Tuple steps: run steps in sequence and collect their outputs in an array.
5
+ *
6
+ * V8 pretenures by allocation site, and only array and object literals have
7
+ * one: an array from `new Array(n)` starts young, so tuples that a parse keeps
8
+ * (a `repeat(seq(...))`, a tree) are copied by a scavenge or two before they
9
+ * are promoted. A literal's site learns that its arrays survive, and V8 then
10
+ * allocates them straight into the old generation. So arities up to
11
+ * {@link maxLiteral} build their tuple with a literal of that arity, each its
12
+ * own site; longer tuples fall back to `new Array(n)` (#86).
13
+ */
14
+ /** The longest tuple built with a literal. */
15
+ const maxLiteral = 8;
16
+ /** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */
17
+ const tupleStep = (steps) => {
18
+ const n = steps.length;
19
+ if (n <= maxLiteral) return literals[n](steps);
20
+ return (state) => {
21
+ const out = new Array(n);
22
+ for (let i = 0; i < n; i++) {
23
+ const a = steps[i](state);
24
+ if (a === Fail) return Fail;
25
+ out[i] = a;
26
+ }
27
+ return out;
28
+ };
29
+ };
30
+ const literals = [
31
+ () => () => [],
32
+ ([s0]) => (state) => {
33
+ const a0 = s0(state);
34
+ if (a0 === Fail) return Fail;
35
+ return [a0];
36
+ },
37
+ ([s0, s1]) => (state) => {
38
+ const a0 = s0(state);
39
+ if (a0 === Fail) return Fail;
40
+ const a1 = s1(state);
41
+ if (a1 === Fail) return Fail;
42
+ return [a0, a1];
43
+ },
44
+ ([s0, s1, s2]) => (state) => {
45
+ const a0 = s0(state);
46
+ if (a0 === Fail) return Fail;
47
+ const a1 = s1(state);
48
+ if (a1 === Fail) return Fail;
49
+ const a2 = s2(state);
50
+ if (a2 === Fail) return Fail;
51
+ return [
52
+ a0,
53
+ a1,
54
+ a2
55
+ ];
56
+ },
57
+ ([s0, s1, s2, s3]) => (state) => {
58
+ const a0 = s0(state);
59
+ if (a0 === Fail) return Fail;
60
+ const a1 = s1(state);
61
+ if (a1 === Fail) return Fail;
62
+ const a2 = s2(state);
63
+ if (a2 === Fail) return Fail;
64
+ const a3 = s3(state);
65
+ if (a3 === Fail) return Fail;
66
+ return [
67
+ a0,
68
+ a1,
69
+ a2,
70
+ a3
71
+ ];
72
+ },
73
+ ([s0, s1, s2, s3, s4]) => (state) => {
74
+ const a0 = s0(state);
75
+ if (a0 === Fail) return Fail;
76
+ const a1 = s1(state);
77
+ if (a1 === Fail) return Fail;
78
+ const a2 = s2(state);
79
+ if (a2 === Fail) return Fail;
80
+ const a3 = s3(state);
81
+ if (a3 === Fail) return Fail;
82
+ const a4 = s4(state);
83
+ if (a4 === Fail) return Fail;
84
+ return [
85
+ a0,
86
+ a1,
87
+ a2,
88
+ a3,
89
+ a4
90
+ ];
91
+ },
92
+ ([s0, s1, s2, s3, s4, s5]) => (state) => {
93
+ const a0 = s0(state);
94
+ if (a0 === Fail) return Fail;
95
+ const a1 = s1(state);
96
+ if (a1 === Fail) return Fail;
97
+ const a2 = s2(state);
98
+ if (a2 === Fail) return Fail;
99
+ const a3 = s3(state);
100
+ if (a3 === Fail) return Fail;
101
+ const a4 = s4(state);
102
+ if (a4 === Fail) return Fail;
103
+ const a5 = s5(state);
104
+ if (a5 === Fail) return Fail;
105
+ return [
106
+ a0,
107
+ a1,
108
+ a2,
109
+ a3,
110
+ a4,
111
+ a5
112
+ ];
113
+ },
114
+ ([s0, s1, s2, s3, s4, s5, s6]) => (state) => {
115
+ const a0 = s0(state);
116
+ if (a0 === Fail) return Fail;
117
+ const a1 = s1(state);
118
+ if (a1 === Fail) return Fail;
119
+ const a2 = s2(state);
120
+ if (a2 === Fail) return Fail;
121
+ const a3 = s3(state);
122
+ if (a3 === Fail) return Fail;
123
+ const a4 = s4(state);
124
+ if (a4 === Fail) return Fail;
125
+ const a5 = s5(state);
126
+ if (a5 === Fail) return Fail;
127
+ const a6 = s6(state);
128
+ if (a6 === Fail) return Fail;
129
+ return [
130
+ a0,
131
+ a1,
132
+ a2,
133
+ a3,
134
+ a4,
135
+ a5,
136
+ a6
137
+ ];
138
+ },
139
+ ([s0, s1, s2, s3, s4, s5, s6, s7]) => (state) => {
140
+ const a0 = s0(state);
141
+ if (a0 === Fail) return Fail;
142
+ const a1 = s1(state);
143
+ if (a1 === Fail) return Fail;
144
+ const a2 = s2(state);
145
+ if (a2 === Fail) return Fail;
146
+ const a3 = s3(state);
147
+ if (a3 === Fail) return Fail;
148
+ const a4 = s4(state);
149
+ if (a4 === Fail) return Fail;
150
+ const a5 = s5(state);
151
+ if (a5 === Fail) return Fail;
152
+ const a6 = s6(state);
153
+ if (a6 === Fail) return Fail;
154
+ const a7 = s7(state);
155
+ if (a7 === Fail) return Fail;
156
+ return [
157
+ a0,
158
+ a1,
159
+ a2,
160
+ a3,
161
+ a4,
162
+ a5,
163
+ a6,
164
+ a7
165
+ ];
166
+ }
167
+ ];
168
+ export { tupleStep };
169
+
170
+ //# sourceMappingURL=tuple.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tuple.js","names":[],"sources":["../../src/internal/tuple.ts"],"sourcesContent":["/**\n * Tuple steps: run steps in sequence and collect their outputs in an array.\n *\n * V8 pretenures by allocation site, and only array and object literals have\n * one: an array from `new Array(n)` starts young, so tuples that a parse keeps\n * (a `repeat(seq(...))`, a tree) are copied by a scavenge or two before they\n * are promoted. A literal's site learns that its arrays survive, and V8 then\n * allocates them straight into the old generation. So arities up to\n * {@link maxLiteral} build their tuple with a literal of that arity, each its\n * own site; longer tuples fall back to `new Array(n)` (#86).\n */\nimport { Fail } from \"../Input.js\"\nimport type { State } from \"../Input.js\"\n\ntype Step = (state: State<any>) => unknown\n\n/** The longest tuple built with a literal. */\nconst maxLiteral = 8\n\n/** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */\nexport const tupleStep = (steps: ReadonlyArray<Step>): ((state: State<any>) => Array<unknown> | Fail) => {\n const n = steps.length\n if (n <= maxLiteral) return literals[n](steps)\n return (state) => {\n const out = new Array<unknown>(n)\n for (let i = 0; i < n; i++) {\n const a = steps[i](state)\n if (a === Fail) return Fail\n out[i] = a\n }\n return out\n }\n}\n\nconst literals: ReadonlyArray<(steps: ReadonlyArray<Step>) => (state: State<any>) => Array<unknown> | Fail> = [\n () => () => [],\n ([s0]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n return [a0]\n },\n ([s0, s1]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n return [a0, a1]\n },\n ([s0, s1, s2]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n return [a0, a1, a2]\n },\n ([s0, s1, s2, s3]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n return [a0, a1, a2, a3]\n },\n ([s0, s1, s2, s3, s4]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n return [a0, a1, a2, a3, a4]\n },\n ([s0, s1, s2, s3, s4, s5]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5]\n },\n ([s0, s1, s2, s3, s4, s5, s6]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n const a6 = s6(state)\n if (a6 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5, a6]\n },\n ([s0, s1, s2, s3, s4, s5, s6, s7]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n const a6 = s6(state)\n if (a6 === Fail) return Fail\n const a7 = s7(state)\n if (a7 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5, a6, a7]\n }\n]\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package",
3
3
  "name": "@thomasfosterau/effect-parse",
4
- "version": "0.4.1",
4
+ "version": "0.6.0",
5
5
  "description": "Parser combinators for Effect, ported from Rust's nom and winnow: text, bytes, bits and token streams, streaming input, compiled parsers and Schema integration",
6
6
  "keywords": [
7
7
  "effect",
@@ -24,7 +24,8 @@
24
24
  "files": [
25
25
  "dist",
26
26
  "src",
27
- "!dist/**/*.tsbuildinfo"
27
+ "!dist/**/*.tsbuildinfo",
28
+ "CHANGELOG.md"
28
29
  ],
29
30
  "type": "module",
30
31
  "sideEffects": false,
@@ -102,18 +103,25 @@
102
103
  "@changesets/changelog-github": "^1.0.1",
103
104
  "@changesets/cli": "^3.0.3",
104
105
  "@effect/language-service": "^0.87.5",
105
- "@effect/tsgo": "0.63.0",
106
- "@enfect/oxlint": "^0.9.0",
106
+ "@effect/platform-node-shared": "4.1.4",
107
+ "@effect/tsgo": "0.67.7",
108
+ "@enfect/oxlint": "^0.10.0",
109
+ "@thomasfosterau/effect-bib": "0.1.0",
110
+ "@thomasfosterau/effect-ext": "0.2.0",
111
+ "@thomasfosterau/effect-ical": "0.1.0",
112
+ "@thomasfosterau/effect-parse": "0.6.0",
113
+ "@thomasfosterau/effect-rdf": "0.2.0",
114
+ "@thomasfosterau/effect-xml": "0.1.0",
107
115
  "@types/node": "^26.6.5",
108
116
  "@typescript/native": "npm:typescript@7.0.2",
109
- "@vitest/coverage-istanbul": "5.0.5",
110
- "effect": "4.1.0",
111
- "fallow": "3.37.0",
117
+ "@vitest/coverage-istanbul": "5.1.0",
118
+ "effect": "4.1.4",
119
+ "fallow": "3.42.0",
112
120
  "rolldown": "^1.2.14",
113
121
  "typescript": "npm:@typescript/typescript6@6.0.2",
114
- "vite": "npm:@voidzero-dev/vite-plus-core@1.4.0",
115
- "vite-plus": "1.4.0",
116
- "vitest": "5.0.5"
122
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.6.0",
123
+ "vite-plus": "1.6.0",
124
+ "vitest": "5.1.0"
117
125
  },
118
126
  "peerDependencies": {
119
127
  "effect": "^4.0.0"