@thomasfosterau/effect-parse 0.4.1 → 0.5.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 (143) hide show
  1. package/README.md +37 -13
  2. package/dist/Ascii.d.ts +11 -4
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +7 -1
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts.map +1 -1
  7. package/dist/Binary.js +64 -35
  8. package/dist/Binary.js.map +1 -1
  9. package/dist/Bits.d.ts.map +1 -1
  10. package/dist/Bits.js +7 -4
  11. package/dist/Bits.js.map +1 -1
  12. package/dist/Compiler.d.ts +74 -2
  13. package/dist/Compiler.d.ts.map +1 -1
  14. package/dist/Compiler.js +78 -1
  15. package/dist/Compiler.js.map +1 -1
  16. package/dist/Expression.d.ts.map +1 -1
  17. package/dist/Expression.js +86 -74
  18. package/dist/Expression.js.map +1 -1
  19. package/dist/Input.d.ts +37 -4
  20. package/dist/Input.d.ts.map +1 -1
  21. package/dist/Input.js +42 -0
  22. package/dist/Input.js.map +1 -1
  23. package/dist/Nom.d.ts +5 -15
  24. package/dist/Nom.d.ts.map +1 -1
  25. package/dist/Nom.js.map +1 -1
  26. package/dist/ParseError.d.ts.map +1 -1
  27. package/dist/ParseError.js.map +1 -1
  28. package/dist/Parser.d.ts +366 -26
  29. package/dist/Parser.d.ts.map +1 -1
  30. package/dist/Parser.js +390 -19
  31. package/dist/Parser.js.map +1 -1
  32. package/dist/ParserSchema.js +1 -1
  33. package/dist/ParserStream.d.ts +3 -2
  34. package/dist/ParserStream.d.ts.map +1 -1
  35. package/dist/ParserStream.js +13 -9
  36. package/dist/ParserStream.js.map +1 -1
  37. package/dist/Syntax.d.ts +23 -5
  38. package/dist/Syntax.d.ts.map +1 -1
  39. package/dist/Syntax.js.map +1 -1
  40. package/dist/Text.d.ts.map +1 -1
  41. package/dist/Text.js +9 -9
  42. package/dist/Text.js.map +1 -1
  43. package/dist/Token.d.ts +55 -10
  44. package/dist/Token.d.ts.map +1 -1
  45. package/dist/Token.js +59 -21
  46. package/dist/Token.js.map +1 -1
  47. package/dist/internal/compiler/closure.d.ts.map +1 -1
  48. package/dist/internal/compiler/closure.js +257 -97
  49. package/dist/internal/compiler/closure.js.map +1 -1
  50. package/dist/internal/compiler/entries.d.ts +3 -1
  51. package/dist/internal/compiler/entries.d.ts.map +1 -1
  52. package/dist/internal/compiler/entries.js +3 -2
  53. package/dist/internal/compiler/entries.js.map +1 -1
  54. package/dist/internal/compiler/first.d.ts.map +1 -1
  55. package/dist/internal/compiler/first.js +7 -1
  56. package/dist/internal/compiler/first.js.map +1 -1
  57. package/dist/internal/compiler/graph.d.ts +17 -0
  58. package/dist/internal/compiler/graph.d.ts.map +1 -0
  59. package/dist/internal/compiler/graph.js +56 -0
  60. package/dist/internal/compiler/graph.js.map +1 -0
  61. package/dist/internal/compiler/jit.d.ts +5 -0
  62. package/dist/internal/compiler/jit.d.ts.map +1 -1
  63. package/dist/internal/compiler/jit.js +185 -96
  64. package/dist/internal/compiler/jit.js.map +1 -1
  65. package/dist/internal/compiler/registry.d.ts +10 -2
  66. package/dist/internal/compiler/registry.d.ts.map +1 -1
  67. package/dist/internal/compiler/registry.js.map +1 -1
  68. package/dist/internal/compiler/search.d.ts +32 -0
  69. package/dist/internal/compiler/search.d.ts.map +1 -0
  70. package/dist/internal/compiler/search.js +68 -0
  71. package/dist/internal/compiler/search.js.map +1 -0
  72. package/dist/internal/compiler/sets.d.ts.map +1 -1
  73. package/dist/internal/compiler/sets.js +1 -1
  74. package/dist/internal/compiler/sets.js.map +1 -1
  75. package/dist/internal/compiler/wasm.d.ts +8 -0
  76. package/dist/internal/compiler/wasm.d.ts.map +1 -0
  77. package/dist/internal/compiler/wasm.js +2769 -0
  78. package/dist/internal/compiler/wasm.js.map +1 -0
  79. package/dist/internal/compiler/wasmAsm.d.ts +199 -0
  80. package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
  81. package/dist/internal/compiler/wasmAsm.js +427 -0
  82. package/dist/internal/compiler/wasmAsm.js.map +1 -0
  83. package/dist/internal/entries.d.ts +3 -1
  84. package/dist/internal/entries.d.ts.map +1 -1
  85. package/dist/internal/entries.js.map +1 -1
  86. package/dist/internal/node.d.ts +58 -2
  87. package/dist/internal/node.d.ts.map +1 -1
  88. package/dist/internal/node.js +13 -3
  89. package/dist/internal/node.js.map +1 -1
  90. package/dist/internal/numbers.d.ts.map +1 -1
  91. package/dist/internal/numbers.js.map +1 -1
  92. package/dist/internal/run.d.ts +12 -0
  93. package/dist/internal/run.d.ts.map +1 -1
  94. package/dist/internal/run.js +51 -11
  95. package/dist/internal/run.js.map +1 -1
  96. package/dist/internal/stack.d.ts +6 -0
  97. package/dist/internal/stack.d.ts.map +1 -1
  98. package/dist/internal/stack.js +8 -2
  99. package/dist/internal/stack.js.map +1 -1
  100. package/dist/internal/syntax.d.ts +4 -4
  101. package/dist/internal/syntax.d.ts.map +1 -1
  102. package/dist/internal/syntax.js +18 -10
  103. package/dist/internal/syntax.js.map +1 -1
  104. package/dist/internal/text.d.ts +32 -0
  105. package/dist/internal/text.d.ts.map +1 -1
  106. package/dist/internal/text.js +68 -14
  107. package/dist/internal/text.js.map +1 -1
  108. package/dist/internal/tokens.d.ts +13 -0
  109. package/dist/internal/tokens.d.ts.map +1 -1
  110. package/dist/internal/tokens.js +59 -39
  111. package/dist/internal/tokens.js.map +1 -1
  112. package/package.json +5 -4
  113. package/src/Ascii.ts +42 -9
  114. package/src/Binary.ts +151 -71
  115. package/src/Bits.ts +12 -6
  116. package/src/Compiler.ts +101 -10
  117. package/src/Expression.ts +94 -81
  118. package/src/Input.ts +65 -6
  119. package/src/Nom.ts +15 -5
  120. package/src/ParseError.ts +3 -0
  121. package/src/Parser.ts +678 -127
  122. package/src/ParserStream.ts +37 -18
  123. package/src/Syntax.ts +60 -36
  124. package/src/Text.ts +16 -15
  125. package/src/Token.ts +138 -29
  126. package/src/internal/compiler/closure.ts +362 -135
  127. package/src/internal/compiler/entries.ts +4 -2
  128. package/src/internal/compiler/first.ts +10 -0
  129. package/src/internal/compiler/graph.ts +68 -0
  130. package/src/internal/compiler/jit.ts +284 -154
  131. package/src/internal/compiler/registry.ts +10 -2
  132. package/src/internal/compiler/search.ts +68 -0
  133. package/src/internal/compiler/sets.ts +7 -3
  134. package/src/internal/compiler/wasm.ts +3203 -0
  135. package/src/internal/compiler/wasmAsm.ts +484 -0
  136. package/src/internal/entries.ts +8 -2
  137. package/src/internal/node.ts +54 -4
  138. package/src/internal/numbers.ts +3 -1
  139. package/src/internal/run.ts +71 -12
  140. package/src/internal/stack.ts +8 -1
  141. package/src/internal/syntax.ts +39 -18
  142. package/src/internal/text.ts +97 -9
  143. package/src/internal/tokens.ts +96 -14
@@ -1 +1 @@
1
- {"version":3,"file":"entries.js","names":[],"sources":["../../src/internal/entries.ts"],"sourcesContent":["/**\n * Building objects as `Object.fromEntries` does, without its array of\n * `[key, value]` pairs: the compilers use these when a parser maps a\n * repetition of pairs with `Object.fromEntries` (see `Parser.fromEntries`).\n */\n\nimport * as Predicate from \"effect/Predicate\"\n\n/** The built-in `Object.fromEntries`, which compiled parsers recognize. */\nexport const fromEntries: <K extends PropertyKey, V>(entries: Iterable<readonly [K, V]>) => { [P in K]: V } =\n Object.fromEntries as any\n\nconst objectPrototype = Object.prototype\n\n/**\n * Whether `o[key] = value` on a new plain object creates the same property\n * as `Object.fromEntries` (a writable, enumerable, configurable data\n * property): `key` is a string that `Object.prototype` has no property for,\n * so there is no setter (`__proto__`) or read-only property to run into.\n */\nexport const isPlainKey = (key: unknown): key is string =>\n Predicate.isString(key) && !Object.hasOwn(objectPrototype, key)\n\nconst define = (o: object, key: unknown, value: unknown): void => {\n Object.defineProperty(o, key as PropertyKey, { value, writable: true, enumerable: true, configurable: true })\n}\n\n/**\n * Adds an entry whose key is not plain to `o`, given the entries already\n * deferred. Keys that are objects may run code when converted to property\n * keys, which `Object.fromEntries` only does once every entry is parsed:\n * from the first such key on, entries are deferred to {@link flushEntries}.\n * Returns the deferred entries, if any.\n */\nexport const addEntry = (\n o: object,\n deferred: Array<unknown> | undefined,\n key: unknown,\n value: unknown\n): Array<unknown> | undefined => {\n if (deferred === undefined && !Predicate.isObjectOrArray(key) && !Predicate.isFunction(key)) {\n define(o, key, value)\n return undefined\n }\n if (deferred === undefined) deferred = []\n deferred.push(key, value)\n return deferred\n}\n\n/** Adds the deferred entries of {@link addEntry} to `o`, in order. */\nexport const flushEntries = (o: object, deferred: ReadonlyArray<unknown>): void => {\n for (let i = 0; i < deferred.length; i += 2) define(o, deferred[i], deferred[i + 1])\n}\n"],"mappings":";;;;;;;;AASA,MAAa,cACX,OAAO;AAET,MAAM,kBAAkB,OAAO;;;;;;;AAQ/B,MAAa,cAAc,QACzB,UAAU,SAAS,GAAG,KAAK,CAAC,OAAO,OAAO,iBAAiB,GAAG;AAEhE,MAAM,UAAU,GAAW,KAAc,UAAyB;CAChE,OAAO,eAAe,GAAG,KAAoB;EAAE;EAAO,UAAU;EAAM,YAAY;EAAM,cAAc;CAAK,CAAC;AAC9G;;;;;;;;AASA,MAAa,YACX,GACA,UACA,KACA,UAC+B;CAC/B,IAAI,aAAa,KAAA,KAAa,CAAC,UAAU,gBAAgB,GAAG,KAAK,CAAC,UAAU,WAAW,GAAG,GAAG;EAC3F,OAAO,GAAG,KAAK,KAAK;EACpB;CACF;CACA,IAAI,aAAa,KAAA,GAAW,WAAW,CAAC;CACxC,SAAS,KAAK,KAAK,KAAK;CACxB,OAAO;AACT;;AAGA,MAAa,gBAAgB,GAAW,aAA2C;CACjF,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,EAAE;AACrF"}
1
+ {"version":3,"file":"entries.js","names":[],"sources":["../../src/internal/entries.ts"],"sourcesContent":["/**\n * Building objects as `Object.fromEntries` does, without its array of\n * `[key, value]` pairs: the compilers use these when a parser maps a\n * repetition of pairs with `Object.fromEntries` (see `Parser.fromEntries`).\n */\n\nimport * as Predicate from \"effect/Predicate\"\n\ntype FromEntries = <K extends PropertyKey, V>(entries: Iterable<readonly [K, V]>) => { [P in K]: V }\n\n/** The built-in `Object.fromEntries`, which compiled parsers recognize. */\n// SAFETY: `Object.fromEntries` gives each `[key, value]` entry an own\n// property `key` holding `value`, so entries keyed by `K` build `{ [P in K]: V }`\nexport const fromEntries: FromEntries = Object.fromEntries as FromEntries\n\nconst objectPrototype = Object.prototype\n\n/**\n * Whether `o[key] = value` on a new plain object creates the same property\n * as `Object.fromEntries` (a writable, enumerable, configurable data\n * property): `key` is a string that `Object.prototype` has no property for,\n * so there is no setter (`__proto__`) or read-only property to run into.\n */\nexport const isPlainKey = (key: unknown): key is string =>\n Predicate.isString(key) && !Object.hasOwn(objectPrototype, key)\n\nconst define = (o: object, key: unknown, value: unknown): void => {\n // SAFETY: `Object.defineProperty` converts any key to a property key\n // (ToPropertyKey), as `Object.fromEntries` does; its `PropertyKey`\n // parameter type is narrower than what it accepts\n Object.defineProperty(o, key as PropertyKey, { value, writable: true, enumerable: true, configurable: true })\n}\n\n/**\n * Adds an entry whose key is not plain to `o`, given the entries already\n * deferred. Keys that are objects may run code when converted to property\n * keys, which `Object.fromEntries` only does once every entry is parsed:\n * from the first such key on, entries are deferred to {@link flushEntries}.\n * Returns the deferred entries, if any.\n */\nexport const addEntry = (\n o: object,\n deferred: Array<unknown> | undefined,\n key: unknown,\n value: unknown\n): Array<unknown> | undefined => {\n if (deferred === undefined && !Predicate.isObjectOrArray(key) && !Predicate.isFunction(key)) {\n define(o, key, value)\n return undefined\n }\n if (deferred === undefined) deferred = []\n deferred.push(key, value)\n return deferred\n}\n\n/** Adds the deferred entries of {@link addEntry} to `o`, in order. */\nexport const flushEntries = (o: object, deferred: ReadonlyArray<unknown>): void => {\n for (let i = 0; i < deferred.length; i += 2) define(o, deferred[i], deferred[i + 1])\n}\n"],"mappings":";;;;;;;;AAaA,MAAa,cAA2B,OAAO;AAE/C,MAAM,kBAAkB,OAAO;;;;;;;AAQ/B,MAAa,cAAc,QACzB,UAAU,SAAS,GAAG,KAAK,CAAC,OAAO,OAAO,iBAAiB,GAAG;AAEhE,MAAM,UAAU,GAAW,KAAc,UAAyB;CAIhE,OAAO,eAAe,GAAG,KAAoB;EAAE;EAAO,UAAU;EAAM,YAAY;EAAM,cAAc;CAAK,CAAC;AAC9G;;;;;;;;AASA,MAAa,YACX,GACA,UACA,KACA,UAC+B;CAC/B,IAAI,aAAa,KAAA,KAAa,CAAC,UAAU,gBAAgB,GAAG,KAAK,CAAC,UAAU,WAAW,GAAG,GAAG;EAC3F,OAAO,GAAG,KAAK,KAAK;EACpB;CACF;CACA,IAAI,aAAa,KAAA,GAAW,WAAW,CAAC;CACxC,SAAS,KAAK,KAAK,KAAK;CACxB,OAAO;AACT;;AAGA,MAAa,gBAAgB,GAAW,aAA2C;CACjF,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,EAAE;AACrF"}
@@ -20,6 +20,12 @@ interface Bounds {
20
20
  * encoding of a `Text` parser.
21
21
  */
22
22
  type Enc = Encoding<any> | undefined;
23
+ /**
24
+ * A user callback building a value from parser outputs: `map`, `mapOrFail`
25
+ * (one output), `mapSpan` (an output and its span), `zipWith` and `seqWith`
26
+ * (one argument per parser).
27
+ */
28
+ type Mapper = (...values: Array<any>) => unknown;
23
29
  export type Node = {
24
30
  readonly _tag: "Opaque";
25
31
  readonly step: Step;
@@ -65,9 +71,17 @@ export type Node = {
65
71
  readonly _tag: "TakeUntil";
66
72
  readonly literal: Input;
67
73
  readonly encoding: Enc;
74
+ } & Bounds) | ({
75
+ readonly _tag: "TakeUntilAny";
76
+ readonly literals: ReadonlyArray<Input>;
77
+ readonly encoding: Enc;
68
78
  } & Bounds) | {
69
79
  readonly _tag: "Rest";
70
80
  readonly encoding: Enc;
81
+ } | {
82
+ readonly _tag: "Fixed";
83
+ readonly size: number;
84
+ readonly read: (bytes: Uint8Array, offset: number, state: State<Uint8Array>) => unknown;
71
85
  } | {
72
86
  readonly _tag: "RestLen";
73
87
  } | {
@@ -91,7 +105,7 @@ export type Node = {
91
105
  } | {
92
106
  readonly _tag: "Map";
93
107
  readonly self: P;
94
- readonly f: (a: any) => unknown;
108
+ readonly f: Mapper;
95
109
  } | {
96
110
  readonly _tag: "As";
97
111
  readonly self: P;
@@ -108,6 +122,12 @@ export type Node = {
108
122
  readonly _tag: "FilterMap";
109
123
  readonly self: P;
110
124
  readonly f: (a: any) => Option.Option<unknown>;
125
+ } |
126
+ /** `mapOrFail`: `f` returns `Fail` to reject the value. */
127
+ {
128
+ readonly _tag: "MapOrFail";
129
+ readonly self: P;
130
+ readonly f: Mapper;
111
131
  } | {
112
132
  readonly _tag: "Filter";
113
133
  readonly self: P;
@@ -129,6 +149,18 @@ export type Node = {
129
149
  } | {
130
150
  readonly _tag: "WithSpan";
131
151
  readonly self: P;
152
+ } |
153
+ /** `mapSpan`: `f(output, start, end)`. */
154
+ {
155
+ readonly _tag: "MapSpan";
156
+ readonly self: P;
157
+ readonly f: Mapper;
158
+ } |
159
+ /** `withFastPath`: `fast` runs first in compiled code; `Defer` runs `self`. */
160
+ {
161
+ readonly _tag: "FastPath";
162
+ readonly self: P;
163
+ readonly fast: Step;
132
164
  } | {
133
165
  readonly _tag: "Mode";
134
166
  readonly self: P;
@@ -142,6 +174,9 @@ export type Node = {
142
174
  readonly _tag: "Expected";
143
175
  readonly self: P;
144
176
  readonly description: string;
177
+ } | {
178
+ readonly _tag: "Quiet";
179
+ readonly self: P;
145
180
  } | {
146
181
  readonly _tag: "MapError";
147
182
  readonly self: P;
@@ -174,7 +209,13 @@ export type Node = {
174
209
  readonly _tag: "ZipWith";
175
210
  readonly self: P;
176
211
  readonly that: P;
177
- readonly f: (a: any, b: any) => unknown;
212
+ readonly f: Mapper;
213
+ } |
214
+ /** `seqWith`: `f` receives one output per parser. */
215
+ {
216
+ readonly _tag: "SeqWith";
217
+ readonly parsers: ReadonlyArray<P>;
218
+ readonly f: Mapper;
178
219
  } | {
179
220
  readonly _tag: "Alt";
180
221
  readonly parsers: ReadonlyArray<P>;
@@ -210,6 +251,17 @@ export type Node = {
210
251
  readonly separator: P;
211
252
  readonly op: (l: any, s: any, r: any) => unknown;
212
253
  readonly right: boolean;
254
+ } |
255
+ /**
256
+ * A combinator whose algorithm the compilers don't know (`Expression.make`,
257
+ * `permutation`): `build` makes its step from the steps of `parsers`. The
258
+ * interpreter passes their own steps; the closure compiler (and the JIT,
259
+ * through it) passes their compiled steps, so the parsers inside compile.
260
+ */
261
+ {
262
+ readonly _tag: "Combinator";
263
+ readonly parsers: ReadonlyArray<P>;
264
+ readonly build: (steps: ReadonlyArray<Step>) => Step;
213
265
  } | {
214
266
  readonly _tag: "Service";
215
267
  } | {
@@ -240,8 +292,12 @@ export type Tag = Node["_tag"];
240
292
  export type NodeOf<T extends Tag> = Extract<Node, {
241
293
  readonly _tag: T;
242
294
  }>;
295
+ /** What a fast path returns to leave the input to its grammar (`Parser.Defer`). */
296
+ export declare const Defer: unique symbol;
243
297
  /** Where a parser's description is stored. */
244
298
  export declare const NodeId: unique symbol;
299
+ /** The description recorded for a parser, if it has one. */
300
+ export declare const describedNode: (p: ParserLike) => Node | undefined;
245
301
  /** The description of a parser: `Opaque` when it has none. */
246
302
  export declare const nodeOf: (p: ParserLike) => Node;
247
303
  /** Normalizes a range, as `repeat`, `takeWhile`, ... do. */
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","names":[],"sources":["../../src/internal/node.ts"],"mappings":";;;;;iBAeiB;WACN,OAAO,OAAO;WACd;;KAGN,IAAI;KACJ,QAAQ,OAAO;;UAGV;WACC;WACA;;;;;;;KAQN,MAAM;YAEC;WAEG;WAAyB,MAAM;;WAC/B;WAA0B;;WAC1B;WAAuB;;WACvB;WAAuB,MAAM;;WAC7B;;WACA;;WACA;WAA0B,eAAe;;WAEzC;WAAsB,UAAU;;WAChC;WAA0B,SAAS;WAAgB;WAA4B,UAAU;;WACzF;WAAwB;WAAuB;WAA0B,UAAU;;WACnF;WAAuB;WAAwB,UAAU;;WACxD;WAA4B;WAAuB;WAA0B,UAAU;IAAQ;WAC/F;WAA4B,SAAS;WAAgB,UAAU;IAAQ;WACxE;WAAuB,UAAU;;WACjC;;WACA;WAAiC,UAAU;;WAC3C;WAA6B,UAAU;;WACvC;WAAsB,UAAU;;WAEhC;WACA,QAAQ;;WAER;WACA,QAAQ;;WAER;WACA,UAAU;;WAGV;WAAsB,MAAM;WAAY,IAAI;;WAC5C;WAAqB,MAAM;WAAY;;WACvC;WAAsB,MAAM;WAAY,IAAI;;WAC5C;WAAyB,MAAM;WAAY,IAAI,WAAW,OAAO;;WACjE;WAA4B,MAAM;WAAY,IAAI,WAAW,OAAO;;WACpE;WAAyB,MAAM;WAAY,YAAY;;WACvD;WAA0B,MAAM;WAAY,IAAI,WAAW;;WAE3D;WAAwB,MAAM;WAAY,UAAU;;WACpD;WAA4B,MAAM;;WAClC;WAAuB,MAAM;;WAC7B;WAA2B,MAAM;;WAEjC;WAAuB,MAAM;WAAY,MAAM;WAAkB,IAAI;;WACrE;WAA0B,MAAM;WAAY;;WAC5C;WAA2B,MAAM;WAAY;;WAC7C;WAA2B,MAAM;;WACjC;WAAyB,MAAM;;WAE/B;WAAsB,MAAM;;WAC5B;WAAgC,MAAM;WAAY;;WAClD;WAAuB,MAAM;;WAC7B;WAAsB,MAAM;;WAG5B;WACA,SAAS,cAAc;;WAEvB;;WAEA;WAAyB,MAAM;WAAgC,SAAS,cAAc;;WACtF;WAA0B,MAAM;WAAY,MAAM;WAAY,IAAI,QAAQ;;WAE1E;WAAsB,SAAS,cAAc;;WAE7C;WACA,UAAU;;WAEV,OAAO,SAAS,OAAO,aAAa;WACpC,WAAW;WACX,SAAS,aAAa;;WAGrB;WAAyB,MAAM;IAAM;WAEtC;WACA,MAAM;WACN;WACA,IAAI,UAAU;;WAEd,SAAS;WACT;IACP;WACQ;WAA6B,MAAM;WAAY,KAAK;IAAM;WAC1D;WAA4B,MAAM;WAAY,WAAW;IAAM;WAEhE;WACA,MAAM;WACN,WAAW;WACX,KAAK,QAAQ,QAAQ;WACrB;;WAGA;;WACA;WAA0B,MAAM;;WAChC;WAA8B,MAAM;WAAY,SAAS;;WACzD;WAA6B,MAAM;WAAY,SAAS;;WACxD;WAAwB,MAAM;WAAY;;;;WAG1C;WACA,MAAM;;WAEN;WACA;;YAGH,MAAM;YAEN,OAAO,UAAU,OAAO,QAAQ;WAAiB,MAAM;;;qBAGtD;;qBAGA,SAAU,GAAG,eAAa;;qBAG1B,SACX;WAA2B;WAAmC;kBAC7D;;;;;;;qBAYU,aAAc,GAAG,YAAY,SAAS,KAAK;;qBAU3C,WAAY,MAAM,SAAO,cAAc"}
1
+ {"version":3,"file":"node.d.ts","names":[],"sources":["../../src/internal/node.ts"],"mappings":"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"}
@@ -8,10 +8,14 @@ import * as Predicate from "effect/Predicate";
8
8
  * child's own step is always at hand for fallback, and recursion through
9
9
  * `Suspend` is just a reference.
10
10
  */
11
+ /** What a fast path returns to leave the input to its grammar (`Parser.Defer`). */
12
+ const Defer = /*#__PURE__*/ Symbol.for("effect-parse/Parser/Defer");
11
13
  /** Where a parser's description is stored. */
12
14
  const NodeId = /*#__PURE__*/ Symbol.for("effect-parse/Parser/node");
15
+ /** The description recorded for a parser, if it has one. */
16
+ const describedNode = (p) => p[NodeId];
13
17
  /** The description of a parser: `Opaque` when it has none. */
14
- const nodeOf = (p) => p[NodeId] ?? {
18
+ const nodeOf = (p) => describedNode(p) ?? {
15
19
  _tag: "Opaque",
16
20
  step: p.step
17
21
  };
@@ -52,15 +56,19 @@ const children = (node) => {
52
56
  case "Tap":
53
57
  case "TryMap":
54
58
  case "FilterMap":
59
+ case "MapOrFail":
55
60
  case "Filter":
56
61
  case "FlatMap":
57
62
  case "Taken":
58
63
  case "WithTaken":
59
64
  case "Span":
60
65
  case "WithSpan":
66
+ case "MapSpan":
61
67
  case "Mode":
62
68
  case "Context":
63
69
  case "Expected":
70
+ case "Quiet":
71
+ case "FastPath":
64
72
  case "MapError":
65
73
  case "OrFail":
66
74
  case "Opt":
@@ -76,7 +84,9 @@ const children = (node) => {
76
84
  case "RetryAfter": return [node.self, node.recover];
77
85
  case "Seq":
78
86
  case "Struct":
79
- case "Alt": return node.parsers;
87
+ case "SeqWith":
88
+ case "Alt":
89
+ case "Combinator": return node.parsers;
80
90
  case "ZipWith": return [node.self, node.that];
81
91
  case "Dispatch": {
82
92
  const out = [node.selector];
@@ -91,6 +101,6 @@ const children = (node) => {
91
101
  default: return [];
92
102
  }
93
103
  };
94
- export { NodeId, bounds, children, nodeOf, scansFloat };
104
+ export { Defer, NodeId, bounds, children, describedNode, nodeOf, scansFloat };
95
105
 
96
106
  //# 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\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: \"Rest\"; readonly encoding: Enc }\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: (a: any) => unknown }\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 | { 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 // 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: \"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: (a: any, b: any) => unknown }\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 // 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/** Where a parser's description is stored. */\nexport const NodeId: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Parser/node\")\n\n/** The description of a parser: `Opaque` when it has none. */\nexport const nodeOf = (p: ParserLike): Node => (p as any)[NodeId] ?? { _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 \"Filter\":\n case \"FlatMap\":\n case \"Taken\":\n case \"WithTaken\":\n case \"Span\":\n case \"WithSpan\":\n case \"Mode\":\n case \"Context\":\n case \"Expected\":\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 \"Alt\":\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 as any])\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":";;;;;;;;;;;AAsJA,MAAa,SAAsC,qBAAO,IAAI,0BAA0B;;AAGxF,MAAa,UAAU,MAAyB,EAAU,WAAW;CAAE,MAAM;CAAU,MAAM,EAAE;AAAK;;AAGpG,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,UACH,OAAO,CAAC,KAAK,IAAI;EACnB,KAAK;EACL,KAAK,cACH,OAAO,CAAC,KAAK,MAAM,KAAK,OAAO;EACjC,KAAK;EACL,KAAK;EACL,KAAK,OACH,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,IAAW;GAEhF,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/** 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 +1 @@
1
- {"version":3,"file":"numbers.d.ts","names":[],"sources":["../../src/internal/numbers.ts"],"mappings":";;qBAUa,SAAU,GAAG;;qBAIb,UAAW,GAAG;;;;;;qBAmBd,YAAU;;qBAGV,YAAa,kBAAkB,GAAG,MAAI;;;;;;qBAatC;;;;;;;;;;;;;;;;qBAiFA,kBAAmB,WAAW,WAAW,yBAAuB;;qBAmFhE,iBAAkB,GAAG,YAAY,WAAW,yBAAuB"}
1
+ {"version":3,"file":"numbers.d.ts","names":[],"sources":["../../src/internal/numbers.ts"],"mappings":";;qBAWa,SAAU,GAAG;;qBAIb,UAAW,GAAG;;;;;;qBAmBd,YAAU;;qBAGV,YAAa,kBAAkB,GAAG,MAAI;;;;;;qBAatC;;;;;;;;;;;;;;;;qBAiFA,kBAAmB,WAAW,WAAW,yBAAuB;;qBAmFhE,iBAAkB,GAAG,YAAY,WAAW,yBAAuB"}
@@ -1 +1 @@
1
- {"version":3,"file":"numbers.js","names":[],"sources":["../../src/internal/numbers.ts"],"sourcesContent":["/**\n * Number conversions shared by the `Ascii` and `Text` parsers and the\n * compilers.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type { Input } from \"../Input.js\"\nimport { Fail } from \"../Input.js\"\nimport { latin1 } from \"./text.js\"\n\n/** The text of an input slice: as is for a string, Latin-1 for bytes, joined for tokens. */\nexport const toText = (s: Input): string =>\n Predicate.isString(s) ? s : s instanceof Uint8Array ? latin1.text(s, 0, s.length) : s.join(\"\")\n\n/** The value of the text matched by `Ascii.float` and `Text.float`. */\nexport const toFloat = (s: Input): number => {\n if (Predicate.isString(s)) {\n // Plain decimal notation (as opposed to `inf` or `nan`) ends in a digit or \".\"\n const last = s.charCodeAt(s.length - 1)\n if ((last >= 48 && last <= 57) || last === 46) return Number(s)\n }\n const t = toText(s).toLowerCase()\n const negative = t.startsWith(\"-\")\n const body = t.startsWith(\"-\") || t.startsWith(\"+\") ? t.slice(1) : t\n if (body === \"nan\") return NaN\n if (body.startsWith(\"inf\")) return negative ? -Infinity : Infinity\n return Number(t)\n}\n\n/**\n * The parsers that `Ascii.float` and `Text.float` map with `toFloat`: the\n * compilers replace them by {@link scanFloatString} and\n * {@link scanFloatBytes} when the text is in decimal notation.\n */\nexport const floatTexts = /*#__PURE__*/ new WeakSet<object>()\n\n/** Adds a parser to {@link floatTexts}. */\nexport const floatText = <P extends object>(p: P): P => {\n floatTexts.add(p)\n return p\n}\n\n/** The powers of ten that doubles represent exactly. */\nconst exact = /*#__PURE__*/ Array.from({ length: 23 }, (_, i) => Number(`1e${i}`))\n\n/**\n * Where the latest scan ended, when it succeeded, and the furthest offset it\n * read (when it succeeded or failed): streaming builds re-run the parser\n * when that is near the end of a partial input.\n */\nexport const floatScan = { end: 0, read: 0 }\n\nconst isDigit = (c: number): boolean => c >= 48 && c <= 57\n\n// Exact products of doubles (Dekker), without allocating: `a * b` is\n// `productHi + productLo` exactly, barring overflow and underflow\nconst Split = 134217729 // 2^27 + 1\nlet productHi = 0\nlet productLo = 0\nconst twoProduct = (a: number, b: number): void => {\n const p = a * b\n let t = Split * a\n const ah = t - (t - a)\n const al = a - ah\n t = Split * b\n const bh = t - (t - b)\n const bl = b - bh\n productHi = p\n productLo = ah * bh - p + ah * bl + al * bh + al * bl\n}\n\n/** 2^-96: a bound on the relative error of {@link decimal}'s 19-digit path. */\nconst Error19 = 1 / 2 ** 96\n\n/**\n * The double nearest to `±(high * 10^low digits + low) * 10^e10`, where\n * `high` holds the first 15 significant digits, and `low` the next `lowDigits`\n * (at most 4). Returns `undefined` when this can't tell it apart from the\n * neighbouring doubles, for the caller to use `Number`.\n *\n * Up to 15 digits, the digits and a power of ten up to 10^22 are exact\n * doubles, so one multiplication or division rounds correctly (Clinger's\n * fast path). Up to 19 digits, the digits are an exact sum of two doubles,\n * and multiplying or dividing that by an exact power of ten gives the value\n * to within a relative 2^-96 (double-double arithmetic). It is then rounded\n * once, and kept only if the bounds of that error round to the same double:\n * this is never the case for an exact tie, so ties go to `Number` too.\n */\nconst decimal = (negative: boolean, high: number, low: number, lowDigits: number, e10: number): number | undefined => {\n let v: number\n if (lowDigits === 0) {\n if (e10 > 22 || e10 < -22) return undefined\n v = e10 === 0 ? high : e10 > 0 ? high * exact[e10] : high / exact[-e10]\n } else {\n if (e10 > 22 || e10 < -22) return undefined\n // The digits: high * 10^lowDigits + low = wh + wl, exactly\n twoProduct(high, exact[lowDigits])\n const wh = productHi + low\n const wl = productLo + (low - (wh - productHi))\n let xh: number\n let xl: number\n if (e10 >= 0) {\n const p = exact[e10]\n twoProduct(wh, p)\n xh = productHi\n xl = productLo + wl * p\n } else {\n const p = exact[-e10]\n xh = wh / p\n twoProduct(xh, p)\n xl = (wh - productHi - productLo + wl) / p\n }\n v = xh + xl\n const error = (xh < 0 ? -xh : xh) * Error19\n if (xh + (xl + error) !== v || xh + (xl - error) !== v) return undefined\n }\n return negative ? -v : v\n}\n\n/**\n * Matches and converts what `Ascii.float` matches at `i`, when it is in\n * decimal notation: an optional sign, then digits or \".\" (the other forms,\n * `nan` and `inf`, start with a letter). Returns the value, setting\n * `floatScan.end`; `Fail` if the float parser fails there (always with\n * `Backtrack`); or `undefined` if the text does not start like a decimal\n * number, for the caller to run the parser.\n *\n * Numbers with up to 19 significant digits and a decimal exponent up to 22\n * are converted by {@link decimal}, the rest by `Number`, so the value is\n * always what `Number` gives for the text.\n */\nexport const scanFloatString = (s: string, i: number, end: number): number | Fail | undefined => {\n const start = i\n let c = i < end ? s.charCodeAt(i) : -1\n if (c === 45 || c === 43) {\n c = i + 1 < end ? s.charCodeAt(i + 1) : -1\n if (!isDigit(c) && c !== 46) return undefined\n i++\n } else if (!isDigit(c) && c !== 46) {\n return undefined\n }\n // The first 15 significant digits, the next 4, how many there are in all,\n // and the decimal exponent of the last one kept\n let high = 0\n let low = 0\n let digits = 0\n let e10 = 0\n if (c !== 46) {\n do {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n } else {\n if (digits < 19) low = low * 10 + (c - 48)\n else e10++\n digits++\n }\n c = ++i < end ? s.charCodeAt(i) : -1\n } while (isDigit(c))\n if (c === 46) c = ++i < end ? s.charCodeAt(i) : -1\n } else {\n // \".\" must be followed by a digit\n c = ++i < end ? s.charCodeAt(i) : -1\n if (!isDigit(c)) {\n floatScan.read = i\n return Fail\n }\n }\n while (isDigit(c)) {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n e10--\n } else {\n if (digits < 19) {\n low = low * 10 + (c - 48)\n e10--\n }\n digits++\n }\n c = ++i < end ? s.charCodeAt(i) : -1\n }\n let read = i\n if (c === 101 || c === 69) {\n // The exponent is optional: without digits, it is not consumed\n let j = i + 1\n c = j < end ? s.charCodeAt(j) : -1\n const negative = c === 45\n if (negative || c === 43) c = ++j < end ? s.charCodeAt(j) : -1\n if (isDigit(c)) {\n let e = 0\n do {\n // Past this, the number can only overflow or underflow\n if (e < 1e6) e = e * 10 + (c - 48)\n c = ++j < end ? s.charCodeAt(j) : -1\n } while (isDigit(c))\n e10 += negative ? -e : e\n i = j\n }\n read = j\n }\n floatScan.end = i\n floatScan.read = read\n const negative = s.charCodeAt(start) === 45\n if (high === 0) return negative ? -0 : 0\n const v = digits > 19 ? undefined : decimal(negative, high, low, digits > 15 ? digits - 15 : 0, e10)\n return v === undefined ? Number(s.slice(start, i)) : v\n}\n\n/** {@link scanFloatString} on bytes, or the units of an ASCII compatible encoding. */\nexport const scanFloatBytes = (b: Uint8Array, i: number, end: number): number | Fail | undefined => {\n const start = i\n let c = i < end ? b[i] : -1\n if (c === 45 || c === 43) {\n c = i + 1 < end ? b[i + 1] : -1\n if (!isDigit(c) && c !== 46) return undefined\n i++\n } else if (!isDigit(c) && c !== 46) {\n return undefined\n }\n let high = 0\n let low = 0\n let digits = 0\n let e10 = 0\n if (c !== 46) {\n do {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n } else {\n if (digits < 19) low = low * 10 + (c - 48)\n else e10++\n digits++\n }\n c = ++i < end ? b[i] : -1\n } while (isDigit(c))\n if (c === 46) c = ++i < end ? b[i] : -1\n } else {\n c = ++i < end ? b[i] : -1\n if (!isDigit(c)) {\n floatScan.read = i\n return Fail\n }\n }\n while (isDigit(c)) {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n e10--\n } else {\n if (digits < 19) {\n low = low * 10 + (c - 48)\n e10--\n }\n digits++\n }\n c = ++i < end ? b[i] : -1\n }\n let read = i\n if (c === 101 || c === 69) {\n let j = i + 1\n c = j < end ? b[j] : -1\n const negative = c === 45\n if (negative || c === 43) c = ++j < end ? b[j] : -1\n if (isDigit(c)) {\n let e = 0\n do {\n if (e < 1e6) e = e * 10 + (c - 48)\n c = ++j < end ? b[j] : -1\n } while (isDigit(c))\n e10 += negative ? -e : e\n i = j\n }\n read = j\n }\n floatScan.end = i\n floatScan.read = read\n const negative = b[start] === 45\n if (high === 0) return negative ? -0 : 0\n const v = digits > 19 ? undefined : decimal(negative, high, low, digits > 15 ? digits - 15 : 0, e10)\n return v === undefined ? Number(asciiText(b, start, i)) : v\n}\n\n/** The text of ASCII bytes. */\nconst asciiText = (b: Uint8Array, start: number, end: number): string =>\n String.fromCharCode.apply(null, b.subarray(start, end) as unknown as Array<number>)\n"],"mappings":"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"}
1
+ {"version":3,"file":"numbers.js","names":[],"sources":["../../src/internal/numbers.ts"],"sourcesContent":["/**\n * Number conversions shared by the `Ascii` and `Text` parsers and the\n * compilers.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type { Input } from \"../Input.js\"\nimport { Fail } from \"../Input.js\"\nimport type { FromCharCodes } from \"./text.js\"\nimport { latin1 } from \"./text.js\"\n\n/** The text of an input slice: as is for a string, Latin-1 for bytes, joined for tokens. */\nexport const toText = (s: Input): string =>\n Predicate.isString(s) ? s : s instanceof Uint8Array ? latin1.text(s, 0, s.length) : s.join(\"\")\n\n/** The value of the text matched by `Ascii.float` and `Text.float`. */\nexport const toFloat = (s: Input): number => {\n if (Predicate.isString(s)) {\n // Plain decimal notation (as opposed to `inf` or `nan`) ends in a digit or \".\"\n const last = s.charCodeAt(s.length - 1)\n if ((last >= 48 && last <= 57) || last === 46) return Number(s)\n }\n const t = toText(s).toLowerCase()\n const negative = t.startsWith(\"-\")\n const body = t.startsWith(\"-\") || t.startsWith(\"+\") ? t.slice(1) : t\n if (body === \"nan\") return NaN\n if (body.startsWith(\"inf\")) return negative ? -Infinity : Infinity\n return Number(t)\n}\n\n/**\n * The parsers that `Ascii.float` and `Text.float` map with `toFloat`: the\n * compilers replace them by {@link scanFloatString} and\n * {@link scanFloatBytes} when the text is in decimal notation.\n */\nexport const floatTexts = /*#__PURE__*/ new WeakSet<object>()\n\n/** Adds a parser to {@link floatTexts}. */\nexport const floatText = <P extends object>(p: P): P => {\n floatTexts.add(p)\n return p\n}\n\n/** The powers of ten that doubles represent exactly. */\nconst exact = /*#__PURE__*/ Array.from({ length: 23 }, (_, i) => Number(`1e${i}`))\n\n/**\n * Where the latest scan ended, when it succeeded, and the furthest offset it\n * read (when it succeeded or failed): streaming builds re-run the parser\n * when that is near the end of a partial input.\n */\nexport const floatScan = { end: 0, read: 0 }\n\nconst isDigit = (c: number): boolean => c >= 48 && c <= 57\n\n// Exact products of doubles (Dekker), without allocating: `a * b` is\n// `productHi + productLo` exactly, barring overflow and underflow\nconst Split = 134217729 // 2^27 + 1\nlet productHi = 0\nlet productLo = 0\nconst twoProduct = (a: number, b: number): void => {\n const p = a * b\n let t = Split * a\n const ah = t - (t - a)\n const al = a - ah\n t = Split * b\n const bh = t - (t - b)\n const bl = b - bh\n productHi = p\n productLo = ah * bh - p + ah * bl + al * bh + al * bl\n}\n\n/** 2^-96: a bound on the relative error of {@link decimal}'s 19-digit path. */\nconst Error19 = 1 / 2 ** 96\n\n/**\n * The double nearest to `±(high * 10^low digits + low) * 10^e10`, where\n * `high` holds the first 15 significant digits, and `low` the next `lowDigits`\n * (at most 4). Returns `undefined` when this can't tell it apart from the\n * neighbouring doubles, for the caller to use `Number`.\n *\n * Up to 15 digits, the digits and a power of ten up to 10^22 are exact\n * doubles, so one multiplication or division rounds correctly (Clinger's\n * fast path). Up to 19 digits, the digits are an exact sum of two doubles,\n * and multiplying or dividing that by an exact power of ten gives the value\n * to within a relative 2^-96 (double-double arithmetic). It is then rounded\n * once, and kept only if the bounds of that error round to the same double:\n * this is never the case for an exact tie, so ties go to `Number` too.\n */\nconst decimal = (negative: boolean, high: number, low: number, lowDigits: number, e10: number): number | undefined => {\n let v: number\n if (lowDigits === 0) {\n if (e10 > 22 || e10 < -22) return undefined\n v = e10 === 0 ? high : e10 > 0 ? high * exact[e10] : high / exact[-e10]\n } else {\n if (e10 > 22 || e10 < -22) return undefined\n // The digits: high * 10^lowDigits + low = wh + wl, exactly\n twoProduct(high, exact[lowDigits])\n const wh = productHi + low\n const wl = productLo + (low - (wh - productHi))\n let xh: number\n let xl: number\n if (e10 >= 0) {\n const p = exact[e10]\n twoProduct(wh, p)\n xh = productHi\n xl = productLo + wl * p\n } else {\n const p = exact[-e10]\n xh = wh / p\n twoProduct(xh, p)\n xl = (wh - productHi - productLo + wl) / p\n }\n v = xh + xl\n const error = (xh < 0 ? -xh : xh) * Error19\n if (xh + (xl + error) !== v || xh + (xl - error) !== v) return undefined\n }\n return negative ? -v : v\n}\n\n/**\n * Matches and converts what `Ascii.float` matches at `i`, when it is in\n * decimal notation: an optional sign, then digits or \".\" (the other forms,\n * `nan` and `inf`, start with a letter). Returns the value, setting\n * `floatScan.end`; `Fail` if the float parser fails there (always with\n * `Backtrack`); or `undefined` if the text does not start like a decimal\n * number, for the caller to run the parser.\n *\n * Numbers with up to 19 significant digits and a decimal exponent up to 22\n * are converted by {@link decimal}, the rest by `Number`, so the value is\n * always what `Number` gives for the text.\n */\nexport const scanFloatString = (s: string, i: number, end: number): number | Fail | undefined => {\n const start = i\n let c = i < end ? s.charCodeAt(i) : -1\n if (c === 45 || c === 43) {\n c = i + 1 < end ? s.charCodeAt(i + 1) : -1\n if (!isDigit(c) && c !== 46) return undefined\n i++\n } else if (!isDigit(c) && c !== 46) {\n return undefined\n }\n // The first 15 significant digits, the next 4, how many there are in all,\n // and the decimal exponent of the last one kept\n let high = 0\n let low = 0\n let digits = 0\n let e10 = 0\n if (c !== 46) {\n do {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n } else {\n if (digits < 19) low = low * 10 + (c - 48)\n else e10++\n digits++\n }\n c = ++i < end ? s.charCodeAt(i) : -1\n } while (isDigit(c))\n if (c === 46) c = ++i < end ? s.charCodeAt(i) : -1\n } else {\n // \".\" must be followed by a digit\n c = ++i < end ? s.charCodeAt(i) : -1\n if (!isDigit(c)) {\n floatScan.read = i\n return Fail\n }\n }\n while (isDigit(c)) {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n e10--\n } else {\n if (digits < 19) {\n low = low * 10 + (c - 48)\n e10--\n }\n digits++\n }\n c = ++i < end ? s.charCodeAt(i) : -1\n }\n let read = i\n if (c === 101 || c === 69) {\n // The exponent is optional: without digits, it is not consumed\n let j = i + 1\n c = j < end ? s.charCodeAt(j) : -1\n const negative = c === 45\n if (negative || c === 43) c = ++j < end ? s.charCodeAt(j) : -1\n if (isDigit(c)) {\n let e = 0\n do {\n // Past this, the number can only overflow or underflow\n if (e < 1e6) e = e * 10 + (c - 48)\n c = ++j < end ? s.charCodeAt(j) : -1\n } while (isDigit(c))\n e10 += negative ? -e : e\n i = j\n }\n read = j\n }\n floatScan.end = i\n floatScan.read = read\n const negative = s.charCodeAt(start) === 45\n if (high === 0) return negative ? -0 : 0\n const v = digits > 19 ? undefined : decimal(negative, high, low, digits > 15 ? digits - 15 : 0, e10)\n return v === undefined ? Number(s.slice(start, i)) : v\n}\n\n/** {@link scanFloatString} on bytes, or the units of an ASCII compatible encoding. */\nexport const scanFloatBytes = (b: Uint8Array, i: number, end: number): number | Fail | undefined => {\n const start = i\n let c = i < end ? b[i] : -1\n if (c === 45 || c === 43) {\n c = i + 1 < end ? b[i + 1] : -1\n if (!isDigit(c) && c !== 46) return undefined\n i++\n } else if (!isDigit(c) && c !== 46) {\n return undefined\n }\n let high = 0\n let low = 0\n let digits = 0\n let e10 = 0\n if (c !== 46) {\n do {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n } else {\n if (digits < 19) low = low * 10 + (c - 48)\n else e10++\n digits++\n }\n c = ++i < end ? b[i] : -1\n } while (isDigit(c))\n if (c === 46) c = ++i < end ? b[i] : -1\n } else {\n c = ++i < end ? b[i] : -1\n if (!isDigit(c)) {\n floatScan.read = i\n return Fail\n }\n }\n while (isDigit(c)) {\n if (digits < 15) {\n if (high !== 0 || c !== 48) {\n high = high * 10 + (c - 48)\n digits++\n }\n e10--\n } else {\n if (digits < 19) {\n low = low * 10 + (c - 48)\n e10--\n }\n digits++\n }\n c = ++i < end ? b[i] : -1\n }\n let read = i\n if (c === 101 || c === 69) {\n let j = i + 1\n c = j < end ? b[j] : -1\n const negative = c === 45\n if (negative || c === 43) c = ++j < end ? b[j] : -1\n if (isDigit(c)) {\n let e = 0\n do {\n if (e < 1e6) e = e * 10 + (c - 48)\n c = ++j < end ? b[j] : -1\n } while (isDigit(c))\n e10 += negative ? -e : e\n i = j\n }\n read = j\n }\n floatScan.end = i\n floatScan.read = read\n const negative = b[start] === 45\n if (high === 0) return negative ? -0 : 0\n const v = digits > 19 ? undefined : decimal(negative, high, low, digits > 15 ? digits - 15 : 0, e10)\n return v === undefined ? Number(asciiText(b, start, i)) : v\n}\n\n/** The text of ASCII bytes. */\nconst asciiText = (b: Uint8Array, start: number, end: number): string =>\n // SAFETY: `apply` takes any array-like argument list, so each byte of the view is passed as a char code\n (String.fromCharCode as FromCharCodes).apply(null, b.subarray(start, end))\n"],"mappings":";;;;;;;;;AAWA,MAAa,UAAU,MACrB,UAAU,SAAS,CAAC,IAAI,IAAI,aAAa,aAAa,OAAO,KAAK,GAAG,GAAG,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE;;AAG/F,MAAa,WAAW,MAAqB;CAC3C,IAAI,UAAU,SAAS,CAAC,GAAG;EAEzB,MAAM,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC;EACtC,IAAK,QAAQ,MAAM,QAAQ,MAAO,SAAS,IAAI,OAAO,OAAO,CAAC;CAChE;CACA,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY;CAChC,MAAM,WAAW,EAAE,WAAW,GAAG;CACjC,MAAM,OAAO,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI;CACnE,IAAI,SAAS,OAAO,OAAO;CAC3B,IAAI,KAAK,WAAW,KAAK,GAAG,OAAO,WAAW,YAAY;CAC1D,OAAO,OAAO,CAAC;AACjB;;;;;;AAOA,MAAa,2BAA2B,IAAI,QAAgB;;AAG5D,MAAa,aAA+B,MAAY;CACtD,WAAW,IAAI,CAAC;CAChB,OAAO;AACT;;AAGA,MAAM,QAAsB,oBAAM,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,MAAM,OAAO,KAAK,GAAG,CAAC;;;;;;AAOjF,MAAa,YAAY;CAAE,KAAK;CAAG,MAAM;AAAE;AAE3C,MAAM,WAAW,MAAuB,KAAK,MAAM,KAAK;AAIxD,MAAM,QAAQ;AACd,IAAI,YAAY;AAChB,IAAI,YAAY;AAChB,MAAM,cAAc,GAAW,MAAoB;CACjD,MAAM,IAAI,IAAI;CACd,IAAI,IAAI,QAAQ;CAChB,MAAM,KAAK,KAAK,IAAI;CACpB,MAAM,KAAK,IAAI;CACf,IAAI,QAAQ;CACZ,MAAM,KAAK,KAAK,IAAI;CACpB,MAAM,KAAK,IAAI;CACf,YAAY;CACZ,YAAY,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK;AACrD;;AAGA,MAAM,UAAU,IAAI,KAAK;;;;;;;;;;;;;;;AAgBzB,MAAM,WAAW,UAAmB,MAAc,KAAa,WAAmB,QAAoC;CACpH,IAAI;CACJ,IAAI,cAAc,GAAG;EACnB,IAAI,MAAM,MAAM,MAAM,KAAK,OAAO,KAAA;EAClC,IAAI,QAAQ,IAAI,OAAO,MAAM,IAAI,OAAO,MAAM,OAAO,OAAO,MAAM,CAAC;CACrE,OAAO;EACL,IAAI,MAAM,MAAM,MAAM,KAAK,OAAO,KAAA;EAElC,WAAW,MAAM,MAAM,UAAU;EACjC,MAAM,KAAK,YAAY;EACvB,MAAM,KAAK,aAAa,OAAO,KAAK;EACpC,IAAI;EACJ,IAAI;EACJ,IAAI,OAAO,GAAG;GACZ,MAAM,IAAI,MAAM;GAChB,WAAW,IAAI,CAAC;GAChB,KAAK;GACL,KAAK,YAAY,KAAK;EACxB,OAAO;GACL,MAAM,IAAI,MAAM,CAAC;GACjB,KAAK,KAAK;GACV,WAAW,IAAI,CAAC;GAChB,MAAM,KAAK,YAAY,YAAY,MAAM;EAC3C;EACA,IAAI,KAAK;EACT,MAAM,SAAS,KAAK,IAAI,CAAC,KAAK,MAAM;EACpC,IAAI,MAAM,KAAK,WAAW,KAAK,MAAM,KAAK,WAAW,GAAG,OAAO,KAAA;CACjE;CACA,OAAO,WAAW,CAAC,IAAI;AACzB;;;;;;;;;;;;;AAcA,MAAa,mBAAmB,GAAW,GAAW,QAA2C;CAC/F,MAAM,QAAQ;CACd,IAAI,IAAI,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;CACpC,IAAI,MAAM,MAAM,MAAM,IAAI;EACxB,IAAI,IAAI,IAAI,MAAM,EAAE,WAAW,IAAI,CAAC,IAAI;EACxC,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,IAAI,OAAO,KAAA;EACpC;CACF,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,IAC9B;CAIF,IAAI,OAAO;CACX,IAAI,MAAM;CACV,IAAI,SAAS;CACb,IAAI,MAAM;CACV,IAAI,MAAM,IAAI;EACZ,GAAG;GACD,IAAI,SAAS,IACP;QAAA,SAAS,KAAK,MAAM,IAAI;KAC1B,OAAO,OAAO,MAAM,IAAI;KACxB;IACF;UACK;IACL,IAAI,SAAS,IAAI,MAAM,MAAM,MAAM,IAAI;SAClC;IACL;GACF;GACA,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;EACpC,SAAS,QAAQ,CAAC;EAClB,IAAI,MAAM,IAAI,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;CAClD,OAAO;EAEL,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;EAClC,IAAI,CAAC,QAAQ,CAAC,GAAG;GACf,UAAU,OAAO;GACjB,OAAO;EACT;CACF;CACA,OAAO,QAAQ,CAAC,GAAG;EACjB,IAAI,SAAS,IAAI;GACf,IAAI,SAAS,KAAK,MAAM,IAAI;IAC1B,OAAO,OAAO,MAAM,IAAI;IACxB;GACF;GACA;EACF,OAAO;GACL,IAAI,SAAS,IAAI;IACf,MAAM,MAAM,MAAM,IAAI;IACtB;GACF;GACA;EACF;EACA,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;CACpC;CACA,IAAI,OAAO;CACX,IAAI,MAAM,OAAO,MAAM,IAAI;EAEzB,IAAI,IAAI,IAAI;EACZ,IAAI,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;EAChC,MAAM,WAAW,MAAM;EACvB,IAAI,YAAY,MAAM,IAAI,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;EAC5D,IAAI,QAAQ,CAAC,GAAG;GACd,IAAI,IAAI;GACR,GAAG;IAED,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI;IAC/B,IAAI,EAAE,IAAI,MAAM,EAAE,WAAW,CAAC,IAAI;GACpC,SAAS,QAAQ,CAAC;GAClB,OAAO,WAAW,CAAC,IAAI;GACvB,IAAI;EACN;EACA,OAAO;CACT;CACA,UAAU,MAAM;CAChB,UAAU,OAAO;CACjB,MAAM,WAAW,EAAE,WAAW,KAAK,MAAM;CACzC,IAAI,SAAS,GAAG,OAAO,WAAW,KAAK;CACvC,MAAM,IAAI,SAAS,KAAK,KAAA,IAAY,QAAQ,UAAU,MAAM,KAAK,SAAS,KAAK,SAAS,KAAK,GAAG,GAAG;CACnG,OAAO,MAAM,KAAA,IAAY,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,IAAI;AACvD;;AAGA,MAAa,kBAAkB,GAAe,GAAW,QAA2C;CAClG,MAAM,QAAQ;CACd,IAAI,IAAI,IAAI,MAAM,EAAE,KAAK;CACzB,IAAI,MAAM,MAAM,MAAM,IAAI;EACxB,IAAI,IAAI,IAAI,MAAM,EAAE,IAAI,KAAK;EAC7B,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,IAAI,OAAO,KAAA;EACpC;CACF,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM,IAC9B;CAEF,IAAI,OAAO;CACX,IAAI,MAAM;CACV,IAAI,SAAS;CACb,IAAI,MAAM;CACV,IAAI,MAAM,IAAI;EACZ,GAAG;GACD,IAAI,SAAS,IACP;QAAA,SAAS,KAAK,MAAM,IAAI;KAC1B,OAAO,OAAO,MAAM,IAAI;KACxB;IACF;UACK;IACL,IAAI,SAAS,IAAI,MAAM,MAAM,MAAM,IAAI;SAClC;IACL;GACF;GACA,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;EACzB,SAAS,QAAQ,CAAC;EAClB,IAAI,MAAM,IAAI,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;CACvC,OAAO;EACL,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;EACvB,IAAI,CAAC,QAAQ,CAAC,GAAG;GACf,UAAU,OAAO;GACjB,OAAO;EACT;CACF;CACA,OAAO,QAAQ,CAAC,GAAG;EACjB,IAAI,SAAS,IAAI;GACf,IAAI,SAAS,KAAK,MAAM,IAAI;IAC1B,OAAO,OAAO,MAAM,IAAI;IACxB;GACF;GACA;EACF,OAAO;GACL,IAAI,SAAS,IAAI;IACf,MAAM,MAAM,MAAM,IAAI;IACtB;GACF;GACA;EACF;EACA,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;CACzB;CACA,IAAI,OAAO;CACX,IAAI,MAAM,OAAO,MAAM,IAAI;EACzB,IAAI,IAAI,IAAI;EACZ,IAAI,IAAI,MAAM,EAAE,KAAK;EACrB,MAAM,WAAW,MAAM;EACvB,IAAI,YAAY,MAAM,IAAI,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;EACjD,IAAI,QAAQ,CAAC,GAAG;GACd,IAAI,IAAI;GACR,GAAG;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI;IAC/B,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK;GACzB,SAAS,QAAQ,CAAC;GAClB,OAAO,WAAW,CAAC,IAAI;GACvB,IAAI;EACN;EACA,OAAO;CACT;CACA,UAAU,MAAM;CAChB,UAAU,OAAO;CACjB,MAAM,WAAW,EAAE,WAAW;CAC9B,IAAI,SAAS,GAAG,OAAO,WAAW,KAAK;CACvC,MAAM,IAAI,SAAS,KAAK,KAAA,IAAY,QAAQ,UAAU,MAAM,KAAK,SAAS,KAAK,SAAS,KAAK,GAAG,GAAG;CACnG,OAAO,MAAM,KAAA,IAAY,OAAO,UAAU,GAAG,OAAO,CAAC,CAAC,IAAI;AAC5D;;AAGA,MAAM,aAAa,GAAe,OAAe,QAE9C,OAAO,aAA+B,MAAM,MAAM,EAAE,SAAS,OAAO,GAAG,CAAC"}
@@ -10,4 +10,16 @@ import { ParserLike } from "./node.js";
10
10
  * with streaming checkpoints) use the resumable build.
11
11
  */
12
12
  export declare const runOn: <A>(p: ParserLike, step: (state: State<any>) => A | Fail, state: State<any>, diagnostics?: boolean) => A | Fail;
13
+ /**
14
+ * Runs a compiled step on `state`: directly when it guards against
15
+ * call-stack overflows itself (the JIT's), else under `Stack.run`.
16
+ */
17
+ export declare const runCompiled: <A>(step: (state: State<any>) => A, guarded: boolean, state: State<any>) => A | Fail;
18
+ /**
19
+ * `runOn(p, p.step, state, diagnostics)` as a function of the state, with
20
+ * the per-run lookup done once: the compiled step is looked up again only
21
+ * when the input kind or the build (plain or resumable) changes from the
22
+ * previous run.
23
+ */
24
+ export declare const prepare: <A>(p: ParserLike, step: (state: State<any>) => A | Fail, diagnostics: boolean) => ((state: State<any>) => A | Fail);
13
25
  //# sourceMappingURL=run.d.ts.map
@@ -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"}
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"}
@@ -18,18 +18,58 @@ import * as Stack from "./stack.js";
18
18
  * with streaming checkpoints) use the resumable build.
19
19
  */
20
20
  const runOn = (p, step, state, diagnostics = true) => {
21
- if (state.tracer === void 0 && state.recovered === void 0 && state.syntax === void 0) {
22
- const compiled = Registry.stepFor(p, state, state.partial || state.resume !== void 0);
23
- if (compiled !== void 0) {
24
- const start = state.pos;
25
- const a = Stack.run(compiled, state);
26
- if (a !== Fail) return a;
27
- state.rewind(start);
28
- if (!diagnostics) return Fail;
21
+ if (state.tracer !== void 0 || state.recovered !== void 0 || state.syntax !== void 0) return Stack.run(step, state);
22
+ const compiled = Registry.compiled(p, state.inputKind, state.partial || state.resume !== void 0);
23
+ return compiled === void 0 ? Stack.run(step, state) : attempt(compiled, step, state, diagnostics);
24
+ };
25
+ /**
26
+ * Runs a compiled step on `state`: directly when it guards against
27
+ * call-stack overflows itself (the JIT's), else under `Stack.run`.
28
+ */
29
+ const runCompiled = (step, guarded, state) => guarded ? step(state) : Stack.run(step, state);
30
+ /**
31
+ * Runs the compiled step of `compiled` (or, if compiling failed, the
32
+ * parser's); if it fails, rewinds and, with `diagnostics`, runs the
33
+ * parser's step to record the failure.
34
+ */
35
+ const attempt = (compiled, step, state, diagnostics) => {
36
+ const c = compiled.step;
37
+ if (c === void 0) return Stack.run(step, state);
38
+ const start = state.pos;
39
+ const a = runCompiled(c, compiled.guarded, state);
40
+ if (a !== Fail) return a;
41
+ state.rewind(start);
42
+ return diagnostics ? Stack.run(step, state) : Fail;
43
+ };
44
+ /** What `prepare` holds before its first run: nothing compiled. */
45
+ const uncompiled = {
46
+ backend: "interpreted",
47
+ step: void 0,
48
+ guarded: false,
49
+ fallbacks: [],
50
+ error: void 0
51
+ };
52
+ /**
53
+ * `runOn(p, p.step, state, diagnostics)` as a function of the state, with
54
+ * the per-run lookup done once: the compiled step is looked up again only
55
+ * when the input kind or the build (plain or resumable) changes from the
56
+ * previous run.
57
+ */
58
+ const prepare = (p, step, diagnostics) => {
59
+ let kind = -1;
60
+ let resumable = false;
61
+ let compiled = uncompiled;
62
+ return (state) => {
63
+ if (state.tracer !== void 0 || state.recovered !== void 0 || state.syntax !== void 0) return Stack.run(step, state);
64
+ const r = state.partial || state.resume !== void 0;
65
+ if (state.inputKind !== kind || r !== resumable) {
66
+ compiled = Registry.compiled(p, state.inputKind, r) ?? uncompiled;
67
+ kind = state.inputKind;
68
+ resumable = r;
29
69
  }
30
- }
31
- return Stack.run(step, state);
70
+ return attempt(compiled, step, state, diagnostics);
71
+ };
32
72
  };
33
- export { runOn };
73
+ export { prepare, runCompiled, runOn };
34
74
 
35
75
  //# sourceMappingURL=run.js.map
@@ -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 const compiled = Registry.stepFor(p, state, state.partial || state.resume !== undefined)\n if (compiled !== undefined) {\n const start = state.pos\n const a = Stack.run(compiled, 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 if (!diagnostics) return Fail\n }\n }\n return Stack.run(step, state)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,MAAa,SACX,GACA,MACA,OACA,cAAuB,SACV;CACb,IAAI,MAAM,WAAW,KAAA,KAAa,MAAM,cAAc,KAAA,KAAa,MAAM,WAAW,KAAA,GAAW;EAC7F,MAAM,WAAW,SAAS,QAAQ,GAAG,OAAO,MAAM,WAAW,MAAM,WAAW,KAAA,CAAS;EACvF,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,QAAQ,MAAM;GACpB,MAAM,IAAI,MAAM,IAAI,UAAU,KAAK;GACnC,IAAI,MAAM,MAER,OAAO;GAET,MAAM,OAAO,KAAK;GAClB,IAAI,CAAC,aAAa,OAAO;EAC3B;CACF;CACA,OAAO,MAAM,IAAI,MAAM,KAAK;AAC9B"}
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"}
@@ -11,4 +11,10 @@ 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
+ * Records the `TooDeep` failure of a call-stack overflow. The JIT's
16
+ * generated entry catches overflows itself, with this, so that the runners
17
+ * can call it without {@link run}.
18
+ */
19
+ export declare const tooDeep: (state: State<any>) => Fail;
14
20
  //# sourceMappingURL=stack.d.ts.map
@@ -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"}
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"}
@@ -27,9 +27,15 @@ const run = (step, state) => {
27
27
  return step(state);
28
28
  } catch (e) {
29
29
  if (!isStackOverflow(e)) throw e;
30
- return state.failMessage("Cut", "TooDeep", tooDeepMessage);
30
+ return tooDeep(state);
31
31
  }
32
32
  };
33
- export { isStackOverflow, run };
33
+ /**
34
+ * Records the `TooDeep` failure of a call-stack overflow. The JIT's
35
+ * generated entry catches overflows itself, with this, so that the runners
36
+ * can call it without {@link run}.
37
+ */
38
+ const tooDeep = (state) => state.failMessage("Cut", "TooDeep", tooDeepMessage);
39
+ export { isStackOverflow, run, tooDeep };
34
40
 
35
41
  //# 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 state.failMessage(\"Cut\", \"TooDeep\", tooDeepMessage)\n }\n}\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,MAAM,YAAY,OAAO,WAAW,cAAc;CAC3D;AACF"}
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"}
@@ -90,8 +90,8 @@ export interface Previous {
90
90
  }
91
91
  /** The hooks that `Syntax` combinators and `Parser.resumeAfter`/`retryAfter` call. */
92
92
  export interface Builder {
93
- node(state: State<any>, step: (state: State<any>) => unknown, key: Key, kind: string, named: boolean): unknown;
94
- field(state: State<any>, step: (state: State<any>) => unknown, name: string): unknown;
93
+ node<A>(state: State<any>, step: (state: State<any>) => A, key: Key, kind: string, named: boolean): A;
94
+ field<A>(state: State<any>, step: (state: State<any>) => A, name: string): A;
95
95
  /** After error recovery: `[start, pos)` was skipped after `failure`. */
96
96
  skipped(start: number, failure: Failure, mode: ErrMode): void;
97
97
  /**
@@ -131,11 +131,11 @@ export declare class SyntaxBuilder implements Builder {
131
131
  rewound(from: number, to: number): void;
132
132
  /** How far the parse looked: {@link highWater}, or the cursor if it is further. */
133
133
  private looked;
134
- node(state: State<any>, step: (state: State<any>) => unknown, key: Key, kind: string, named: boolean): unknown;
134
+ node<A>(state: State<any>, step: (state: State<any>) => A, key: Key, kind: string, named: boolean): A;
135
135
  read(end: number): void;
136
136
  /** Records `failure` as the furthest failure if it is, as `failWith` does. */
137
137
  private deepen;
138
- field(state: State<any>, step: (state: State<any>) => unknown, name: string): unknown;
138
+ field<A>(state: State<any>, step: (state: State<any>) => A, name: string): A;
139
139
  skipped(start: number, failure: Failure, mode: ErrMode): void;
140
140
  /**
141
141
  * Builds the root over the whole input from the nodes left on the stack.
@@ -1 +1 @@
1
- {"version":3,"file":"syntax.d.ts","names":[],"sources":["../../src/internal/syntax.ts"],"mappings":";;;;iBA4CiB;WACN,SAAS;WACT,MAAM;;;qBAIJ;WAEA;WACA;;WAEA,KAAK;WACL;;WAEA;WACA,UAAU,cAAc;;WAExB,SAAS;;WAET,QAAQ;WACR;;WAEA,OAAO;;WAEP;;WAEA,aAAa;EAlBb,YAAA,cACA;;EAEA,KAAK,iBACL;;EAEA,mBACA,UAAU,cAAc;;EAExB,SAAS;;EAET,QAAQ,+CACR;;EAEA,OAAO;;EAEP;;EAEA,aAAa;;;;;;;iBAST;;WAEN,SAAS;;WAET;;WAEA;WACA,cAAc;;;cAInB;WAEO,OAAO;WACP;WACA;EACF;EAHE,YAAA,OAAO,OACP,eACA,aACF;;qBAIE;;qBAMA,WAAY,GAAG,SAAS,kBAAgB;;;;;iBAuCpC;WACN;WACA;WACA;;;iBAIM;WACN,MAAM;WACN;WACA;WACA,UAAU,cAAc;WACxB,OAAO;;WAEP;WACA,UAAU;;;iBAIJ;EACf,KAAK,OAAO,YAAY,OAAO,OAAO,wBAAwB,KAAK,KAAK,cAAc;EACtF,MAAM,OAAO,YAAY,OAAO,OAAO,wBAAwB;;EAE/D,QAAQ,eAAe,SAAS,SAAS,MAAM;;;;;EAK/C,KAAK;;EAEL,MAAM;;EAEN,QAAQ,cAAc;;;;;;;;qBASX,yBAAyB;WAgBzB,OAAO;WACP,UAAU;;;;;;EAXrB;;WAES,OAAO,MAAM;;EAEtB;;EAEA,YAAY;EACZ;EAGW,YAAA,OAAO,YACP,UAAU;EAQrB,MAAM;EAIN,QAAQ,cAAc;;UAQd;EAIR,KAAK,OAAO,YAAY,OAAO,OAAO,wBAAwB,KAAK,KAAK,cAAc;EA0DtF,KAAK;;UAMG;EAIR,MAAM,OAAO,YAAY,OAAO,OAAO,wBAAwB;EAQ/D,QAAQ,eAAe,SAAS,SAAS,MAAM;;;;;;EAiB/C,OAAO,cAAc,gBAAgB,OAAO,uBAAuB,qBAAqB;;;;;;;UAqBhF;;UAsCA"}
1
+ {"version":3,"file":"syntax.d.ts","names":[],"sources":["../../src/internal/syntax.ts"],"mappings":";;;;iBA4CiB;WACN,SAAS;WACT,MAAM;;;qBAIJ;WAEA;WACA;;WAEA,KAAK;WACL;;WAEA;WACA,UAAU,cAAc;;WAExB,SAAS;;WAET,QAAQ;WACR;;WAEA,OAAO;;WAEP;;WAEA,aAAa;EAlBb,YAAA,cACA;;EAEA,KAAK,iBACL;;EAEA,mBACA,UAAU,cAAc;;EAExB,SAAS;;EAET,QAAQ,+CACR;;EAEA,OAAO;;EAEP;;EAEA,aAAa;;;;;;;iBAST;;WAEN,SAAS;;WAET;;WAEA;WACA,cAAc;;;cAInB;WAEO,OAAO;WACP;WACA;EACF;EAHE,YAAA,OAAO,OACP,eACA,aACF;;qBAIE;;qBAMA,WAAY,GAAG,SAAS,kBAAgB;;;;;iBA2DpC;WACN;WACA;WACA;;;iBAIM;WACN,MAAM;WACN;WACA;WACA,UAAU,cAAc;WACxB,OAAO;;WAEP;WACA,UAAU;;;iBAIJ;EACf,KAAK,GAAG,OAAO,YAAY,OAAO,OAAO,eAAe,GAAG,KAAK,KAAK,cAAc,iBAAiB;EACpG,MAAM,GAAG,OAAO,YAAY,OAAO,OAAO,eAAe,GAAG,eAAe;;EAE3E,QAAQ,eAAe,SAAS,SAAS,MAAM;;;;;EAK/C,KAAK;;EAEL,MAAM;;EAEN,QAAQ,cAAc;;;;;;;;qBASX,yBAAyB;WAgBzB,OAAO;WACP,UAAU;;;;;;EAXrB;;WAES,OAAO,MAAM;;EAEtB;;EAEA,YAAY;EACZ;EAGW,YAAA,OAAO,YACP,UAAU;EAQrB,MAAM;EAIN,QAAQ,cAAc;;UAQd;EAIR,KAAK,GAAG,OAAO,YAAY,OAAO,OAAO,eAAe,GAAG,KAAK,KAAK,cAAc,iBAAiB;EA0DpG,KAAK;;UAMG;EAIR,MAAM,GAAG,OAAO,YAAY,OAAO,OAAO,eAAe,GAAG,eAAe;EAQ3E,QAAQ,eAAe,SAAS,SAAS,MAAM;;;;;;EAkB/C,OAAO,cAAc,gBAAgB,OAAO,uBAAuB,qBAAqB;;;;;;;UAqBhF;;UAsCA"}