@thomasfosterau/effect-parse 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +202 -0
- package/README.md +56 -14
- package/dist/Ascii.d.ts +11 -4
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +12 -4
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +5 -2
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +83 -37
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +11 -4
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +74 -2
- package/dist/Compiler.d.ts.map +1 -1
- package/dist/Compiler.js +78 -1
- package/dist/Compiler.js.map +1 -1
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +86 -74
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +56 -5
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +70 -1
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +5 -15
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +69 -11
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +129 -28
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +375 -29
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +394 -37
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +2 -3
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +122 -14
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +293 -62
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +23 -5
- package/dist/Syntax.d.ts.map +1 -1
- package/dist/Syntax.js +1 -1
- package/dist/Syntax.js.map +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +21 -15
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +65 -11
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +73 -26
- package/dist/Token.js.map +1 -1
- package/dist/internal/compiler/closure.d.ts +1 -1
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +263 -113
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +3 -1
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +3 -2
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +9 -2
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/graph.d.ts +39 -0
- package/dist/internal/compiler/graph.d.ts.map +1 -0
- package/dist/internal/compiler/graph.js +78 -0
- package/dist/internal/compiler/graph.js.map +1 -0
- package/dist/internal/compiler/jit.d.ts +5 -0
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +208 -106
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +11 -3
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/search.d.ts +32 -0
- package/dist/internal/compiler/search.d.ts.map +1 -0
- package/dist/internal/compiler/search.js +68 -0
- package/dist/internal/compiler/search.js.map +1 -0
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +1 -1
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/compiler/wasm.d.ts +8 -0
- package/dist/internal/compiler/wasm.d.ts.map +1 -0
- package/dist/internal/compiler/wasm.js +2840 -0
- package/dist/internal/compiler/wasm.js.map +1 -0
- package/dist/internal/compiler/wasmAsm.d.ts +199 -0
- package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
- package/dist/internal/compiler/wasmAsm.js +427 -0
- package/dist/internal/compiler/wasmAsm.js.map +1 -0
- package/dist/internal/entries.d.ts +3 -1
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +77 -3
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +54 -10
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/run.d.ts +14 -0
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +53 -11
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +14 -0
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +24 -2
- package/dist/internal/stack.js.map +1 -1
- package/dist/internal/syntax.d.ts +4 -4
- package/dist/internal/syntax.d.ts.map +1 -1
- package/dist/internal/syntax.js +18 -10
- package/dist/internal/syntax.js.map +1 -1
- package/dist/internal/text.d.ts +32 -0
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +68 -14
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +20 -0
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +72 -39
- package/dist/internal/tokens.js.map +1 -1
- package/dist/internal/tuple.d.ts +6 -0
- package/dist/internal/tuple.d.ts.map +1 -0
- package/dist/internal/tuple.js +170 -0
- package/dist/internal/tuple.js.map +1 -0
- package/package.json +18 -10
- package/src/Ascii.ts +47 -12
- package/src/Binary.ts +174 -73
- package/src/Bits.ts +16 -6
- package/src/Compiler.ts +101 -10
- package/src/Expression.ts +94 -81
- package/src/Input.ts +99 -7
- package/src/Nom.ts +15 -5
- package/src/ParseError.ts +209 -52
- package/src/Parser.ts +684 -143
- package/src/ParserSchema.ts +1 -2
- package/src/ParserStream.ts +361 -68
- package/src/Syntax.ts +60 -36
- package/src/Text.ts +32 -27
- package/src/Token.ts +152 -34
- package/src/internal/compiler/closure.ts +371 -153
- package/src/internal/compiler/entries.ts +4 -2
- package/src/internal/compiler/first.ts +16 -0
- package/src/internal/compiler/graph.ts +96 -0
- package/src/internal/compiler/jit.ts +319 -169
- package/src/internal/compiler/registry.ts +10 -2
- package/src/internal/compiler/search.ts +68 -0
- package/src/internal/compiler/sets.ts +7 -3
- package/src/internal/compiler/wasm.ts +3276 -0
- package/src/internal/compiler/wasmAsm.ts +484 -0
- package/src/internal/entries.ts +8 -2
- package/src/internal/node.ts +103 -7
- package/src/internal/numbers.ts +3 -1
- package/src/internal/run.ts +73 -12
- package/src/internal/stack.ts +25 -1
- package/src/internal/syntax.ts +39 -18
- package/src/internal/text.ts +97 -9
- package/src/internal/tokens.ts +106 -14
- package/src/internal/tuple.ts +141 -0
|
@@ -11,15 +11,23 @@ import type { Fallback, Step } from "./closure.js"
|
|
|
11
11
|
|
|
12
12
|
/** What was compiled for a parser and an input kind. */
|
|
13
13
|
export interface Compiled {
|
|
14
|
-
/** The compiler actually used. */
|
|
15
|
-
readonly backend: "jit" | "closure" |
|
|
14
|
+
/** The compiler actually used: `interpreted` when compilation failed. */
|
|
15
|
+
readonly backend: "wasm" | "jit" | "closure" | "interpreted"
|
|
16
16
|
readonly step: Step | undefined
|
|
17
|
+
/**
|
|
18
|
+
* Whether `step` reports a call-stack overflow as a `TooDeep` failure
|
|
19
|
+
* itself, as `Stack.run` would (the JIT's generated entry does), so that
|
|
20
|
+
* it runs without that guard.
|
|
21
|
+
*/
|
|
22
|
+
readonly guarded: boolean
|
|
17
23
|
/** Parts of the grammar that run interpreted, and why. */
|
|
18
24
|
readonly fallbacks: ReadonlyArray<Fallback>
|
|
19
25
|
/** Why compilation failed, if it did (the parser then runs interpreted). */
|
|
20
26
|
readonly error: unknown
|
|
21
27
|
/** Why the JIT failed, if it did (the closure compiler is then used). */
|
|
22
28
|
readonly jitError?: unknown
|
|
29
|
+
/** Why the WebAssembly compiler failed, if it did (the JIT is then used). */
|
|
30
|
+
readonly wasmError?: unknown
|
|
23
31
|
/** The generated source, for the JIT. */
|
|
24
32
|
readonly source?: string
|
|
25
33
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Searching for the stop characters of `Token.takeTill` on string input
|
|
3
|
+
* (#75): a run is scanned a unit at a time for `SearchHead` units, then
|
|
4
|
+
* found with `indexOf`, which V8 runs much faster on long runs. Both
|
|
5
|
+
* compilers use these; the interpreter scans unit by unit.
|
|
6
|
+
*/
|
|
7
|
+
import * as Arr from "effect/Array"
|
|
8
|
+
import type { State } from "../../Input.js"
|
|
9
|
+
import type { CharSet } from "./sets.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* How many units a compiled `takeTill` tests one at a time before it
|
|
13
|
+
* searches with `indexOf` (twice as many for several stop characters, whose
|
|
14
|
+
* cached search costs more): short runs, most tokens, are faster scanned.
|
|
15
|
+
*/
|
|
16
|
+
export const SearchHead = 8
|
|
17
|
+
|
|
18
|
+
/** The most stop characters a compiled `takeTill` searches for. */
|
|
19
|
+
const MaxStops = 3
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The stop characters of a `takeTill` set, as UTF-16 units, when there are
|
|
23
|
+
* one to `MaxStops` of them, each a whole code point (not a surrogate).
|
|
24
|
+
*/
|
|
25
|
+
export const stopChars = (cs: CharSet): ReadonlyArray<number> | undefined => {
|
|
26
|
+
const ranges = cs.ranges
|
|
27
|
+
if (ranges === undefined || Arr.isReadonlyArrayEmpty(ranges) || ranges.length > MaxStops) return undefined
|
|
28
|
+
if (!ranges.every(([a, b]) => a === b && (a < 0xd800 || (a > 0xdfff && a <= 0xffff)))) return undefined
|
|
29
|
+
return ranges.map(([a]) => a)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The stop characters of one compiled `takeTill`, identifying its search site.
|
|
34
|
+
* The state holds, under this site, where each one next occurs (see
|
|
35
|
+
* `nextStop`).
|
|
36
|
+
*/
|
|
37
|
+
export class StopCache {
|
|
38
|
+
constructor(readonly chars: ReadonlyArray<string>) {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The first index from `p` of any of `site.chars` in the input of `s`, or
|
|
43
|
+
* `s.end`. The state remembers, for each stop character `i`, the first
|
|
44
|
+
* index at or after `from` where it occurs (`-1` if none), as
|
|
45
|
+
* `[from, at]` at `2 * i` in `s.searches.get(site)`: successive runs over
|
|
46
|
+
* one input then pay a comparison per stop character instead of a search,
|
|
47
|
+
* and one that never occurs is searched for once.
|
|
48
|
+
*/
|
|
49
|
+
export const nextStop = (site: StopCache, s: State<string>, p: number): number => {
|
|
50
|
+
const searches = (s.searches ??= new Map())
|
|
51
|
+
let memo = searches.get(site)
|
|
52
|
+
if (memo === undefined) {
|
|
53
|
+
memo = site.chars.flatMap(() => [-1, -1])
|
|
54
|
+
searches.set(site, memo)
|
|
55
|
+
}
|
|
56
|
+
let best = s.end
|
|
57
|
+
for (let i = 0; i < site.chars.length; i++) {
|
|
58
|
+
const from = memo[2 * i]
|
|
59
|
+
let at = memo[2 * i + 1]
|
|
60
|
+
if (from < 0 || p < from || (at >= 0 && at < p)) {
|
|
61
|
+
at = s.input.indexOf(site.chars[i], p)
|
|
62
|
+
memo[2 * i] = p
|
|
63
|
+
memo[2 * i + 1] = at
|
|
64
|
+
}
|
|
65
|
+
if (at >= 0 && at < best) best = at
|
|
66
|
+
}
|
|
67
|
+
return best
|
|
68
|
+
}
|
|
@@ -7,6 +7,7 @@ import * as Order from "effect/Order"
|
|
|
7
7
|
import * as Predicate from "effect/Predicate"
|
|
8
8
|
import type { Encoding } from "../../Encoding.js"
|
|
9
9
|
import { firstCodePoint } from "../text.js"
|
|
10
|
+
import type { TokenRangeLike } from "../tokens.js"
|
|
10
11
|
import { compile, compileAny, PredicateRanges } from "../tokens.js"
|
|
11
12
|
|
|
12
13
|
/** Size of the membership table: every byte, and the Latin-1 code points. */
|
|
@@ -28,8 +29,7 @@ export const acceptTable = (set: CharSet, negate: boolean): Uint8Array => {
|
|
|
28
29
|
return t
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
const isRange = (u: unknown): u is
|
|
32
|
-
Predicate.isObjectOrArray(u) && (u as any)._tag === "TokenRange"
|
|
32
|
+
const isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && Predicate.isTagged(u, "TokenRange")
|
|
33
33
|
|
|
34
34
|
const toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))
|
|
35
35
|
|
|
@@ -57,7 +57,11 @@ const rangesOf = (set: unknown): Array<[number, number]> | undefined => {
|
|
|
57
57
|
return true
|
|
58
58
|
}
|
|
59
59
|
if (Predicate.isFunction(u)) {
|
|
60
|
-
|
|
60
|
+
// SAFETY: `codePointPredicate` is the only writer of `PredicateRanges`, and it stores the
|
|
61
|
+
// predicate's sorted inclusive code point ranges there (or nothing)
|
|
62
|
+
const r = (u as { readonly [PredicateRanges]?: ReadonlyArray<readonly [number, number]> | undefined })[
|
|
63
|
+
PredicateRanges
|
|
64
|
+
]
|
|
61
65
|
if (r === undefined) return false
|
|
62
66
|
for (const [a, b] of r) out.push([a, b])
|
|
63
67
|
return true
|