@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/internal/tokens.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
// fallow-ignore-file duplicate-export -- `End` and `scan` here are the token-set versions of the text
|
|
2
|
+
// helpers in ./text.ts; both are internal modules, imported by path, never re-exported from one barrel.
|
|
3
|
+
import * as Predicate from "effect/Predicate"
|
|
1
4
|
import type { Input, State } from "../Input.js"
|
|
5
|
+
import { charOf, firstCodePoint } from "./text.js"
|
|
2
6
|
|
|
3
7
|
/** A compiled token set. */
|
|
4
8
|
export interface Matcher {
|
|
@@ -17,21 +21,20 @@ export interface TokenRangeLike {
|
|
|
17
21
|
readonly to: string | number
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
const isRange = (u: unknown): u is TokenRangeLike =>
|
|
21
|
-
typeof u === "object" && u !== null && (u as any)._tag === "TokenRange"
|
|
24
|
+
const isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && (u as any)._tag === "TokenRange"
|
|
22
25
|
|
|
23
|
-
const toCode = (u: string | number): number =>
|
|
26
|
+
const toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))
|
|
24
27
|
|
|
25
28
|
/** @internal */
|
|
26
29
|
export const describeChar = (s: string): string => JSON.stringify(s)
|
|
27
30
|
|
|
28
31
|
const describeSet = (u: unknown): string => {
|
|
29
|
-
if (
|
|
32
|
+
if (Predicate.isString(u)) {
|
|
30
33
|
const chars = Array.from(u)
|
|
31
34
|
return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`
|
|
32
35
|
}
|
|
33
|
-
if (
|
|
34
|
-
if (
|
|
36
|
+
if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, "0")}`
|
|
37
|
+
if (Predicate.isFunction(u)) return u.name ? u.name : "a matching token"
|
|
35
38
|
if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`
|
|
36
39
|
if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`
|
|
37
40
|
if (Array.isArray(u)) return u.map(describeSet).join(" or ")
|
|
@@ -39,10 +42,10 @@ const describeSet = (u: unknown): string => {
|
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/** Renders bytes as a Rust-style byte string literal: b"GET\r\n". */
|
|
42
|
-
|
|
43
|
-
let out =
|
|
45
|
+
const describeBytes = (bytes: Uint8Array): string => {
|
|
46
|
+
let out = 'b"'
|
|
44
47
|
for (const b of bytes) {
|
|
45
|
-
if (b === 0x22) out += "
|
|
48
|
+
if (b === 0x22) out += '\\"'
|
|
46
49
|
else if (b === 0x5c) out += "\\\\"
|
|
47
50
|
else if (b === 0x0a) out += "\\n"
|
|
48
51
|
else if (b === 0x0d) out += "\\r"
|
|
@@ -50,20 +53,20 @@ export const describeBytes = (bytes: Uint8Array): string => {
|
|
|
50
53
|
else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b)
|
|
51
54
|
else out += `\\x${b.toString(16).padStart(2, "0")}`
|
|
52
55
|
}
|
|
53
|
-
return out + "
|
|
56
|
+
return out + '"'
|
|
54
57
|
}
|
|
55
58
|
|
|
56
|
-
const compileCode = (u: unknown): (code: number) => boolean => {
|
|
57
|
-
if (
|
|
58
|
-
const codes = Array.from(u,
|
|
59
|
+
const compileCode = (u: unknown): ((code: number) => boolean) => {
|
|
60
|
+
if (Predicate.isString(u)) {
|
|
61
|
+
const codes = Array.from(u, firstCodePoint)
|
|
59
62
|
if (codes.length === 1) {
|
|
60
|
-
const c = codes[0]
|
|
63
|
+
const c = codes[0]
|
|
61
64
|
return (x) => x === c
|
|
62
65
|
}
|
|
63
66
|
return bitmap(codes)
|
|
64
67
|
}
|
|
65
|
-
if (
|
|
66
|
-
if (
|
|
68
|
+
if (Predicate.isNumber(u)) return (x) => x === u
|
|
69
|
+
if (Predicate.isFunction(u)) return u as (code: number) => boolean
|
|
67
70
|
if (u instanceof Uint8Array) return bitmap(Array.from(u))
|
|
68
71
|
if (isRange(u)) {
|
|
69
72
|
const from = toCode(u.from)
|
|
@@ -72,16 +75,16 @@ const compileCode = (u: unknown): (code: number) => boolean => {
|
|
|
72
75
|
}
|
|
73
76
|
if (Array.isArray(u)) {
|
|
74
77
|
const tests = u.map(compileCode)
|
|
75
|
-
if (tests.length === 1) return tests[0]
|
|
78
|
+
if (tests.length === 1) return tests[0]
|
|
76
79
|
return (x) => {
|
|
77
|
-
for (let i = 0; i < tests.length; i++) if (tests[i]
|
|
80
|
+
for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true
|
|
78
81
|
return false
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
84
|
throw new TypeError(`invalid token set: ${String(u)}`)
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
const bitmap = (codes: ReadonlyArray<number>): (code: number) => boolean => {
|
|
87
|
+
const bitmap = (codes: ReadonlyArray<number>): ((code: number) => boolean) => {
|
|
85
88
|
const ascii = new Uint8Array(256)
|
|
86
89
|
let other: Set<number> | undefined
|
|
87
90
|
for (const c of codes) {
|
|
@@ -90,11 +93,11 @@ const bitmap = (codes: ReadonlyArray<number>): (code: number) => boolean => {
|
|
|
90
93
|
}
|
|
91
94
|
if (other === undefined) return (x) => x < 256 && ascii[x] === 1
|
|
92
95
|
const set = other
|
|
93
|
-
return (x) => x < 256 ? ascii[x] === 1 : set.has(x)
|
|
96
|
+
return (x) => (x < 256 ? ascii[x] === 1 : set.has(x))
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
const compileToken = (u: unknown): (token: unknown) => boolean => {
|
|
97
|
-
if (
|
|
99
|
+
const compileToken = (u: unknown): ((token: unknown) => boolean) => {
|
|
100
|
+
if (Predicate.isFunction(u)) return u as (token: unknown) => boolean
|
|
98
101
|
if (Array.isArray(u)) {
|
|
99
102
|
const set = new Set(u)
|
|
100
103
|
return (t) => set.has(t)
|
|
@@ -107,14 +110,14 @@ const compileToken = (u: unknown): (token: unknown) => boolean => {
|
|
|
107
110
|
* number), so string inputs can call it without allocating a string per
|
|
108
111
|
* character.
|
|
109
112
|
*/
|
|
110
|
-
|
|
113
|
+
const CodePointPredicate: unique symbol = /*#__PURE__*/ Symbol.for("effect-parse/CodePointPredicate")
|
|
111
114
|
|
|
112
115
|
/**
|
|
113
116
|
* The code points accepted by a predicate, as sorted, disjoint, inclusive
|
|
114
117
|
* ranges, when they are known. The compiler turns such predicates into
|
|
115
118
|
* comparisons or tables.
|
|
116
119
|
*/
|
|
117
|
-
export const PredicateRanges: unique symbol = Symbol.for("effect-parse/PredicateRanges")
|
|
120
|
+
export const PredicateRanges: unique symbol = /*#__PURE__*/ Symbol.for("effect-parse/PredicateRanges")
|
|
118
121
|
|
|
119
122
|
/**
|
|
120
123
|
* Marks `f` as a {@link CodePointPredicate} named `name` (used in error
|
|
@@ -133,26 +136,27 @@ export const codePointPredicate = <F extends (c: never) => boolean>(
|
|
|
133
136
|
|
|
134
137
|
/**
|
|
135
138
|
* Compiles a token set. Predicates for string inputs receive the token as a
|
|
136
|
-
* string, so they are wrapped here.
|
|
139
|
+
* string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,
|
|
140
|
+
* which is several times slower, for the Basic Multilingual Plane.
|
|
137
141
|
*/
|
|
138
142
|
export const compile = (set: unknown, kind: "string" | "code" = "code"): Matcher => {
|
|
139
143
|
const description = describeSet(set)
|
|
140
144
|
let code: (code: number) => boolean
|
|
141
|
-
if (
|
|
145
|
+
if (Predicate.isFunction(set) && kind === "string" && !(CodePointPredicate in set)) {
|
|
142
146
|
const pred = set as (c: string) => boolean
|
|
143
|
-
code = (x) => pred(
|
|
147
|
+
code = (x) => pred(charOf(x))
|
|
144
148
|
} else {
|
|
145
149
|
code = compileCodeSafe(set, kind)
|
|
146
150
|
}
|
|
147
151
|
return { code, token: compileToken(set), description }
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
const compileCodeSafe = (set: unknown, kind: "string" | "code"): (code: number) => boolean => {
|
|
154
|
+
const compileCodeSafe = (set: unknown, kind: "string" | "code"): ((code: number) => boolean) => {
|
|
151
155
|
if (Array.isArray(set) && kind === "string") {
|
|
152
156
|
// Predicates nested in arrays also take strings
|
|
153
157
|
const tests = set.map((s) => compile(s, kind).code)
|
|
154
158
|
return (x) => {
|
|
155
|
-
for (let i = 0; i < tests.length; i++) if (tests[i]
|
|
159
|
+
for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true
|
|
156
160
|
return false
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -173,9 +177,42 @@ export interface AnyMatcher {
|
|
|
173
177
|
readonly description: string
|
|
174
178
|
}
|
|
175
179
|
|
|
176
|
-
|
|
180
|
+
/**
|
|
181
|
+
* A small cache keyed by value, for the parts of a parser that are costly to
|
|
182
|
+
* build and depend only on a string (compiled sets, descriptions). Parsers
|
|
183
|
+
* built inside `Parser.gen` bodies are rebuilt on every run, usually from the
|
|
184
|
+
* same few strings. Dynamic strings could grow it without bound, so it is
|
|
185
|
+
* cleared when full.
|
|
186
|
+
*/
|
|
187
|
+
const cached = <A>(cache: Map<string, A>, key: string, build: (key: string) => A): A => {
|
|
188
|
+
let a = cache.get(key)
|
|
189
|
+
if (a === undefined) {
|
|
190
|
+
if (cache.size >= 1024) cache.clear()
|
|
191
|
+
a = build(key)
|
|
192
|
+
cache.set(key, a)
|
|
193
|
+
}
|
|
194
|
+
return a
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const literalDescriptions = /*#__PURE__*/ new Map<string, string>()
|
|
198
|
+
|
|
199
|
+
/** Describes a literal for error messages: `"abc"`, `b"abc"` or `["a", 1]`. */
|
|
200
|
+
export const describeLiteral = (lit: Input): string =>
|
|
201
|
+
Predicate.isString(lit)
|
|
202
|
+
? cached(literalDescriptions, lit, describeChar)
|
|
203
|
+
: lit instanceof Uint8Array
|
|
204
|
+
? describeBytes(lit)
|
|
205
|
+
: `[${lit.map((t) => JSON.stringify(t)).join(", ")}]`
|
|
206
|
+
|
|
207
|
+
const stringMatchers = /*#__PURE__*/ new Map<string, AnyMatcher>()
|
|
208
|
+
|
|
209
|
+
export const compileAny = (set: unknown): AnyMatcher =>
|
|
210
|
+
// Matchers for strings are pure functions of the string, so they're shared
|
|
211
|
+
Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set)
|
|
212
|
+
|
|
213
|
+
const compileAnyImpl = (set: unknown): AnyMatcher => {
|
|
177
214
|
const forCode = compile(set, "code")
|
|
178
|
-
const needsString =
|
|
215
|
+
const needsString = Predicate.isFunction(set) || Array.isArray(set)
|
|
179
216
|
return {
|
|
180
217
|
forString: needsString ? compile(set, "string") : forCode,
|
|
181
218
|
forCode,
|
|
@@ -195,7 +232,7 @@ export const splitSurrogate = (state: State<Input>, i: number): boolean => {
|
|
|
195
232
|
}
|
|
196
233
|
|
|
197
234
|
/** Reads the code point at `i` of a string. */
|
|
198
|
-
|
|
235
|
+
const codePointAt = (s: string, i: number): number => {
|
|
199
236
|
const c = s.charCodeAt(i)
|
|
200
237
|
if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
201
238
|
const d = s.charCodeAt(i + 1)
|
|
@@ -208,14 +245,10 @@ export const codePointAt = (s: string, i: number): number => {
|
|
|
208
245
|
* Tests the token at the current position. Returns the token (as the input's
|
|
209
246
|
* token type) and advances, or returns `NoMatch`/`End`.
|
|
210
247
|
*/
|
|
211
|
-
export const NoMatch: unique symbol = Symbol("NoMatch")
|
|
212
|
-
export const End: unique symbol = Symbol("End")
|
|
248
|
+
export const NoMatch: unique symbol = /*#__PURE__*/ Symbol("NoMatch")
|
|
249
|
+
export const End: unique symbol = /*#__PURE__*/ Symbol("End")
|
|
213
250
|
|
|
214
|
-
export const nextIf = (
|
|
215
|
-
state: State<Input>,
|
|
216
|
-
m: AnyMatcher,
|
|
217
|
-
negate: boolean
|
|
218
|
-
): unknown => {
|
|
251
|
+
export const nextIf = (state: State<Input>, m: AnyMatcher, negate: boolean): unknown => {
|
|
219
252
|
const pos = state.pos
|
|
220
253
|
if (pos >= state.end) return End
|
|
221
254
|
switch (state.inputKind) {
|
|
@@ -229,7 +262,7 @@ export const nextIf = (
|
|
|
229
262
|
return len === 1 ? s[pos] : s.slice(pos, pos + 2)
|
|
230
263
|
}
|
|
231
264
|
case 1: {
|
|
232
|
-
const b = (state.input as Uint8Array)[pos]
|
|
265
|
+
const b = (state.input as Uint8Array)[pos]
|
|
233
266
|
if (m.forCode.code(b) === negate) return NoMatch
|
|
234
267
|
state.pos = pos + 1
|
|
235
268
|
return b
|
|
@@ -282,7 +315,7 @@ export const scan = (
|
|
|
282
315
|
const test = m.forCode.code
|
|
283
316
|
while (count < max) {
|
|
284
317
|
if (i >= end) return { offset: i, count, hitEnd: true }
|
|
285
|
-
if (test(bytes[i]
|
|
318
|
+
if (test(bytes[i]) === negate) break
|
|
286
319
|
i++
|
|
287
320
|
count++
|
|
288
321
|
}
|
|
@@ -333,18 +366,23 @@ export const countTokens = (state: State<Input>, start: number, end: number): nu
|
|
|
333
366
|
return count
|
|
334
367
|
}
|
|
335
368
|
|
|
336
|
-
/** Finds `needle`
|
|
369
|
+
/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
|
|
337
370
|
export const indexOf = (state: State<Input>, needle: Input, from: number): number => {
|
|
371
|
+
// The whole needle must lie before `state.end`, which may narrow the input
|
|
372
|
+
const last = state.end - needle.length
|
|
373
|
+
if (from > last) return -1
|
|
338
374
|
switch (state.inputKind) {
|
|
339
|
-
case 0:
|
|
340
|
-
|
|
375
|
+
case 0: {
|
|
376
|
+
const i = (state.input as string).indexOf(needle as string, from)
|
|
377
|
+
return i <= last ? i : -1
|
|
378
|
+
}
|
|
341
379
|
case 1: {
|
|
342
380
|
const hay = state.input as Uint8Array
|
|
343
381
|
const n = needle as Uint8Array
|
|
344
|
-
if (n.length === 0) return from
|
|
345
|
-
const first = n[0]
|
|
382
|
+
if (n.length === 0) return from
|
|
383
|
+
const first = n[0]
|
|
346
384
|
let i = hay.indexOf(first, from)
|
|
347
|
-
while (i !== -1 && i
|
|
385
|
+
while (i !== -1 && i <= last) {
|
|
348
386
|
let j = 1
|
|
349
387
|
while (j < n.length && hay[i + j] === n[j]) j++
|
|
350
388
|
if (j === n.length) return i
|
|
@@ -355,7 +393,7 @@ export const indexOf = (state: State<Input>, needle: Input, from: number): numbe
|
|
|
355
393
|
default: {
|
|
356
394
|
const hay = state.input as ReadonlyArray<unknown>
|
|
357
395
|
const n = needle as ReadonlyArray<unknown>
|
|
358
|
-
outer: for (let i = from; i
|
|
396
|
+
outer: for (let i = from; i <= last; i++) {
|
|
359
397
|
for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer
|
|
360
398
|
return i
|
|
361
399
|
}
|
|
@@ -370,6 +408,13 @@ export const indexOf = (state: State<Input>, needle: Input, from: number): numbe
|
|
|
370
408
|
* -1 on mismatch, or -2 when the input ends while matching a prefix.
|
|
371
409
|
*/
|
|
372
410
|
export const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean): number => {
|
|
411
|
+
const r = match(state, lit, caseless)
|
|
412
|
+
// A failed match may have read up to its length past where it fails (see `Syntax`)
|
|
413
|
+
if (r < 0 && state.syntax !== undefined) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos))
|
|
414
|
+
return r
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const match = (state: State<Input>, lit: Input, caseless: boolean): number => {
|
|
373
418
|
const pos = state.pos
|
|
374
419
|
const len = lit.length
|
|
375
420
|
const avail = state.end - pos
|
|
@@ -391,8 +436,8 @@ export const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean)
|
|
|
391
436
|
const b = state.input as Uint8Array
|
|
392
437
|
const l = lit as Uint8Array
|
|
393
438
|
for (let i = 0; i < n; i++) {
|
|
394
|
-
const x = b[pos + i]
|
|
395
|
-
const y = l[i]
|
|
439
|
+
const x = b[pos + i]
|
|
440
|
+
const y = l[i]
|
|
396
441
|
if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1
|
|
397
442
|
}
|
|
398
443
|
return n === len ? len : -2
|
|
@@ -406,4 +451,4 @@ export const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean)
|
|
|
406
451
|
}
|
|
407
452
|
}
|
|
408
453
|
|
|
409
|
-
const lowerAscii = (c: number): number => c >= 65 && c <= 90 ? c + 32 : c
|
|
454
|
+
const lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA"}
|