@thomasfosterau/effect-parse 0.5.0 → 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 (99) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +19 -1
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +5 -3
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts +5 -2
  7. package/dist/Binary.d.ts.map +1 -1
  8. package/dist/Binary.js +20 -3
  9. package/dist/Binary.js.map +1 -1
  10. package/dist/Bits.d.ts.map +1 -1
  11. package/dist/Bits.js +4 -0
  12. package/dist/Bits.js.map +1 -1
  13. package/dist/Input.d.ts +21 -3
  14. package/dist/Input.d.ts.map +1 -1
  15. package/dist/Input.js +31 -4
  16. package/dist/Input.js.map +1 -1
  17. package/dist/Nom.d.ts.map +1 -1
  18. package/dist/ParseError.d.ts +69 -11
  19. package/dist/ParseError.d.ts.map +1 -1
  20. package/dist/ParseError.js +129 -28
  21. package/dist/ParseError.js.map +1 -1
  22. package/dist/Parser.d.ts +10 -4
  23. package/dist/Parser.d.ts.map +1 -1
  24. package/dist/Parser.js +10 -24
  25. package/dist/Parser.js.map +1 -1
  26. package/dist/ParserSchema.d.ts.map +1 -1
  27. package/dist/ParserSchema.js +1 -2
  28. package/dist/ParserSchema.js.map +1 -1
  29. package/dist/ParserStream.d.ts +119 -12
  30. package/dist/ParserStream.d.ts.map +1 -1
  31. package/dist/ParserStream.js +282 -55
  32. package/dist/ParserStream.js.map +1 -1
  33. package/dist/Syntax.js +1 -1
  34. package/dist/Text.d.ts.map +1 -1
  35. package/dist/Text.js +13 -7
  36. package/dist/Text.js.map +1 -1
  37. package/dist/Token.d.ts +10 -1
  38. package/dist/Token.d.ts.map +1 -1
  39. package/dist/Token.js +14 -5
  40. package/dist/Token.js.map +1 -1
  41. package/dist/internal/compiler/closure.d.ts +1 -1
  42. package/dist/internal/compiler/closure.d.ts.map +1 -1
  43. package/dist/internal/compiler/closure.js +7 -17
  44. package/dist/internal/compiler/closure.js.map +1 -1
  45. package/dist/internal/compiler/first.d.ts.map +1 -1
  46. package/dist/internal/compiler/first.js +2 -1
  47. package/dist/internal/compiler/first.js.map +1 -1
  48. package/dist/internal/compiler/graph.d.ts +23 -1
  49. package/dist/internal/compiler/graph.d.ts.map +1 -1
  50. package/dist/internal/compiler/graph.js +27 -5
  51. package/dist/internal/compiler/graph.js.map +1 -1
  52. package/dist/internal/compiler/jit.d.ts.map +1 -1
  53. package/dist/internal/compiler/jit.js +26 -13
  54. package/dist/internal/compiler/jit.js.map +1 -1
  55. package/dist/internal/compiler/registry.d.ts +1 -1
  56. package/dist/internal/compiler/wasm.d.ts.map +1 -1
  57. package/dist/internal/compiler/wasm.js +105 -34
  58. package/dist/internal/compiler/wasm.js.map +1 -1
  59. package/dist/internal/node.d.ts +19 -1
  60. package/dist/internal/node.d.ts.map +1 -1
  61. package/dist/internal/node.js +42 -8
  62. package/dist/internal/node.js.map +1 -1
  63. package/dist/internal/run.d.ts +3 -1
  64. package/dist/internal/run.d.ts.map +1 -1
  65. package/dist/internal/run.js +4 -2
  66. package/dist/internal/run.js.map +1 -1
  67. package/dist/internal/stack.d.ts +8 -0
  68. package/dist/internal/stack.d.ts.map +1 -1
  69. package/dist/internal/stack.js +17 -1
  70. package/dist/internal/stack.js.map +1 -1
  71. package/dist/internal/tokens.d.ts +10 -3
  72. package/dist/internal/tokens.d.ts.map +1 -1
  73. package/dist/internal/tokens.js +22 -9
  74. package/dist/internal/tokens.js.map +1 -1
  75. package/dist/internal/tuple.d.ts +6 -0
  76. package/dist/internal/tuple.d.ts.map +1 -0
  77. package/dist/internal/tuple.js +170 -0
  78. package/dist/internal/tuple.js.map +1 -0
  79. package/package.json +17 -10
  80. package/src/Ascii.ts +5 -3
  81. package/src/Binary.ts +24 -3
  82. package/src/Bits.ts +4 -0
  83. package/src/Input.ts +37 -4
  84. package/src/ParseError.ts +206 -52
  85. package/src/Parser.ts +19 -29
  86. package/src/ParserSchema.ts +1 -2
  87. package/src/ParserStream.ts +336 -62
  88. package/src/Text.ts +16 -12
  89. package/src/Token.ts +14 -5
  90. package/src/internal/compiler/closure.ts +9 -18
  91. package/src/internal/compiler/first.ts +6 -0
  92. package/src/internal/compiler/graph.ts +32 -4
  93. package/src/internal/compiler/jit.ts +37 -17
  94. package/src/internal/compiler/wasm.ts +141 -68
  95. package/src/internal/node.ts +49 -3
  96. package/src/internal/run.ts +4 -2
  97. package/src/internal/stack.ts +17 -0
  98. package/src/internal/tokens.ts +20 -10
  99. package/src/internal/tuple.ts +141 -0
@@ -300,11 +300,29 @@ export declare const NodeId: unique symbol;
300
300
  export declare const describedNode: (p: ParserLike) => Node | undefined;
301
301
  /** The description of a parser: `Opaque` when it has none. */
302
302
  export declare const nodeOf: (p: ParserLike) => Node;
303
- /** Normalizes a range, as `repeat`, `takeWhile`, ... do. */
303
+ /**
304
+ * `count` as given, which must be a non-negative safe integer, else a
305
+ * `RangeError`. A count is a `number` only in the types, and each backend
306
+ * read a negative, fractional, `NaN` or non-number count its own way: the
307
+ * interpreter moved the cursor backwards, and the JIT wrote the value into
308
+ * the source it compiles.
309
+ */
310
+ export declare const checkCount: (count: number, what?: string) => number;
311
+ /**
312
+ * Normalizes a range, as `repeat`, `takeWhile`, ... do. Throws a
313
+ * `RangeError` unless both bounds are non-negative integers (`max` may be
314
+ * `Infinity`) with `min <= max` (see {@link checkCount}).
315
+ */
304
316
  export declare const bounds: (range: number | {
305
317
  readonly min?: number | undefined;
306
318
  readonly max?: number | undefined;
307
319
  } | undefined) => Bounds;
320
+ /**
321
+ * The code of a control character given as a one-character string or a
322
+ * code: a non-negative integer, else a `RangeError` (it is compared with
323
+ * input units, and the JIT writes it into the source it compiles).
324
+ */
325
+ export declare const controlCode: (control: string | number, read: (s: string) => number) => number;
308
326
  /**
309
327
  * Whether the compilers' one-pass float scan applies to `p`, the text
310
328
  * parser of `Ascii.float` / `Text.float`: a `taken` (under any `expected`
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","names":[],"sources":["../../src/internal/node.ts"],"mappings":"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"}
1
+ {"version":3,"file":"node.d.ts","names":[],"sources":["../../src/internal/node.ts"],"mappings":"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"}
@@ -19,22 +19,56 @@ const nodeOf = (p) => describedNode(p) ?? {
19
19
  _tag: "Opaque",
20
20
  step: p.step
21
21
  };
22
- /** Normalizes a range, as `repeat`, `takeWhile`, ... do. */
22
+ /** How a rejected argument reads in an error: never the argument's own text. */
23
+ const describeArgument = (u) => Predicate.isNumber(u) || Predicate.isBigInt(u) || u === void 0 || u === null ? String(u) : Predicate.isString(u) ? "a string" : "a value that is not a number";
24
+ /**
25
+ * `count` as given, which must be a non-negative safe integer, else a
26
+ * `RangeError`. A count is a `number` only in the types, and each backend
27
+ * read a negative, fractional, `NaN` or non-number count its own way: the
28
+ * interpreter moved the cursor backwards, and the JIT wrote the value into
29
+ * the source it compiles.
30
+ */
31
+ const checkCount = (count, what = "count") => {
32
+ if (!Number.isSafeInteger(count) || count < 0) throw new RangeError(`invalid ${what}: expected a non-negative integer, got ${describeArgument(count)}`);
33
+ return count;
34
+ };
35
+ /**
36
+ * Normalizes a range, as `repeat`, `takeWhile`, ... do. Throws a
37
+ * `RangeError` unless both bounds are non-negative integers (`max` may be
38
+ * `Infinity`) with `min <= max` (see {@link checkCount}).
39
+ */
23
40
  const bounds = (range) => {
24
41
  if (range === void 0) return {
25
42
  min: 0,
26
43
  max: Infinity
27
44
  };
28
- if (Predicate.isNumber(range)) return {
29
- min: range,
30
- max: range
31
- };
45
+ if (!Predicate.isObject(range)) {
46
+ const count = checkCount(range);
47
+ return {
48
+ min: count,
49
+ max: count
50
+ };
51
+ }
52
+ const min = checkCount(range.min ?? 0, "range: min");
53
+ const max = range.max ?? Infinity;
54
+ if (max !== Infinity) checkCount(max, "range: max");
55
+ if (min > max) throw new RangeError(`invalid range: min (${min}) > max (${max})`);
32
56
  return {
33
- min: range.min ?? 0,
34
- max: range.max ?? Infinity
57
+ min,
58
+ max
35
59
  };
36
60
  };
37
61
  /**
62
+ * The code of a control character given as a one-character string or a
63
+ * code: a non-negative integer, else a `RangeError` (it is compared with
64
+ * input units, and the JIT writes it into the source it compiles).
65
+ */
66
+ const controlCode = (control, read) => {
67
+ const code = Predicate.isString(control) ? read(control) : control;
68
+ if (!Number.isSafeInteger(code) || code < 0) throw new RangeError(`invalid control character: expected a character or its code, got ${describeArgument(control)}`);
69
+ return code;
70
+ };
71
+ /**
38
72
  * Whether the compilers' one-pass float scan applies to `p`, the text
39
73
  * parser of `Ascii.float` / `Text.float`: a `taken` (under any `expected`
40
74
  * labels) in an encoding that `native` accepts, reading one ASCII-compatible
@@ -101,6 +135,6 @@ const children = (node) => {
101
135
  default: return [];
102
136
  }
103
137
  };
104
- export { Defer, NodeId, bounds, children, describedNode, nodeOf, scansFloat };
138
+ export { Defer, NodeId, bounds, checkCount, children, controlCode, describedNode, nodeOf, scansFloat };
105
139
 
106
140
  //# sourceMappingURL=node.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","names":[],"sources":["../../src/internal/node.ts"],"sourcesContent":["/**\n * Descriptions of parsers, recorded next to their steps so that parsers can\n * be compiled (see `docs/DESIGN.md`, \"Compiled parsers\").\n *\n * Nodes refer to their child parsers rather than to child nodes, so a\n * child's own step is always at hand for fallback, and recursion through\n * `Suspend` is just a reference.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Option from \"effect/Option\"\nimport type * as Result from \"effect/Result\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { ErrMode, Input, State } from \"../Input.js\"\n\n/** The parts of a parser the compiler needs. */\nexport interface ParserLike {\n readonly step: (state: State<any>) => unknown\n readonly name: string | undefined\n}\n\ntype P = ParserLike\ntype Step = (state: State<any>) => unknown\n\n/** A repetition range, normalized: `max` may be `Infinity`. */\ninterface Bounds {\n readonly min: number\n readonly max: number\n}\n\n/**\n * For token nodes: `undefined` for the `Token`/`Ascii` parsers (code points\n * of strings with lenient surrogates, bytes, or array elements), or the\n * encoding of a `Text` parser.\n */\ntype Enc = Encoding<any> | undefined\n\n/**\n * A user callback building a value from parser outputs: `map`, `mapOrFail`\n * (one output), `mapSpan` (an output and its span), `zipWith` and `seqWith`\n * (one argument per parser).\n */\ntype Mapper = (...values: Array<any>) => unknown\n\nexport type Node =\n // Constants\n | { readonly _tag: \"Opaque\"; readonly step: Step }\n | { readonly _tag: \"Succeed\"; readonly value: unknown }\n | { readonly _tag: \"Sync\"; readonly evaluate: () => unknown }\n | { readonly _tag: \"Fail\"; readonly mode: ErrMode }\n | { readonly _tag: \"Eof\" }\n | { readonly _tag: \"Location\" }\n | { readonly _tag: \"Suspend\"; readonly resolve: () => P }\n // Tokens\n | { readonly _tag: \"Any\"; readonly encoding: Enc }\n | { readonly _tag: \"Literal\"; readonly literal: Input; readonly caseless: boolean; readonly encoding: Enc }\n | { readonly _tag: \"OneOf\"; readonly set: unknown; readonly negate: boolean; readonly encoding: Enc }\n | { readonly _tag: \"Take\"; readonly count: number; readonly encoding: Enc }\n | ({ readonly _tag: \"TakeWhile\"; readonly set: unknown; readonly negate: boolean; readonly encoding: Enc } & Bounds)\n | ({ readonly _tag: \"TakeUntil\"; readonly literal: Input; readonly encoding: Enc } & Bounds)\n | ({ readonly _tag: \"TakeUntilAny\"; readonly literals: ReadonlyArray<Input>; readonly encoding: Enc } & Bounds)\n | { readonly _tag: \"Rest\"; readonly encoding: Enc }\n // `Binary`'s fixed-size numbers: `read` reads `size` bytes at an offset of the state's bytes\n | {\n readonly _tag: \"Fixed\"\n readonly size: number\n readonly read: (bytes: Uint8Array, offset: number, state: State<Uint8Array>) => unknown\n }\n | { readonly _tag: \"RestLen\" }\n | { readonly _tag: \"TillLineEnding\"; readonly encoding: Enc }\n | { readonly _tag: \"Identifier\"; readonly encoding: Enc }\n | { readonly _tag: \"Bom\"; readonly encoding: Enc }\n | {\n readonly _tag: \"Escaped\"\n readonly normal: P\n /** The control character, as a code point (or a byte / unit for `Ascii`). */\n readonly control: number\n readonly escape: P\n /** `takeEscaped`: return the raw slice instead of the unescaped text. */\n readonly raw: boolean\n readonly encoding: Enc\n }\n // Mapping\n | { readonly _tag: \"Map\"; readonly self: P; readonly f: Mapper }\n | { readonly _tag: \"As\"; readonly self: P; readonly value: unknown }\n | { readonly _tag: \"Tap\"; readonly self: P; readonly f: (a: any) => void }\n | { readonly _tag: \"TryMap\"; readonly self: P; readonly f: (a: any) => Result.Result<unknown, unknown> }\n | { readonly _tag: \"FilterMap\"; readonly self: P; readonly f: (a: any) => Option.Option<unknown> }\n /** `mapOrFail`: `f` returns `Fail` to reject the value. */\n | { readonly _tag: \"MapOrFail\"; readonly self: P; readonly f: Mapper }\n | { readonly _tag: \"Filter\"; readonly self: P; readonly predicate: (a: any) => boolean }\n | { readonly _tag: \"FlatMap\"; readonly self: P; readonly f: (a: any) => P }\n // Consumed input\n | { readonly _tag: \"Taken\"; readonly self: P; readonly encoding: Enc }\n | { readonly _tag: \"WithTaken\"; readonly self: P }\n | { readonly _tag: \"Span\"; readonly self: P }\n | { readonly _tag: \"WithSpan\"; readonly self: P }\n /** `mapSpan`: `f(output, start, end)`. */\n | { readonly _tag: \"MapSpan\"; readonly self: P; readonly f: Mapper }\n /** `withFastPath`: `fast` runs first in compiled code; `Defer` runs `self`. */\n | { readonly _tag: \"FastPath\"; readonly self: P; readonly fast: Step }\n // Errors\n | { readonly _tag: \"Mode\"; readonly self: P; readonly from: ErrMode; readonly to: ErrMode }\n | { readonly _tag: \"Context\"; readonly self: P; readonly label: string }\n | { readonly _tag: \"Expected\"; readonly self: P; readonly description: string }\n | { readonly _tag: \"Quiet\"; readonly self: P }\n | { readonly _tag: \"MapError\"; readonly self: P }\n | { readonly _tag: \"OrFail\"; readonly self: P }\n // Control\n | { readonly _tag: \"Opt\"; readonly self: P }\n | { readonly _tag: \"OrElseSucceed\"; readonly self: P; readonly value: () => unknown }\n | { readonly _tag: \"Peek\"; readonly self: P }\n | { readonly _tag: \"Not\"; readonly self: P }\n // Sequencing\n | {\n readonly _tag: \"Seq\"\n readonly parsers: ReadonlyArray<P>\n /** Which outputs are kept: all (a tuple), one index, or a pair of indices. */\n readonly output: \"tuple\" | number | readonly [number, number]\n }\n | { readonly _tag: \"Struct\"; readonly keys: ReadonlyArray<string>; readonly parsers: ReadonlyArray<P> }\n | { readonly _tag: \"ZipWith\"; readonly self: P; readonly that: P; readonly f: Mapper }\n /** `seqWith`: `f` receives one output per parser. */\n | { readonly _tag: \"SeqWith\"; readonly parsers: ReadonlyArray<P>; readonly f: Mapper }\n // Choice\n | { readonly _tag: \"Alt\"; readonly parsers: ReadonlyArray<P> }\n | {\n readonly _tag: \"Dispatch\"\n readonly selector: P\n /** A record of cases, when `dispatch` was given one. */\n readonly cases: Readonly<Record<PropertyKey, P>> | undefined\n readonly otherwise: P | undefined\n readonly choose: (key: any) => P | undefined\n }\n // Repetition\n | ({ readonly _tag: \"Repeat\"; readonly self: P } & Bounds)\n | ({\n readonly _tag: \"Fold\"\n readonly self: P\n readonly init: () => unknown\n readonly f: (acc: any, a: any) => unknown\n /** Stops the repetition once false of the accumulator (after `min` elements). */\n readonly while: ((acc: any) => boolean) | undefined\n readonly name: string\n } & Bounds)\n | ({ readonly _tag: \"RepeatTill\"; readonly self: P; readonly end: P } & Bounds)\n | ({ readonly _tag: \"Separated\"; readonly self: P; readonly separator: P } & Bounds)\n | {\n readonly _tag: \"SeparatedFold\"\n readonly self: P\n readonly separator: P\n readonly op: (l: any, s: any, r: any) => unknown\n readonly right: boolean\n }\n /**\n * A combinator whose algorithm the compilers don't know (`Expression.make`,\n * `permutation`): `build` makes its step from the steps of `parsers`. The\n * interpreter passes their own steps; the closure compiler (and the JIT,\n * through it) passes their compiled steps, so the parsers inside compile.\n */\n | {\n readonly _tag: \"Combinator\"\n readonly parsers: ReadonlyArray<P>\n readonly build: (steps: ReadonlyArray<Step>) => Step\n }\n // Services, recovery, debugging\n | { readonly _tag: \"Service\" }\n | { readonly _tag: \"Provide\"; readonly self: P }\n | { readonly _tag: \"ResumeAfter\"; readonly self: P; readonly recover: P }\n | { readonly _tag: \"RetryAfter\"; readonly self: P; readonly recover: P }\n | { readonly _tag: \"Trace\"; readonly self: P; readonly name: string }\n /** `Syntax.node`, `Syntax.token` and `Syntax.field`: identities outside `Syntax` parses. */\n | {\n readonly _tag: \"Syntax\"\n readonly self: P\n /** The node kind, or `undefined` for a field. */\n readonly kind: string | undefined\n readonly named: boolean\n }\n\nexport type Tag = Node[\"_tag\"]\n\nexport type NodeOf<T extends Tag> = Extract<Node, { readonly _tag: T }>\n\n/** What a fast path returns to leave the input to its grammar (`Parser.Defer`). */\nexport const Defer: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Parser/Defer\")\n\n/** Where a parser's description is stored. */\nexport const NodeId: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Parser/node\")\n\n/** The description recorded for a parser, if it has one. */\nexport const describedNode = (p: ParserLike): Node | undefined =>\n // SAFETY: `Parser.described` stores a parser's `Node` under `NodeId`;\n // reading it from any other parser (or one built by `Parser.make`, which\n // stores `undefined`) yields `undefined`\n (p as ParserLike & { readonly [NodeId]?: Node })[NodeId]\n\n/** The description of a parser: `Opaque` when it has none. */\nexport const nodeOf = (p: ParserLike): Node => describedNode(p) ?? { _tag: \"Opaque\", step: p.step }\n\n/** Normalizes a range, as `repeat`, `takeWhile`, ... do. */\nexport const bounds = (\n range: number | { readonly min?: number | undefined; readonly max?: number | undefined } | undefined\n): Bounds => {\n if (range === undefined) return { min: 0, max: Infinity }\n if (Predicate.isNumber(range)) return { min: range, max: range }\n return { min: range.min ?? 0, max: range.max ?? Infinity }\n}\n\n/**\n * Whether the compilers' one-pass float scan applies to `p`, the text\n * parser of `Ascii.float` / `Text.float`: a `taken` (under any `expected`\n * labels) in an encoding that `native` accepts, reading one ASCII-compatible\n * unit at a time, or in no encoding at all.\n */\nexport const scansFloat = (p: ParserLike, native: (enc: Encoding<any>) => boolean): boolean => {\n let taken = nodeOf(p)\n while (Predicate.isTagged(taken, \"Expected\")) taken = nodeOf(taken.self)\n if (!Predicate.isTagged(taken, \"Taken\")) return false\n const enc = taken.encoding\n // Decimal notation is ASCII, which these encodings read unit by unit\n return enc === undefined || (native(enc) && enc.unit === 1 && enc.asciiCompatible)\n}\n\n/** The child parsers of a node, in evaluation order. */\nexport const children = (node: Node): ReadonlyArray<P> => {\n switch (node._tag) {\n case \"Escaped\":\n return [node.normal, node.escape]\n case \"Map\":\n case \"As\":\n case \"Tap\":\n case \"TryMap\":\n case \"FilterMap\":\n case \"MapOrFail\":\n case \"Filter\":\n case \"FlatMap\":\n case \"Taken\":\n case \"WithTaken\":\n case \"Span\":\n case \"WithSpan\":\n case \"MapSpan\":\n case \"Mode\":\n case \"Context\":\n case \"Expected\":\n case \"Quiet\":\n case \"FastPath\":\n case \"MapError\":\n case \"OrFail\":\n case \"Opt\":\n case \"OrElseSucceed\":\n case \"Peek\":\n case \"Not\":\n case \"Repeat\":\n case \"Fold\":\n case \"Provide\":\n case \"Trace\":\n case \"Syntax\":\n return [node.self]\n case \"ResumeAfter\":\n case \"RetryAfter\":\n return [node.self, node.recover]\n case \"Seq\":\n case \"Struct\":\n case \"SeqWith\":\n case \"Alt\":\n case \"Combinator\":\n return node.parsers\n case \"ZipWith\":\n return [node.self, node.that]\n case \"Dispatch\": {\n const out: Array<P> = [node.selector]\n if (node.cases !== undefined) {\n for (const key of Reflect.ownKeys(node.cases)) out.push(node.cases[key])\n }\n if (node.otherwise !== undefined) out.push(node.otherwise)\n return out\n }\n case \"RepeatTill\":\n return [node.self, node.end]\n case \"Separated\":\n case \"SeparatedFold\":\n return [node.self, node.separator]\n case \"Suspend\":\n return [node.resolve()]\n default:\n return []\n }\n}\n"],"mappings":";;;;;;;;;;;AAwLA,MAAa,QAAqC,qBAAO,IAAI,2BAA2B;;AAGxF,MAAa,SAAsC,qBAAO,IAAI,0BAA0B;;AAGxF,MAAa,iBAAiB,MAI3B,EAAgD;;AAGnD,MAAa,UAAU,MAAwB,cAAc,CAAC,KAAK;CAAE,MAAM;CAAU,MAAM,EAAE;AAAK;;AAGlG,MAAa,UACX,UACW;CACX,IAAI,UAAU,KAAA,GAAW,OAAO;EAAE,KAAK;EAAG,KAAK;CAAS;CACxD,IAAI,UAAU,SAAS,KAAK,GAAG,OAAO;EAAE,KAAK;EAAO,KAAK;CAAM;CAC/D,OAAO;EAAE,KAAK,MAAM,OAAO;EAAG,KAAK,MAAM,OAAO;CAAS;AAC3D;;;;;;;AAQA,MAAa,cAAc,GAAe,WAAqD;CAC7F,IAAI,QAAQ,OAAO,CAAC;CACpB,OAAO,UAAU,SAAS,OAAO,UAAU,GAAG,QAAQ,OAAO,MAAM,IAAI;CACvE,IAAI,CAAC,UAAU,SAAS,OAAO,OAAO,GAAG,OAAO;CAChD,MAAM,MAAM,MAAM;CAElB,OAAO,QAAQ,KAAA,KAAc,OAAO,GAAG,KAAK,IAAI,SAAS,KAAK,IAAI;AACpE;;AAGA,MAAa,YAAY,SAAiC;CACxD,QAAQ,KAAK,MAAb;EACE,KAAK,WACH,OAAO,CAAC,KAAK,QAAQ,KAAK,MAAM;EAClC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACH,OAAO,CAAC,KAAK,IAAI;EACnB,KAAK;EACL,KAAK,cACH,OAAO,CAAC,KAAK,MAAM,KAAK,OAAO;EACjC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,cACH,OAAO,KAAK;EACd,KAAK,WACH,OAAO,CAAC,KAAK,MAAM,KAAK,IAAI;EAC9B,KAAK,YAAY;GACf,MAAM,MAAgB,CAAC,KAAK,QAAQ;GACpC,IAAI,KAAK,UAAU,KAAA,GACjB,KAAK,MAAM,OAAO,QAAQ,QAAQ,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,MAAM,IAAI;GAEzE,IAAI,KAAK,cAAc,KAAA,GAAW,IAAI,KAAK,KAAK,SAAS;GACzD,OAAO;EACT;EACA,KAAK,cACH,OAAO,CAAC,KAAK,MAAM,KAAK,GAAG;EAC7B,KAAK;EACL,KAAK,iBACH,OAAO,CAAC,KAAK,MAAM,KAAK,SAAS;EACnC,KAAK,WACH,OAAO,CAAC,KAAK,QAAQ,CAAC;EACxB,SACE,OAAO,CAAC;CACZ;AACF"}
1
+ {"version":3,"file":"node.js","names":[],"sources":["../../src/internal/node.ts"],"sourcesContent":["/**\n * Descriptions of parsers, recorded next to their steps so that parsers can\n * be compiled (see `docs/DESIGN.md`, \"Compiled parsers\").\n *\n * Nodes refer to their child parsers rather than to child nodes, so a\n * child's own step is always at hand for fallback, and recursion through\n * `Suspend` is just a reference.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Option from \"effect/Option\"\nimport type * as Result from \"effect/Result\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { ErrMode, Input, State } from \"../Input.js\"\n\n/** The parts of a parser the compiler needs. */\nexport interface ParserLike {\n readonly step: (state: State<any>) => unknown\n readonly name: string | undefined\n}\n\ntype P = ParserLike\ntype Step = (state: State<any>) => unknown\n\n/** A repetition range, normalized: `max` may be `Infinity`. */\ninterface Bounds {\n readonly min: number\n readonly max: number\n}\n\n/**\n * For token nodes: `undefined` for the `Token`/`Ascii` parsers (code points\n * of strings with lenient surrogates, bytes, or array elements), or the\n * encoding of a `Text` parser.\n */\ntype Enc = Encoding<any> | undefined\n\n/**\n * A user callback building a value from parser outputs: `map`, `mapOrFail`\n * (one output), `mapSpan` (an output and its span), `zipWith` and `seqWith`\n * (one argument per parser).\n */\ntype Mapper = (...values: Array<any>) => unknown\n\nexport type Node =\n // Constants\n | { readonly _tag: \"Opaque\"; readonly step: Step }\n | { readonly _tag: \"Succeed\"; readonly value: unknown }\n | { readonly _tag: \"Sync\"; readonly evaluate: () => unknown }\n | { readonly _tag: \"Fail\"; readonly mode: ErrMode }\n | { readonly _tag: \"Eof\" }\n | { readonly _tag: \"Location\" }\n | { readonly _tag: \"Suspend\"; readonly resolve: () => P }\n // Tokens\n | { readonly _tag: \"Any\"; readonly encoding: Enc }\n | { readonly _tag: \"Literal\"; readonly literal: Input; readonly caseless: boolean; readonly encoding: Enc }\n | { readonly _tag: \"OneOf\"; readonly set: unknown; readonly negate: boolean; readonly encoding: Enc }\n | { readonly _tag: \"Take\"; readonly count: number; readonly encoding: Enc }\n | ({ readonly _tag: \"TakeWhile\"; readonly set: unknown; readonly negate: boolean; readonly encoding: Enc } & Bounds)\n | ({ readonly _tag: \"TakeUntil\"; readonly literal: Input; readonly encoding: Enc } & Bounds)\n | ({ readonly _tag: \"TakeUntilAny\"; readonly literals: ReadonlyArray<Input>; readonly encoding: Enc } & Bounds)\n | { readonly _tag: \"Rest\"; readonly encoding: Enc }\n // `Binary`'s fixed-size numbers: `read` reads `size` bytes at an offset of the state's bytes\n | {\n readonly _tag: \"Fixed\"\n readonly size: number\n readonly read: (bytes: Uint8Array, offset: number, state: State<Uint8Array>) => unknown\n }\n | { readonly _tag: \"RestLen\" }\n | { readonly _tag: \"TillLineEnding\"; readonly encoding: Enc }\n | { readonly _tag: \"Identifier\"; readonly encoding: Enc }\n | { readonly _tag: \"Bom\"; readonly encoding: Enc }\n | {\n readonly _tag: \"Escaped\"\n readonly normal: P\n /** The control character, as a code point (or a byte / unit for `Ascii`). */\n readonly control: number\n readonly escape: P\n /** `takeEscaped`: return the raw slice instead of the unescaped text. */\n readonly raw: boolean\n readonly encoding: Enc\n }\n // Mapping\n | { readonly _tag: \"Map\"; readonly self: P; readonly f: Mapper }\n | { readonly _tag: \"As\"; readonly self: P; readonly value: unknown }\n | { readonly _tag: \"Tap\"; readonly self: P; readonly f: (a: any) => void }\n | { readonly _tag: \"TryMap\"; readonly self: P; readonly f: (a: any) => Result.Result<unknown, unknown> }\n | { readonly _tag: \"FilterMap\"; readonly self: P; readonly f: (a: any) => Option.Option<unknown> }\n /** `mapOrFail`: `f` returns `Fail` to reject the value. */\n | { readonly _tag: \"MapOrFail\"; readonly self: P; readonly f: Mapper }\n | { readonly _tag: \"Filter\"; readonly self: P; readonly predicate: (a: any) => boolean }\n | { readonly _tag: \"FlatMap\"; readonly self: P; readonly f: (a: any) => P }\n // Consumed input\n | { readonly _tag: \"Taken\"; readonly self: P; readonly encoding: Enc }\n | { readonly _tag: \"WithTaken\"; readonly self: P }\n | { readonly _tag: \"Span\"; readonly self: P }\n | { readonly _tag: \"WithSpan\"; readonly self: P }\n /** `mapSpan`: `f(output, start, end)`. */\n | { readonly _tag: \"MapSpan\"; readonly self: P; readonly f: Mapper }\n /** `withFastPath`: `fast` runs first in compiled code; `Defer` runs `self`. */\n | { readonly _tag: \"FastPath\"; readonly self: P; readonly fast: Step }\n // Errors\n | { readonly _tag: \"Mode\"; readonly self: P; readonly from: ErrMode; readonly to: ErrMode }\n | { readonly _tag: \"Context\"; readonly self: P; readonly label: string }\n | { readonly _tag: \"Expected\"; readonly self: P; readonly description: string }\n | { readonly _tag: \"Quiet\"; readonly self: P }\n | { readonly _tag: \"MapError\"; readonly self: P }\n | { readonly _tag: \"OrFail\"; readonly self: P }\n // Control\n | { readonly _tag: \"Opt\"; readonly self: P }\n | { readonly _tag: \"OrElseSucceed\"; readonly self: P; readonly value: () => unknown }\n | { readonly _tag: \"Peek\"; readonly self: P }\n | { readonly _tag: \"Not\"; readonly self: P }\n // Sequencing\n | {\n readonly _tag: \"Seq\"\n readonly parsers: ReadonlyArray<P>\n /** Which outputs are kept: all (a tuple), one index, or a pair of indices. */\n readonly output: \"tuple\" | number | readonly [number, number]\n }\n | { readonly _tag: \"Struct\"; readonly keys: ReadonlyArray<string>; readonly parsers: ReadonlyArray<P> }\n | { readonly _tag: \"ZipWith\"; readonly self: P; readonly that: P; readonly f: Mapper }\n /** `seqWith`: `f` receives one output per parser. */\n | { readonly _tag: \"SeqWith\"; readonly parsers: ReadonlyArray<P>; readonly f: Mapper }\n // Choice\n | { readonly _tag: \"Alt\"; readonly parsers: ReadonlyArray<P> }\n | {\n readonly _tag: \"Dispatch\"\n readonly selector: P\n /** A record of cases, when `dispatch` was given one. */\n readonly cases: Readonly<Record<PropertyKey, P>> | undefined\n readonly otherwise: P | undefined\n readonly choose: (key: any) => P | undefined\n }\n // Repetition\n | ({ readonly _tag: \"Repeat\"; readonly self: P } & Bounds)\n | ({\n readonly _tag: \"Fold\"\n readonly self: P\n readonly init: () => unknown\n readonly f: (acc: any, a: any) => unknown\n /** Stops the repetition once false of the accumulator (after `min` elements). */\n readonly while: ((acc: any) => boolean) | undefined\n readonly name: string\n } & Bounds)\n | ({ readonly _tag: \"RepeatTill\"; readonly self: P; readonly end: P } & Bounds)\n | ({ readonly _tag: \"Separated\"; readonly self: P; readonly separator: P } & Bounds)\n | {\n readonly _tag: \"SeparatedFold\"\n readonly self: P\n readonly separator: P\n readonly op: (l: any, s: any, r: any) => unknown\n readonly right: boolean\n }\n /**\n * A combinator whose algorithm the compilers don't know (`Expression.make`,\n * `permutation`): `build` makes its step from the steps of `parsers`. The\n * interpreter passes their own steps; the closure compiler (and the JIT,\n * through it) passes their compiled steps, so the parsers inside compile.\n */\n | {\n readonly _tag: \"Combinator\"\n readonly parsers: ReadonlyArray<P>\n readonly build: (steps: ReadonlyArray<Step>) => Step\n }\n // Services, recovery, debugging\n | { readonly _tag: \"Service\" }\n | { readonly _tag: \"Provide\"; readonly self: P }\n | { readonly _tag: \"ResumeAfter\"; readonly self: P; readonly recover: P }\n | { readonly _tag: \"RetryAfter\"; readonly self: P; readonly recover: P }\n | { readonly _tag: \"Trace\"; readonly self: P; readonly name: string }\n /** `Syntax.node`, `Syntax.token` and `Syntax.field`: identities outside `Syntax` parses. */\n | {\n readonly _tag: \"Syntax\"\n readonly self: P\n /** The node kind, or `undefined` for a field. */\n readonly kind: string | undefined\n readonly named: boolean\n }\n\nexport type Tag = Node[\"_tag\"]\n\nexport type NodeOf<T extends Tag> = Extract<Node, { readonly _tag: T }>\n\n/** What a fast path returns to leave the input to its grammar (`Parser.Defer`). */\nexport const Defer: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Parser/Defer\")\n\n/** Where a parser's description is stored. */\nexport const NodeId: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Parser/node\")\n\n/** The description recorded for a parser, if it has one. */\nexport const describedNode = (p: ParserLike): Node | undefined =>\n // SAFETY: `Parser.described` stores a parser's `Node` under `NodeId`;\n // reading it from any other parser (or one built by `Parser.make`, which\n // stores `undefined`) yields `undefined`\n (p as ParserLike & { readonly [NodeId]?: Node })[NodeId]\n\n/** The description of a parser: `Opaque` when it has none. */\nexport const nodeOf = (p: ParserLike): Node => describedNode(p) ?? { _tag: \"Opaque\", step: p.step }\n\n/** How a rejected argument reads in an error: never the argument's own text. */\nconst describeArgument = (u: unknown): string =>\n Predicate.isNumber(u) || Predicate.isBigInt(u) || u === undefined || u === null\n ? String(u)\n : Predicate.isString(u)\n ? \"a string\"\n : \"a value that is not a number\"\n\n/**\n * `count` as given, which must be a non-negative safe integer, else a\n * `RangeError`. A count is a `number` only in the types, and each backend\n * read a negative, fractional, `NaN` or non-number count its own way: the\n * interpreter moved the cursor backwards, and the JIT wrote the value into\n * the source it compiles.\n */\nexport const checkCount = (count: number, what: string = \"count\"): number => {\n if (!Number.isSafeInteger(count) || count < 0)\n throw new RangeError(`invalid ${what}: expected a non-negative integer, got ${describeArgument(count)}`)\n return count\n}\n\n/**\n * Normalizes a range, as `repeat`, `takeWhile`, ... do. Throws a\n * `RangeError` unless both bounds are non-negative integers (`max` may be\n * `Infinity`) with `min <= max` (see {@link checkCount}).\n */\nexport const bounds = (\n range: number | { readonly min?: number | undefined; readonly max?: number | undefined } | undefined\n): Bounds => {\n if (range === undefined) return { min: 0, max: Infinity }\n if (!Predicate.isObject(range)) {\n const count = checkCount(range)\n return { min: count, max: count }\n }\n const min = checkCount(range.min ?? 0, \"range: min\")\n const max = range.max ?? Infinity\n if (max !== Infinity) checkCount(max, \"range: max\")\n if (min > max) throw new RangeError(`invalid range: min (${min}) > max (${max})`)\n return { min, max }\n}\n\n/**\n * The code of a control character given as a one-character string or a\n * code: a non-negative integer, else a `RangeError` (it is compared with\n * input units, and the JIT writes it into the source it compiles).\n */\nexport const controlCode = (control: string | number, read: (s: string) => number): number => {\n const code = Predicate.isString(control) ? read(control) : control\n if (!Number.isSafeInteger(code) || code < 0)\n throw new RangeError(\n `invalid control character: expected a character or its code, got ${describeArgument(control)}`\n )\n return code\n}\n\n/**\n * Whether the compilers' one-pass float scan applies to `p`, the text\n * parser of `Ascii.float` / `Text.float`: a `taken` (under any `expected`\n * labels) in an encoding that `native` accepts, reading one ASCII-compatible\n * unit at a time, or in no encoding at all.\n */\nexport const scansFloat = (p: ParserLike, native: (enc: Encoding<any>) => boolean): boolean => {\n let taken = nodeOf(p)\n while (Predicate.isTagged(taken, \"Expected\")) taken = nodeOf(taken.self)\n if (!Predicate.isTagged(taken, \"Taken\")) return false\n const enc = taken.encoding\n // Decimal notation is ASCII, which these encodings read unit by unit\n return enc === undefined || (native(enc) && enc.unit === 1 && enc.asciiCompatible)\n}\n\n/** The child parsers of a node, in evaluation order. */\nexport const children = (node: Node): ReadonlyArray<P> => {\n switch (node._tag) {\n case \"Escaped\":\n return [node.normal, node.escape]\n case \"Map\":\n case \"As\":\n case \"Tap\":\n case \"TryMap\":\n case \"FilterMap\":\n case \"MapOrFail\":\n case \"Filter\":\n case \"FlatMap\":\n case \"Taken\":\n case \"WithTaken\":\n case \"Span\":\n case \"WithSpan\":\n case \"MapSpan\":\n case \"Mode\":\n case \"Context\":\n case \"Expected\":\n case \"Quiet\":\n case \"FastPath\":\n case \"MapError\":\n case \"OrFail\":\n case \"Opt\":\n case \"OrElseSucceed\":\n case \"Peek\":\n case \"Not\":\n case \"Repeat\":\n case \"Fold\":\n case \"Provide\":\n case \"Trace\":\n case \"Syntax\":\n return [node.self]\n case \"ResumeAfter\":\n case \"RetryAfter\":\n return [node.self, node.recover]\n case \"Seq\":\n case \"Struct\":\n case \"SeqWith\":\n case \"Alt\":\n case \"Combinator\":\n return node.parsers\n case \"ZipWith\":\n return [node.self, node.that]\n case \"Dispatch\": {\n const out: Array<P> = [node.selector]\n if (node.cases !== undefined) {\n for (const key of Reflect.ownKeys(node.cases)) out.push(node.cases[key])\n }\n if (node.otherwise !== undefined) out.push(node.otherwise)\n return out\n }\n case \"RepeatTill\":\n return [node.self, node.end]\n case \"Separated\":\n case \"SeparatedFold\":\n return [node.self, node.separator]\n case \"Suspend\":\n return [node.resolve()]\n default:\n return []\n }\n}\n"],"mappings":"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"}
@@ -12,7 +12,9 @@ import { ParserLike } from "./node.js";
12
12
  export declare const runOn: <A>(p: ParserLike, step: (state: State<any>) => A | Fail, state: State<any>, diagnostics?: boolean) => A | Fail;
13
13
  /**
14
14
  * Runs a compiled step on `state`: directly when it guards against
15
- * call-stack overflows itself (the JIT's), else under `Stack.run`.
15
+ * call-stack overflows itself (the JIT's), else under `Stack.run`. While it
16
+ * runs, `state.compiledRun` is set, so the interpreted steps it calls skip
17
+ * building the failures it throws away (#82).
16
18
  */
17
19
  export declare const runCompiled: <A>(step: (state: State<any>) => A, guarded: boolean, state: State<any>) => A | Fail;
18
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","names":[],"sources":["../../src/internal/run.ts"],"mappings":";;;;;;;;;;;qBAoBa,QAAS,GACpB,GAAG,YACH,OAAO,OAAO,eAAe,IAAI,MACjC,OAAO,YACP,0BACC,IAAI;;;;;qBAYM,cAAe,GAAG,OAAO,OAAO,eAAe,GAAG,kBAAkB,OAAO,eAAa,IAAI;;;;;;;qBAyC5F,UAAW,GACtB,GAAG,YACH,OAAO,OAAO,eAAe,IAAI,MACjC,2BACG,OAAO,eAAe,IAAI"}
1
+ {"version":3,"file":"run.d.ts","names":[],"sources":["../../src/internal/run.ts"],"mappings":";;;;;;;;;;;qBAoBa,QAAS,GACpB,GAAG,YACH,OAAO,OAAO,eAAe,IAAI,MACjC,OAAO,YACP,0BACC,IAAI;;;;;;;qBAcM,cAAe,GAAG,OAAO,OAAO,eAAe,GAAG,kBAAkB,OAAO,eAAa,IAAI;;;;;;;qBAyC5F,UAAW,GACtB,GAAG,YACH,OAAO,OAAO,eAAe,IAAI,MACjC,2BACG,OAAO,eAAe,IAAI"}
@@ -24,9 +24,11 @@ const runOn = (p, step, state, diagnostics = true) => {
24
24
  };
25
25
  /**
26
26
  * Runs a compiled step on `state`: directly when it guards against
27
- * call-stack overflows itself (the JIT's), else under `Stack.run`.
27
+ * call-stack overflows itself (the JIT's), else under `Stack.run`. While it
28
+ * runs, `state.compiledRun` is set, so the interpreted steps it calls skip
29
+ * building the failures it throws away (#82).
28
30
  */
29
- const runCompiled = (step, guarded, state) => guarded ? step(state) : Stack.run(step, state);
31
+ const runCompiled = (step, guarded, state) => Stack.runCompiled(step, guarded, state);
30
32
  /**
31
33
  * Runs the compiled step of `compiled` (or, if compiling failed, the
32
34
  * parser's); if it fails, rewinds and, with `diagnostics`, runs the
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","names":[],"sources":["../../src/internal/run.ts"],"sourcesContent":["/**\n * Running a parser on a caller-owned `State`, compiled when possible.\n *\n * Shared by `Parser.run` and `ParserStream.parseMany`, which keep one\n * state across many small runs.\n */\nimport { Fail, type State } from \"../Input.js\"\nimport * as Registry from \"./compiler/registry.js\"\nimport type { ParserLike } from \"./node.js\"\nimport * as Stack from \"./stack.js\"\n\n/**\n * Runs `p` on `state` from `state.pos`: its compiled form when it has one\n * and the state allows it, else its step. A compiled run that fails is\n * thrown away and the step runs again from the same position, so a\n * failure leaves the state exactly as the interpreter would; with\n * `diagnostics` false it is not, and the state keeps the compiled run's\n * `mode`, with the cursor back at the start. Partial states (and states\n * with streaming checkpoints) use the resumable build.\n */\nexport const runOn = <A>(\n p: ParserLike,\n step: (state: State<any>) => A | Fail,\n state: State<any>,\n diagnostics: boolean = true\n): A | Fail => {\n if (state.tracer !== undefined || state.recovered !== undefined || state.syntax !== undefined) {\n return Stack.run(step, state)\n }\n const compiled = Registry.compiled(p, state.inputKind, state.partial || state.resume !== undefined)\n return compiled === undefined ? Stack.run(step, state) : attempt(compiled, step, state, diagnostics)\n}\n\n/**\n * Runs a compiled step on `state`: directly when it guards against\n * call-stack overflows itself (the JIT's), else under `Stack.run`.\n */\nexport const runCompiled = <A>(step: (state: State<any>) => A, guarded: boolean, state: State<any>): A | Fail =>\n guarded ? step(state) : Stack.run(step, state)\n\n/**\n * Runs the compiled step of `compiled` (or, if compiling failed, the\n * parser's); if it fails, rewinds and, with `diagnostics`, runs the\n * parser's step to record the failure.\n */\nconst attempt = <A>(\n compiled: Registry.Compiled,\n step: (state: State<any>) => A | Fail,\n state: State<any>,\n diagnostics: boolean\n): A | Fail => {\n const c = compiled.step\n if (c === undefined) return Stack.run(step, state)\n const start = state.pos\n const a = runCompiled(c, compiled.guarded, state)\n if (a !== Fail) {\n // SAFETY: the compiled step returns what the parser's step returns\n return a as A\n }\n state.rewind(start)\n return diagnostics ? Stack.run(step, state) : Fail\n}\n\n/** What `prepare` holds before its first run: nothing compiled. */\nconst uncompiled: Registry.Compiled = {\n backend: \"interpreted\",\n step: undefined,\n guarded: false,\n fallbacks: [],\n error: undefined\n}\n\n/**\n * `runOn(p, p.step, state, diagnostics)` as a function of the state, with\n * the per-run lookup done once: the compiled step is looked up again only\n * when the input kind or the build (plain or resumable) changes from the\n * previous run.\n */\nexport const prepare = <A>(\n p: ParserLike,\n step: (state: State<any>) => A | Fail,\n diagnostics: boolean\n): ((state: State<any>) => A | Fail) => {\n // The build of the previous run: its input kind (-1 before the first run) and whether it is resumable\n let kind = -1\n let resumable = false\n let compiled = uncompiled\n return (state) => {\n if (state.tracer !== undefined || state.recovered !== undefined || state.syntax !== undefined) {\n return Stack.run(step, state)\n }\n const r = state.partial || state.resume !== undefined\n if (state.inputKind !== kind || r !== resumable) {\n compiled = Registry.compiled(p, state.inputKind, r) ?? uncompiled\n kind = state.inputKind\n resumable = r\n }\n return attempt(compiled, step, state, diagnostics)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,MAAa,SACX,GACA,MACA,OACA,cAAuB,SACV;CACb,IAAI,MAAM,WAAW,KAAA,KAAa,MAAM,cAAc,KAAA,KAAa,MAAM,WAAW,KAAA,GAClF,OAAO,MAAM,IAAI,MAAM,KAAK;CAE9B,MAAM,WAAW,SAAS,SAAS,GAAG,MAAM,WAAW,MAAM,WAAW,MAAM,WAAW,KAAA,CAAS;CAClG,OAAO,aAAa,KAAA,IAAY,MAAM,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,MAAM,OAAO,WAAW;AACrG;;;;;AAMA,MAAa,eAAkB,MAAgC,SAAkB,UAC/E,UAAU,KAAK,KAAK,IAAI,MAAM,IAAI,MAAM,KAAK;;;;;;AAO/C,MAAM,WACJ,UACA,MACA,OACA,gBACa;CACb,MAAM,IAAI,SAAS;CACnB,IAAI,MAAM,KAAA,GAAW,OAAO,MAAM,IAAI,MAAM,KAAK;CACjD,MAAM,QAAQ,MAAM;CACpB,MAAM,IAAI,YAAY,GAAG,SAAS,SAAS,KAAK;CAChD,IAAI,MAAM,MAER,OAAO;CAET,MAAM,OAAO,KAAK;CAClB,OAAO,cAAc,MAAM,IAAI,MAAM,KAAK,IAAI;AAChD;;AAGA,MAAM,aAAgC;CACpC,SAAS;CACT,MAAM,KAAA;CACN,SAAS;CACT,WAAW,CAAC;CACZ,OAAO,KAAA;AACT;;;;;;;AAQA,MAAa,WACX,GACA,MACA,gBACsC;CAEtC,IAAI,OAAO;CACX,IAAI,YAAY;CAChB,IAAI,WAAW;CACf,QAAQ,UAAU;EAChB,IAAI,MAAM,WAAW,KAAA,KAAa,MAAM,cAAc,KAAA,KAAa,MAAM,WAAW,KAAA,GAClF,OAAO,MAAM,IAAI,MAAM,KAAK;EAE9B,MAAM,IAAI,MAAM,WAAW,MAAM,WAAW,KAAA;EAC5C,IAAI,MAAM,cAAc,QAAQ,MAAM,WAAW;GAC/C,WAAW,SAAS,SAAS,GAAG,MAAM,WAAW,CAAC,KAAK;GACvD,OAAO,MAAM;GACb,YAAY;EACd;EACA,OAAO,QAAQ,UAAU,MAAM,OAAO,WAAW;CACnD;AACF"}
1
+ {"version":3,"file":"run.js","names":[],"sources":["../../src/internal/run.ts"],"sourcesContent":["/**\n * Running a parser on a caller-owned `State`, compiled when possible.\n *\n * Shared by `Parser.run` and `ParserStream.parseMany`, which keep one\n * state across many small runs.\n */\nimport { Fail, type State } from \"../Input.js\"\nimport * as Registry from \"./compiler/registry.js\"\nimport type { ParserLike } from \"./node.js\"\nimport * as Stack from \"./stack.js\"\n\n/**\n * Runs `p` on `state` from `state.pos`: its compiled form when it has one\n * and the state allows it, else its step. A compiled run that fails is\n * thrown away and the step runs again from the same position, so a\n * failure leaves the state exactly as the interpreter would; with\n * `diagnostics` false it is not, and the state keeps the compiled run's\n * `mode`, with the cursor back at the start. Partial states (and states\n * with streaming checkpoints) use the resumable build.\n */\nexport const runOn = <A>(\n p: ParserLike,\n step: (state: State<any>) => A | Fail,\n state: State<any>,\n diagnostics: boolean = true\n): A | Fail => {\n if (state.tracer !== undefined || state.recovered !== undefined || state.syntax !== undefined) {\n return Stack.run(step, state)\n }\n const compiled = Registry.compiled(p, state.inputKind, state.partial || state.resume !== undefined)\n return compiled === undefined ? Stack.run(step, state) : attempt(compiled, step, state, diagnostics)\n}\n\n/**\n * Runs a compiled step on `state`: directly when it guards against\n * call-stack overflows itself (the JIT's), else under `Stack.run`. While it\n * runs, `state.compiledRun` is set, so the interpreted steps it calls skip\n * building the failures it throws away (#82).\n */\nexport const runCompiled = <A>(step: (state: State<any>) => A, guarded: boolean, state: State<any>): A | Fail =>\n Stack.runCompiled(step, guarded, state)\n\n/**\n * Runs the compiled step of `compiled` (or, if compiling failed, the\n * parser's); if it fails, rewinds and, with `diagnostics`, runs the\n * parser's step to record the failure.\n */\nconst attempt = <A>(\n compiled: Registry.Compiled,\n step: (state: State<any>) => A | Fail,\n state: State<any>,\n diagnostics: boolean\n): A | Fail => {\n const c = compiled.step\n if (c === undefined) return Stack.run(step, state)\n const start = state.pos\n const a = runCompiled(c, compiled.guarded, state)\n if (a !== Fail) {\n // SAFETY: the compiled step returns what the parser's step returns\n return a as A\n }\n state.rewind(start)\n return diagnostics ? Stack.run(step, state) : Fail\n}\n\n/** What `prepare` holds before its first run: nothing compiled. */\nconst uncompiled: Registry.Compiled = {\n backend: \"interpreted\",\n step: undefined,\n guarded: false,\n fallbacks: [],\n error: undefined\n}\n\n/**\n * `runOn(p, p.step, state, diagnostics)` as a function of the state, with\n * the per-run lookup done once: the compiled step is looked up again only\n * when the input kind or the build (plain or resumable) changes from the\n * previous run.\n */\nexport const prepare = <A>(\n p: ParserLike,\n step: (state: State<any>) => A | Fail,\n diagnostics: boolean\n): ((state: State<any>) => A | Fail) => {\n // The build of the previous run: its input kind (-1 before the first run) and whether it is resumable\n let kind = -1\n let resumable = false\n let compiled = uncompiled\n return (state) => {\n if (state.tracer !== undefined || state.recovered !== undefined || state.syntax !== undefined) {\n return Stack.run(step, state)\n }\n const r = state.partial || state.resume !== undefined\n if (state.inputKind !== kind || r !== resumable) {\n compiled = Registry.compiled(p, state.inputKind, r) ?? uncompiled\n kind = state.inputKind\n resumable = r\n }\n return attempt(compiled, step, state, diagnostics)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,MAAa,SACX,GACA,MACA,OACA,cAAuB,SACV;CACb,IAAI,MAAM,WAAW,KAAA,KAAa,MAAM,cAAc,KAAA,KAAa,MAAM,WAAW,KAAA,GAClF,OAAO,MAAM,IAAI,MAAM,KAAK;CAE9B,MAAM,WAAW,SAAS,SAAS,GAAG,MAAM,WAAW,MAAM,WAAW,MAAM,WAAW,KAAA,CAAS;CAClG,OAAO,aAAa,KAAA,IAAY,MAAM,IAAI,MAAM,KAAK,IAAI,QAAQ,UAAU,MAAM,OAAO,WAAW;AACrG;;;;;;;AAQA,MAAa,eAAkB,MAAgC,SAAkB,UAC/E,MAAM,YAAY,MAAM,SAAS,KAAK;;;;;;AAOxC,MAAM,WACJ,UACA,MACA,OACA,gBACa;CACb,MAAM,IAAI,SAAS;CACnB,IAAI,MAAM,KAAA,GAAW,OAAO,MAAM,IAAI,MAAM,KAAK;CACjD,MAAM,QAAQ,MAAM;CACpB,MAAM,IAAI,YAAY,GAAG,SAAS,SAAS,KAAK;CAChD,IAAI,MAAM,MAER,OAAO;CAET,MAAM,OAAO,KAAK;CAClB,OAAO,cAAc,MAAM,IAAI,MAAM,KAAK,IAAI;AAChD;;AAGA,MAAM,aAAgC;CACpC,SAAS;CACT,MAAM,KAAA;CACN,SAAS;CACT,WAAW,CAAC;CACZ,OAAO,KAAA;AACT;;;;;;;AAQA,MAAa,WACX,GACA,MACA,gBACsC;CAEtC,IAAI,OAAO;CACX,IAAI,YAAY;CAChB,IAAI,WAAW;CACf,QAAQ,UAAU;EAChB,IAAI,MAAM,WAAW,KAAA,KAAa,MAAM,cAAc,KAAA,KAAa,MAAM,WAAW,KAAA,GAClF,OAAO,MAAM,IAAI,MAAM,KAAK;EAE9B,MAAM,IAAI,MAAM,WAAW,MAAM,WAAW,KAAA;EAC5C,IAAI,MAAM,cAAc,QAAQ,MAAM,WAAW;GAC/C,WAAW,SAAS,SAAS,GAAG,MAAM,WAAW,CAAC,KAAK;GACvD,OAAO,MAAM;GACb,YAAY;EACd;EACA,OAAO,QAAQ,UAAU,MAAM,OAAO,WAAW;CACnD;AACF"}
@@ -11,6 +11,14 @@ export declare const isStackOverflow: (e: unknown) => boolean;
11
11
  * propagate.
12
12
  */
13
13
  export declare const run: <S extends State<any>, A>(step: (state: S) => A, state: S) => A | Fail;
14
+ /**
15
+ * Runs a compiled step with `state.compiledRun` set, so that the
16
+ * interpreted steps it calls skip building the failures it throws away
17
+ * (#82): directly when the step guards against call-stack overflows itself
18
+ * (the JIT's), else under {@link run}. The flag is restored however the
19
+ * step ends, a throw included, since the state may be the caller's.
20
+ */
21
+ export declare const runCompiled: <S extends State<any>, A>(step: (state: S) => A, guarded: boolean, state: S) => A | Fail;
14
22
  /**
15
23
  * Records the `TooDeep` failure of a call-stack overflow. The JIT's
16
24
  * generated entry catches overflows itself, with this, so that the runners
@@ -1 +1 @@
1
- {"version":3,"file":"stack.d.ts","names":[],"sources":["../../src/internal/stack.ts"],"mappings":";;;;;;qBAoBa,kBAAmB;;;;;;qBAanB,MAAO,UAAU,YAAY,GAAG,OAAO,OAAO,MAAM,GAAG,OAAO,MAAI,IAAI;;;;;;qBActE,UAAW,OAAO,eAAa"}
1
+ {"version":3,"file":"stack.d.ts","names":[],"sources":["../../src/internal/stack.ts"],"mappings":";;;;;;qBAoBa,kBAAmB;;;;;;qBAanB,MAAO,UAAU,YAAY,GAAG,OAAO,OAAO,MAAM,GAAG,OAAO,MAAI,IAAI;;;;;;;;qBAgBtE,cAAe,UAAU,YAAY,GAAG,OAAO,OAAO,MAAM,GAAG,kBAAkB,OAAO,MAAI,IAAI;;;;;;qBAehG,UAAW,OAAO,eAAa"}
@@ -31,11 +31,27 @@ const run = (step, state) => {
31
31
  }
32
32
  };
33
33
  /**
34
+ * Runs a compiled step with `state.compiledRun` set, so that the
35
+ * interpreted steps it calls skip building the failures it throws away
36
+ * (#82): directly when the step guards against call-stack overflows itself
37
+ * (the JIT's), else under {@link run}. The flag is restored however the
38
+ * step ends, a throw included, since the state may be the caller's.
39
+ */
40
+ const runCompiled = (step, guarded, state) => {
41
+ const outer = state.compiledRun;
42
+ state.compiledRun = true;
43
+ try {
44
+ return guarded ? step(state) : run(step, state);
45
+ } finally {
46
+ state.compiledRun = outer;
47
+ }
48
+ };
49
+ /**
34
50
  * Records the `TooDeep` failure of a call-stack overflow. The JIT's
35
51
  * generated entry catches overflows itself, with this, so that the runners
36
52
  * can call it without {@link run}.
37
53
  */
38
54
  const tooDeep = (state) => state.failMessage("Cut", "TooDeep", tooDeepMessage);
39
- export { isStackOverflow, run, tooDeep };
55
+ export { isStackOverflow, run, runCompiled, tooDeep };
40
56
 
41
57
  //# sourceMappingURL=stack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"stack.js","names":[],"sources":["../../src/internal/stack.ts"],"sourcesContent":["/**\n * Call-stack overflows.\n *\n * The interpreter and the compiled backends recurse once (or more) per\n * nesting level of a recursive grammar, so deeply nested input, such as\n * thousands of `{`, can exhaust the call stack. The runners catch the\n * engine's overflow error and report a `TooDeep` failure instead, keeping\n * their `Result` contract on untrusted input.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type { Fail, State } from \"../Input.js\"\n\n/** The message of a `TooDeep` failure. */\nconst tooDeepMessage = \"input is nested too deeply: parsing exhausted the call stack\"\n\n/**\n * Whether `e` is the engine's call-stack overflow: a `RangeError` in V8\n * and JavaScriptCore, an `InternalError` (\"too much recursion\") in\n * SpiderMonkey.\n */\nexport const isStackOverflow = (e: unknown): boolean =>\n (e instanceof RangeError && /call stack/i.test(e.message)) ||\n (Predicate.hasProperty(e, \"name\") &&\n Predicate.hasProperty(e, \"message\") &&\n e.name === \"InternalError\" &&\n Predicate.isString(e.message) &&\n /recursion/i.test(e.message))\n\n/**\n * Runs `step`, turning a call-stack overflow into an unrecoverable\n * `TooDeep` failure at the offset parsing had reached. Other exceptions\n * propagate.\n */\nexport const run = <S extends State<any>, A>(step: (state: S) => A, state: S): A | Fail => {\n try {\n return step(state)\n } catch (e) {\n if (!isStackOverflow(e)) throw e\n return tooDeep(state)\n }\n}\n\n/**\n * Records the `TooDeep` failure of a call-stack overflow. The JIT's\n * generated entry catches overflows itself, with this, so that the runners\n * can call it without {@link run}.\n */\nexport const tooDeep = (state: State<any>): Fail => state.failMessage(\"Cut\", \"TooDeep\", tooDeepMessage)\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,iBAAiB;;;;;;AAOvB,MAAa,mBAAmB,MAC7B,aAAa,cAAc,cAAc,KAAK,EAAE,OAAO,KACvD,UAAU,YAAY,GAAG,MAAM,KAC9B,UAAU,YAAY,GAAG,SAAS,KAClC,EAAE,SAAS,mBACX,UAAU,SAAS,EAAE,OAAO,KAC5B,aAAa,KAAK,EAAE,OAAO;;;;;;AAO/B,MAAa,OAAgC,MAAuB,UAAuB;CACzF,IAAI;EACF,OAAO,KAAK,KAAK;CACnB,SAAS,GAAG;EACV,IAAI,CAAC,gBAAgB,CAAC,GAAG,MAAM;EAC/B,OAAO,QAAQ,KAAK;CACtB;AACF;;;;;;AAOA,MAAa,WAAW,UAA4B,MAAM,YAAY,OAAO,WAAW,cAAc"}
1
+ {"version":3,"file":"stack.js","names":[],"sources":["../../src/internal/stack.ts"],"sourcesContent":["/**\n * Call-stack overflows.\n *\n * The interpreter and the compiled backends recurse once (or more) per\n * nesting level of a recursive grammar, so deeply nested input, such as\n * thousands of `{`, can exhaust the call stack. The runners catch the\n * engine's overflow error and report a `TooDeep` failure instead, keeping\n * their `Result` contract on untrusted input.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type { Fail, State } from \"../Input.js\"\n\n/** The message of a `TooDeep` failure. */\nconst tooDeepMessage = \"input is nested too deeply: parsing exhausted the call stack\"\n\n/**\n * Whether `e` is the engine's call-stack overflow: a `RangeError` in V8\n * and JavaScriptCore, an `InternalError` (\"too much recursion\") in\n * SpiderMonkey.\n */\nexport const isStackOverflow = (e: unknown): boolean =>\n (e instanceof RangeError && /call stack/i.test(e.message)) ||\n (Predicate.hasProperty(e, \"name\") &&\n Predicate.hasProperty(e, \"message\") &&\n e.name === \"InternalError\" &&\n Predicate.isString(e.message) &&\n /recursion/i.test(e.message))\n\n/**\n * Runs `step`, turning a call-stack overflow into an unrecoverable\n * `TooDeep` failure at the offset parsing had reached. Other exceptions\n * propagate.\n */\nexport const run = <S extends State<any>, A>(step: (state: S) => A, state: S): A | Fail => {\n try {\n return step(state)\n } catch (e) {\n if (!isStackOverflow(e)) throw e\n return tooDeep(state)\n }\n}\n\n/**\n * Runs a compiled step with `state.compiledRun` set, so that the\n * interpreted steps it calls skip building the failures it throws away\n * (#82): directly when the step guards against call-stack overflows itself\n * (the JIT's), else under {@link run}. The flag is restored however the\n * step ends, a throw included, since the state may be the caller's.\n */\nexport const runCompiled = <S extends State<any>, A>(step: (state: S) => A, guarded: boolean, state: S): A | Fail => {\n const outer = state.compiledRun\n state.compiledRun = true\n try {\n return guarded ? step(state) : run(step, state)\n } finally {\n state.compiledRun = outer\n }\n}\n\n/**\n * Records the `TooDeep` failure of a call-stack overflow. The JIT's\n * generated entry catches overflows itself, with this, so that the runners\n * can call it without {@link run}.\n */\nexport const tooDeep = (state: State<any>): Fail => state.failMessage(\"Cut\", \"TooDeep\", tooDeepMessage)\n"],"mappings":";;;;;;;;;;;;AAaA,MAAM,iBAAiB;;;;;;AAOvB,MAAa,mBAAmB,MAC7B,aAAa,cAAc,cAAc,KAAK,EAAE,OAAO,KACvD,UAAU,YAAY,GAAG,MAAM,KAC9B,UAAU,YAAY,GAAG,SAAS,KAClC,EAAE,SAAS,mBACX,UAAU,SAAS,EAAE,OAAO,KAC5B,aAAa,KAAK,EAAE,OAAO;;;;;;AAO/B,MAAa,OAAgC,MAAuB,UAAuB;CACzF,IAAI;EACF,OAAO,KAAK,KAAK;CACnB,SAAS,GAAG;EACV,IAAI,CAAC,gBAAgB,CAAC,GAAG,MAAM;EAC/B,OAAO,QAAQ,KAAK;CACtB;AACF;;;;;;;;AASA,MAAa,eAAwC,MAAuB,SAAkB,UAAuB;CACnH,MAAM,QAAQ,MAAM;CACpB,MAAM,cAAc;CACpB,IAAI;EACF,OAAO,UAAU,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK;CAChD,UAAU;EACR,MAAM,cAAc;CACtB;AACF;;;;;;AAOA,MAAa,WAAW,UAA4B,MAAM,YAAY,OAAO,WAAW,cAAc"}
@@ -86,9 +86,16 @@ export declare const countTokens: (state: State<Input>, start: number, end: numb
86
86
  /**
87
87
  * The first index at or after `from` of any of `needles` within
88
88
  * `[from, state.end)`, or -1. The state remembers, under `needles`, where
89
- * each one next occurs (`[from, at]` at `2 * i`), so successive searches
90
- * forwards over one input search each needle once per occurrence rather
91
- * than once per call (as `nextStop` does for `takeTill`).
89
+ * each one next occurs (`[from, at, end]` at `3 * i`), so successive
90
+ * searches forwards over one input search each needle once per occurrence
91
+ * rather than once per call (as `nextStop` does for `takeTill`).
92
+ *
93
+ * A remembered answer is used only where it still holds: an occurrence, when
94
+ * the search starts between where it was searched from and where it was
95
+ * found, and it still fits before the end; "not found", when the search
96
+ * starts no earlier and the end is no further than the end that search ran
97
+ * to (a parser may narrow `state.end` for a while, and `reset` widens it
98
+ * again, so a miss within a narrower end says nothing about a wider one).
92
99
  */
93
100
  export declare const indexOfAny: (state: State<Input>, needles: ReadonlyArray<Input>, from: number) => number;
94
101
  /** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","names":[],"sources":["../../src/internal/tokens.ts"],"mappings":";;iBAMiB;;WAEN,OAAO;;WAEP,QAAQ;;WAER;;;iBAIM;WACN;WACA;WACA;;;qBAQE,eAAgB;;;;;;qBAiGhB;;;;;qBAMA,qBAAsB,WAAW,sBAC5C,cACA,GAAG,GACH,SAAS,6CACR;;;;;;qBAiBU,UAAW,cAAc,6BAAmC;;;;;iBAgCxD;WACN,WAAW;WACX,SAAS;WACT;;;qBAuBE,kBAAmB,KAAK;qBASxB,aAAc,iBAAe;;;;;;qBAmB7B,iBAAkB,OAAO,MAAM,QAAQ;;;;;qBAqBvC;qBACA;qBAEA,SAAU,OAAO,MAAM,QAAQ,GAAG,YAAY;;iBAgC1C,gBAAgB;;WAEtB;;;;;;;;;;;;qBA8BE,OAAQ,OAAO,MAAM,QAAQ,GAAG,YAAY,iBAAiB,gBAAc;;iBAqDvE;WACN;WACA;;;qBAIE,UAAW,OAAO,MAAM,QAAQ,eAAe,cAAY;;qBAmB3D,cAAe,OAAO,MAAM,QAAQ,eAAe;;;;;;;;qBAoBnD,aAAc,OAAO,MAAM,QAAQ,SAAS,cAAc,QAAQ;;qBAwBlE,UAAW,OAAO,MAAM,QAAQ,QAAQ,OAAO;;;;;;qBA6C/C,eAAgB,OAAO,MAAM,QAAQ,KAAK,OAAO"}
1
+ {"version":3,"file":"tokens.d.ts","names":[],"sources":["../../src/internal/tokens.ts"],"mappings":";;iBAMiB;;WAEN,OAAO;;WAEP,QAAQ;;WAER;;;iBAIM;WACN;WACA;WACA;;;qBAQE,eAAgB;;;;;;qBAiGhB;;;;;qBAMA,qBAAsB,WAAW,sBAC5C,cACA,GAAG,GACH,SAAS,6CACR;;;;;;qBAiBU,UAAW,cAAc,6BAAmC;;;;;iBAgCxD;WACN,WAAW;WACX,SAAS;WACT;;;qBAuBE,kBAAmB,KAAK;qBASxB,aAAc,iBAAe;;;;;;qBAmB7B,iBAAkB,OAAO,MAAM,QAAQ;;;;;qBAqBvC;qBACA;qBAEA,SAAU,OAAO,MAAM,QAAQ,GAAG,YAAY;;iBAgC1C,gBAAgB;;WAEtB;;;;;;;;;;;;qBA8BE,OAAQ,OAAO,MAAM,QAAQ,GAAG,YAAY,iBAAiB,gBAAc;;iBAqDvE;WACN;WACA;;;qBAIE,UAAW,OAAO,MAAM,QAAQ,eAAe,cAAY;;qBAmB3D,cAAe,OAAO,MAAM,QAAQ,eAAe;;;;;;;;;;;;;;;qBA2BnD,aAAc,OAAO,MAAM,QAAQ,SAAS,cAAc,QAAQ;;qBA2BlE,UAAW,OAAO,MAAM,QAAQ,QAAQ,OAAO;;;;;;qBA6C/C,eAAgB,OAAO,MAAM,QAAQ,KAAK,OAAO"}
@@ -313,26 +313,39 @@ const countTokens = (state, start, end) => {
313
313
  /**
314
314
  * The first index at or after `from` of any of `needles` within
315
315
  * `[from, state.end)`, or -1. The state remembers, under `needles`, where
316
- * each one next occurs (`[from, at]` at `2 * i`), so successive searches
317
- * forwards over one input search each needle once per occurrence rather
318
- * than once per call (as `nextStop` does for `takeTill`).
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).
319
326
  */
320
327
  const indexOfAny = (state, needles, from) => {
321
328
  const searches = state.searches ??= /* @__PURE__ */ new Map();
322
329
  let memo = searches.get(needles);
323
330
  if (memo === void 0) {
324
- memo = needles.flatMap(() => [-1, -1]);
331
+ memo = needles.flatMap(() => [
332
+ -1,
333
+ -1,
334
+ -1
335
+ ]);
325
336
  searches.set(needles, memo);
326
337
  }
327
338
  let best = -1;
328
339
  for (let i = 0; i < needles.length; i++) {
329
- const known = memo[2 * i] ?? -1;
330
- let at = memo[2 * i + 1] ?? -1;
340
+ const known = memo[3 * i] ?? -1;
341
+ let at = memo[3 * i + 1] ?? -1;
342
+ const searchedTo = memo[3 * i + 2] ?? -1;
331
343
  const needle = needles[i] ?? "";
332
- if (known < 0 || from < known || at >= 0 && (at < from || at > state.end - needle.length)) {
344
+ if (known < 0 || from < known || (at >= 0 ? at < from || at > state.end - needle.length : state.end > searchedTo)) {
333
345
  at = indexOf(state, needle, from);
334
- memo[2 * i] = from;
335
- memo[2 * i + 1] = at;
346
+ memo[3 * i] = from;
347
+ memo[3 * i + 1] = at;
348
+ memo[3 * i + 2] = state.end;
336
349
  }
337
350
  if (at >= 0 && (best < 0 || at < best)) best = at;
338
351
  }
@@ -1 +1 @@
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]` at `2 * i`), so successive searches\n * forwards over one input search each needle once per occurrence rather\n * than once per call (as `nextStop` does for `takeTill`).\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])\n searches.set(needles, memo)\n }\n let best = -1\n for (let i = 0; i < needles.length; i++) {\n const known = memo[2 * i] ?? -1\n let at = memo[2 * i + 1] ?? -1\n const needle = needles[i] ?? \"\"\n // Searched again when the input's end moved before a remembered occurrence\n if (known < 0 || from < known || (at >= 0 && (at < from || at > state.end - needle.length))) {\n at = indexOf(state, needle, from)\n memo[2 * i] = from\n memo[2 * i + 1] = at\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":";;;;AAsBA,MAAM,WAAW,MAAoC,UAAU,gBAAgB,CAAC,KAAK,UAAU,SAAS,GAAG,YAAY;AAEvH,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,GAExB,OAAO;CAET,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,GAExB,OAAO;CAET,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;CAEhD,MAAM,SAAS;CAIf,OAAO,sBAAsB;CAC7B,IAAI,WAAW,KAAA,GAAW,OAAO,mBAAmB;CACpD,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;EAElF,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;CAElD,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;GAEN,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;GAEN,MAAM,IAAK,MAAM,MAAqB;GACtC,IAAI,EAAE,QAAQ,KAAK,CAAC,MAAM,QAAQ,OAAO;GACzC,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;EACA,SAAS;GAEP,MAAM,IAAK,MAAM,MAAiC;GAClD,IAAI,EAAE,QAAQ,MAAM,CAAC,MAAM,QAAQ,OAAO;GAC1C,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;CACF;AACF;;AASA,IAAM,aAAN,MAAoC;CAClC,SAAS;CACT,QAAQ;CACR,SAAS;AACX;AAEA,MAAM,wBAAwB,IAAI,WAAW;;AAG7C,MAAM,aAAa,QAAgB,OAAe,WAA6B;CAC7E,QAAQ,SAAS;CACjB,QAAQ,QAAQ;CAChB,QAAQ,SAAS;CACjB,OAAO;AACT;;;;;;;;;;;AAYA,MAAa,QAAQ,OAAqB,GAAe,QAAiB,QAAyB;CACjG,IAAI,IAAI,MAAM;CACd,MAAM,MAAM,MAAM;CAClB,IAAI,QAAQ;CACZ,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GAEN,MAAM,IAAI,MAAM;GAChB,MAAM,OAAO,EAAE,UAAU;GACzB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,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,UAAU,GAAG,OAAO,IAAI;KAC7D,MAAM,KAAK,YAAY,GAAG,CAAC;KAC3B,IAAI,KAAK,EAAE,MAAM,QAAQ;KACzB,KAAK,KAAK,QAAS,IAAI;IACzB;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;EACA,KAAK,GAAG;GAEN,MAAM,QAAQ,MAAM;GACpB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,IAAI,KAAK,MAAM,EAAE,MAAM,QAAQ;IAC/B;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;EACA,SAAS;GAEP,MAAM,MAAM,MAAM;GAClB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,IAAI,KAAK,IAAI,EAAE,MAAM,QAAQ;IAC7B;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;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;CAEA,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;CAExC,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;;;;;;;;AASA,MAAa,cAAc,OAAqB,SAA+B,SAAyB;CACtG,MAAM,WAAY,MAAM,6BAAa,IAAI,IAAI;CAC7C,IAAI,OAAO,SAAS,IAAI,OAAO;CAC/B,IAAI,SAAS,KAAA,GAAW;EACtB,OAAO,QAAQ,cAAc,CAAC,IAAI,EAAE,CAAC;EACrC,SAAS,IAAI,SAAS,IAAI;CAC5B;CACA,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,QAAQ,KAAK,IAAI,MAAM;EAC7B,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM;EAC5B,MAAM,SAAS,QAAQ,MAAM;EAE7B,IAAI,QAAQ,KAAK,OAAO,SAAU,MAAM,MAAM,KAAK,QAAQ,KAAK,MAAM,MAAM,OAAO,SAAU;GAC3F,KAAK,QAAQ,OAAO,QAAQ,IAAI;GAChC,KAAK,IAAI,KAAK;GACd,KAAK,IAAI,IAAI,KAAK;EACpB;EACA,IAAI,MAAM,MAAM,OAAO,KAAK,KAAK,OAAO,OAAO;CACjD;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;GAEN,MAAM,IAAK,MAAM,MAAiB,QAAQ,QAAkB,IAAI;GAChE,OAAO,KAAK,OAAO,IAAI;EACzB;EACA,KAAK,GAAG;GAEN,MAAM,MAAM,MAAM;GAElB,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;GAEP,MAAM,MAAM,MAAM;GAElB,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;GAEN,MAAM,IAAI,MAAM;GAEhB,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;GAEN,MAAM,IAAI,MAAM;GAEhB,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;GAEP,MAAM,IAAI,MAAM;GAEhB,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"}