@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.
- package/README.md +247 -230
- package/dist/Ascii.d.ts +32 -53
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +576 -571
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +6 -29
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +129 -116
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts +4 -2
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +121 -123
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +39 -0
- package/dist/Compiler.d.ts.map +1 -0
- package/dist/Compiler.js +48 -0
- package/dist/Compiler.js.map +1 -0
- package/dist/Encoding.d.ts +29 -46
- package/dist/Encoding.d.ts.map +1 -1
- package/dist/Encoding.js +76 -75
- package/dist/Encoding.js.map +1 -1
- package/dist/Expression.d.ts +15 -49
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +143 -131
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +206 -177
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +317 -299
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +44 -84
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js +423 -453
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +54 -49
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +233 -275
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +345 -313
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +2010 -1802
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts +8 -7
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +49 -49
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +26 -20
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +267 -255
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +401 -0
- package/dist/Syntax.d.ts.map +1 -0
- package/dist/Syntax.js +717 -0
- package/dist/Syntax.js.map +1 -0
- package/dist/Text.d.ts +98 -134
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +534 -496
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +60 -42
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +331 -265
- package/dist/Token.js.map +1 -1
- package/dist/index.d.ts +16 -17
- package/dist/index.js +16 -17
- package/dist/internal/compiler/closure.d.ts +14 -16
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +1458 -1637
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +11 -11
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +36 -26
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts +19 -19
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +251 -227
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/jit.d.ts +6 -17
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +860 -988
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +20 -21
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js +21 -41
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/sets.d.ts +9 -13
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +76 -73
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/entries.d.ts +3 -3
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js +38 -30
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +177 -173
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +77 -66
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts +7 -8
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js +246 -276
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/resume.d.ts +6 -24
- package/dist/internal/resume.d.ts.map +1 -1
- package/dist/internal/resume.js +30 -29
- package/dist/internal/resume.js.map +1 -1
- package/dist/internal/run.d.ts +15 -0
- package/dist/internal/run.d.ts.map +1 -0
- package/dist/internal/run.js +36 -0
- package/dist/internal/run.js.map +1 -0
- package/dist/internal/stack.d.ts +16 -0
- package/dist/internal/stack.d.ts.map +1 -0
- package/dist/internal/stack.js +26 -0
- package/dist/internal/stack.js.map +1 -0
- package/dist/internal/syntax.d.ts +146 -0
- package/dist/internal/syntax.d.ts.map +1 -0
- package/dist/internal/syntax.js +305 -0
- package/dist/internal/syntax.js.map +1 -0
- package/dist/internal/text.d.ts +10 -2
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +295 -345
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +25 -30
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +369 -363
- package/dist/internal/tokens.js.map +1 -1
- package/package.json +42 -28
- package/src/Ascii.ts +278 -187
- package/src/Binary.ts +150 -44
- package/src/Bits.ts +6 -3
- package/src/Compiler.ts +98 -0
- package/src/Expression.ts +10 -5
- package/src/Input.ts +106 -28
- package/src/Nom.ts +4 -3
- package/src/ParseError.ts +48 -51
- package/src/Parser.ts +1163 -795
- package/src/ParserStream.ts +104 -80
- package/src/Syntax.ts +900 -0
- package/src/Text.ts +272 -187
- package/src/Token.ts +180 -87
- package/src/index.ts +2 -0
- package/src/internal/compiler/closure.ts +121 -88
- package/src/internal/compiler/entries.ts +21 -8
- package/src/internal/compiler/first.ts +17 -15
- package/src/internal/compiler/jit.ts +360 -157
- package/src/internal/compiler/registry.ts +12 -33
- package/src/internal/compiler/sets.ts +17 -11
- package/src/internal/entries.ts +4 -2
- package/src/internal/node.ts +51 -37
- package/src/internal/numbers.ts +22 -20
- package/src/internal/resume.ts +8 -4
- package/src/internal/run.ts +41 -0
- package/src/internal/stack.ts +36 -0
- package/src/internal/syntax.ts +421 -0
- package/src/internal/text.ts +32 -25
- package/src/internal/tokens.ts +96 -51
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/src/Binary.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* @since 0.1.0
|
|
19
19
|
*/
|
|
20
|
+
import * as Predicate from "effect/Predicate"
|
|
20
21
|
import type { Input, Slice, State } from "./Input.js"
|
|
21
22
|
import { Fail } from "./Input.js"
|
|
22
23
|
import type { Parser } from "./Parser.js"
|
|
@@ -41,9 +42,13 @@ export {
|
|
|
41
42
|
*/
|
|
42
43
|
export type Endianness = "big" | "little" | "native"
|
|
43
44
|
|
|
44
|
-
const nativeLittle = new Uint8Array(new Uint16Array([1]).buffer)[0] === 1
|
|
45
|
+
const nativeLittle = /*#__PURE__*/ new Uint8Array(/*#__PURE__*/ new Uint16Array([1]).buffer)[0] === 1
|
|
45
46
|
|
|
46
|
-
const fixed = <A>(
|
|
47
|
+
const fixed = <A>(
|
|
48
|
+
size: number,
|
|
49
|
+
name: string,
|
|
50
|
+
read: (view: DataView, offset: number) => A
|
|
51
|
+
): Parser<A, never, never, Uint8Array> => {
|
|
47
52
|
const expected = [`${size} byte${size === 1 ? "" : "s"}`]
|
|
48
53
|
return P.make((state: State<Uint8Array>) => {
|
|
49
54
|
const pos = state.pos
|
|
@@ -86,7 +91,7 @@ const readI128 = (little: boolean) => {
|
|
|
86
91
|
* @since 0.1.0
|
|
87
92
|
* @category integers
|
|
88
93
|
*/
|
|
89
|
-
export const u8: Parser<number, never, never, Uint8Array> = fixed(1, "u8", (v, o) => v.getUint8(o))
|
|
94
|
+
export const u8: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(1, "u8", (v, o) => v.getUint8(o))
|
|
90
95
|
|
|
91
96
|
/**
|
|
92
97
|
* A signed byte.
|
|
@@ -94,60 +99,126 @@ export const u8: Parser<number, never, never, Uint8Array> = fixed(1, "u8", (v, o
|
|
|
94
99
|
* @since 0.1.0
|
|
95
100
|
* @category integers
|
|
96
101
|
*/
|
|
97
|
-
export const i8: Parser<number, never, never, Uint8Array> = fixed(1, "i8", (v, o) => v.getInt8(o))
|
|
102
|
+
export const i8: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(1, "i8", (v, o) => v.getInt8(o))
|
|
98
103
|
|
|
99
104
|
/** @since 0.1.0 @category integers */
|
|
100
|
-
export const beU16: Parser<number, never, never, Uint8Array> = fixed(2, "beU16", (v, o) =>
|
|
105
|
+
export const beU16: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(2, "beU16", (v, o) =>
|
|
106
|
+
v.getUint16(o, false)
|
|
107
|
+
)
|
|
101
108
|
/** @since 0.1.0 @category integers */
|
|
102
|
-
export const leU16: Parser<number, never, never, Uint8Array> = fixed(2, "leU16", (v, o) =>
|
|
109
|
+
export const leU16: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(2, "leU16", (v, o) =>
|
|
110
|
+
v.getUint16(o, true)
|
|
111
|
+
)
|
|
103
112
|
/** @since 0.1.0 @category integers */
|
|
104
|
-
export const beI16: Parser<number, never, never, Uint8Array> = fixed(2, "beI16", (v, o) =>
|
|
113
|
+
export const beI16: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(2, "beI16", (v, o) =>
|
|
114
|
+
v.getInt16(o, false)
|
|
115
|
+
)
|
|
105
116
|
/** @since 0.1.0 @category integers */
|
|
106
|
-
export const leI16: Parser<number, never, never, Uint8Array> = fixed(2, "leI16", (v, o) =>
|
|
117
|
+
export const leI16: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(2, "leI16", (v, o) =>
|
|
118
|
+
v.getInt16(o, true)
|
|
119
|
+
)
|
|
107
120
|
/** @since 0.1.0 @category integers */
|
|
108
|
-
export const beU24: Parser<number, never, never, Uint8Array> = fixed(
|
|
121
|
+
export const beU24: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
122
|
+
3,
|
|
123
|
+
"beU24",
|
|
124
|
+
/*#__PURE__*/ readU24(false)
|
|
125
|
+
)
|
|
109
126
|
/** @since 0.1.0 @category integers */
|
|
110
|
-
export const leU24: Parser<number, never, never, Uint8Array> = fixed(
|
|
127
|
+
export const leU24: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
128
|
+
3,
|
|
129
|
+
"leU24",
|
|
130
|
+
/*#__PURE__*/ readU24(true)
|
|
131
|
+
)
|
|
111
132
|
/** @since 0.1.0 @category integers */
|
|
112
|
-
export const beI24: Parser<number, never, never, Uint8Array> = fixed(
|
|
133
|
+
export const beI24: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
134
|
+
3,
|
|
135
|
+
"beI24",
|
|
136
|
+
/*#__PURE__*/ readI24(false)
|
|
137
|
+
)
|
|
113
138
|
/** @since 0.1.0 @category integers */
|
|
114
|
-
export const leI24: Parser<number, never, never, Uint8Array> = fixed(
|
|
139
|
+
export const leI24: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
140
|
+
3,
|
|
141
|
+
"leI24",
|
|
142
|
+
/*#__PURE__*/ readI24(true)
|
|
143
|
+
)
|
|
115
144
|
/** @since 0.1.0 @category integers */
|
|
116
|
-
export const beU32: Parser<number, never, never, Uint8Array> = fixed(4, "beU32", (v, o) =>
|
|
145
|
+
export const beU32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "beU32", (v, o) =>
|
|
146
|
+
v.getUint32(o, false)
|
|
147
|
+
)
|
|
117
148
|
/** @since 0.1.0 @category integers */
|
|
118
|
-
export const leU32: Parser<number, never, never, Uint8Array> = fixed(4, "leU32", (v, o) =>
|
|
149
|
+
export const leU32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "leU32", (v, o) =>
|
|
150
|
+
v.getUint32(o, true)
|
|
151
|
+
)
|
|
119
152
|
/** @since 0.1.0 @category integers */
|
|
120
|
-
export const beI32: Parser<number, never, never, Uint8Array> = fixed(4, "beI32", (v, o) =>
|
|
153
|
+
export const beI32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "beI32", (v, o) =>
|
|
154
|
+
v.getInt32(o, false)
|
|
155
|
+
)
|
|
121
156
|
/** @since 0.1.0 @category integers */
|
|
122
|
-
export const leI32: Parser<number, never, never, Uint8Array> = fixed(4, "leI32", (v, o) =>
|
|
157
|
+
export const leI32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "leI32", (v, o) =>
|
|
158
|
+
v.getInt32(o, true)
|
|
159
|
+
)
|
|
123
160
|
/** @since 0.1.0 @category integers */
|
|
124
|
-
export const beU64: Parser<bigint, never, never, Uint8Array> = fixed(8, "beU64", (v, o) =>
|
|
161
|
+
export const beU64: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "beU64", (v, o) =>
|
|
162
|
+
v.getBigUint64(o, false)
|
|
163
|
+
)
|
|
125
164
|
/** @since 0.1.0 @category integers */
|
|
126
|
-
export const leU64: Parser<bigint, never, never, Uint8Array> = fixed(8, "leU64", (v, o) =>
|
|
165
|
+
export const leU64: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "leU64", (v, o) =>
|
|
166
|
+
v.getBigUint64(o, true)
|
|
167
|
+
)
|
|
127
168
|
/** @since 0.1.0 @category integers */
|
|
128
|
-
export const beI64: Parser<bigint, never, never, Uint8Array> = fixed(8, "beI64", (v, o) =>
|
|
169
|
+
export const beI64: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "beI64", (v, o) =>
|
|
170
|
+
v.getBigInt64(o, false)
|
|
171
|
+
)
|
|
129
172
|
/** @since 0.1.0 @category integers */
|
|
130
|
-
export const leI64: Parser<bigint, never, never, Uint8Array> = fixed(8, "leI64", (v, o) =>
|
|
173
|
+
export const leI64: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "leI64", (v, o) =>
|
|
174
|
+
v.getBigInt64(o, true)
|
|
175
|
+
)
|
|
131
176
|
/** @since 0.1.0 @category integers */
|
|
132
|
-
export const beU128: Parser<bigint, never, never, Uint8Array> = fixed(
|
|
177
|
+
export const beU128: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
178
|
+
16,
|
|
179
|
+
"beU128",
|
|
180
|
+
/*#__PURE__*/ readU128(false)
|
|
181
|
+
)
|
|
133
182
|
/** @since 0.1.0 @category integers */
|
|
134
|
-
export const leU128: Parser<bigint, never, never, Uint8Array> = fixed(
|
|
183
|
+
export const leU128: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
184
|
+
16,
|
|
185
|
+
"leU128",
|
|
186
|
+
/*#__PURE__*/ readU128(true)
|
|
187
|
+
)
|
|
135
188
|
/** @since 0.1.0 @category integers */
|
|
136
|
-
export const beI128: Parser<bigint, never, never, Uint8Array> = fixed(
|
|
189
|
+
export const beI128: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
190
|
+
16,
|
|
191
|
+
"beI128",
|
|
192
|
+
/*#__PURE__*/ readI128(false)
|
|
193
|
+
)
|
|
137
194
|
/** @since 0.1.0 @category integers */
|
|
138
|
-
export const leI128: Parser<bigint, never, never, Uint8Array> = fixed(
|
|
195
|
+
export const leI128: Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ fixed(
|
|
196
|
+
16,
|
|
197
|
+
"leI128",
|
|
198
|
+
/*#__PURE__*/ readI128(true)
|
|
199
|
+
)
|
|
139
200
|
|
|
140
201
|
/** @since 0.1.0 @category floats */
|
|
141
|
-
export const beF32: Parser<number, never, never, Uint8Array> = fixed(4, "beF32", (v, o) =>
|
|
202
|
+
export const beF32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "beF32", (v, o) =>
|
|
203
|
+
v.getFloat32(o, false)
|
|
204
|
+
)
|
|
142
205
|
/** @since 0.1.0 @category floats */
|
|
143
|
-
export const leF32: Parser<number, never, never, Uint8Array> = fixed(4, "leF32", (v, o) =>
|
|
206
|
+
export const leF32: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(4, "leF32", (v, o) =>
|
|
207
|
+
v.getFloat32(o, true)
|
|
208
|
+
)
|
|
144
209
|
/** @since 0.1.0 @category floats */
|
|
145
|
-
export const beF64: Parser<number, never, never, Uint8Array> = fixed(8, "beF64", (v, o) =>
|
|
210
|
+
export const beF64: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "beF64", (v, o) =>
|
|
211
|
+
v.getFloat64(o, false)
|
|
212
|
+
)
|
|
146
213
|
/** @since 0.1.0 @category floats */
|
|
147
|
-
export const leF64: Parser<number, never, never, Uint8Array> = fixed(8, "leF64", (v, o) =>
|
|
214
|
+
export const leF64: Parser<number, never, never, Uint8Array> = /*#__PURE__*/ fixed(8, "leF64", (v, o) =>
|
|
215
|
+
v.getFloat64(o, true)
|
|
216
|
+
)
|
|
148
217
|
|
|
149
|
-
const byEndian =
|
|
150
|
-
|
|
218
|
+
const byEndian =
|
|
219
|
+
<A>(big: A, little: A) =>
|
|
220
|
+
(endian: Endianness): A =>
|
|
221
|
+
endian === "big" ? big : endian === "little" ? little : nativeLittle ? little : big
|
|
151
222
|
|
|
152
223
|
/**
|
|
153
224
|
* An unsigned 16-bit integer in the given byte order (winnow's `u16`).
|
|
@@ -155,32 +226,67 @@ const byEndian = <A>(big: A, little: A) => (endian: Endianness): A =>
|
|
|
155
226
|
* @since 0.1.0
|
|
156
227
|
* @category integers
|
|
157
228
|
*/
|
|
158
|
-
export const u16: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
229
|
+
export const u16: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
230
|
+
beU16,
|
|
231
|
+
leU16
|
|
232
|
+
)
|
|
159
233
|
/** @since 0.1.0 @category integers */
|
|
160
|
-
export const i16: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
234
|
+
export const i16: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
235
|
+
beI16,
|
|
236
|
+
leI16
|
|
237
|
+
)
|
|
161
238
|
/** @since 0.1.0 @category integers */
|
|
162
|
-
export const u24: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
239
|
+
export const u24: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
240
|
+
beU24,
|
|
241
|
+
leU24
|
|
242
|
+
)
|
|
163
243
|
/** @since 0.1.0 @category integers */
|
|
164
|
-
export const i24: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
244
|
+
export const i24: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
245
|
+
beI24,
|
|
246
|
+
leI24
|
|
247
|
+
)
|
|
165
248
|
/** @since 0.1.0 @category integers */
|
|
166
|
-
export const u32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
249
|
+
export const u32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
250
|
+
beU32,
|
|
251
|
+
leU32
|
|
252
|
+
)
|
|
167
253
|
/** @since 0.1.0 @category integers */
|
|
168
|
-
export const i32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
254
|
+
export const i32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
255
|
+
beI32,
|
|
256
|
+
leI32
|
|
257
|
+
)
|
|
169
258
|
/** @since 0.1.0 @category integers */
|
|
170
|
-
export const u64: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = byEndian(
|
|
259
|
+
export const u64: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
260
|
+
beU64,
|
|
261
|
+
leU64
|
|
262
|
+
)
|
|
171
263
|
/** @since 0.1.0 @category integers */
|
|
172
|
-
export const i64: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = byEndian(
|
|
264
|
+
export const i64: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
265
|
+
beI64,
|
|
266
|
+
leI64
|
|
267
|
+
)
|
|
173
268
|
/** @since 0.1.0 @category integers */
|
|
174
|
-
export const u128: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = byEndian(
|
|
269
|
+
export const u128: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
270
|
+
beU128,
|
|
271
|
+
leU128
|
|
272
|
+
)
|
|
175
273
|
/** @since 0.1.0 @category integers */
|
|
176
|
-
export const i128: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = byEndian(
|
|
274
|
+
export const i128: (endian: Endianness) => Parser<bigint, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
275
|
+
beI128,
|
|
276
|
+
leI128
|
|
277
|
+
)
|
|
177
278
|
/** @since 0.1.0 @category floats */
|
|
178
|
-
export const f32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
279
|
+
export const f32: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
280
|
+
beF32,
|
|
281
|
+
leF32
|
|
282
|
+
)
|
|
179
283
|
/** @since 0.1.0 @category floats */
|
|
180
|
-
export const f64: (endian: Endianness) => Parser<number, never, never, Uint8Array> = byEndian(
|
|
284
|
+
export const f64: (endian: Endianness) => Parser<number, never, never, Uint8Array> = /*#__PURE__*/ byEndian(
|
|
285
|
+
beF64,
|
|
286
|
+
leF64
|
|
287
|
+
)
|
|
181
288
|
|
|
182
|
-
|
|
183
|
-
const toCount = (n: number | bigint): number => typeof n === "bigint" ? Number(n) : n
|
|
289
|
+
const toCount = (n: number | bigint): number => (Predicate.isBigInt(n) ? Number(n) : n)
|
|
184
290
|
|
|
185
291
|
/**
|
|
186
292
|
* Parses a length with `count`, then takes that many tokens (winnow's
|
package/src/Bits.ts
CHANGED
|
@@ -68,9 +68,12 @@ const inUnits = <A>(state: State<any>, factor: number, step: (state: State<any>)
|
|
|
68
68
|
state.pos = factor > 1 ? Math.floor(state.pos / factor) : state.pos / factor
|
|
69
69
|
const f = state.failure
|
|
70
70
|
state.failure = scale(f, 1 / factor)
|
|
71
|
+
// A committed failure keeps only the failures recorded after the commit
|
|
72
|
+
// (see `Parser.cut`), so none from before these units
|
|
73
|
+
if (state.mode === "Cut") state.deepest = undefined
|
|
71
74
|
if (inner !== undefined) {
|
|
72
75
|
const d = inner === f ? state.failure : scale(inner, 1 / factor)
|
|
73
|
-
if (deepest === undefined || d.offset >= deepest.offset) state.deepest = d
|
|
76
|
+
if (state.deepest === undefined || d.offset >= state.deepest.offset) state.deepest = d
|
|
74
77
|
}
|
|
75
78
|
return Fail
|
|
76
79
|
}
|
|
@@ -111,7 +114,7 @@ const readBits = (state: State<any>, count: number): number => {
|
|
|
111
114
|
let pos = state.pos
|
|
112
115
|
let value = 0
|
|
113
116
|
for (let i = 0; i < count; i++) {
|
|
114
|
-
const byte = input[pos >>> 3]
|
|
117
|
+
const byte = input[pos >>> 3]
|
|
115
118
|
value = value * 2 + ((byte >>> (7 - (pos & 7))) & 1)
|
|
116
119
|
pos++
|
|
117
120
|
}
|
|
@@ -186,7 +189,7 @@ export const pattern = (pattern: number, count: number): Parser<number, never, n
|
|
|
186
189
|
* @since 0.1.0
|
|
187
190
|
* @category parsers
|
|
188
191
|
*/
|
|
189
|
-
export const bool: Parser<boolean, never, never, BitInput> = make((state: State<any>) => {
|
|
192
|
+
export const bool: Parser<boolean, never, never, BitInput> = /*#__PURE__*/ make((state: State<any>) => {
|
|
190
193
|
if (state.pos >= state.end) return state.eoi("Bits", ["1 bit"], 1)
|
|
191
194
|
return readBits(state, 1) === 1
|
|
192
195
|
}, "bool")
|
package/src/Compiler.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiles parsers into fused, specialized code. Grammars are written as
|
|
3
|
+
* usual; compiling the root of a grammar only makes `Parser.parse`,
|
|
4
|
+
* `Parser.parseSync`, `Parser.parsePeek`, `Parser.parsePartial` and
|
|
5
|
+
* `Parser.parseEffect` faster, from any `offset`.
|
|
6
|
+
*
|
|
7
|
+
* There are two compilers, one function each, so a program bundles only the
|
|
8
|
+
* one it uses, and a program that compiles nothing bundles neither:
|
|
9
|
+
*
|
|
10
|
+
* - {@link jit} generates code with `new Function` where it is allowed, and
|
|
11
|
+
* otherwise uses the closure compiler. It is the fastest.
|
|
12
|
+
* - {@link closure} builds specialized closures only. It never generates
|
|
13
|
+
* code, and a bundle that uses only it contains no `new Function`, so it
|
|
14
|
+
* is the choice under a Content Security Policy, where even probing for
|
|
15
|
+
* `new Function` is reported as a violation.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { Ascii, Compiler, Parser, Token } from "@thomasfosterau/effect-parse"
|
|
19
|
+
*
|
|
20
|
+
* export const list = Compiler.jit(
|
|
21
|
+
* Parser.separated(Ascii.decInt, Token.literal(","))
|
|
22
|
+
* )
|
|
23
|
+
* Parser.parse(list, "1,2,3") // Result.succeed([1, 2, 3]), compiled
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* Both return the same parser, so they also work in a pipe:
|
|
27
|
+
* `p.pipe(Compiler.closure)`. The code is built lazily on the first run, for
|
|
28
|
+
* each kind of input (string, bytes or array), and cached with the parser.
|
|
29
|
+
* Compiling a parser again, with either function, replaces its compiled
|
|
30
|
+
* form.
|
|
31
|
+
*
|
|
32
|
+
* **Results and errors are unchanged.** Compiled code records no
|
|
33
|
+
* diagnostics. When it fails, the parser runs again, interpreted, from the
|
|
34
|
+
* same offset, so every `ParseError` (offset, expected, context, cause and
|
|
35
|
+
* message) is exactly the one the interpreter reports.
|
|
36
|
+
*
|
|
37
|
+
* **Callbacks should be pure.** On an input that fails, the callbacks given
|
|
38
|
+
* to `map`, `filter`, `tryMap`, `tap`, `fold`, ... may run twice, once
|
|
39
|
+
* compiled and once interpreted. Callbacks whose results are discarded
|
|
40
|
+
* (a `map` inside `taken` or `preceded`, for example) may not run at all,
|
|
41
|
+
* nor those of a branch that is certain to fail, and token-set predicates
|
|
42
|
+
* may be called once per character code and cached.
|
|
43
|
+
*
|
|
44
|
+
* `Parser.parsePartial` and `ParserStream.parseAll` run a build that
|
|
45
|
+
* handles partial input. `ParserStream.parseMany`, `Parser.parseRecoverable`
|
|
46
|
+
* and runs with the `trace` option are always interpreted. Parsers that
|
|
47
|
+
* can't be described, such as `Parser.make` and `Parser.gen`, run
|
|
48
|
+
* interpreted inside compiled code.
|
|
49
|
+
*
|
|
50
|
+
* @since 0.2.0
|
|
51
|
+
*/
|
|
52
|
+
import type { Input } from "./Input.js"
|
|
53
|
+
import type { Parser } from "./Parser.js"
|
|
54
|
+
import { backend as closureBackend } from "./internal/compiler/closure.js"
|
|
55
|
+
import { backend as jitBackend } from "./internal/compiler/jit.js"
|
|
56
|
+
import { register } from "./internal/compiler/registry.js"
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Compiles a parser with the JIT: generated code where `new Function` is
|
|
60
|
+
* allowed, otherwise specialized closures (see {@link closure}). Returns the
|
|
61
|
+
* same parser.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { Ascii, Compiler, Parser, Token } from "@thomasfosterau/effect-parse"
|
|
66
|
+
*
|
|
67
|
+
* const list = Compiler.jit(Parser.separated(Ascii.decInt, Token.literal(",")))
|
|
68
|
+
* Parser.parse(list, "1,2,3") // Result.succeed([1, 2, 3])
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @since 0.2.0
|
|
72
|
+
* @category compilation
|
|
73
|
+
*/
|
|
74
|
+
export const jit = <A, E, R, I extends Input>(self: Parser<A, E, R, I>): Parser<A, E, R, I> => {
|
|
75
|
+
register(self, jitBackend)
|
|
76
|
+
return self
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Compiles a parser into specialized closures. Returns the same parser.
|
|
81
|
+
* Nothing is generated, so it works under a Content Security Policy, and a
|
|
82
|
+
* bundle that compiles only with `closure` contains no `new Function`.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* import { Ascii, Compiler, Parser, Token } from "@thomasfosterau/effect-parse"
|
|
87
|
+
*
|
|
88
|
+
* const list = Compiler.closure(Parser.separated(Ascii.decInt, Token.literal(",")))
|
|
89
|
+
* Parser.parse(list, "1,2,3") // Result.succeed([1, 2, 3])
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* @since 0.2.0
|
|
93
|
+
* @category compilation
|
|
94
|
+
*/
|
|
95
|
+
export const closure = <A, E, R, I extends Input>(self: Parser<A, E, R, I>): Parser<A, E, R, I> => {
|
|
96
|
+
register(self, closureBackend)
|
|
97
|
+
return self
|
|
98
|
+
}
|
package/src/Expression.ts
CHANGED
|
@@ -166,7 +166,7 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
166
166
|
const tryOps = (state: State<any>, ops: ReadonlyArray<OperatorBase<any, any, any>>, mustConsume: boolean): number => {
|
|
167
167
|
const start = state.pos
|
|
168
168
|
for (let i = 0; i < ops.length; i++) {
|
|
169
|
-
const out = ops[i]
|
|
169
|
+
const out = ops[i].parser.step(state)
|
|
170
170
|
if (out !== Fail) {
|
|
171
171
|
// A prefix or postfix operator matching nothing would apply forever
|
|
172
172
|
if (mustConsume && state.pos === start) {
|
|
@@ -189,7 +189,7 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
189
189
|
const p = tryOps(state, prefixes, true)
|
|
190
190
|
if (p === -2) return Fail
|
|
191
191
|
if (p >= 0) {
|
|
192
|
-
const op = prefixes[p]
|
|
192
|
+
const op = prefixes[p]
|
|
193
193
|
const opOut = matched
|
|
194
194
|
const operandValue = expr(state, op.precedence * 2)
|
|
195
195
|
if (operandValue === Fail) return Fail
|
|
@@ -211,7 +211,7 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
211
211
|
const q = tryOps(state, postfixes, true)
|
|
212
212
|
if (q === -2) return Fail
|
|
213
213
|
if (q >= 0) {
|
|
214
|
-
const op = postfixes[q]
|
|
214
|
+
const op = postfixes[q]
|
|
215
215
|
if (op.precedence * 2 < minPower) {
|
|
216
216
|
state.pos = start
|
|
217
217
|
break
|
|
@@ -223,11 +223,16 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
223
223
|
const i = tryOps(state, infixes, false)
|
|
224
224
|
if (i === -2) return Fail
|
|
225
225
|
if (i < 0) {
|
|
226
|
-
const f =
|
|
226
|
+
const f =
|
|
227
|
+
postfixFailure === undefined
|
|
228
|
+
? failure
|
|
229
|
+
: failure === undefined
|
|
230
|
+
? postfixFailure
|
|
231
|
+
: mergeFailures(postfixFailure, failure)
|
|
227
232
|
if (f !== undefined && f.offset === state.pos) state.setHint(f.offset, f.expected)
|
|
228
233
|
break
|
|
229
234
|
}
|
|
230
|
-
const op = infixes[i]
|
|
235
|
+
const op = infixes[i]
|
|
231
236
|
const leftPower = op.precedence * 2
|
|
232
237
|
if (leftPower < minPower) {
|
|
233
238
|
state.pos = start
|
package/src/Input.ts
CHANGED
|
@@ -8,13 +8,16 @@
|
|
|
8
8
|
* failure.
|
|
9
9
|
*
|
|
10
10
|
* Most users never touch `State` directly. It is exposed for writing custom
|
|
11
|
-
* low-level parsers with `Parser.make
|
|
11
|
+
* low-level parsers with `Parser.make`, and for drivers that run a parser's
|
|
12
|
+
* `step` many times over one input, reusing a state with {@link State.reset}.
|
|
12
13
|
*
|
|
13
14
|
* @since 0.1.0
|
|
14
15
|
*/
|
|
16
|
+
import * as Predicate from "effect/Predicate"
|
|
15
17
|
import * as Context from "effect/Context"
|
|
16
18
|
import type { Encoding } from "./Encoding.js"
|
|
17
19
|
import type { ErrorKind } from "./ParseError.js"
|
|
20
|
+
import type { Builder as SyntaxBuilder } from "./internal/syntax.js"
|
|
18
21
|
|
|
19
22
|
/**
|
|
20
23
|
* The kinds of input a parser can consume.
|
|
@@ -70,7 +73,7 @@ export const fromSource: {
|
|
|
70
73
|
(source: BinaryInput): Uint8Array
|
|
71
74
|
<I extends Input>(source: Source<I>): I
|
|
72
75
|
} = (source: Input | BinaryInput): any => {
|
|
73
|
-
if (
|
|
76
|
+
if (Predicate.isString(source) || source instanceof Uint8Array || Array.isArray(source)) return source
|
|
74
77
|
if (ArrayBuffer.isView(source)) return new Uint8Array(source.buffer, source.byteOffset, source.byteLength)
|
|
75
78
|
// An explicit length fixes the view's size even for a resizable buffer
|
|
76
79
|
if (isArrayBufferLike(source)) return new Uint8Array(source, 0, source.byteLength)
|
|
@@ -78,7 +81,7 @@ export const fromSource: {
|
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
const isArrayBufferLike = (u: unknown): u is ArrayBufferLike =>
|
|
81
|
-
u instanceof ArrayBuffer || (
|
|
84
|
+
u instanceof ArrayBuffer || (globalThis.SharedArrayBuffer !== undefined && u instanceof SharedArrayBuffer)
|
|
82
85
|
|
|
83
86
|
/**
|
|
84
87
|
* The type of a single token of an input.
|
|
@@ -86,10 +89,13 @@ const isArrayBufferLike = (u: unknown): u is ArrayBufferLike =>
|
|
|
86
89
|
* @since 0.1.0
|
|
87
90
|
* @category models
|
|
88
91
|
*/
|
|
89
|
-
export type Token<I> = I extends string
|
|
90
|
-
|
|
91
|
-
: I extends
|
|
92
|
-
|
|
92
|
+
export type Token<I> = I extends string
|
|
93
|
+
? string
|
|
94
|
+
: I extends Uint8Array
|
|
95
|
+
? number
|
|
96
|
+
: I extends ReadonlyArray<infer T>
|
|
97
|
+
? T
|
|
98
|
+
: never
|
|
93
99
|
|
|
94
100
|
/**
|
|
95
101
|
* The type of a contiguous slice of an input.
|
|
@@ -97,10 +103,13 @@ export type Token<I> = I extends string ? string
|
|
|
97
103
|
* @since 0.1.0
|
|
98
104
|
* @category models
|
|
99
105
|
*/
|
|
100
|
-
export type Slice<I> = I extends string
|
|
101
|
-
|
|
102
|
-
: I extends
|
|
103
|
-
|
|
106
|
+
export type Slice<I> = I extends string
|
|
107
|
+
? string
|
|
108
|
+
: I extends Uint8Array
|
|
109
|
+
? Uint8Array
|
|
110
|
+
: I extends ReadonlyArray<infer T>
|
|
111
|
+
? ReadonlyArray<T>
|
|
112
|
+
: never
|
|
104
113
|
|
|
105
114
|
/**
|
|
106
115
|
* Sentinel returned by a parser step to signal failure. The failure details
|
|
@@ -109,7 +118,7 @@ export type Slice<I> = I extends string ? string
|
|
|
109
118
|
* @since 0.1.0
|
|
110
119
|
* @category failure
|
|
111
120
|
*/
|
|
112
|
-
export const Fail: unique symbol = Symbol.for("effect-parse/Fail")
|
|
121
|
+
export const Fail: unique symbol = /*#__PURE__*/ Symbol.for("effect-parse/Fail")
|
|
113
122
|
|
|
114
123
|
/**
|
|
115
124
|
* @since 0.1.0
|
|
@@ -158,6 +167,9 @@ export class Failure {
|
|
|
158
167
|
|
|
159
168
|
const empty: ReadonlyArray<string> = []
|
|
160
169
|
|
|
170
|
+
/** The failure a {@link State} starts with, before any step has failed. */
|
|
171
|
+
const initialFailure = /*#__PURE__*/ new Failure(0, "Fail", empty, empty, false, undefined, undefined, 0)
|
|
172
|
+
|
|
161
173
|
/** @internal */
|
|
162
174
|
export const emptyStrings = empty
|
|
163
175
|
|
|
@@ -189,7 +201,8 @@ export class State<I extends Input = Input> {
|
|
|
189
201
|
/** The full input being parsed. */
|
|
190
202
|
readonly input: I
|
|
191
203
|
/** The current offset. Advanced by parsers, rewound on backtracking. */
|
|
192
|
-
|
|
204
|
+
// Declared, not defined, so that a subclass can make it an accessor
|
|
205
|
+
declare pos: number
|
|
193
206
|
/** The end offset (the input's length; in bits inside `Bits.bits`). */
|
|
194
207
|
end: number
|
|
195
208
|
/** 0 = string, 1 = Uint8Array, 2 = array. */
|
|
@@ -216,7 +229,9 @@ export class State<I extends Input = Input> {
|
|
|
216
229
|
* were later swallowed by backtracking (for example a trailing separator
|
|
217
230
|
* followed by an invalid element). It is reported instead of the final
|
|
218
231
|
* failure when it lies further into the input. This is the classic PEG
|
|
219
|
-
* "farthest failure" heuristic.
|
|
232
|
+
* "farthest failure" heuristic. `Parser.cut` keeps only the failures
|
|
233
|
+
* recorded inside it when it commits, and `Parser.peek` and `Parser.not`
|
|
234
|
+
* forget the failures of a lookahead that succeeded.
|
|
220
235
|
*/
|
|
221
236
|
deepest: Failure | undefined = undefined
|
|
222
237
|
/** When defined, `Parser.resumeAfter`/`retryAfter` record failures here. */
|
|
@@ -237,20 +252,81 @@ export class State<I extends Input = Input> {
|
|
|
237
252
|
* @internal
|
|
238
253
|
*/
|
|
239
254
|
resume: Map<object, Map<number, unknown>> | undefined = undefined
|
|
255
|
+
/**
|
|
256
|
+
* The tree builder of a `Syntax` parse; `undefined` otherwise.
|
|
257
|
+
*
|
|
258
|
+
* @internal
|
|
259
|
+
*/
|
|
260
|
+
syntax: SyntaxBuilder | undefined = undefined
|
|
240
261
|
|
|
241
|
-
constructor(
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
262
|
+
constructor(
|
|
263
|
+
source: I | Source<I>,
|
|
264
|
+
options?: {
|
|
265
|
+
readonly partial?: boolean | undefined
|
|
266
|
+
readonly context?: Context.Context<never> | undefined
|
|
267
|
+
readonly offset?: number | undefined
|
|
268
|
+
}
|
|
269
|
+
) {
|
|
246
270
|
const input = fromSource(source as Input) as I
|
|
247
271
|
this.input = input
|
|
248
272
|
this.end = input.length
|
|
249
273
|
this.pos = options?.offset ?? 0
|
|
250
274
|
this.partial = options?.partial ?? false
|
|
251
275
|
this.context = options?.context ?? Context.empty()
|
|
252
|
-
this.inputKind =
|
|
253
|
-
this.failure =
|
|
276
|
+
this.inputKind = Predicate.isString(input) ? 0 : input instanceof Uint8Array ? 1 : 2
|
|
277
|
+
this.failure = initialFailure
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Prepares the state for another run over the same input, starting at
|
|
282
|
+
* `offset`: afterwards it behaves exactly like
|
|
283
|
+
* `new State(state.input, { ...options, offset })`, without allocating a
|
|
284
|
+
* new state.
|
|
285
|
+
*
|
|
286
|
+
* Every per-run field is reset: the cursor and end, the latest failure,
|
|
287
|
+
* hints and furthest failure, recorded recoveries, the tracer and tracing
|
|
288
|
+
* depth, the recorded encoding and streaming checkpoints. Like the
|
|
289
|
+
* constructor, `partial` defaults to `false` and `context` to the empty
|
|
290
|
+
* context, so pass them again on every reset.
|
|
291
|
+
*
|
|
292
|
+
* Use it to run many small parses over one buffer, for example one per
|
|
293
|
+
* token, with `parser.step`. A state can be reused after any run,
|
|
294
|
+
* including one that failed, returned `Incomplete` or threw.
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* ```ts
|
|
298
|
+
* import { Ascii, Input } from "@thomasfosterau/effect-parse"
|
|
299
|
+
*
|
|
300
|
+
* const state = new Input.State("12 34")
|
|
301
|
+
* Ascii.decUint.step(state) // 12
|
|
302
|
+
* state.reset(3)
|
|
303
|
+
* Ascii.decUint.step(state) // 34
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @since 0.2.0
|
|
307
|
+
*/
|
|
308
|
+
reset(
|
|
309
|
+
offset: number = 0,
|
|
310
|
+
options?: {
|
|
311
|
+
readonly partial?: boolean | undefined
|
|
312
|
+
readonly context?: Context.Context<never> | undefined
|
|
313
|
+
}
|
|
314
|
+
): this {
|
|
315
|
+
this.pos = offset
|
|
316
|
+
this.end = this.input.length
|
|
317
|
+
this.partial = options?.partial ?? false
|
|
318
|
+
this.context = options?.context ?? Context.empty()
|
|
319
|
+
this.mode = "Backtrack"
|
|
320
|
+
this.failure = initialFailure
|
|
321
|
+
this.hintOffset = -1
|
|
322
|
+
this.hintExpected = empty
|
|
323
|
+
this.deepest = undefined
|
|
324
|
+
this.recovered = undefined
|
|
325
|
+
this.tracer = undefined
|
|
326
|
+
this.depth = 0
|
|
327
|
+
this.encoding = undefined
|
|
328
|
+
this.resume = undefined
|
|
329
|
+
return this
|
|
254
330
|
}
|
|
255
331
|
|
|
256
332
|
/**
|
|
@@ -359,12 +435,17 @@ export class State<I extends Input = Input> {
|
|
|
359
435
|
const f = this.failure
|
|
360
436
|
const d = this.deepest
|
|
361
437
|
if (
|
|
362
|
-
d === undefined ||
|
|
363
|
-
|
|
438
|
+
d === undefined ||
|
|
439
|
+
d === f ||
|
|
440
|
+
d.offset <= f.offset ||
|
|
441
|
+
this.mode === "Incomplete" ||
|
|
442
|
+
f.hasCause ||
|
|
443
|
+
f.message !== undefined
|
|
364
444
|
) {
|
|
365
445
|
return f
|
|
366
446
|
}
|
|
367
|
-
const context =
|
|
447
|
+
const context =
|
|
448
|
+
d.context.length === 0 ? f.context : [...d.context, ...f.context.filter((l) => !d.context.includes(l))]
|
|
368
449
|
return new Failure(d.offset, d.kind, d.expected, context, d.hasCause, d.cause, d.message, d.needed)
|
|
369
450
|
}
|
|
370
451
|
|
|
@@ -392,10 +473,7 @@ export class State<I extends Input = Input> {
|
|
|
392
473
|
}
|
|
393
474
|
|
|
394
475
|
/** @internal */
|
|
395
|
-
export const mergeExpected = (
|
|
396
|
-
a: ReadonlyArray<string>,
|
|
397
|
-
b: ReadonlyArray<string>
|
|
398
|
-
): ReadonlyArray<string> => {
|
|
476
|
+
export const mergeExpected = (a: ReadonlyArray<string>, b: ReadonlyArray<string>): ReadonlyArray<string> => {
|
|
399
477
|
if (a.length === 0) return b
|
|
400
478
|
if (b.length === 0) return a
|
|
401
479
|
const out = a.slice()
|