@thomasfosterau/effect-parse 0.1.0 → 0.3.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 +291 -231
- 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 +151 -132
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +251 -177
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +409 -299
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +45 -85
- 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 +232 -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 +2034 -1802
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts +206 -7
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +678 -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 +36 -0
- package/dist/internal/stack.js.map +1 -0
- package/dist/internal/syntax.d.ts +147 -0
- package/dist/internal/syntax.d.ts.map +1 -0
- package/dist/internal/syntax.js +309 -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/ties.d.ts +30 -0
- package/dist/internal/ties.d.ts.map +1 -0
- package/dist/internal/ties.js +67 -0
- package/dist/internal/ties.js.map +1 -0
- 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 +24 -16
- package/src/Input.ts +210 -35
- package/src/Nom.ts +4 -3
- package/src/ParseError.ts +49 -52
- package/src/Parser.ts +1199 -799
- package/src/ParserSchema.ts +982 -23
- 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 +41 -0
- package/src/internal/syntax.ts +426 -0
- package/src/internal/text.ts +32 -25
- package/src/internal/ties.ts +83 -0
- 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
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
* @since 0.1.0
|
|
36
36
|
*/
|
|
37
37
|
import type { Input, State } from "./Input.js"
|
|
38
|
-
import { Fail
|
|
39
|
-
import type { Failure } from "./Input.js"
|
|
38
|
+
import { Fail } from "./Input.js"
|
|
40
39
|
import type { Parser } from "./Parser.js"
|
|
41
40
|
import { make as makeParser } from "./Parser.js"
|
|
41
|
+
import { TiedFailures } from "./internal/ties.js"
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* An operator in an expression grammar.
|
|
@@ -160,13 +160,15 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
160
160
|
|
|
161
161
|
// Attempts each operator in turn. Returns the index of the first match
|
|
162
162
|
// (with its output in `matched`), -1 if none matched, or -2 on a fatal
|
|
163
|
-
// failure.
|
|
163
|
+
// failure. Failed attempts are folded into `failures`, merged only when
|
|
164
|
+
// read (#44): a round in which an operator matches discards them unmerged.
|
|
165
|
+
// Like `matched`, it is shared by nested expressions, which clear it.
|
|
164
166
|
let matched: unknown
|
|
165
|
-
|
|
167
|
+
const failures = new TiedFailures()
|
|
166
168
|
const tryOps = (state: State<any>, ops: ReadonlyArray<OperatorBase<any, any, any>>, mustConsume: boolean): number => {
|
|
167
169
|
const start = state.pos
|
|
168
170
|
for (let i = 0; i < ops.length; i++) {
|
|
169
|
-
const out = ops[i]
|
|
171
|
+
const out = ops[i].parser.step(state)
|
|
170
172
|
if (out !== Fail) {
|
|
171
173
|
// A prefix or postfix operator matching nothing would apply forever
|
|
172
174
|
if (mustConsume && state.pos === start) {
|
|
@@ -177,29 +179,36 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
177
179
|
return i
|
|
178
180
|
}
|
|
179
181
|
if (state.mode !== "Backtrack") return -2
|
|
180
|
-
failure = failure === undefined ? state.failure : mergeFailures(failure, state.failure)
|
|
181
182
|
state.pos = start
|
|
183
|
+
failures.add(state)
|
|
182
184
|
}
|
|
183
185
|
return -1
|
|
184
186
|
}
|
|
185
187
|
|
|
186
188
|
const expr = (state: State<any>, minPower: number): A | Fail => {
|
|
187
189
|
let lhs: A | Fail
|
|
188
|
-
|
|
190
|
+
failures.clear()
|
|
189
191
|
const p = tryOps(state, prefixes, true)
|
|
190
192
|
if (p === -2) return Fail
|
|
191
193
|
if (p >= 0) {
|
|
192
|
-
const op = prefixes[p]
|
|
194
|
+
const op = prefixes[p]
|
|
193
195
|
const opOut = matched
|
|
194
196
|
const operandValue = expr(state, op.precedence * 2)
|
|
195
197
|
if (operandValue === Fail) return Fail
|
|
196
198
|
lhs = op.fold(opOut, operandValue)
|
|
197
199
|
} else {
|
|
198
|
-
const prefixFailure = failure
|
|
200
|
+
const prefixFailure = failures.failure
|
|
201
|
+
const prefixTie1 = failures.tie1
|
|
202
|
+
const prefixTie2 = failures.tie2
|
|
199
203
|
lhs = operand(state)
|
|
200
204
|
if (lhs === Fail) {
|
|
201
205
|
if (prefixFailure !== undefined && state.mode === "Backtrack") {
|
|
202
|
-
|
|
206
|
+
// The operand may have parsed nested expressions, which reuse `failures`
|
|
207
|
+
failures.failure = prefixFailure
|
|
208
|
+
failures.tie1 = prefixTie1
|
|
209
|
+
failures.tie2 = prefixTie2
|
|
210
|
+
failures.add(state)
|
|
211
|
+
failures.fail(state)
|
|
203
212
|
}
|
|
204
213
|
return Fail
|
|
205
214
|
}
|
|
@@ -207,11 +216,11 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
207
216
|
|
|
208
217
|
while (true) {
|
|
209
218
|
const start = state.pos
|
|
210
|
-
|
|
219
|
+
failures.clear()
|
|
211
220
|
const q = tryOps(state, postfixes, true)
|
|
212
221
|
if (q === -2) return Fail
|
|
213
222
|
if (q >= 0) {
|
|
214
|
-
const op = postfixes[q]
|
|
223
|
+
const op = postfixes[q]
|
|
215
224
|
if (op.precedence * 2 < minPower) {
|
|
216
225
|
state.pos = start
|
|
217
226
|
break
|
|
@@ -219,15 +228,14 @@ export const make = <A, E, R, I extends Input, const Ops extends ReadonlyArray<O
|
|
|
219
228
|
lhs = op.fold(lhs, matched)
|
|
220
229
|
continue
|
|
221
230
|
}
|
|
222
|
-
|
|
231
|
+
// The infix attempts are folded on top of the postfix ones
|
|
223
232
|
const i = tryOps(state, infixes, false)
|
|
224
233
|
if (i === -2) return Fail
|
|
225
234
|
if (i < 0) {
|
|
226
|
-
|
|
227
|
-
if (f !== undefined && f.offset === state.pos) state.setHint(f.offset, f.expected)
|
|
235
|
+
failures.hint(state)
|
|
228
236
|
break
|
|
229
237
|
}
|
|
230
|
-
const op = infixes[i]
|
|
238
|
+
const op = infixes[i]
|
|
231
239
|
const leftPower = op.precedence * 2
|
|
232
240
|
if (leftPower < minPower) {
|
|
233
241
|
state.pos = start
|