@thomasfosterau/effect-parse 0.4.0 → 0.5.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 +40 -14
- package/dist/Ascii.d.ts +11 -4
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +7 -1
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +64 -35
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +7 -4
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +74 -2
- package/dist/Compiler.d.ts.map +1 -1
- package/dist/Compiler.js +78 -1
- package/dist/Compiler.js.map +1 -1
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +86 -74
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +37 -4
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +42 -0
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +5 -15
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +2 -2
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +1 -1
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +370 -28
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +390 -19
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.js +2 -2
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +3 -2
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +15 -10
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +23 -5
- package/dist/Syntax.d.ts.map +1 -1
- package/dist/Syntax.js.map +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +9 -9
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +55 -10
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +59 -21
- package/dist/Token.js.map +1 -1
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +257 -97
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +3 -1
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +3 -2
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +7 -1
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/graph.d.ts +17 -0
- package/dist/internal/compiler/graph.d.ts.map +1 -0
- package/dist/internal/compiler/graph.js +56 -0
- package/dist/internal/compiler/graph.js.map +1 -0
- package/dist/internal/compiler/jit.d.ts +5 -0
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +185 -96
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +10 -2
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/search.d.ts +32 -0
- package/dist/internal/compiler/search.d.ts.map +1 -0
- package/dist/internal/compiler/search.js +68 -0
- package/dist/internal/compiler/search.js.map +1 -0
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +1 -1
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/compiler/wasm.d.ts +8 -0
- package/dist/internal/compiler/wasm.d.ts.map +1 -0
- package/dist/internal/compiler/wasm.js +2769 -0
- package/dist/internal/compiler/wasm.js.map +1 -0
- package/dist/internal/compiler/wasmAsm.d.ts +199 -0
- package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
- package/dist/internal/compiler/wasmAsm.js +427 -0
- package/dist/internal/compiler/wasmAsm.js.map +1 -0
- package/dist/internal/entries.d.ts +3 -1
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js +1 -2
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +58 -2
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +13 -3
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/run.d.ts +12 -0
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +51 -11
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +6 -0
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +8 -2
- package/dist/internal/stack.js.map +1 -1
- package/dist/internal/syntax.d.ts +4 -4
- package/dist/internal/syntax.d.ts.map +1 -1
- package/dist/internal/syntax.js +18 -10
- package/dist/internal/syntax.js.map +1 -1
- package/dist/internal/text.d.ts +32 -0
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +68 -14
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +13 -0
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +59 -39
- package/dist/internal/tokens.js.map +1 -1
- package/package.json +5 -4
- package/src/Ascii.ts +42 -9
- package/src/Binary.ts +151 -71
- package/src/Bits.ts +12 -6
- package/src/Compiler.ts +101 -10
- package/src/Expression.ts +94 -81
- package/src/Input.ts +65 -6
- package/src/Nom.ts +15 -5
- package/src/ParseError.ts +9 -4
- package/src/Parser.ts +682 -129
- package/src/ParserSchema.ts +1 -1
- package/src/ParserStream.ts +40 -19
- package/src/Syntax.ts +60 -36
- package/src/Text.ts +16 -15
- package/src/Token.ts +138 -29
- package/src/internal/compiler/closure.ts +362 -135
- package/src/internal/compiler/entries.ts +4 -2
- package/src/internal/compiler/first.ts +10 -0
- package/src/internal/compiler/graph.ts +68 -0
- package/src/internal/compiler/jit.ts +284 -154
- package/src/internal/compiler/registry.ts +10 -2
- package/src/internal/compiler/search.ts +68 -0
- package/src/internal/compiler/sets.ts +7 -3
- package/src/internal/compiler/wasm.ts +3203 -0
- package/src/internal/compiler/wasmAsm.ts +484 -0
- package/src/internal/entries.ts +10 -4
- package/src/internal/node.ts +54 -4
- package/src/internal/numbers.ts +3 -1
- package/src/internal/run.ts +71 -12
- package/src/internal/stack.ts +8 -1
- package/src/internal/syntax.ts +39 -18
- package/src/internal/text.ts +97 -9
- package/src/internal/tokens.ts +96 -14
|
@@ -24,11 +24,13 @@ export const pairOf = (p: ParserLike): EntryPair | undefined => {
|
|
|
24
24
|
return { parsers: node.parsers, key: output[0], value: output[1] }
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
/** Whether a node only changes diagnostics: its parser parses as its child does. */
|
|
28
|
+
export const isDiagnostic = (
|
|
28
29
|
node: Node
|
|
29
|
-
): node is NodeOf<"Context" | "Expected" | "MapError" | "OrFail" | "Trace" | "Syntax" | "RetryAfter"> =>
|
|
30
|
+
): node is NodeOf<"Context" | "Expected" | "Quiet" | "MapError" | "OrFail" | "Trace" | "Syntax" | "RetryAfter"> =>
|
|
30
31
|
Predicate.isTagged(node, "Context") ||
|
|
31
32
|
Predicate.isTagged(node, "Expected") ||
|
|
33
|
+
Predicate.isTagged(node, "Quiet") ||
|
|
32
34
|
Predicate.isTagged(node, "MapError") ||
|
|
33
35
|
Predicate.isTagged(node, "OrFail") ||
|
|
34
36
|
Predicate.isTagged(node, "Trace") ||
|
|
@@ -92,6 +92,7 @@ export class FirstSets {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
private compute(node: Node): First {
|
|
95
|
+
// SAFETY: `compute` is only called from `of`, which returns before it when `kind` is 2
|
|
95
96
|
const kind = this.kind as 0 | 1
|
|
96
97
|
switch (node._tag) {
|
|
97
98
|
case "Succeed":
|
|
@@ -111,6 +112,7 @@ export class FirstSets {
|
|
|
111
112
|
if (node.encoding !== undefined) {
|
|
112
113
|
if (kindOfEncoding(node.encoding) !== kind) return unknown
|
|
113
114
|
if (node.caseless) return isEmptyUnits(lit) ? unknown : anyUnit
|
|
115
|
+
// SAFETY: a `Literal` with an encoding is a `Text` literal, which records the string it encodes
|
|
114
116
|
const encoded = node.encoding.encode(lit as string)
|
|
115
117
|
if (isEmptyUnits(encoded)) return emptyOptional
|
|
116
118
|
return ofUnits([Predicate.isString(encoded) ? encoded.charCodeAt(0) : encoded[0]])
|
|
@@ -141,13 +143,18 @@ export class FirstSets {
|
|
|
141
143
|
case "Tap":
|
|
142
144
|
case "TryMap":
|
|
143
145
|
case "FilterMap":
|
|
146
|
+
case "MapOrFail":
|
|
144
147
|
case "Filter":
|
|
145
148
|
case "Taken":
|
|
146
149
|
case "WithTaken":
|
|
147
150
|
case "Span":
|
|
148
151
|
case "WithSpan":
|
|
152
|
+
case "MapSpan":
|
|
149
153
|
case "Context":
|
|
150
154
|
case "Expected":
|
|
155
|
+
case "Quiet":
|
|
156
|
+
// A fast path accepts what its grammar accepts (`Parser.withFastPath`)
|
|
157
|
+
case "FastPath":
|
|
151
158
|
case "MapError":
|
|
152
159
|
case "OrFail":
|
|
153
160
|
case "Peek":
|
|
@@ -173,6 +180,7 @@ export class FirstSets {
|
|
|
173
180
|
}
|
|
174
181
|
case "Seq":
|
|
175
182
|
case "Struct":
|
|
183
|
+
case "SeqWith":
|
|
176
184
|
return this.sequence(node.parsers)
|
|
177
185
|
case "ZipWith":
|
|
178
186
|
return this.sequence([node.self, node.that])
|
|
@@ -198,6 +206,8 @@ export class FirstSets {
|
|
|
198
206
|
}
|
|
199
207
|
case "Suspend":
|
|
200
208
|
return this.of(node.resolve())
|
|
209
|
+
case "Fixed":
|
|
210
|
+
return kind !== 1 ? unknown : node.size === 0 ? emptyOptional : anyUnit
|
|
201
211
|
default:
|
|
202
212
|
return unknown
|
|
203
213
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shape of a grammar, as the code-generating compilers (the JIT and the
|
|
3
|
+
* WebAssembly compiler) see it: which parsers are leaves, which are shared
|
|
4
|
+
* and which are small enough to inline everywhere.
|
|
5
|
+
*/
|
|
6
|
+
import * as Predicate from "effect/Predicate"
|
|
7
|
+
import type { Node, ParserLike } from "../node.js"
|
|
8
|
+
import { children, nodeOf } from "../node.js"
|
|
9
|
+
|
|
10
|
+
/** Whether a node is a token or a constant, always generated inline. */
|
|
11
|
+
export const isLeaf = (node: Node): boolean =>
|
|
12
|
+
Predicate.isTagged(node, "Succeed") ||
|
|
13
|
+
Predicate.isTagged(node, "Fail") ||
|
|
14
|
+
Predicate.isTagged(node, "Eof") ||
|
|
15
|
+
Predicate.isTagged(node, "Location") ||
|
|
16
|
+
Predicate.isTagged(node, "RestLen") ||
|
|
17
|
+
Predicate.isTagged(node, "Any") ||
|
|
18
|
+
Predicate.isTagged(node, "Literal") ||
|
|
19
|
+
Predicate.isTagged(node, "OneOf") ||
|
|
20
|
+
Predicate.isTagged(node, "TakeWhile")
|
|
21
|
+
|
|
22
|
+
/** The number of distinct parents of each parser reachable from `root`. */
|
|
23
|
+
export const countRefs = (root: ParserLike): WeakMap<ParserLike, number> => {
|
|
24
|
+
const refs = new WeakMap<ParserLike, number>()
|
|
25
|
+
const seen = new WeakSet<ParserLike>()
|
|
26
|
+
const stack = [root]
|
|
27
|
+
for (let p = stack.pop(); p !== undefined; p = stack.pop()) {
|
|
28
|
+
if (seen.has(p)) continue
|
|
29
|
+
seen.add(p)
|
|
30
|
+
const counted = new WeakSet<ParserLike>()
|
|
31
|
+
for (const c of children(nodeOf(p))) {
|
|
32
|
+
if (counted.has(c)) continue
|
|
33
|
+
counted.add(c)
|
|
34
|
+
refs.set(c, (refs.get(c) ?? 0) + 1)
|
|
35
|
+
stack.push(c)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return refs
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Whether a parser is small enough to inline wherever it is used. */
|
|
42
|
+
export const isSmall = (p: ParserLike): boolean => {
|
|
43
|
+
let budget = 6
|
|
44
|
+
const visit = (q: ParserLike): boolean => {
|
|
45
|
+
const node = nodeOf(q)
|
|
46
|
+
if (
|
|
47
|
+
--budget < 0 ||
|
|
48
|
+
Predicate.isTagged(node, "Suspend") ||
|
|
49
|
+
Predicate.isTagged(node, "Escaped") ||
|
|
50
|
+
Predicate.isTagged(node, "Dispatch")
|
|
51
|
+
)
|
|
52
|
+
return false
|
|
53
|
+
return children(node).every(visit)
|
|
54
|
+
}
|
|
55
|
+
return visit(p)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The node a `dispatch` selects on, and whether it is looked at with `peek`. */
|
|
59
|
+
export const selectorOf = (selector: ParserLike): { readonly node: Node; readonly peek: boolean } => {
|
|
60
|
+
const node = nodeOf(selector)
|
|
61
|
+
return Predicate.isTagged(node, "Peek") ? { node: nodeOf(node.self), peek: true } : { node, peek: false }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** ASCII lower case. */
|
|
65
|
+
export const lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)
|
|
66
|
+
|
|
67
|
+
/** Whether a code is an ASCII letter. */
|
|
68
|
+
export const isLetter = (c: number): boolean => (c >= 65 && c <= 90) || (c >= 97 && c <= 122)
|