@thomasfosterau/effect-parse 0.5.0 → 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 +19 -1
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +5 -3
- 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 +20 -3
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +4 -0
- package/dist/Bits.js.map +1 -1
- package/dist/Input.d.ts +21 -3
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +31 -4
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts.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 +10 -4
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +10 -24
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +1 -2
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +119 -12
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +282 -55
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.js +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +13 -7
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +10 -1
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +14 -5
- 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 +7 -17
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +2 -1
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/graph.d.ts +23 -1
- package/dist/internal/compiler/graph.d.ts.map +1 -1
- package/dist/internal/compiler/graph.js +27 -5
- package/dist/internal/compiler/graph.js.map +1 -1
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +26 -13
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +1 -1
- package/dist/internal/compiler/wasm.d.ts.map +1 -1
- package/dist/internal/compiler/wasm.js +105 -34
- package/dist/internal/compiler/wasm.js.map +1 -1
- package/dist/internal/node.d.ts +19 -1
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +42 -8
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/run.d.ts +3 -1
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +4 -2
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +8 -0
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +17 -1
- package/dist/internal/stack.js.map +1 -1
- package/dist/internal/tokens.d.ts +10 -3
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +22 -9
- 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 +17 -10
- package/src/Ascii.ts +5 -3
- package/src/Binary.ts +24 -3
- package/src/Bits.ts +4 -0
- package/src/Input.ts +37 -4
- package/src/ParseError.ts +206 -52
- package/src/Parser.ts +19 -29
- package/src/ParserSchema.ts +1 -2
- package/src/ParserStream.ts +336 -62
- package/src/Text.ts +16 -12
- package/src/Token.ts +14 -5
- package/src/internal/compiler/closure.ts +9 -18
- package/src/internal/compiler/first.ts +6 -0
- package/src/internal/compiler/graph.ts +32 -4
- package/src/internal/compiler/jit.ts +37 -17
- package/src/internal/compiler/wasm.ts +141 -68
- package/src/internal/node.ts +49 -3
- package/src/internal/run.ts +4 -2
- package/src/internal/stack.ts +17 -0
- package/src/internal/tokens.ts +20 -10
- package/src/internal/tuple.ts +141 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { Fail } from "../Input.js";
|
|
2
|
+
// src/internal/tuple.ts
|
|
3
|
+
/**
|
|
4
|
+
* Tuple steps: run steps in sequence and collect their outputs in an array.
|
|
5
|
+
*
|
|
6
|
+
* V8 pretenures by allocation site, and only array and object literals have
|
|
7
|
+
* one: an array from `new Array(n)` starts young, so tuples that a parse keeps
|
|
8
|
+
* (a `repeat(seq(...))`, a tree) are copied by a scavenge or two before they
|
|
9
|
+
* are promoted. A literal's site learns that its arrays survive, and V8 then
|
|
10
|
+
* allocates them straight into the old generation. So arities up to
|
|
11
|
+
* {@link maxLiteral} build their tuple with a literal of that arity, each its
|
|
12
|
+
* own site; longer tuples fall back to `new Array(n)` (#86).
|
|
13
|
+
*/
|
|
14
|
+
/** The longest tuple built with a literal. */
|
|
15
|
+
const maxLiteral = 8;
|
|
16
|
+
/** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */
|
|
17
|
+
const tupleStep = (steps) => {
|
|
18
|
+
const n = steps.length;
|
|
19
|
+
if (n <= maxLiteral) return literals[n](steps);
|
|
20
|
+
return (state) => {
|
|
21
|
+
const out = new Array(n);
|
|
22
|
+
for (let i = 0; i < n; i++) {
|
|
23
|
+
const a = steps[i](state);
|
|
24
|
+
if (a === Fail) return Fail;
|
|
25
|
+
out[i] = a;
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
const literals = [
|
|
31
|
+
() => () => [],
|
|
32
|
+
([s0]) => (state) => {
|
|
33
|
+
const a0 = s0(state);
|
|
34
|
+
if (a0 === Fail) return Fail;
|
|
35
|
+
return [a0];
|
|
36
|
+
},
|
|
37
|
+
([s0, s1]) => (state) => {
|
|
38
|
+
const a0 = s0(state);
|
|
39
|
+
if (a0 === Fail) return Fail;
|
|
40
|
+
const a1 = s1(state);
|
|
41
|
+
if (a1 === Fail) return Fail;
|
|
42
|
+
return [a0, a1];
|
|
43
|
+
},
|
|
44
|
+
([s0, s1, s2]) => (state) => {
|
|
45
|
+
const a0 = s0(state);
|
|
46
|
+
if (a0 === Fail) return Fail;
|
|
47
|
+
const a1 = s1(state);
|
|
48
|
+
if (a1 === Fail) return Fail;
|
|
49
|
+
const a2 = s2(state);
|
|
50
|
+
if (a2 === Fail) return Fail;
|
|
51
|
+
return [
|
|
52
|
+
a0,
|
|
53
|
+
a1,
|
|
54
|
+
a2
|
|
55
|
+
];
|
|
56
|
+
},
|
|
57
|
+
([s0, s1, s2, s3]) => (state) => {
|
|
58
|
+
const a0 = s0(state);
|
|
59
|
+
if (a0 === Fail) return Fail;
|
|
60
|
+
const a1 = s1(state);
|
|
61
|
+
if (a1 === Fail) return Fail;
|
|
62
|
+
const a2 = s2(state);
|
|
63
|
+
if (a2 === Fail) return Fail;
|
|
64
|
+
const a3 = s3(state);
|
|
65
|
+
if (a3 === Fail) return Fail;
|
|
66
|
+
return [
|
|
67
|
+
a0,
|
|
68
|
+
a1,
|
|
69
|
+
a2,
|
|
70
|
+
a3
|
|
71
|
+
];
|
|
72
|
+
},
|
|
73
|
+
([s0, s1, s2, s3, s4]) => (state) => {
|
|
74
|
+
const a0 = s0(state);
|
|
75
|
+
if (a0 === Fail) return Fail;
|
|
76
|
+
const a1 = s1(state);
|
|
77
|
+
if (a1 === Fail) return Fail;
|
|
78
|
+
const a2 = s2(state);
|
|
79
|
+
if (a2 === Fail) return Fail;
|
|
80
|
+
const a3 = s3(state);
|
|
81
|
+
if (a3 === Fail) return Fail;
|
|
82
|
+
const a4 = s4(state);
|
|
83
|
+
if (a4 === Fail) return Fail;
|
|
84
|
+
return [
|
|
85
|
+
a0,
|
|
86
|
+
a1,
|
|
87
|
+
a2,
|
|
88
|
+
a3,
|
|
89
|
+
a4
|
|
90
|
+
];
|
|
91
|
+
},
|
|
92
|
+
([s0, s1, s2, s3, s4, s5]) => (state) => {
|
|
93
|
+
const a0 = s0(state);
|
|
94
|
+
if (a0 === Fail) return Fail;
|
|
95
|
+
const a1 = s1(state);
|
|
96
|
+
if (a1 === Fail) return Fail;
|
|
97
|
+
const a2 = s2(state);
|
|
98
|
+
if (a2 === Fail) return Fail;
|
|
99
|
+
const a3 = s3(state);
|
|
100
|
+
if (a3 === Fail) return Fail;
|
|
101
|
+
const a4 = s4(state);
|
|
102
|
+
if (a4 === Fail) return Fail;
|
|
103
|
+
const a5 = s5(state);
|
|
104
|
+
if (a5 === Fail) return Fail;
|
|
105
|
+
return [
|
|
106
|
+
a0,
|
|
107
|
+
a1,
|
|
108
|
+
a2,
|
|
109
|
+
a3,
|
|
110
|
+
a4,
|
|
111
|
+
a5
|
|
112
|
+
];
|
|
113
|
+
},
|
|
114
|
+
([s0, s1, s2, s3, s4, s5, s6]) => (state) => {
|
|
115
|
+
const a0 = s0(state);
|
|
116
|
+
if (a0 === Fail) return Fail;
|
|
117
|
+
const a1 = s1(state);
|
|
118
|
+
if (a1 === Fail) return Fail;
|
|
119
|
+
const a2 = s2(state);
|
|
120
|
+
if (a2 === Fail) return Fail;
|
|
121
|
+
const a3 = s3(state);
|
|
122
|
+
if (a3 === Fail) return Fail;
|
|
123
|
+
const a4 = s4(state);
|
|
124
|
+
if (a4 === Fail) return Fail;
|
|
125
|
+
const a5 = s5(state);
|
|
126
|
+
if (a5 === Fail) return Fail;
|
|
127
|
+
const a6 = s6(state);
|
|
128
|
+
if (a6 === Fail) return Fail;
|
|
129
|
+
return [
|
|
130
|
+
a0,
|
|
131
|
+
a1,
|
|
132
|
+
a2,
|
|
133
|
+
a3,
|
|
134
|
+
a4,
|
|
135
|
+
a5,
|
|
136
|
+
a6
|
|
137
|
+
];
|
|
138
|
+
},
|
|
139
|
+
([s0, s1, s2, s3, s4, s5, s6, s7]) => (state) => {
|
|
140
|
+
const a0 = s0(state);
|
|
141
|
+
if (a0 === Fail) return Fail;
|
|
142
|
+
const a1 = s1(state);
|
|
143
|
+
if (a1 === Fail) return Fail;
|
|
144
|
+
const a2 = s2(state);
|
|
145
|
+
if (a2 === Fail) return Fail;
|
|
146
|
+
const a3 = s3(state);
|
|
147
|
+
if (a3 === Fail) return Fail;
|
|
148
|
+
const a4 = s4(state);
|
|
149
|
+
if (a4 === Fail) return Fail;
|
|
150
|
+
const a5 = s5(state);
|
|
151
|
+
if (a5 === Fail) return Fail;
|
|
152
|
+
const a6 = s6(state);
|
|
153
|
+
if (a6 === Fail) return Fail;
|
|
154
|
+
const a7 = s7(state);
|
|
155
|
+
if (a7 === Fail) return Fail;
|
|
156
|
+
return [
|
|
157
|
+
a0,
|
|
158
|
+
a1,
|
|
159
|
+
a2,
|
|
160
|
+
a3,
|
|
161
|
+
a4,
|
|
162
|
+
a5,
|
|
163
|
+
a6,
|
|
164
|
+
a7
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
export { tupleStep };
|
|
169
|
+
|
|
170
|
+
//# sourceMappingURL=tuple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuple.js","names":[],"sources":["../../src/internal/tuple.ts"],"sourcesContent":["/**\n * Tuple steps: run steps in sequence and collect their outputs in an array.\n *\n * V8 pretenures by allocation site, and only array and object literals have\n * one: an array from `new Array(n)` starts young, so tuples that a parse keeps\n * (a `repeat(seq(...))`, a tree) are copied by a scavenge or two before they\n * are promoted. A literal's site learns that its arrays survive, and V8 then\n * allocates them straight into the old generation. So arities up to\n * {@link maxLiteral} build their tuple with a literal of that arity, each its\n * own site; longer tuples fall back to `new Array(n)` (#86).\n */\nimport { Fail } from \"../Input.js\"\nimport type { State } from \"../Input.js\"\n\ntype Step = (state: State<any>) => unknown\n\n/** The longest tuple built with a literal. */\nconst maxLiteral = 8\n\n/** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */\nexport const tupleStep = (steps: ReadonlyArray<Step>): ((state: State<any>) => Array<unknown> | Fail) => {\n const n = steps.length\n if (n <= maxLiteral) return literals[n](steps)\n return (state) => {\n const out = new Array<unknown>(n)\n for (let i = 0; i < n; i++) {\n const a = steps[i](state)\n if (a === Fail) return Fail\n out[i] = a\n }\n return out\n }\n}\n\nconst literals: ReadonlyArray<(steps: ReadonlyArray<Step>) => (state: State<any>) => Array<unknown> | Fail> = [\n () => () => [],\n ([s0]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n return [a0]\n },\n ([s0, s1]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n return [a0, a1]\n },\n ([s0, s1, s2]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n return [a0, a1, a2]\n },\n ([s0, s1, s2, s3]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n return [a0, a1, a2, a3]\n },\n ([s0, s1, s2, s3, s4]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n return [a0, a1, a2, a3, a4]\n },\n ([s0, s1, s2, s3, s4, s5]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5]\n },\n ([s0, s1, s2, s3, s4, s5, s6]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n const a6 = s6(state)\n if (a6 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5, a6]\n },\n ([s0, s1, s2, s3, s4, s5, s6, s7]) =>\n (state) => {\n const a0 = s0(state)\n if (a0 === Fail) return Fail\n const a1 = s1(state)\n if (a1 === Fail) return Fail\n const a2 = s2(state)\n if (a2 === Fail) return Fail\n const a3 = s3(state)\n if (a3 === Fail) return Fail\n const a4 = s4(state)\n if (a4 === Fail) return Fail\n const a5 = s5(state)\n if (a5 === Fail) return Fail\n const a6 = s6(state)\n if (a6 === Fail) return Fail\n const a7 = s7(state)\n if (a7 === Fail) return Fail\n return [a0, a1, a2, a3, a4, a5, a6, a7]\n }\n]\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package",
|
|
3
3
|
"name": "@thomasfosterau/effect-parse",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.0",
|
|
5
5
|
"description": "Parser combinators for Effect, ported from Rust's nom and winnow: text, bytes, bits and token streams, streaming input, compiled parsers and Schema integration",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"effect",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|
|
26
26
|
"src",
|
|
27
|
-
"!dist/**/*.tsbuildinfo"
|
|
27
|
+
"!dist/**/*.tsbuildinfo",
|
|
28
|
+
"CHANGELOG.md"
|
|
28
29
|
],
|
|
29
30
|
"type": "module",
|
|
30
31
|
"sideEffects": false,
|
|
@@ -102,19 +103,25 @@
|
|
|
102
103
|
"@changesets/changelog-github": "^1.0.1",
|
|
103
104
|
"@changesets/cli": "^3.0.3",
|
|
104
105
|
"@effect/language-service": "^0.87.5",
|
|
105
|
-
"@effect/platform-node-shared": "4.1.
|
|
106
|
-
"@effect/tsgo": "0.
|
|
106
|
+
"@effect/platform-node-shared": "4.1.4",
|
|
107
|
+
"@effect/tsgo": "0.67.7",
|
|
107
108
|
"@enfect/oxlint": "^0.10.0",
|
|
109
|
+
"@thomasfosterau/effect-bib": "0.1.0",
|
|
110
|
+
"@thomasfosterau/effect-ext": "0.2.0",
|
|
111
|
+
"@thomasfosterau/effect-ical": "0.1.0",
|
|
112
|
+
"@thomasfosterau/effect-parse": "0.6.0",
|
|
113
|
+
"@thomasfosterau/effect-rdf": "0.2.0",
|
|
114
|
+
"@thomasfosterau/effect-xml": "0.1.0",
|
|
108
115
|
"@types/node": "^26.6.5",
|
|
109
116
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
110
|
-
"@vitest/coverage-istanbul": "5.0
|
|
111
|
-
"effect": "4.1.
|
|
112
|
-
"fallow": "3.
|
|
117
|
+
"@vitest/coverage-istanbul": "5.1.0",
|
|
118
|
+
"effect": "4.1.4",
|
|
119
|
+
"fallow": "3.42.0",
|
|
113
120
|
"rolldown": "^1.2.14",
|
|
114
121
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
115
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@1.
|
|
116
|
-
"vite-plus": "1.
|
|
117
|
-
"vitest": "5.0
|
|
122
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.6.0",
|
|
123
|
+
"vite-plus": "1.6.0",
|
|
124
|
+
"vitest": "5.1.0"
|
|
118
125
|
},
|
|
119
126
|
"peerDependencies": {
|
|
120
127
|
"effect": "^4.0.0"
|
package/src/Ascii.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type { Parser } from "./Parser.js"
|
|
|
31
31
|
import * as P from "./Parser.js"
|
|
32
32
|
import * as numbers from "./internal/numbers.js"
|
|
33
33
|
import { Key } from "./internal/key.js"
|
|
34
|
+
import { controlCode } from "./internal/node.js"
|
|
34
35
|
import * as Resume from "./internal/resume.js"
|
|
35
36
|
import { codePointPredicate } from "./internal/tokens.js"
|
|
36
37
|
import { literalImpl, range, takeWhileImpl } from "./Token.js"
|
|
@@ -533,7 +534,8 @@ export const caseless: CaselessFn = (lit: string | Uint8Array): any => literalIm
|
|
|
533
534
|
// Escapes
|
|
534
535
|
// -----------------------------------------------------------------------------
|
|
535
536
|
|
|
536
|
-
|
|
537
|
+
/** The first UTF-16 unit of a control character: what `atControl` compares with a string's units. */
|
|
538
|
+
const firstUnit = (s: string): number => s.charCodeAt(0)
|
|
537
539
|
|
|
538
540
|
const atControl = (state: State<Input>, control: number): boolean => {
|
|
539
541
|
if (state.pos >= state.end) return false
|
|
@@ -567,7 +569,7 @@ export const takeEscaped = <A, E, R, I extends Input, B, E2, R2, I2 extends Inpu
|
|
|
567
569
|
control: string | number,
|
|
568
570
|
escapable: Parser<B, E2, R2, I2>
|
|
569
571
|
): Parser<Slice<I & I2>, E | E2, R | R2, I & I2> => {
|
|
570
|
-
const ctrl = controlCode(control)
|
|
572
|
+
const ctrl = controlCode(control, firstUnit)
|
|
571
573
|
return takeEscapedImpl(
|
|
572
574
|
normal,
|
|
573
575
|
(state) => {
|
|
@@ -684,7 +686,7 @@ export const escaped = <E, R, I extends Input, E2, R2, I2 extends Input>(
|
|
|
684
686
|
control: string | number,
|
|
685
687
|
escape: Parser<string, E2, R2, I2>
|
|
686
688
|
): Parser<string, E | E2, R | R2, I & I2> => {
|
|
687
|
-
const ctrl = controlCode(control)
|
|
689
|
+
const ctrl = controlCode(control, firstUnit)
|
|
688
690
|
return escapedImpl(
|
|
689
691
|
normal,
|
|
690
692
|
(state) => {
|
package/src/Binary.ts
CHANGED
|
@@ -334,6 +334,18 @@ export const f64: (endian: Endianness) => Parser<number, never, never, Uint8Arra
|
|
|
334
334
|
leF64
|
|
335
335
|
)
|
|
336
336
|
|
|
337
|
+
const MaxCount = /*#__PURE__*/ BigInt(Number.MAX_SAFE_INTEGER)
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Whether a length read from the input is a count: a non-negative integer
|
|
341
|
+
* of at most `Number.MAX_SAFE_INTEGER`. A signed, fractional or `NaN`
|
|
342
|
+
* length is the input's to choose, so it fails the parse where it was read
|
|
343
|
+
* (as `Parser.filter` does) and never reaches `Token.take` or
|
|
344
|
+
* `Parser.repeat`, which throw on one.
|
|
345
|
+
*/
|
|
346
|
+
const isCount = (n: number | bigint): boolean =>
|
|
347
|
+
Predicate.isBigInt(n) ? n >= 0n && n <= MaxCount : Number.isSafeInteger(n) && n >= 0
|
|
348
|
+
|
|
337
349
|
const toCount = (n: number | bigint): number => (Predicate.isBigInt(n) ? Number(n) : n)
|
|
338
350
|
|
|
339
351
|
/** How many counts {@link byCount} keeps the parsers of. */
|
|
@@ -359,7 +371,9 @@ const byCount = <A>(build: (n: number) => A): ((n: number | bigint) => A) => {
|
|
|
359
371
|
|
|
360
372
|
/**
|
|
361
373
|
* Parses a length with `count`, then takes that many tokens (winnow's
|
|
362
|
-
* `length_take`, nom's `length_data`).
|
|
374
|
+
* `length_take`, nom's `length_data`). A length that is not a non-negative
|
|
375
|
+
* integer (a negative `i8`, a fractional float) fails the parse at the
|
|
376
|
+
* length.
|
|
363
377
|
*
|
|
364
378
|
* @since 0.1.0
|
|
365
379
|
* @category length-prefixed
|
|
@@ -373,9 +387,15 @@ export const lengthTake = <E, R, I extends Input = Uint8Array>(
|
|
|
373
387
|
[count],
|
|
374
388
|
([countStep]) =>
|
|
375
389
|
(state: State<I>) => {
|
|
390
|
+
const start = state.pos
|
|
376
391
|
// SAFETY: the count parser's step, interpreted or compiled, returns its output (a number or bigint) or `Fail`
|
|
377
392
|
const n = countStep(state) as number | bigint | Fail
|
|
378
393
|
if (n === Fail) return Fail
|
|
394
|
+
// As `Parser.filter` fails: at the length, backtracking
|
|
395
|
+
if (!isCount(n)) {
|
|
396
|
+
state.rewind(start)
|
|
397
|
+
return state.backtrack("Verify")
|
|
398
|
+
}
|
|
379
399
|
return take(n)(state)
|
|
380
400
|
},
|
|
381
401
|
"lengthTake"
|
|
@@ -384,7 +404,8 @@ export const lengthTake = <E, R, I extends Input = Uint8Array>(
|
|
|
384
404
|
|
|
385
405
|
/**
|
|
386
406
|
* Parses a length with `count`, then applies `parser` that many times
|
|
387
|
-
* (winnow's `length_repeat`, nom's `length_count`).
|
|
407
|
+
* (winnow's `length_repeat`, nom's `length_count`). A length that is not a
|
|
408
|
+
* non-negative integer fails the parse at the length.
|
|
388
409
|
*
|
|
389
410
|
* @since 0.1.0
|
|
390
411
|
* @category length-prefixed
|
|
@@ -394,7 +415,7 @@ export const lengthRepeat = <E, R, I extends Input, A, E2, R2, I2 extends Input>
|
|
|
394
415
|
parser: Parser<A, E2, R2, I2>
|
|
395
416
|
): Parser<Array<A>, E | E2, R | R2, I & I2> =>
|
|
396
417
|
P.flatMap(
|
|
397
|
-
count,
|
|
418
|
+
P.filter(count, isCount),
|
|
398
419
|
byCount((n) => P.repeat(parser, n))
|
|
399
420
|
)
|
|
400
421
|
|
package/src/Bits.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { State } from "./Input.js"
|
|
|
24
24
|
import { Fail, Failure } from "./Input.js"
|
|
25
25
|
import type { Parser } from "./Parser.js"
|
|
26
26
|
import { make } from "./Parser.js"
|
|
27
|
+
import { checkCount } from "./internal/node.js"
|
|
27
28
|
|
|
28
29
|
declare const BitInputBrand: unique symbol
|
|
29
30
|
|
|
@@ -136,6 +137,7 @@ const readBits = (state: State<any>, count: number): number => {
|
|
|
136
137
|
* @category parsers
|
|
137
138
|
*/
|
|
138
139
|
export const take = (count: number): Parser<number, never, never, BitInput> => {
|
|
140
|
+
checkCount(count)
|
|
139
141
|
if (count > 53) throw new RangeError("Bits.take: use Bits.takeBig for more than 53 bits")
|
|
140
142
|
const expected = [`${count} bits`]
|
|
141
143
|
return make((state: State<any>) => {
|
|
@@ -152,6 +154,7 @@ export const take = (count: number): Parser<number, never, never, BitInput> => {
|
|
|
152
154
|
* @category parsers
|
|
153
155
|
*/
|
|
154
156
|
export const takeBig = (count: number): Parser<bigint, never, never, BitInput> => {
|
|
157
|
+
checkCount(count)
|
|
155
158
|
const expected = [`${count} bits`]
|
|
156
159
|
return make((state: State<any>) => {
|
|
157
160
|
const avail = state.end - state.pos
|
|
@@ -175,6 +178,7 @@ export const takeBig = (count: number): Parser<bigint, never, never, BitInput> =
|
|
|
175
178
|
* @category parsers
|
|
176
179
|
*/
|
|
177
180
|
export const pattern = (pattern: number, count: number): Parser<number, never, never, BitInput> => {
|
|
181
|
+
checkCount(count)
|
|
178
182
|
const expected = [`bit pattern ${pattern.toString(2).padStart(count, "0")}`]
|
|
179
183
|
return make((state: State<any>) => {
|
|
180
184
|
const start = state.pos
|
package/src/Input.ts
CHANGED
|
@@ -276,6 +276,18 @@ export class State<I extends Input = Input> {
|
|
|
276
276
|
this.deepestIsLatest = false
|
|
277
277
|
this.deepestFailure = failure
|
|
278
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Whether compiled code is running on this state. A compiled run that fails
|
|
281
|
+
* is thrown away (the interpreter runs again to build the error) and one
|
|
282
|
+
* that succeeds records no diagnostics, so interpreted steps called from it
|
|
283
|
+
* (an opaque `Parser.make`, a leaf near the end of a partial input) record
|
|
284
|
+
* a `Backtrack` or `Cut` failure's mode only, without building its
|
|
285
|
+
* {@link Failure} (#82). `Incomplete` failures are still built: a compiled
|
|
286
|
+
* run's `Incomplete` is reported as it stands.
|
|
287
|
+
*
|
|
288
|
+
* @internal
|
|
289
|
+
*/
|
|
290
|
+
compiledRun = false
|
|
279
291
|
/** When defined, `Parser.resumeAfter`/`retryAfter` record failures here. */
|
|
280
292
|
recovered: Array<Failure> | undefined = undefined
|
|
281
293
|
/** When defined, `Parser.trace` reports events here. */
|
|
@@ -304,8 +316,10 @@ export class State<I extends Input = Input> {
|
|
|
304
316
|
/**
|
|
305
317
|
* Where the stop characters of compiled `takeTill`s next occur in this
|
|
306
318
|
* state's input, by search site; created on first use. It lives as long
|
|
307
|
-
* as the state
|
|
308
|
-
* the
|
|
319
|
+
* as the state. `reset` keeps it for string input (a string never
|
|
320
|
+
* changes, and the positions are absolute, so they hold wherever the next
|
|
321
|
+
* run starts) and drops it for bytes and arrays, which a caller may
|
|
322
|
+
* refill in place between runs.
|
|
309
323
|
*
|
|
310
324
|
* @internal
|
|
311
325
|
*/
|
|
@@ -383,7 +397,11 @@ export class State<I extends Input = Input> {
|
|
|
383
397
|
*
|
|
384
398
|
* Every per-run field is reset: the cursor and end, the latest failure,
|
|
385
399
|
* hints and furthest failure, recorded recoveries, the tracer and tracing
|
|
386
|
-
* depth, the recorded encoding and streaming checkpoints.
|
|
400
|
+
* depth, the recorded encoding and streaming checkpoints. For string
|
|
401
|
+
* input, what the state has learnt about the string (where the stop
|
|
402
|
+
* characters of `takeTill` and the literals of `takeUntilAny` occur) is
|
|
403
|
+
* kept, as a string cannot change; for bytes and arrays it is dropped, so
|
|
404
|
+
* a buffer refilled in place between runs is searched afresh. Like the
|
|
387
405
|
* constructor, `partial` defaults to `false` and `context` to the empty
|
|
388
406
|
* context, so pass them again on every reset.
|
|
389
407
|
*
|
|
@@ -422,12 +440,19 @@ export class State<I extends Input = Input> {
|
|
|
422
440
|
this.hintExpected = empty
|
|
423
441
|
this.deepestFailure = undefined
|
|
424
442
|
this.deepestIsLatest = false
|
|
443
|
+
this.compiledRun = false
|
|
425
444
|
this.recovered = undefined
|
|
426
445
|
this.tracer = undefined
|
|
427
446
|
this.depth = 0
|
|
428
447
|
this.encoding = undefined
|
|
429
448
|
this.resume = undefined
|
|
430
|
-
|
|
449
|
+
// For a string, `searches` is kept: it remembers where stop characters
|
|
450
|
+
// and literals occur by absolute position, and a string never changes,
|
|
451
|
+
// so it holds at any offset. A lexer that resets before each token
|
|
452
|
+
// otherwise searched to the end of the buffer again for every token
|
|
453
|
+
// (#126). Bytes and arrays can be refilled in place between runs (a
|
|
454
|
+
// `Uint8Array` source is viewed, not copied), so theirs is dropped.
|
|
455
|
+
if (this.inputKind !== 0) this.searches = undefined
|
|
431
456
|
this.asciiRun = undefined
|
|
432
457
|
return this
|
|
433
458
|
}
|
|
@@ -503,6 +528,10 @@ export class State<I extends Input = Input> {
|
|
|
503
528
|
* Records a recoverable failure at the current offset and returns {@link Fail}.
|
|
504
529
|
*/
|
|
505
530
|
backtrack(kind: ErrorKind, expected: ReadonlyArray<string> = empty, offset: number = this.pos): Fail {
|
|
531
|
+
if (this.compiledRun) {
|
|
532
|
+
this.mode = "Backtrack"
|
|
533
|
+
return Fail
|
|
534
|
+
}
|
|
506
535
|
return this.failWith("Backtrack", this.makeFailure(offset, kind, expected))
|
|
507
536
|
}
|
|
508
537
|
|
|
@@ -510,6 +539,10 @@ export class State<I extends Input = Input> {
|
|
|
510
539
|
* Records an unrecoverable failure at the current offset and returns {@link Fail}.
|
|
511
540
|
*/
|
|
512
541
|
cut(kind: ErrorKind, expected: ReadonlyArray<string> = empty, offset: number = this.pos): Fail {
|
|
542
|
+
if (this.compiledRun) {
|
|
543
|
+
this.mode = "Cut"
|
|
544
|
+
return Fail
|
|
545
|
+
}
|
|
513
546
|
return this.failWith("Cut", this.makeFailure(offset, kind, expected))
|
|
514
547
|
}
|
|
515
548
|
|