@thomasfosterau/effect-parse 0.1.0 → 0.2.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 (155) hide show
  1. package/README.md +247 -230
  2. package/dist/Ascii.d.ts +32 -53
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +576 -571
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts +6 -29
  7. package/dist/Binary.d.ts.map +1 -1
  8. package/dist/Binary.js +129 -116
  9. package/dist/Binary.js.map +1 -1
  10. package/dist/Bits.d.ts +4 -2
  11. package/dist/Bits.d.ts.map +1 -1
  12. package/dist/Bits.js +121 -123
  13. package/dist/Bits.js.map +1 -1
  14. package/dist/Compiler.d.ts +39 -0
  15. package/dist/Compiler.d.ts.map +1 -0
  16. package/dist/Compiler.js +48 -0
  17. package/dist/Compiler.js.map +1 -0
  18. package/dist/Encoding.d.ts +29 -46
  19. package/dist/Encoding.d.ts.map +1 -1
  20. package/dist/Encoding.js +76 -75
  21. package/dist/Encoding.js.map +1 -1
  22. package/dist/Expression.d.ts +15 -49
  23. package/dist/Expression.d.ts.map +1 -1
  24. package/dist/Expression.js +143 -131
  25. package/dist/Expression.js.map +1 -1
  26. package/dist/Input.d.ts +206 -177
  27. package/dist/Input.d.ts.map +1 -1
  28. package/dist/Input.js +317 -299
  29. package/dist/Input.js.map +1 -1
  30. package/dist/Nom.d.ts +44 -84
  31. package/dist/Nom.d.ts.map +1 -1
  32. package/dist/Nom.js +423 -453
  33. package/dist/Nom.js.map +1 -1
  34. package/dist/ParseError.d.ts +54 -49
  35. package/dist/ParseError.d.ts.map +1 -1
  36. package/dist/ParseError.js +233 -275
  37. package/dist/ParseError.js.map +1 -1
  38. package/dist/Parser.d.ts +345 -313
  39. package/dist/Parser.d.ts.map +1 -1
  40. package/dist/Parser.js +2010 -1802
  41. package/dist/Parser.js.map +1 -1
  42. package/dist/ParserSchema.d.ts +8 -7
  43. package/dist/ParserSchema.d.ts.map +1 -1
  44. package/dist/ParserSchema.js +49 -49
  45. package/dist/ParserSchema.js.map +1 -1
  46. package/dist/ParserStream.d.ts +26 -20
  47. package/dist/ParserStream.d.ts.map +1 -1
  48. package/dist/ParserStream.js +267 -255
  49. package/dist/ParserStream.js.map +1 -1
  50. package/dist/Syntax.d.ts +401 -0
  51. package/dist/Syntax.d.ts.map +1 -0
  52. package/dist/Syntax.js +717 -0
  53. package/dist/Syntax.js.map +1 -0
  54. package/dist/Text.d.ts +98 -134
  55. package/dist/Text.d.ts.map +1 -1
  56. package/dist/Text.js +534 -496
  57. package/dist/Text.js.map +1 -1
  58. package/dist/Token.d.ts +60 -42
  59. package/dist/Token.d.ts.map +1 -1
  60. package/dist/Token.js +331 -265
  61. package/dist/Token.js.map +1 -1
  62. package/dist/index.d.ts +16 -17
  63. package/dist/index.js +16 -17
  64. package/dist/internal/compiler/closure.d.ts +14 -16
  65. package/dist/internal/compiler/closure.d.ts.map +1 -1
  66. package/dist/internal/compiler/closure.js +1458 -1637
  67. package/dist/internal/compiler/closure.js.map +1 -1
  68. package/dist/internal/compiler/entries.d.ts +11 -11
  69. package/dist/internal/compiler/entries.d.ts.map +1 -1
  70. package/dist/internal/compiler/entries.js +36 -26
  71. package/dist/internal/compiler/entries.js.map +1 -1
  72. package/dist/internal/compiler/first.d.ts +19 -19
  73. package/dist/internal/compiler/first.d.ts.map +1 -1
  74. package/dist/internal/compiler/first.js +251 -227
  75. package/dist/internal/compiler/first.js.map +1 -1
  76. package/dist/internal/compiler/jit.d.ts +6 -17
  77. package/dist/internal/compiler/jit.d.ts.map +1 -1
  78. package/dist/internal/compiler/jit.js +860 -988
  79. package/dist/internal/compiler/jit.js.map +1 -1
  80. package/dist/internal/compiler/registry.d.ts +20 -21
  81. package/dist/internal/compiler/registry.d.ts.map +1 -1
  82. package/dist/internal/compiler/registry.js +21 -41
  83. package/dist/internal/compiler/registry.js.map +1 -1
  84. package/dist/internal/compiler/sets.d.ts +9 -13
  85. package/dist/internal/compiler/sets.d.ts.map +1 -1
  86. package/dist/internal/compiler/sets.js +76 -73
  87. package/dist/internal/compiler/sets.js.map +1 -1
  88. package/dist/internal/entries.d.ts +3 -3
  89. package/dist/internal/entries.d.ts.map +1 -1
  90. package/dist/internal/entries.js +38 -30
  91. package/dist/internal/entries.js.map +1 -1
  92. package/dist/internal/node.d.ts +177 -173
  93. package/dist/internal/node.d.ts.map +1 -1
  94. package/dist/internal/node.js +77 -66
  95. package/dist/internal/node.js.map +1 -1
  96. package/dist/internal/numbers.d.ts +7 -8
  97. package/dist/internal/numbers.d.ts.map +1 -1
  98. package/dist/internal/numbers.js +246 -276
  99. package/dist/internal/numbers.js.map +1 -1
  100. package/dist/internal/resume.d.ts +6 -24
  101. package/dist/internal/resume.d.ts.map +1 -1
  102. package/dist/internal/resume.js +30 -29
  103. package/dist/internal/resume.js.map +1 -1
  104. package/dist/internal/run.d.ts +15 -0
  105. package/dist/internal/run.d.ts.map +1 -0
  106. package/dist/internal/run.js +36 -0
  107. package/dist/internal/run.js.map +1 -0
  108. package/dist/internal/stack.d.ts +16 -0
  109. package/dist/internal/stack.d.ts.map +1 -0
  110. package/dist/internal/stack.js +26 -0
  111. package/dist/internal/stack.js.map +1 -0
  112. package/dist/internal/syntax.d.ts +146 -0
  113. package/dist/internal/syntax.d.ts.map +1 -0
  114. package/dist/internal/syntax.js +305 -0
  115. package/dist/internal/syntax.js.map +1 -0
  116. package/dist/internal/text.d.ts +10 -2
  117. package/dist/internal/text.d.ts.map +1 -1
  118. package/dist/internal/text.js +295 -345
  119. package/dist/internal/text.js.map +1 -1
  120. package/dist/internal/tokens.d.ts +25 -30
  121. package/dist/internal/tokens.d.ts.map +1 -1
  122. package/dist/internal/tokens.js +369 -363
  123. package/dist/internal/tokens.js.map +1 -1
  124. package/package.json +42 -28
  125. package/src/Ascii.ts +278 -187
  126. package/src/Binary.ts +150 -44
  127. package/src/Bits.ts +6 -3
  128. package/src/Compiler.ts +98 -0
  129. package/src/Expression.ts +10 -5
  130. package/src/Input.ts +106 -28
  131. package/src/Nom.ts +4 -3
  132. package/src/ParseError.ts +48 -51
  133. package/src/Parser.ts +1163 -795
  134. package/src/ParserStream.ts +104 -80
  135. package/src/Syntax.ts +900 -0
  136. package/src/Text.ts +272 -187
  137. package/src/Token.ts +180 -87
  138. package/src/index.ts +2 -0
  139. package/src/internal/compiler/closure.ts +121 -88
  140. package/src/internal/compiler/entries.ts +21 -8
  141. package/src/internal/compiler/first.ts +17 -15
  142. package/src/internal/compiler/jit.ts +360 -157
  143. package/src/internal/compiler/registry.ts +12 -33
  144. package/src/internal/compiler/sets.ts +17 -11
  145. package/src/internal/entries.ts +4 -2
  146. package/src/internal/node.ts +51 -37
  147. package/src/internal/numbers.ts +22 -20
  148. package/src/internal/resume.ts +8 -4
  149. package/src/internal/run.ts +41 -0
  150. package/src/internal/stack.ts +36 -0
  151. package/src/internal/syntax.ts +421 -0
  152. package/src/internal/text.ts +32 -25
  153. package/src/internal/tokens.ts +96 -51
  154. package/dist/index.d.ts.map +0 -1
  155. package/dist/index.js.map +0 -1
package/src/Nom.ts CHANGED
@@ -116,8 +116,9 @@ export const isA = <I extends Input = string>(set: TokenSet<I>): Parser<Slice<No
116
116
  * @since 0.1.0
117
117
  * @category bytes
118
118
  */
119
- export const isNot = <I extends Input = string>(set: TokenSet<I>): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> =>
120
- Token.takeTill<I>(set, { min: 1 })
119
+ export const isNot = <I extends Input = string>(
120
+ set: TokenSet<I>
121
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeTill<I>(set, { min: 1 })
121
122
 
122
123
  /**
123
124
  * @since 0.1.0
@@ -265,7 +266,7 @@ export const double = Ascii.float
265
266
  * @since 0.1.0
266
267
  * @category number
267
268
  */
268
- export const recognizeFloat: Parser<string> = P.taken(Ascii.float)
269
+ export const recognizeFloat: Parser<string> = /*#__PURE__*/ P.taken(Ascii.float)
269
270
 
270
271
  /**
271
272
  * nom's `hex_u32`.
package/src/ParseError.ts CHANGED
@@ -19,6 +19,7 @@
19
19
  *
20
20
  * @since 0.1.0
21
21
  */
22
+ import * as Predicate from "effect/Predicate"
22
23
  import * as Data from "effect/Data"
23
24
  import * as Option from "effect/Option"
24
25
  import type { Encoding } from "./Encoding.js"
@@ -29,6 +30,9 @@ import * as text from "./internal/text.js"
29
30
  * The kind of parser that produced an error, in the spirit of nom's
30
31
  * `ErrorKind`.
31
32
  *
33
+ * `"TooDeep"` is not produced by a parser: the runners report it when
34
+ * deeply nested input exhausts the call stack (see `Parser.suspend`).
35
+ *
32
36
  * @since 0.1.0
33
37
  * @category models
34
38
  */
@@ -64,13 +68,14 @@ export type ErrorKind =
64
68
  | "TakeUntil"
65
69
  | "TakeWhile"
66
70
  | "Token"
71
+ | "TooDeep"
67
72
  | "Verify"
68
73
 
69
74
  /**
70
75
  * @since 0.1.0
71
76
  * @category type ids
72
77
  */
73
- export const TypeId: "~effect-parse/ParseError" = "~effect-parse/ParseError"
78
+ export const TypeId = "~effect-parse/ParseError" as const
74
79
 
75
80
  /**
76
81
  * An error produced by running a parser.
@@ -78,29 +83,31 @@ export const TypeId: "~effect-parse/ParseError" = "~effect-parse/ParseError"
78
83
  * @since 0.1.0
79
84
  * @category models
80
85
  */
81
- export class ParseError<out E = never> extends Data.TaggedError("ParseError")<{
82
- /** The input that was being parsed. */
83
- readonly input: Input
84
- /** The offset of the failure in the input. */
85
- readonly offset: number
86
- /** The kind of parser that failed. */
87
- readonly kind: ErrorKind
88
- /** How the error propagated before parsing stopped. */
89
- readonly mode: ErrMode
90
- /** Descriptions of what was expected at `offset`. */
91
- readonly expected: ReadonlyArray<string>
92
- /** Context labels (`Parser.context`), innermost first. */
93
- readonly context: ReadonlyArray<string>
94
- /** The user supplied cause, if any. */
95
- readonly cause: E | undefined
96
- /** An optional free-form description. */
97
- readonly description: string | undefined
98
- /**
99
- * For byte inputs parsed by `Text` parsers, the text encoding. Errors
100
- * then show the input as text, with line and column numbers.
101
- */
102
- readonly encoding?: Encoding<Uint8Array> | undefined
103
- }> {
86
+ export class ParseError<out E = never>
87
+ extends /*#__PURE__*/ Data.TaggedError("ParseError")<{
88
+ /** The input that was being parsed. */
89
+ readonly input: Input
90
+ /** The offset of the failure in the input. */
91
+ readonly offset: number
92
+ /** The kind of parser that failed. */
93
+ readonly kind: ErrorKind
94
+ /** How the error propagated before parsing stopped. */
95
+ readonly mode: ErrMode
96
+ /** Descriptions of what was expected at `offset`. */
97
+ readonly expected: ReadonlyArray<string>
98
+ /** Context labels (`Parser.context`), innermost first. */
99
+ readonly context: ReadonlyArray<string>
100
+ /** The user supplied cause, if any. */
101
+ readonly cause: E | undefined
102
+ /** An optional free-form description. */
103
+ readonly description: string | undefined
104
+ /**
105
+ * For byte inputs parsed by `Text` parsers, the text encoding. Errors
106
+ * then show the input as text, with line and column numbers.
107
+ */
108
+ readonly encoding?: Encoding<Uint8Array> | undefined
109
+ }>
110
+ {
104
111
  /**
105
112
  * @since 0.1.0
106
113
  */
@@ -137,8 +144,7 @@ export class ParseError<out E = never> extends Data.TaggedError("ParseError")<{
137
144
  * @since 0.1.0
138
145
  * @category guards
139
146
  */
140
- export const isParseError = (u: unknown): u is ParseError<unknown> =>
141
- typeof u === "object" && u !== null && TypeId in u
147
+ export const isParseError = (u: unknown): u is ParseError<unknown> => Predicate.isObjectOrArray(u) && TypeId in u
142
148
 
143
149
  /**
144
150
  * Builds a `ParseError` from the failure details recorded while parsing.
@@ -159,7 +165,7 @@ export const fromFailure = <E = never>(
159
165
  mode,
160
166
  expected: failure.expected,
161
167
  context: failure.context,
162
- cause: failure.hasCause ? failure.cause as E : undefined,
168
+ cause: failure.hasCause ? (failure.cause as E) : undefined,
163
169
  description: failure.message,
164
170
  encoding: input instanceof Uint8Array ? encoding : undefined
165
171
  })
@@ -207,7 +213,7 @@ export const lineColumn = (input: Input, offset: number, encoding?: Encoding<any
207
213
  })
208
214
  return { line, column }
209
215
  }
210
- if (typeof input !== "string") return { line: 1, column: offset + 1 }
216
+ if (!Predicate.isString(input)) return { line: 1, column: offset + 1 }
211
217
  let line = 1
212
218
  let lineStart = 0
213
219
  for (let i = 0; i < offset && i < input.length; i++) {
@@ -240,7 +246,7 @@ const codePointCount = (s: string, start: number, end: number): number => {
240
246
  */
241
247
  export const formatExpected = (expected: ReadonlyArray<string>): string => {
242
248
  if (expected.length === 0) return ""
243
- if (expected.length === 1) return expected[0]!
249
+ if (expected.length === 1) return expected[0]
244
250
  return `${expected.slice(0, -1).join(", ")} or ${expected[expected.length - 1]}`
245
251
  }
246
252
 
@@ -257,20 +263,20 @@ const describeFound = (input: Input, offset: number, encoding: Encoding<any> | u
257
263
  ? `incomplete ${encoding.name} sequence ${hexBytes(input.subarray(offset))}`
258
264
  : `invalid ${encoding.name} ${hexBytes(bad)}`
259
265
  }
260
- if (typeof input === "string") {
261
- const cp = input.codePointAt(offset)!
266
+ if (Predicate.isString(input)) {
267
+ const cp = input.codePointAt(offset) ?? Number.NaN
262
268
  return JSON.stringify(String.fromCodePoint(cp))
263
269
  }
264
270
  if (input instanceof Uint8Array) {
265
- return `0x${input[offset]!.toString(16).padStart(2, "0")}`
271
+ return `0x${input[offset].toString(16).padStart(2, "0")}`
266
272
  }
267
273
  return inspectToken(input[offset])
268
274
  }
269
275
 
270
276
  /** @internal */
271
277
  export const inspectToken = (u: unknown): string => {
272
- if (typeof u === "string") return JSON.stringify(u)
273
- if (typeof u === "object" && u !== null) {
278
+ if (Predicate.isString(u)) return JSON.stringify(u)
279
+ if (Predicate.isObjectOrArray(u)) {
274
280
  try {
275
281
  return JSON.stringify(u)
276
282
  } catch {
@@ -282,9 +288,9 @@ export const inspectToken = (u: unknown): string => {
282
288
 
283
289
  const causeMessage = (cause: unknown): string | undefined => {
284
290
  if (cause === undefined) return undefined
285
- if (typeof cause === "string") return cause
291
+ if (Predicate.isString(cause)) return cause
286
292
  if (cause instanceof Error) return cause.message
287
- if (typeof cause === "object" && cause !== null && "message" in cause && typeof cause.message === "string") {
293
+ if (Predicate.isObjectOrArray(cause) && "message" in cause && Predicate.isString(cause.message)) {
288
294
  return cause.message
289
295
  }
290
296
  return inspectToken(cause)
@@ -314,12 +320,9 @@ const renderSnippet = (input: Input, offset: number, encoding: Encoding<any> | u
314
320
  if (line.endsWith("\r")) line = line.slice(0, -1)
315
321
  const gutter = String(lineColumn(input, offset, encoding).line)
316
322
  const pad = " ".repeat(gutter.length)
317
- return [
318
- `${gutter} | ${line}`,
319
- `${pad} | ${" ".repeat(column - 1)}^`
320
- ]
323
+ return [`${gutter} | ${line}`, `${pad} | ${" ".repeat(column - 1)}^`]
321
324
  }
322
- if (typeof input === "string") {
325
+ if (Predicate.isString(input)) {
323
326
  const { column, line } = lineColumn(input, offset)
324
327
  let start = offset
325
328
  while (start > 0 && input.charCodeAt(start - 1) !== 10) start--
@@ -329,21 +332,15 @@ const renderSnippet = (input: Input, offset: number, encoding: Encoding<any> | u
329
332
  if (text.endsWith("\r")) text = text.slice(0, -1)
330
333
  const gutter = String(line)
331
334
  const pad = " ".repeat(gutter.length)
332
- return [
333
- `${gutter} | ${text}`,
334
- `${pad} | ${" ".repeat(column - 1)}^`
335
- ]
335
+ return [`${gutter} | ${text}`, `${pad} | ${" ".repeat(column - 1)}^`]
336
336
  }
337
337
  if (input instanceof Uint8Array) {
338
338
  const start = Math.max(0, offset - 8)
339
339
  const end = Math.min(input.length, offset + 8)
340
340
  const bytes: Array<string> = []
341
- for (let i = start; i < end; i++) bytes.push(input[i]!.toString(16).padStart(2, "0"))
341
+ for (let i = start; i < end; i++) bytes.push(input[i].toString(16).padStart(2, "0"))
342
342
  const caret = (offset - start) * 3
343
- return [
344
- `${start.toString(16).padStart(8, "0")} | ${bytes.join(" ")}`,
345
- `${" ".repeat(8)} | ${" ".repeat(caret)}^`
346
- ]
343
+ return [`${start.toString(16).padStart(8, "0")} | ${bytes.join(" ")}`, `${" ".repeat(8)} | ${" ".repeat(caret)}^`]
347
344
  }
348
345
  return []
349
346
  }
@@ -351,7 +348,7 @@ const renderSnippet = (input: Input, offset: number, encoding: Encoding<any> | u
351
348
  const render = (error: ParseError<unknown>): string => {
352
349
  const { encoding, input, offset } = error
353
350
  const lines: Array<string> = []
354
- if (typeof input === "string") {
351
+ if (Predicate.isString(input)) {
355
352
  const { column, line } = lineColumn(input, offset)
356
353
  lines.push(`Parse error at line ${line}, column ${column}:`)
357
354
  } else if (encoding !== undefined) {