@thomasfosterau/effect-parse 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +202 -0
- package/README.md +56 -14
- package/dist/Ascii.d.ts +11 -4
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +12 -4
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +5 -2
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +83 -37
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +11 -4
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +74 -2
- package/dist/Compiler.d.ts.map +1 -1
- package/dist/Compiler.js +78 -1
- package/dist/Compiler.js.map +1 -1
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +86 -74
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +56 -5
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +70 -1
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +5 -15
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +69 -11
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +129 -28
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +375 -29
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +394 -37
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +2 -3
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +122 -14
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +293 -62
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +23 -5
- package/dist/Syntax.d.ts.map +1 -1
- package/dist/Syntax.js +1 -1
- package/dist/Syntax.js.map +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +21 -15
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +65 -11
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +73 -26
- package/dist/Token.js.map +1 -1
- package/dist/internal/compiler/closure.d.ts +1 -1
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +263 -113
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +3 -1
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +3 -2
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +9 -2
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/graph.d.ts +39 -0
- package/dist/internal/compiler/graph.d.ts.map +1 -0
- package/dist/internal/compiler/graph.js +78 -0
- package/dist/internal/compiler/graph.js.map +1 -0
- package/dist/internal/compiler/jit.d.ts +5 -0
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +208 -106
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +11 -3
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/search.d.ts +32 -0
- package/dist/internal/compiler/search.d.ts.map +1 -0
- package/dist/internal/compiler/search.js +68 -0
- package/dist/internal/compiler/search.js.map +1 -0
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +1 -1
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/compiler/wasm.d.ts +8 -0
- package/dist/internal/compiler/wasm.d.ts.map +1 -0
- package/dist/internal/compiler/wasm.js +2840 -0
- package/dist/internal/compiler/wasm.js.map +1 -0
- package/dist/internal/compiler/wasmAsm.d.ts +199 -0
- package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
- package/dist/internal/compiler/wasmAsm.js +427 -0
- package/dist/internal/compiler/wasmAsm.js.map +1 -0
- package/dist/internal/entries.d.ts +3 -1
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +77 -3
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +54 -10
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/run.d.ts +14 -0
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +53 -11
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +14 -0
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +24 -2
- package/dist/internal/stack.js.map +1 -1
- package/dist/internal/syntax.d.ts +4 -4
- package/dist/internal/syntax.d.ts.map +1 -1
- package/dist/internal/syntax.js +18 -10
- package/dist/internal/syntax.js.map +1 -1
- package/dist/internal/text.d.ts +32 -0
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +68 -14
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +20 -0
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +72 -39
- package/dist/internal/tokens.js.map +1 -1
- package/dist/internal/tuple.d.ts +6 -0
- package/dist/internal/tuple.d.ts.map +1 -0
- package/dist/internal/tuple.js +170 -0
- package/dist/internal/tuple.js.map +1 -0
- package/package.json +18 -10
- package/src/Ascii.ts +47 -12
- package/src/Binary.ts +174 -73
- package/src/Bits.ts +16 -6
- package/src/Compiler.ts +101 -10
- package/src/Expression.ts +94 -81
- package/src/Input.ts +99 -7
- package/src/Nom.ts +15 -5
- package/src/ParseError.ts +209 -52
- package/src/Parser.ts +684 -143
- package/src/ParserSchema.ts +1 -2
- package/src/ParserStream.ts +361 -68
- package/src/Syntax.ts +60 -36
- package/src/Text.ts +32 -27
- package/src/Token.ts +152 -34
- package/src/internal/compiler/closure.ts +371 -153
- package/src/internal/compiler/entries.ts +4 -2
- package/src/internal/compiler/first.ts +16 -0
- package/src/internal/compiler/graph.ts +96 -0
- package/src/internal/compiler/jit.ts +319 -169
- package/src/internal/compiler/registry.ts +10 -2
- package/src/internal/compiler/search.ts +68 -0
- package/src/internal/compiler/sets.ts +7 -3
- package/src/internal/compiler/wasm.ts +3276 -0
- package/src/internal/compiler/wasmAsm.ts +484 -0
- package/src/internal/entries.ts +8 -2
- package/src/internal/node.ts +103 -7
- package/src/internal/numbers.ts +3 -1
- package/src/internal/run.ts +73 -12
- package/src/internal/stack.ts +25 -1
- package/src/internal/syntax.ts +39 -18
- package/src/internal/text.ts +97 -9
- package/src/internal/tokens.ts +106 -14
- package/src/internal/tuple.ts +141 -0
package/src/ParseError.ts
CHANGED
|
@@ -79,37 +79,140 @@ export type ErrorKind =
|
|
|
79
79
|
*/
|
|
80
80
|
export const TypeId = "~effect-parse/ParseError" as const
|
|
81
81
|
|
|
82
|
+
/** What a {@link ParseError} is built from. */
|
|
83
|
+
interface Fields<E> {
|
|
84
|
+
/** The input that was being parsed. */
|
|
85
|
+
readonly input: Input
|
|
86
|
+
/** The offset of the failure in the input. */
|
|
87
|
+
readonly offset: number
|
|
88
|
+
/** The kind of parser that failed. */
|
|
89
|
+
readonly kind: ErrorKind
|
|
90
|
+
/** How the error propagated before parsing stopped. */
|
|
91
|
+
readonly mode: ErrMode
|
|
92
|
+
/** Descriptions of what was expected at `offset`. */
|
|
93
|
+
readonly expected: ReadonlyArray<string>
|
|
94
|
+
/** Context labels (`Parser.context`), innermost first. */
|
|
95
|
+
readonly context: ReadonlyArray<string>
|
|
96
|
+
/** The user supplied cause, if any. */
|
|
97
|
+
readonly cause: E | undefined
|
|
98
|
+
/** An optional free-form description. */
|
|
99
|
+
readonly description: string | undefined
|
|
100
|
+
/**
|
|
101
|
+
* For byte inputs parsed by `Text` parsers, the text encoding. Errors
|
|
102
|
+
* then show the input as text, with line and column numbers.
|
|
103
|
+
*/
|
|
104
|
+
readonly encoding?: Encoding<Uint8Array> | undefined
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* What a {@link ParseError} serialises as (`toJSON`): everything but the
|
|
109
|
+
* input it was parsing and the encoding it was read in.
|
|
110
|
+
*
|
|
111
|
+
* @since 0.6.0
|
|
112
|
+
* @category models
|
|
113
|
+
*/
|
|
114
|
+
export interface ParseErrorJson<out E = never> {
|
|
115
|
+
readonly _tag: "ParseError"
|
|
116
|
+
/** The offset of the failure in the input. */
|
|
117
|
+
readonly offset: number
|
|
118
|
+
/** The 1-based line and column of the failure. */
|
|
119
|
+
readonly position: LineColumn
|
|
120
|
+
readonly kind: ErrorKind
|
|
121
|
+
readonly mode: ErrMode
|
|
122
|
+
readonly expected: ReadonlyArray<string>
|
|
123
|
+
readonly context: ReadonlyArray<string>
|
|
124
|
+
readonly cause: E | undefined
|
|
125
|
+
readonly description: string | undefined
|
|
126
|
+
/** The rendered message, which shows a bounded window of the input around the failure. */
|
|
127
|
+
readonly message: string
|
|
128
|
+
}
|
|
129
|
+
|
|
82
130
|
/**
|
|
83
131
|
* An error produced by running a parser.
|
|
84
132
|
*
|
|
133
|
+
* The error keeps the whole input alive for as long as it is retained
|
|
134
|
+
* (`input`), but does not serialise it: `input` and `encoding` are
|
|
135
|
+
* accessors, not own properties, `toJSON` (which `JSON.stringify`,
|
|
136
|
+
* Effect's `Cause` rendering and Node's `inspect` use) leaves them out, and
|
|
137
|
+
* `message` shows a bounded window around the failure, never a whole line.
|
|
138
|
+
*
|
|
85
139
|
* @since 0.1.0
|
|
86
140
|
* @category models
|
|
87
141
|
*/
|
|
88
142
|
export class ParseError<out E = never>
|
|
89
|
-
extends /*#__PURE__*/ Data.TaggedError("ParseError")<
|
|
90
|
-
/** The input that was being parsed. */
|
|
91
|
-
readonly input: Input
|
|
92
|
-
/** The offset of the failure in the input. */
|
|
93
|
-
readonly offset: number
|
|
94
|
-
/** The kind of parser that failed. */
|
|
95
|
-
readonly kind: ErrorKind
|
|
96
|
-
/** How the error propagated before parsing stopped. */
|
|
97
|
-
readonly mode: ErrMode
|
|
98
|
-
/** Descriptions of what was expected at `offset`. */
|
|
99
|
-
readonly expected: ReadonlyArray<string>
|
|
100
|
-
/** Context labels (`Parser.context`), innermost first. */
|
|
101
|
-
readonly context: ReadonlyArray<string>
|
|
102
|
-
/** The user supplied cause, if any. */
|
|
103
|
-
readonly cause: E | undefined
|
|
104
|
-
/** An optional free-form description. */
|
|
105
|
-
readonly description: string | undefined
|
|
106
|
-
/**
|
|
107
|
-
* For byte inputs parsed by `Text` parsers, the text encoding. Errors
|
|
108
|
-
* then show the input as text, with line and column numbers.
|
|
109
|
-
*/
|
|
110
|
-
readonly encoding?: Encoding<Uint8Array> | undefined
|
|
111
|
-
}>
|
|
143
|
+
extends /*#__PURE__*/ Data.TaggedError("ParseError")<Omit<Fields<unknown>, "input" | "encoding">>
|
|
112
144
|
{
|
|
145
|
+
/** The user supplied cause, if any. */
|
|
146
|
+
declare readonly cause: E | undefined
|
|
147
|
+
|
|
148
|
+
// Private fields, not properties: nothing that walks the error (its own
|
|
149
|
+
// keys, enumerable or not, or the arguments `Data.TaggedError` keeps for
|
|
150
|
+
// `toJSON` and structural equality) can reach the input (#117)
|
|
151
|
+
readonly #input: Input
|
|
152
|
+
readonly #encoding: Encoding<Uint8Array> | undefined
|
|
153
|
+
// Both are functions of the fields above, which never change, and both
|
|
154
|
+
// scan the input up to the failure: computed on first use, then kept
|
|
155
|
+
#position: LineColumn | undefined
|
|
156
|
+
#message: string | undefined
|
|
157
|
+
|
|
158
|
+
constructor(fields: Fields<E>) {
|
|
159
|
+
super({
|
|
160
|
+
offset: fields.offset,
|
|
161
|
+
kind: fields.kind,
|
|
162
|
+
mode: fields.mode,
|
|
163
|
+
expected: fields.expected,
|
|
164
|
+
context: fields.context,
|
|
165
|
+
cause: fields.cause,
|
|
166
|
+
description: fields.description
|
|
167
|
+
})
|
|
168
|
+
this.#input = fields.input
|
|
169
|
+
this.#encoding = fields.encoding
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* The input that was being parsed. The error holds it (for
|
|
174
|
+
* {@link ParseError.position} and the message) and keeps it alive, but it
|
|
175
|
+
* is not one of the error's own properties, so `JSON.stringify`, object
|
|
176
|
+
* spread, `Object.keys`, `toJSON` and loggers do not see it.
|
|
177
|
+
*
|
|
178
|
+
* @since 0.1.0
|
|
179
|
+
*/
|
|
180
|
+
get input(): Input {
|
|
181
|
+
return this.#input
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* For byte inputs parsed by `Text` parsers, the text encoding. Errors
|
|
186
|
+
* then show the input as text, with line and column numbers. Like
|
|
187
|
+
* `input`, it is not an own property.
|
|
188
|
+
*
|
|
189
|
+
* @since 0.1.0
|
|
190
|
+
*/
|
|
191
|
+
get encoding(): Encoding<Uint8Array> | undefined {
|
|
192
|
+
return this.#encoding
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The error without its `input` and `encoding`: what `JSON.stringify`,
|
|
197
|
+
* Effect's `Cause` rendering and Node's `inspect` show.
|
|
198
|
+
*
|
|
199
|
+
* @since 0.6.0
|
|
200
|
+
*/
|
|
201
|
+
override toJSON(): ParseErrorJson<E> {
|
|
202
|
+
return {
|
|
203
|
+
_tag: this._tag,
|
|
204
|
+
offset: this.offset,
|
|
205
|
+
position: this.position,
|
|
206
|
+
kind: this.kind,
|
|
207
|
+
mode: this.mode,
|
|
208
|
+
expected: this.expected,
|
|
209
|
+
context: this.context,
|
|
210
|
+
cause: this.cause,
|
|
211
|
+
description: this.description,
|
|
212
|
+
message: this.message
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
113
216
|
/**
|
|
114
217
|
* @since 0.1.0
|
|
115
218
|
*/
|
|
@@ -122,7 +225,7 @@ export class ParseError<out E = never>
|
|
|
122
225
|
* @since 0.1.0
|
|
123
226
|
*/
|
|
124
227
|
get position(): LineColumn {
|
|
125
|
-
return lineColumn(this
|
|
228
|
+
return (this.#position ??= lineColumn(this.#input, this.offset, this.#encoding))
|
|
126
229
|
}
|
|
127
230
|
|
|
128
231
|
/**
|
|
@@ -131,7 +234,7 @@ export class ParseError<out E = never>
|
|
|
131
234
|
* @since 0.1.0
|
|
132
235
|
*/
|
|
133
236
|
override get message(): string {
|
|
134
|
-
return render(this)
|
|
237
|
+
return (this.#message ??= render(this))
|
|
135
238
|
}
|
|
136
239
|
|
|
137
240
|
/**
|
|
@@ -167,6 +270,9 @@ export const fromFailure = <E = never>(
|
|
|
167
270
|
mode,
|
|
168
271
|
expected: failure.expected,
|
|
169
272
|
context: failure.context,
|
|
273
|
+
// SAFETY: `E` is the user error type of the parser whose run recorded
|
|
274
|
+
// `failure`; a failure with `hasCause` carries a cause raised by that
|
|
275
|
+
// parser's `fail` / `mapError`
|
|
170
276
|
cause: failure.hasCause ? (failure.cause as E) : undefined,
|
|
171
277
|
description: failure.message,
|
|
172
278
|
encoding: input instanceof Uint8Array ? encoding : undefined
|
|
@@ -300,43 +406,94 @@ const causeMessage = (cause: unknown): string | undefined => {
|
|
|
300
406
|
return inspectToken(cause)
|
|
301
407
|
}
|
|
302
408
|
|
|
303
|
-
|
|
409
|
+
/**
|
|
410
|
+
* How many characters of the failing line a message shows on each side of
|
|
411
|
+
* the failure. A line has no length limit (minified JSON is one line), and
|
|
412
|
+
* the input's sender chooses its length, so the message shows a window
|
|
413
|
+
* and marks what it left out with `…`.
|
|
414
|
+
*/
|
|
415
|
+
const SnippetWindow = 60
|
|
416
|
+
|
|
417
|
+
const Ellipsis = "…"
|
|
418
|
+
|
|
419
|
+
/** The two lines of a text snippet: the window of the line, and a caret under the failure. */
|
|
420
|
+
const snippetLines = (line: number, window: string, before: number, cutStart: boolean, cutEnd: boolean) => {
|
|
421
|
+
const gutter = String(line)
|
|
422
|
+
const pad = " ".repeat(gutter.length)
|
|
423
|
+
const shown = window.endsWith("\r") && !cutEnd ? window.slice(0, -1) : window
|
|
424
|
+
return [
|
|
425
|
+
`${gutter} | ${cutStart ? Ellipsis : ""}${shown}${cutEnd ? Ellipsis : ""}`,
|
|
426
|
+
`${pad} | ${" ".repeat(before + (cutStart ? 1 : 0))}^`
|
|
427
|
+
]
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const isHighSurrogate = (c: number): boolean => c >= 0xd800 && c <= 0xdbff
|
|
431
|
+
const isLowSurrogate = (c: number): boolean => c >= 0xdc00 && c <= 0xdfff
|
|
432
|
+
|
|
433
|
+
const renderSnippet = (
|
|
434
|
+
input: Input,
|
|
435
|
+
offset: number,
|
|
436
|
+
encoding: Encoding<any> | undefined,
|
|
437
|
+
line: number
|
|
438
|
+
): Array<string> => {
|
|
304
439
|
if (encoding !== undefined && input instanceof Uint8Array) {
|
|
305
|
-
//
|
|
440
|
+
// The window is found in one walk: where the last `SnippetWindow`
|
|
441
|
+
// characters before the failure start (a ring of their offsets), and
|
|
442
|
+
// where the line or the window ends after it
|
|
443
|
+
const ring = new Array<number>(SnippetWindow)
|
|
444
|
+
let before = 0
|
|
306
445
|
let lineStart = 0
|
|
446
|
+
let after = 0
|
|
307
447
|
let end = input.length
|
|
308
|
-
let
|
|
448
|
+
let cutEnd = false
|
|
309
449
|
text.walk(encoding, input, 0, input.length, (cp, i, w) => {
|
|
310
|
-
if (i >= offset && cp === 10) {
|
|
311
|
-
end = i
|
|
312
|
-
return false
|
|
313
|
-
}
|
|
314
450
|
if (i < offset) {
|
|
315
451
|
if (cp === 10) {
|
|
452
|
+
before = 0
|
|
316
453
|
lineStart = i + w
|
|
317
|
-
column = 1
|
|
318
454
|
} else {
|
|
319
|
-
|
|
455
|
+
ring[before % SnippetWindow] = i
|
|
456
|
+
before++
|
|
320
457
|
}
|
|
458
|
+
return
|
|
321
459
|
}
|
|
460
|
+
if (cp === 10) {
|
|
461
|
+
end = i
|
|
462
|
+
return false
|
|
463
|
+
}
|
|
464
|
+
if (after === SnippetWindow) {
|
|
465
|
+
end = i
|
|
466
|
+
cutEnd = true
|
|
467
|
+
return false
|
|
468
|
+
}
|
|
469
|
+
after++
|
|
322
470
|
})
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
return [`${gutter} | ${line}`, `${pad} | ${" ".repeat(column - 1)}^`]
|
|
471
|
+
const cutStart = before > SnippetWindow
|
|
472
|
+
const start = cutStart ? ring[before % SnippetWindow] : lineStart
|
|
473
|
+
const shown = Math.min(before, SnippetWindow)
|
|
474
|
+
return snippetLines(line, text.lenientText(encoding, input, start, end), shown, cutStart, cutEnd)
|
|
328
475
|
}
|
|
329
476
|
if (Predicate.isString(input)) {
|
|
330
|
-
const
|
|
331
|
-
let start =
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
477
|
+
const at = Math.min(offset, input.length)
|
|
478
|
+
let start = at
|
|
479
|
+
let before = 0
|
|
480
|
+
while (start > 0 && input.charCodeAt(start - 1) !== 10 && before < SnippetWindow) {
|
|
481
|
+
start--
|
|
482
|
+
// A surrogate pair is one character of the window, and is never split
|
|
483
|
+
if (start > 0 && isLowSurrogate(input.charCodeAt(start)) && isHighSurrogate(input.charCodeAt(start - 1))) start--
|
|
484
|
+
before++
|
|
485
|
+
}
|
|
486
|
+
const cutStart = start > 0 && input.charCodeAt(start - 1) !== 10
|
|
487
|
+
let end = at
|
|
488
|
+
let after = 0
|
|
489
|
+
while (end < input.length && input.charCodeAt(end) !== 10 && after < SnippetWindow) {
|
|
490
|
+
if (isHighSurrogate(input.charCodeAt(end)) && end + 1 < input.length && isLowSurrogate(input.charCodeAt(end + 1)))
|
|
491
|
+
end++
|
|
492
|
+
end++
|
|
493
|
+
after++
|
|
494
|
+
}
|
|
495
|
+
const cutEnd = end < input.length && input.charCodeAt(end) !== 10
|
|
496
|
+
return snippetLines(line, input.slice(start, end), before, cutStart, cutEnd)
|
|
340
497
|
}
|
|
341
498
|
if (input instanceof Uint8Array) {
|
|
342
499
|
const start = Math.max(0, offset - 8)
|
|
@@ -353,15 +510,15 @@ const render = (error: ParseError<unknown>): string => {
|
|
|
353
510
|
const { encoding, input, offset } = error
|
|
354
511
|
const lines: Array<string> = []
|
|
355
512
|
if (Predicate.isString(input)) {
|
|
356
|
-
const { column, line } =
|
|
513
|
+
const { column, line } = error.position
|
|
357
514
|
lines.push(`Parse error at line ${line}, column ${column}:`)
|
|
358
515
|
} else if (encoding !== undefined) {
|
|
359
|
-
const { column, line } =
|
|
516
|
+
const { column, line } = error.position
|
|
360
517
|
lines.push(`Parse error at line ${line}, column ${column} (byte ${offset}):`)
|
|
361
518
|
} else {
|
|
362
519
|
lines.push(`Parse error at offset ${offset}:`)
|
|
363
520
|
}
|
|
364
|
-
lines.push(...renderSnippet(input, offset, encoding))
|
|
521
|
+
lines.push(...renderSnippet(input, offset, encoding, error.position.line))
|
|
365
522
|
for (let i = error.context.length - 1; i >= 0; i--) {
|
|
366
523
|
lines.push(`while parsing ${error.context[i]}`)
|
|
367
524
|
}
|