@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
package/dist/internal/tokens.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as Predicate from "effect/Predicate";
|
|
|
2
2
|
import * as Result from "effect/Result";
|
|
3
3
|
import { charOf, firstCodePoint } from "./text.js";
|
|
4
4
|
// src/internal/tokens.ts
|
|
5
|
-
const isRange = (u) => Predicate.isObjectOrArray(u) && u
|
|
5
|
+
const isRange = (u) => Predicate.isObjectOrArray(u) && Predicate.isTagged(u, "TokenRange");
|
|
6
6
|
const toCode = (u) => Predicate.isNumber(u) ? u : firstCodePoint(u);
|
|
7
7
|
/** @internal */
|
|
8
8
|
const describeChar = (s) => JSON.stringify(s);
|
|
@@ -89,8 +89,9 @@ const PredicateRanges = /*#__PURE__*/ Symbol.for("effect-parse/PredicateRanges")
|
|
|
89
89
|
*/
|
|
90
90
|
const codePointPredicate = (name, f, ranges) => {
|
|
91
91
|
Object.defineProperty(f, "name", { value: name });
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const marked = f;
|
|
93
|
+
marked[CodePointPredicate] = true;
|
|
94
|
+
if (ranges !== void 0) marked[PredicateRanges] = ranges;
|
|
94
95
|
return f;
|
|
95
96
|
};
|
|
96
97
|
/**
|
|
@@ -202,10 +203,29 @@ const nextIf = (state, m, negate) => {
|
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
205
|
};
|
|
206
|
+
/** The one record {@link scan} fills; see there. */
|
|
207
|
+
var ScanResult = class {
|
|
208
|
+
offset = 0;
|
|
209
|
+
count = 0;
|
|
210
|
+
hitEnd = false;
|
|
211
|
+
};
|
|
212
|
+
const scanned = /*#__PURE__*/ new ScanResult();
|
|
213
|
+
/** Fills {@link scanned} and returns it. */
|
|
214
|
+
const scannedAt = (offset, count, hitEnd) => {
|
|
215
|
+
scanned.offset = offset;
|
|
216
|
+
scanned.count = count;
|
|
217
|
+
scanned.hitEnd = hitEnd;
|
|
218
|
+
return scanned;
|
|
219
|
+
};
|
|
205
220
|
/**
|
|
206
221
|
* Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`
|
|
207
222
|
* tokens. Returns the offset reached, the number of tokens matched, and
|
|
208
223
|
* whether the end of input was hit before `max` tokens.
|
|
224
|
+
*
|
|
225
|
+
* The result is one shared record, overwritten by the next scan: read it
|
|
226
|
+
* before running anything else. Allocating one per call cost the
|
|
227
|
+
* interpreter a record per token, since `scan` (shared by every `takeWhile`)
|
|
228
|
+
* is too polymorphic for V8 to inline and remove it.
|
|
209
229
|
*/
|
|
210
230
|
const scan = (state, m, negate, max) => {
|
|
211
231
|
let i = state.pos;
|
|
@@ -216,70 +236,42 @@ const scan = (state, m, negate, max) => {
|
|
|
216
236
|
const s = state.input;
|
|
217
237
|
const test = m.forString.code;
|
|
218
238
|
while (count < max) {
|
|
219
|
-
if (i >= end) return
|
|
220
|
-
offset: i,
|
|
221
|
-
count,
|
|
222
|
-
hitEnd: true
|
|
223
|
-
};
|
|
239
|
+
if (i >= end) return scannedAt(i, count, true);
|
|
224
240
|
const c = s.charCodeAt(i);
|
|
225
241
|
if (c < 55296 || c > 56319) {
|
|
226
242
|
if (test(c) === negate) break;
|
|
227
243
|
i++;
|
|
228
244
|
} else {
|
|
229
|
-
if (splitSurrogate(state, i)) return
|
|
230
|
-
offset: i,
|
|
231
|
-
count,
|
|
232
|
-
hitEnd: true
|
|
233
|
-
};
|
|
245
|
+
if (splitSurrogate(state, i)) return scannedAt(i, count, true);
|
|
234
246
|
const cp = codePointAt(s, i);
|
|
235
247
|
if (test(cp) === negate) break;
|
|
236
248
|
i += cp > 65535 ? 2 : 1;
|
|
237
249
|
}
|
|
238
250
|
count++;
|
|
239
251
|
}
|
|
240
|
-
return
|
|
241
|
-
offset: i,
|
|
242
|
-
count,
|
|
243
|
-
hitEnd: false
|
|
244
|
-
};
|
|
252
|
+
return scannedAt(i, count, false);
|
|
245
253
|
}
|
|
246
254
|
case 1: {
|
|
247
255
|
const bytes = state.input;
|
|
248
256
|
const test = m.forCode.code;
|
|
249
257
|
while (count < max) {
|
|
250
|
-
if (i >= end) return
|
|
251
|
-
offset: i,
|
|
252
|
-
count,
|
|
253
|
-
hitEnd: true
|
|
254
|
-
};
|
|
258
|
+
if (i >= end) return scannedAt(i, count, true);
|
|
255
259
|
if (test(bytes[i]) === negate) break;
|
|
256
260
|
i++;
|
|
257
261
|
count++;
|
|
258
262
|
}
|
|
259
|
-
return
|
|
260
|
-
offset: i,
|
|
261
|
-
count,
|
|
262
|
-
hitEnd: false
|
|
263
|
-
};
|
|
263
|
+
return scannedAt(i, count, false);
|
|
264
264
|
}
|
|
265
265
|
default: {
|
|
266
266
|
const arr = state.input;
|
|
267
267
|
const test = m.forCode.token;
|
|
268
268
|
while (count < max) {
|
|
269
|
-
if (i >= end) return
|
|
270
|
-
offset: i,
|
|
271
|
-
count,
|
|
272
|
-
hitEnd: true
|
|
273
|
-
};
|
|
269
|
+
if (i >= end) return scannedAt(i, count, true);
|
|
274
270
|
if (test(arr[i]) === negate) break;
|
|
275
271
|
i++;
|
|
276
272
|
count++;
|
|
277
273
|
}
|
|
278
|
-
return
|
|
279
|
-
offset: i,
|
|
280
|
-
count,
|
|
281
|
-
hitEnd: false
|
|
282
|
-
};
|
|
274
|
+
return scannedAt(i, count, false);
|
|
283
275
|
}
|
|
284
276
|
}
|
|
285
277
|
};
|
|
@@ -318,6 +310,47 @@ const countTokens = (state, start, end) => {
|
|
|
318
310
|
}
|
|
319
311
|
return count;
|
|
320
312
|
};
|
|
313
|
+
/**
|
|
314
|
+
* The first index at or after `from` of any of `needles` within
|
|
315
|
+
* `[from, state.end)`, or -1. The state remembers, under `needles`, where
|
|
316
|
+
* each one next occurs (`[from, at, end]` at `3 * i`), so successive
|
|
317
|
+
* searches forwards over one input search each needle once per occurrence
|
|
318
|
+
* rather than once per call (as `nextStop` does for `takeTill`).
|
|
319
|
+
*
|
|
320
|
+
* A remembered answer is used only where it still holds: an occurrence, when
|
|
321
|
+
* the search starts between where it was searched from and where it was
|
|
322
|
+
* found, and it still fits before the end; "not found", when the search
|
|
323
|
+
* starts no earlier and the end is no further than the end that search ran
|
|
324
|
+
* to (a parser may narrow `state.end` for a while, and `reset` widens it
|
|
325
|
+
* again, so a miss within a narrower end says nothing about a wider one).
|
|
326
|
+
*/
|
|
327
|
+
const indexOfAny = (state, needles, from) => {
|
|
328
|
+
const searches = state.searches ??= /* @__PURE__ */ new Map();
|
|
329
|
+
let memo = searches.get(needles);
|
|
330
|
+
if (memo === void 0) {
|
|
331
|
+
memo = needles.flatMap(() => [
|
|
332
|
+
-1,
|
|
333
|
+
-1,
|
|
334
|
+
-1
|
|
335
|
+
]);
|
|
336
|
+
searches.set(needles, memo);
|
|
337
|
+
}
|
|
338
|
+
let best = -1;
|
|
339
|
+
for (let i = 0; i < needles.length; i++) {
|
|
340
|
+
const known = memo[3 * i] ?? -1;
|
|
341
|
+
let at = memo[3 * i + 1] ?? -1;
|
|
342
|
+
const searchedTo = memo[3 * i + 2] ?? -1;
|
|
343
|
+
const needle = needles[i] ?? "";
|
|
344
|
+
if (known < 0 || from < known || (at >= 0 ? at < from || at > state.end - needle.length : state.end > searchedTo)) {
|
|
345
|
+
at = indexOf(state, needle, from);
|
|
346
|
+
memo[3 * i] = from;
|
|
347
|
+
memo[3 * i + 1] = at;
|
|
348
|
+
memo[3 * i + 2] = state.end;
|
|
349
|
+
}
|
|
350
|
+
if (at >= 0 && (best < 0 || at < best)) best = at;
|
|
351
|
+
}
|
|
352
|
+
return best;
|
|
353
|
+
};
|
|
321
354
|
/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
|
|
322
355
|
const indexOf = (state, needle, from) => {
|
|
323
356
|
const last = state.end - needle.length;
|
|
@@ -397,6 +430,6 @@ const match = (state, lit, caseless) => {
|
|
|
397
430
|
}
|
|
398
431
|
};
|
|
399
432
|
const lowerAscii = (c) => c >= 65 && c <= 90 ? c + 32 : c;
|
|
400
|
-
export { End, NoMatch, PredicateRanges, advance, codePointPredicate, compile, compileAny, countTokens, describeChar, describeLiteral, indexOf, matchLiteral, nextIf, scan, splitSurrogate };
|
|
433
|
+
export { End, NoMatch, PredicateRanges, advance, codePointPredicate, compile, compileAny, countTokens, describeChar, describeLiteral, indexOf, indexOfAny, matchLiteral, nextIf, scan, splitSurrogate };
|
|
401
434
|
|
|
402
435
|
//# sourceMappingURL=tokens.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","names":[],"sources":["../../src/internal/tokens.ts"],"sourcesContent":["// fallow-ignore-file duplicate-export -- `End` and `scan` here are the token-set versions of the text\n// helpers in ./text.ts; both are internal modules, imported by path, never re-exported from one barrel.\nimport * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport type { Input, State } from \"../Input.js\"\nimport { charOf, firstCodePoint } from \"./text.js\"\n\n/** A compiled token set. */\nexport interface Matcher {\n /** Tests a code point (string input) or a byte (Uint8Array input). */\n readonly code: (code: number) => boolean\n /** Tests an element of an array input. */\n readonly token: (token: unknown) => boolean\n /** Human readable description, used in error messages. */\n readonly description: string\n}\n\n/** @internal */\nexport interface TokenRangeLike {\n readonly _tag: \"TokenRange\"\n readonly from: string | number\n readonly to: string | number\n}\n\nconst isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && (u as any)._tag === \"TokenRange\"\n\nconst toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))\n\n/** @internal */\nexport const describeChar = (s: string): string => JSON.stringify(s)\n\nconst describeSet = (u: unknown): string => {\n if (Predicate.isString(u)) {\n const chars = Array.from(u)\n return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`\n }\n if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, \"0\")}`\n if (Predicate.isFunction(u)) return u.name ? u.name : \"a matching token\"\n if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`\n if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`\n if (Array.isArray(u)) return u.map(describeSet).join(\" or \")\n return JSON.stringify(u)\n}\n\n/** Renders bytes as a Rust-style byte string literal: b\"GET\\r\\n\". */\nconst describeBytes = (bytes: Uint8Array): string => {\n let out = 'b\"'\n for (const b of bytes) {\n if (b === 0x22) out += '\\\\\"'\n else if (b === 0x5c) out += \"\\\\\\\\\"\n else if (b === 0x0a) out += \"\\\\n\"\n else if (b === 0x0d) out += \"\\\\r\"\n else if (b === 0x09) out += \"\\\\t\"\n else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b)\n else out += `\\\\x${b.toString(16).padStart(2, \"0\")}`\n }\n return out + '\"'\n}\n\nconst compileCode = (u: unknown): ((code: number) => boolean) => {\n if (Predicate.isString(u)) {\n const codes = Array.from(u, firstCodePoint)\n if (codes.length === 1) {\n const c = codes[0]\n return (x) => x === c\n }\n return bitmap(codes)\n }\n if (Predicate.isNumber(u)) return (x) => x === u\n if (Predicate.isFunction(u)) return u as (code: number) => boolean\n if (u instanceof Uint8Array) return bitmap(Array.from(u))\n if (isRange(u)) {\n const from = toCode(u.from)\n const to = toCode(u.to)\n return (x) => x >= from && x <= to\n }\n if (Array.isArray(u)) {\n const tests = u.map(compileCode)\n if (tests.length === 1) return tests[0]\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n throw new TypeError(`invalid token set: ${String(u)}`)\n}\n\nconst bitmap = (codes: ReadonlyArray<number>): ((code: number) => boolean) => {\n const ascii = new Uint8Array(256)\n let other: Set<number> | undefined\n for (const c of codes) {\n if (c < 256) ascii[c] = 1\n else (other ??= new Set()).add(c)\n }\n if (other === undefined) return (x) => x < 256 && ascii[x] === 1\n const set = other\n return (x) => (x < 256 ? ascii[x] === 1 : set.has(x))\n}\n\nconst compileToken = (u: unknown): ((token: unknown) => boolean) => {\n if (Predicate.isFunction(u)) return u as (token: unknown) => boolean\n if (Array.isArray(u)) {\n const set = new Set(u)\n return (t) => set.has(t)\n }\n return (t) => t === u\n}\n\n/**\n * Marks a predicate over characters that also accepts a code point (a\n * number), so string inputs can call it without allocating a string per\n * character.\n */\nconst CodePointPredicate: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/CodePointPredicate\")\n\n/**\n * The code points accepted by a predicate, as sorted, disjoint, inclusive\n * ranges, when they are known. The compiler turns such predicates into\n * comparisons or tables.\n */\nexport const PredicateRanges: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/PredicateRanges\")\n\n/**\n * Marks `f` as a {@link CodePointPredicate} named `name` (used in error\n * messages), optionally recording the code point ranges it accepts.\n */\nexport const codePointPredicate = <F extends (c: never) => boolean>(\n name: string,\n f: F,\n ranges?: ReadonlyArray<readonly [number, number]>\n): F => {\n Object.defineProperty(f, \"name\", { value: name })\n ;(f as any)[CodePointPredicate] = true\n if (ranges !== undefined) (f as any)[PredicateRanges] = ranges\n return f\n}\n\n/**\n * Compiles a token set. Predicates for string inputs receive the token as a\n * string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,\n * which is several times slower, for the Basic Multilingual Plane.\n */\nexport const compile = (set: unknown, kind: \"string\" | \"code\" = \"code\"): Matcher => {\n const description = describeSet(set)\n let code: (code: number) => boolean\n if (Predicate.isFunction(set) && kind === \"string\" && !(CodePointPredicate in set)) {\n const pred = set as (c: string) => boolean\n code = (x) => pred(charOf(x))\n } else {\n code = compileCodeSafe(set, kind)\n }\n return { code, token: compileToken(set), description }\n}\n\nconst compileCodeSafe = (set: unknown, kind: \"string\" | \"code\"): ((code: number) => boolean) => {\n if (Array.isArray(set) && kind === \"string\") {\n // Predicates nested in arrays also take strings\n const tests = set.map((s) => compile(s, kind).code)\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n return Result.getOrElse(\n Result.try(() => compileCode(set)),\n (): ((code: number) => boolean) => () => false\n )\n}\n\n/**\n * A matcher that works for every input kind. String predicates receive the\n * token as a string, byte predicates receive numbers.\n */\nexport interface AnyMatcher {\n readonly forString: Matcher\n readonly forCode: Matcher\n readonly description: string\n}\n\n/**\n * A small cache keyed by value, for the parts of a parser that are costly to\n * build and depend only on a string (compiled sets, descriptions). Parsers\n * built inside `Parser.gen` bodies are rebuilt on every run, usually from the\n * same few strings. Dynamic strings could grow it without bound, so it is\n * cleared when full.\n */\nconst cached = <A>(cache: Map<string, A>, key: string, build: (key: string) => A): A => {\n let a = cache.get(key)\n if (a === undefined) {\n if (cache.size >= 1024) cache.clear()\n a = build(key)\n cache.set(key, a)\n }\n return a\n}\n\nconst literalDescriptions = /*#__PURE__*/ new Map<string, string>()\n\n/** Describes a literal for error messages: `\"abc\"`, `b\"abc\"` or `[\"a\", 1]`. */\nexport const describeLiteral = (lit: Input): string =>\n Predicate.isString(lit)\n ? cached(literalDescriptions, lit, describeChar)\n : lit instanceof Uint8Array\n ? describeBytes(lit)\n : `[${lit.map((t) => JSON.stringify(t)).join(\", \")}]`\n\nconst stringMatchers = /*#__PURE__*/ new Map<string, AnyMatcher>()\n\nexport const compileAny = (set: unknown): AnyMatcher =>\n // Matchers for strings are pure functions of the string, so they're shared\n Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set)\n\nconst compileAnyImpl = (set: unknown): AnyMatcher => {\n const forCode = compile(set, \"code\")\n const needsString = Predicate.isFunction(set) || Array.isArray(set)\n return {\n forString: needsString ? compile(set, \"string\") : forCode,\n forCode,\n description: forCode.description\n }\n}\n\n/**\n * Whether the string token at `i` is a high surrogate at the very end of a\n * partial input, i.e. the first half of a code point whose second half has\n * not arrived yet.\n */\nexport const splitSurrogate = (state: State<Input>, i: number): boolean => {\n if (!state.partial || i !== state.end - 1) return false\n const c = (state.input as string).charCodeAt(i)\n return c >= 0xd800 && c <= 0xdbff\n}\n\n/** Reads the code point at `i` of a string. */\nconst codePointAt = (s: string, i: number): number => {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {\n const d = s.charCodeAt(i + 1)\n if (d >= 0xdc00 && d <= 0xdfff) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return c\n}\n\n/**\n * Tests the token at the current position. Returns the token (as the input's\n * token type) and advances, or returns `NoMatch`/`End`.\n */\nexport const NoMatch: unique symbol = /*#__PURE__*/ Symbol(\"NoMatch\")\nexport const End: unique symbol = /*#__PURE__*/ Symbol(\"End\")\n\nexport const nextIf = (state: State<Input>, m: AnyMatcher, negate: boolean): unknown => {\n const pos = state.pos\n if (pos >= state.end) return End\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n if (splitSurrogate(state, pos)) return End\n const cp = codePointAt(s, pos)\n if (m.forString.code(cp) === negate) return NoMatch\n const len = cp > 0xffff ? 2 : 1\n state.pos = pos + len\n return len === 1 ? s[pos] : s.slice(pos, pos + 2)\n }\n case 1: {\n const b = (state.input as Uint8Array)[pos]\n if (m.forCode.code(b) === negate) return NoMatch\n state.pos = pos + 1\n return b\n }\n default: {\n const t = (state.input as ReadonlyArray<unknown>)[pos]\n if (m.forCode.token(t) === negate) return NoMatch\n state.pos = pos + 1\n return t\n }\n }\n}\n\n/** How far a {@link scan} got. */\nexport interface Scanned extends Advanced {\n /** Whether the end of input was hit before `max` tokens. */\n readonly hitEnd: boolean\n}\n\n/**\n * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`\n * tokens. Returns the offset reached, the number of tokens matched, and\n * whether the end of input was hit before `max` tokens.\n */\nexport const scan = (state: State<Input>, m: AnyMatcher, negate: boolean, max: number): Scanned => {\n let i = state.pos\n const end = state.end\n let count = 0\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n const test = m.forString.code\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n const c = s.charCodeAt(i)\n if (c < 0xd800 || c > 0xdbff) {\n if (test(c) === negate) break\n i++\n } else {\n if (splitSurrogate(state, i)) return { offset: i, count, hitEnd: true }\n const cp = codePointAt(s, i)\n if (test(cp) === negate) break\n i += cp > 0xffff ? 2 : 1\n }\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n case 1: {\n const bytes = state.input as Uint8Array\n const test = m.forCode.code\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n if (test(bytes[i]) === negate) break\n i++\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n default: {\n const arr = state.input as ReadonlyArray<unknown>\n const test = m.forCode.token\n while (count < max) {\n if (i >= end) return { offset: i, count, hitEnd: true }\n if (test(arr[i]) === negate) break\n i++\n count++\n }\n return { offset: i, count, hitEnd: false }\n }\n }\n}\n\n/** The offset reached and the number of tokens passed. */\nexport interface Advanced {\n readonly offset: number\n readonly count: number\n}\n\n/** Advances `n` tokens from `start`, returning the offset reached and the count. */\nexport const advance = (state: State<Input>, start: number, n: number): Advanced => {\n if (state.inputKind !== 0) {\n const offset = Math.min(state.end, start + n)\n return { offset, count: offset - start }\n }\n const s = state.input as string\n let i = start\n let count = 0\n while (count < n && i < state.end) {\n if (splitSurrogate(state, i)) break\n const c = s.charCodeAt(i)\n i += c >= 0xd800 && c <= 0xdbff && i + 1 < s.length && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00 ? 2 : 1\n count++\n }\n return { offset: i, count }\n}\n\n/** Counts tokens between two offsets. */\nexport const countTokens = (state: State<Input>, start: number, end: number): number => {\n if (state.inputKind !== 0) return end - start\n const s = state.input as string\n let count = 0\n for (let i = start; i < end; i++) {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < end && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00) i++\n count++\n }\n return count\n}\n\n/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */\nexport const indexOf = (state: State<Input>, needle: Input, from: number): number => {\n // The whole needle must lie before `state.end`, which may narrow the input\n const last = state.end - needle.length\n if (from > last) return -1\n switch (state.inputKind) {\n case 0: {\n const i = (state.input as string).indexOf(needle as string, from)\n return i <= last ? i : -1\n }\n case 1: {\n const hay = state.input as Uint8Array\n const n = needle as Uint8Array\n if (n.byteLength === 0) return from\n const first = n[0]\n let i = hay.indexOf(first, from)\n while (i !== -1 && i <= last) {\n let j = 1\n while (j < n.length && hay[i + j] === n[j]) j++\n if (j === n.length) return i\n i = hay.indexOf(first, i + 1)\n }\n return -1\n }\n default: {\n const hay = state.input as ReadonlyArray<unknown>\n const n = needle as ReadonlyArray<unknown>\n outer: for (let i = from; i <= last; i++) {\n for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer\n return i\n }\n return -1\n }\n }\n}\n\n/**\n * Compares the input at the current position with a literal. Returns the\n * number of matching units if the literal matches completely (its length),\n * -1 on mismatch, or -2 when the input ends while matching a prefix.\n */\nexport const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const r = match(state, lit, caseless)\n // A failed match may have read up to its length past where it fails (see `Syntax`)\n if (r < 0 && state.syntax !== undefined) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos))\n return r\n}\n\nconst match = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const pos = state.pos\n const len = lit.length\n const avail = state.end - pos\n const n = Math.min(len, avail)\n switch (state.inputKind) {\n case 0: {\n const s = state.input as string\n const l = lit as string\n if (!caseless) {\n if (avail >= len) return s.startsWith(l, pos) ? len : -1\n return l.startsWith(s.slice(pos)) ? -2 : -1\n }\n for (let i = 0; i < n; i++) {\n if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i))) return -1\n }\n return n === len ? len : -2\n }\n case 1: {\n const b = state.input as Uint8Array\n const l = lit as Uint8Array\n for (let i = 0; i < n; i++) {\n const x = b[pos + i]\n const y = l[i]\n if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1\n }\n return n === len ? len : -2\n }\n default: {\n const a = state.input as ReadonlyArray<unknown>\n const l = lit as ReadonlyArray<unknown>\n for (let i = 0; i < n; i++) if (a[pos + i] !== l[i]) return -1\n return n === len ? len : -2\n }\n }\n}\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tokens.js","names":[],"sources":["../../src/internal/tokens.ts"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\nimport * as Result from \"effect/Result\"\nimport type { Input, State } from \"../Input.js\"\nimport { charOf, firstCodePoint } from \"./text.js\"\n\n/** A compiled token set. */\nexport interface Matcher {\n /** Tests a code point (string input) or a byte (Uint8Array input). */\n readonly code: (code: number) => boolean\n /** Tests an element of an array input. */\n readonly token: (token: unknown) => boolean\n /** Human readable description, used in error messages. */\n readonly description: string\n}\n\n/** @internal */\nexport interface TokenRangeLike {\n readonly _tag: \"TokenRange\"\n readonly from: string | number\n readonly to: string | number\n}\n\nconst isRange = (u: unknown): u is TokenRangeLike => Predicate.isObjectOrArray(u) && Predicate.isTagged(u, \"TokenRange\")\n\nconst toCode = (u: string | number): number => (Predicate.isNumber(u) ? u : firstCodePoint(u))\n\n/** @internal */\nexport const describeChar = (s: string): string => JSON.stringify(s)\n\nconst describeSet = (u: unknown): string => {\n if (Predicate.isString(u)) {\n const chars = Array.from(u)\n return chars.length === 1 ? describeChar(u) : `one of ${JSON.stringify(u)}`\n }\n if (Predicate.isNumber(u)) return `0x${u.toString(16).padStart(2, \"0\")}`\n if (Predicate.isFunction(u)) return u.name ? u.name : \"a matching token\"\n if (u instanceof Uint8Array) return `one of ${describeBytes(u)}`\n if (isRange(u)) return `${describeSet(u.from)}..=${describeSet(u.to)}`\n if (Array.isArray(u)) return u.map(describeSet).join(\" or \")\n return JSON.stringify(u)\n}\n\n/** Renders bytes as a Rust-style byte string literal: b\"GET\\r\\n\". */\nconst describeBytes = (bytes: Uint8Array): string => {\n let out = 'b\"'\n for (const b of bytes) {\n if (b === 0x22) out += '\\\\\"'\n else if (b === 0x5c) out += \"\\\\\\\\\"\n else if (b === 0x0a) out += \"\\\\n\"\n else if (b === 0x0d) out += \"\\\\r\"\n else if (b === 0x09) out += \"\\\\t\"\n else if (b >= 0x20 && b < 0x7f) out += String.fromCharCode(b)\n else out += `\\\\x${b.toString(16).padStart(2, \"0\")}`\n }\n return out + '\"'\n}\n\nconst compileCode = (u: unknown): ((code: number) => boolean) => {\n if (Predicate.isString(u)) {\n const codes = Array.from(u, firstCodePoint)\n if (codes.length === 1) {\n const c = codes[0]\n return (x) => x === c\n }\n return bitmap(codes)\n }\n if (Predicate.isNumber(u)) return (x) => x === u\n if (Predicate.isFunction(u)) {\n // SAFETY: a predicate compiled for codes is a byte, code point or `codePoints` predicate (`compile` wraps string predicates first)\n return u as (code: number) => boolean\n }\n if (u instanceof Uint8Array) return bitmap(Array.from(u))\n if (isRange(u)) {\n const from = toCode(u.from)\n const to = toCode(u.to)\n return (x) => x >= from && x <= to\n }\n if (Array.isArray(u)) {\n const tests = u.map(compileCode)\n if (tests.length === 1) return tests[0]\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n throw new TypeError(`invalid token set: ${String(u)}`)\n}\n\nconst bitmap = (codes: ReadonlyArray<number>): ((code: number) => boolean) => {\n const ascii = new Uint8Array(256)\n let other: Set<number> | undefined\n for (const c of codes) {\n if (c < 256) ascii[c] = 1\n else (other ??= new Set()).add(c)\n }\n if (other === undefined) return (x) => x < 256 && ascii[x] === 1\n const set = other\n return (x) => (x < 256 ? ascii[x] === 1 : set.has(x))\n}\n\nconst compileToken = (u: unknown): ((token: unknown) => boolean) => {\n if (Predicate.isFunction(u)) {\n // SAFETY: a predicate in an array input's token set takes the array's elements, the tokens tested here\n return u as (token: unknown) => boolean\n }\n if (Array.isArray(u)) {\n const set = new Set(u)\n return (t) => set.has(t)\n }\n return (t) => t === u\n}\n\n/**\n * Marks a predicate over characters that also accepts a code point (a\n * number), so string inputs can call it without allocating a string per\n * character.\n */\nconst CodePointPredicate: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/CodePointPredicate\")\n\n/**\n * The code points accepted by a predicate, as sorted, disjoint, inclusive\n * ranges, when they are known. The compiler turns such predicates into\n * comparisons or tables.\n */\nexport const PredicateRanges: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/PredicateRanges\")\n\n/**\n * Marks `f` as a {@link CodePointPredicate} named `name` (used in error\n * messages), optionally recording the code point ranges it accepts.\n */\nexport const codePointPredicate = <F extends (c: never) => boolean>(\n name: string,\n f: F,\n ranges?: ReadonlyArray<readonly [number, number]>\n): F => {\n Object.defineProperty(f, \"name\", { value: name })\n // SAFETY: `f` is a function object, which takes new properties; the intersection only names the two markers set here\n const marked = f as F & {\n [CodePointPredicate]?: true\n [PredicateRanges]?: ReadonlyArray<readonly [number, number]>\n }\n marked[CodePointPredicate] = true\n if (ranges !== undefined) marked[PredicateRanges] = ranges\n return f\n}\n\n/**\n * Compiles a token set. Predicates for string inputs receive the token as a\n * string, so they are wrapped here; `charOf` avoids `String.fromCodePoint`,\n * which is several times slower, for the Basic Multilingual Plane.\n */\nexport const compile = (set: unknown, kind: \"string\" | \"code\" = \"code\"): Matcher => {\n const description = describeSet(set)\n let code: (code: number) => boolean\n if (Predicate.isFunction(set) && kind === \"string\" && !(CodePointPredicate in set)) {\n // SAFETY: an unmarked predicate in a string token set takes each character as a string (`StringTokenSet`)\n const pred = set as (c: string) => boolean\n code = (x) => pred(charOf(x))\n } else {\n code = compileCodeSafe(set, kind)\n }\n return { code, token: compileToken(set), description }\n}\n\nconst compileCodeSafe = (set: unknown, kind: \"string\" | \"code\"): ((code: number) => boolean) => {\n if (Array.isArray(set) && kind === \"string\") {\n // Predicates nested in arrays also take strings\n const tests = set.map((s) => compile(s, kind).code)\n return (x) => {\n for (let i = 0; i < tests.length; i++) if (tests[i](x)) return true\n return false\n }\n }\n return Result.getOrElse(\n Result.try(() => compileCode(set)),\n (): ((code: number) => boolean) => () => false\n )\n}\n\n/**\n * A matcher that works for every input kind. String predicates receive the\n * token as a string, byte predicates receive numbers.\n */\nexport interface AnyMatcher {\n readonly forString: Matcher\n readonly forCode: Matcher\n readonly description: string\n}\n\n/**\n * A small cache keyed by value, for the parts of a parser that are costly to\n * build and depend only on a string (compiled sets, descriptions). Parsers\n * built inside `Parser.gen` bodies are rebuilt on every run, usually from the\n * same few strings. Dynamic strings could grow it without bound, so it is\n * cleared when full.\n */\nconst cached = <A>(cache: Map<string, A>, key: string, build: (key: string) => A): A => {\n let a = cache.get(key)\n if (a === undefined) {\n if (cache.size >= 1024) cache.clear()\n a = build(key)\n cache.set(key, a)\n }\n return a\n}\n\nconst literalDescriptions = /*#__PURE__*/ new Map<string, string>()\n\n/** Describes a literal for error messages: `\"abc\"`, `b\"abc\"` or `[\"a\", 1]`. */\nexport const describeLiteral = (lit: Input): string =>\n Predicate.isString(lit)\n ? cached(literalDescriptions, lit, describeChar)\n : lit instanceof Uint8Array\n ? describeBytes(lit)\n : `[${lit.map((t) => JSON.stringify(t)).join(\", \")}]`\n\nconst stringMatchers = /*#__PURE__*/ new Map<string, AnyMatcher>()\n\nexport const compileAny = (set: unknown): AnyMatcher =>\n // Matchers for strings are pure functions of the string, so they're shared\n Predicate.isString(set) ? cached(stringMatchers, set, compileAnyImpl) : compileAnyImpl(set)\n\nconst compileAnyImpl = (set: unknown): AnyMatcher => {\n const forCode = compile(set, \"code\")\n const needsString = Predicate.isFunction(set) || Array.isArray(set)\n return {\n forString: needsString ? compile(set, \"string\") : forCode,\n forCode,\n description: forCode.description\n }\n}\n\n/**\n * Whether the string token at `i` is a high surrogate at the very end of a\n * partial input, i.e. the first half of a code point whose second half has\n * not arrived yet.\n */\nexport const splitSurrogate = (state: State<Input>, i: number): boolean => {\n if (!state.partial || i !== state.end - 1) return false\n // SAFETY: called only on string input (the `inputKind === 0` paths of `nextIf`, `scan`, `advance` and `Token.any`)\n const c = (state.input as string).charCodeAt(i)\n return c >= 0xd800 && c <= 0xdbff\n}\n\n/** Reads the code point at `i` of a string. */\nconst codePointAt = (s: string, i: number): number => {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {\n const d = s.charCodeAt(i + 1)\n if (d >= 0xdc00 && d <= 0xdfff) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return c\n}\n\n/**\n * Tests the token at the current position. Returns the token (as the input's\n * token type) and advances, or returns `NoMatch`/`End`.\n */\nexport const NoMatch: unique symbol = /*#__PURE__*/ Symbol(\"NoMatch\")\nexport const End: unique symbol = /*#__PURE__*/ Symbol(\"End\")\n\nexport const nextIf = (state: State<Input>, m: AnyMatcher, negate: boolean): unknown => {\n const pos = state.pos\n if (pos >= state.end) return End\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n if (splitSurrogate(state, pos)) return End\n const cp = codePointAt(s, pos)\n if (m.forString.code(cp) === negate) return NoMatch\n const len = cp > 0xffff ? 2 : 1\n state.pos = pos + len\n return len === 1 ? s[pos] : s.slice(pos, pos + 2)\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const b = (state.input as Uint8Array)[pos]\n if (m.forCode.code(b) === negate) return NoMatch\n state.pos = pos + 1\n return b\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const t = (state.input as ReadonlyArray<unknown>)[pos]\n if (m.forCode.token(t) === negate) return NoMatch\n state.pos = pos + 1\n return t\n }\n }\n}\n\n/** How far a {@link scan} got. */\nexport interface Scanned extends Advanced {\n /** Whether the end of input was hit before `max` tokens. */\n readonly hitEnd: boolean\n}\n\n/** The one record {@link scan} fills; see there. */\nclass ScanResult implements Scanned {\n offset = 0\n count = 0\n hitEnd = false\n}\n\nconst scanned = /*#__PURE__*/ new ScanResult()\n\n/** Fills {@link scanned} and returns it. */\nconst scannedAt = (offset: number, count: number, hitEnd: boolean): Scanned => {\n scanned.offset = offset\n scanned.count = count\n scanned.hitEnd = hitEnd\n return scanned\n}\n\n/**\n * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`\n * tokens. Returns the offset reached, the number of tokens matched, and\n * whether the end of input was hit before `max` tokens.\n *\n * The result is one shared record, overwritten by the next scan: read it\n * before running anything else. Allocating one per call cost the\n * interpreter a record per token, since `scan` (shared by every `takeWhile`)\n * is too polymorphic for V8 to inline and remove it.\n */\nexport const scan = (state: State<Input>, m: AnyMatcher, negate: boolean, max: number): Scanned => {\n let i = state.pos\n const end = state.end\n let count = 0\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n const test = m.forString.code\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n const c = s.charCodeAt(i)\n if (c < 0xd800 || c > 0xdbff) {\n if (test(c) === negate) break\n i++\n } else {\n if (splitSurrogate(state, i)) return scannedAt(i, count, true)\n const cp = codePointAt(s, i)\n if (test(cp) === negate) break\n i += cp > 0xffff ? 2 : 1\n }\n count++\n }\n return scannedAt(i, count, false)\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const bytes = state.input as Uint8Array\n const test = m.forCode.code\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n if (test(bytes[i]) === negate) break\n i++\n count++\n }\n return scannedAt(i, count, false)\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const arr = state.input as ReadonlyArray<unknown>\n const test = m.forCode.token\n while (count < max) {\n if (i >= end) return scannedAt(i, count, true)\n if (test(arr[i]) === negate) break\n i++\n count++\n }\n return scannedAt(i, count, false)\n }\n }\n}\n\n/** The offset reached and the number of tokens passed. */\nexport interface Advanced {\n readonly offset: number\n readonly count: number\n}\n\n/** Advances `n` tokens from `start`, returning the offset reached and the count. */\nexport const advance = (state: State<Input>, start: number, n: number): Advanced => {\n if (state.inputKind !== 0) {\n const offset = Math.min(state.end, start + n)\n return { offset, count: offset - start }\n }\n // SAFETY: the other input kinds returned above, and `inputKind` 0 is set only for a string input\n const s = state.input as string\n let i = start\n let count = 0\n while (count < n && i < state.end) {\n if (splitSurrogate(state, i)) break\n const c = s.charCodeAt(i)\n i += c >= 0xd800 && c <= 0xdbff && i + 1 < s.length && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00 ? 2 : 1\n count++\n }\n return { offset: i, count }\n}\n\n/** Counts tokens between two offsets. */\nexport const countTokens = (state: State<Input>, start: number, end: number): number => {\n if (state.inputKind !== 0) return end - start\n // SAFETY: the other input kinds returned above, and `inputKind` 0 is set only for a string input\n const s = state.input as string\n let count = 0\n for (let i = start; i < end; i++) {\n const c = s.charCodeAt(i)\n if (c >= 0xd800 && c <= 0xdbff && i + 1 < end && (s.charCodeAt(i + 1) & 0xfc00) === 0xdc00) i++\n count++\n }\n return count\n}\n\n/**\n * The first index at or after `from` of any of `needles` within\n * `[from, state.end)`, or -1. The state remembers, under `needles`, where\n * each one next occurs (`[from, at, end]` at `3 * i`), so successive\n * searches forwards over one input search each needle once per occurrence\n * rather than once per call (as `nextStop` does for `takeTill`).\n *\n * A remembered answer is used only where it still holds: an occurrence, when\n * the search starts between where it was searched from and where it was\n * found, and it still fits before the end; \"not found\", when the search\n * starts no earlier and the end is no further than the end that search ran\n * to (a parser may narrow `state.end` for a while, and `reset` widens it\n * again, so a miss within a narrower end says nothing about a wider one).\n */\nexport const indexOfAny = (state: State<Input>, needles: ReadonlyArray<Input>, from: number): number => {\n const searches = (state.searches ??= new Map())\n let memo = searches.get(needles)\n if (memo === undefined) {\n memo = needles.flatMap(() => [-1, -1, -1])\n searches.set(needles, memo)\n }\n let best = -1\n for (let i = 0; i < needles.length; i++) {\n const known = memo[3 * i] ?? -1\n let at = memo[3 * i + 1] ?? -1\n const searchedTo = memo[3 * i + 2] ?? -1\n const needle = needles[i] ?? \"\"\n const stale =\n known < 0 || from < known || (at >= 0 ? at < from || at > state.end - needle.length : state.end > searchedTo)\n if (stale) {\n at = indexOf(state, needle, from)\n memo[3 * i] = from\n memo[3 * i + 1] = at\n memo[3 * i + 2] = state.end\n }\n if (at >= 0 && (best < 0 || at < best)) best = at\n }\n return best\n}\n\n/** Finds `needle` within `[from, state.end)`; returns -1 if absent. */\nexport const indexOf = (state: State<Input>, needle: Input, from: number): number => {\n // The whole needle must lie before `state.end`, which may narrow the input\n const last = state.end - needle.length\n if (from > last) return -1\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input, and the callers' types give the needle the input's kind\n const i = (state.input as string).indexOf(needle as string, from)\n return i <= last ? i : -1\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const hay = state.input as Uint8Array\n // SAFETY: the callers' types give the needle the input's kind (`Text` encodes it for byte input)\n const n = needle as Uint8Array\n if (n.byteLength === 0) return from\n const first = n[0]\n let i = hay.indexOf(first, from)\n while (i !== -1 && i <= last) {\n let j = 1\n while (j < n.length && hay[i + j] === n[j]) j++\n if (j === n.length) return i\n i = hay.indexOf(first, i + 1)\n }\n return -1\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const hay = state.input as ReadonlyArray<unknown>\n // SAFETY: the callers' types give the needle the input's kind, an array of the same element type\n const n = needle as ReadonlyArray<unknown>\n outer: for (let i = from; i <= last; i++) {\n for (let j = 0; j < n.length; j++) if (hay[i + j] !== n[j]) continue outer\n return i\n }\n return -1\n }\n }\n}\n\n/**\n * Compares the input at the current position with a literal. Returns the\n * number of matching units if the literal matches completely (its length),\n * -1 on mismatch, or -2 when the input ends while matching a prefix.\n */\nexport const matchLiteral = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const r = match(state, lit, caseless)\n // A failed match may have read up to its length past where it fails (see `Syntax`)\n if (r < 0 && state.syntax !== undefined) state.syntax.read(state.pos + Math.min(lit.length, state.end - state.pos))\n return r\n}\n\nconst match = (state: State<Input>, lit: Input, caseless: boolean): number => {\n const pos = state.pos\n const len = lit.length\n const avail = state.end - pos\n const n = Math.min(len, avail)\n switch (state.inputKind) {\n case 0: {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n // SAFETY: the callers' types give the literal the input's kind (`Token.literal` encodes a string literal for byte input)\n const l = lit as string\n if (!caseless) {\n if (avail >= len) return s.startsWith(l, pos) ? len : -1\n return l.startsWith(s.slice(pos)) ? -2 : -1\n }\n for (let i = 0; i < n; i++) {\n if (lowerAscii(s.charCodeAt(pos + i)) !== lowerAscii(l.charCodeAt(i))) return -1\n }\n return n === len ? len : -2\n }\n case 1: {\n // SAFETY: `inputKind` 1 is set only for a `Uint8Array` input\n const b = state.input as Uint8Array\n // SAFETY: the callers' types give the literal the input's kind (`Token.literal` and `Text` encode string literals for byte input)\n const l = lit as Uint8Array\n for (let i = 0; i < n; i++) {\n const x = b[pos + i]\n const y = l[i]\n if (caseless ? lowerAscii(x) !== lowerAscii(y) : x !== y) return -1\n }\n return n === len ? len : -2\n }\n default: {\n // SAFETY: `inputKind` 2 is set for every input that is neither a string nor a `Uint8Array`, an array\n const a = state.input as ReadonlyArray<unknown>\n // SAFETY: the callers' types give the literal the input's kind, an array of the same element type\n const l = lit as ReadonlyArray<unknown>\n for (let i = 0; i < n; i++) if (a[pos + i] !== l[i]) return -1\n return n === len ? len : -2\n }\n }\n}\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\n"],"mappings":";;;;AAsBA,MAAM,WAAW,MAAoC,UAAU,gBAAgB,CAAC,KAAK,UAAU,SAAS,GAAG,YAAY;AAEvH,MAAM,UAAU,MAAgC,UAAU,SAAS,CAAC,IAAI,IAAI,eAAe,CAAC;;AAG5F,MAAa,gBAAgB,MAAsB,KAAK,UAAU,CAAC;AAEnE,MAAM,eAAe,MAAuB;CAC1C,IAAI,UAAU,SAAS,CAAC,GAEtB,OADc,MAAM,KAAK,CACd,CAAC,CAAC,WAAW,IAAI,aAAa,CAAC,IAAI,UAAU,KAAK,UAAU,CAAC;CAE1E,IAAI,UAAU,SAAS,CAAC,GAAG,OAAO,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CACrE,IAAI,UAAU,WAAW,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO;CACtD,IAAI,aAAa,YAAY,OAAO,UAAU,cAAc,CAAC;CAC7D,IAAI,QAAQ,CAAC,GAAG,OAAO,GAAG,YAAY,EAAE,IAAI,EAAE,KAAK,YAAY,EAAE,EAAE;CACnE,IAAI,MAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,IAAI,WAAW,CAAC,CAAC,KAAK,MAAM;CAC3D,OAAO,KAAK,UAAU,CAAC;AACzB;;AAGA,MAAM,iBAAiB,UAA8B;CACnD,IAAI,MAAM;CACV,KAAK,MAAM,KAAK,OACd,IAAI,MAAM,IAAM,OAAO;MAClB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,IAAM,OAAO;MACvB,IAAI,MAAM,GAAM,OAAO;MACvB,IAAI,KAAK,MAAQ,IAAI,KAAM,OAAO,OAAO,aAAa,CAAC;MACvD,OAAO,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAElD,OAAO,MAAM;AACf;AAEA,MAAM,eAAe,MAA4C;CAC/D,IAAI,UAAU,SAAS,CAAC,GAAG;EACzB,MAAM,QAAQ,MAAM,KAAK,GAAG,cAAc;EAC1C,IAAI,MAAM,WAAW,GAAG;GACtB,MAAM,IAAI,MAAM;GAChB,QAAQ,MAAM,MAAM;EACtB;EACA,OAAO,OAAO,KAAK;CACrB;CACA,IAAI,UAAU,SAAS,CAAC,GAAG,QAAQ,MAAM,MAAM;CAC/C,IAAI,UAAU,WAAW,CAAC,GAExB,OAAO;CAET,IAAI,aAAa,YAAY,OAAO,OAAO,MAAM,KAAK,CAAC,CAAC;CACxD,IAAI,QAAQ,CAAC,GAAG;EACd,MAAM,OAAO,OAAO,EAAE,IAAI;EAC1B,MAAM,KAAK,OAAO,EAAE,EAAE;EACtB,QAAQ,MAAM,KAAK,QAAQ,KAAK;CAClC;CACA,IAAI,MAAM,QAAQ,CAAC,GAAG;EACpB,MAAM,QAAQ,EAAE,IAAI,WAAW;EAC/B,IAAI,MAAM,WAAW,GAAG,OAAO,MAAM;EACrC,QAAQ,MAAM;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO;GAC/D,OAAO;EACT;CACF;CACA,MAAM,IAAI,UAAU,sBAAsB,OAAO,CAAC,GAAG;AACvD;AAEA,MAAM,UAAU,UAA8D;CAC5E,MAAM,wBAAQ,IAAI,WAAW,GAAG;CAChC,IAAI;CACJ,KAAK,MAAM,KAAK,OACd,IAAI,IAAI,KAAK,MAAM,KAAK;MACnB,CAAC,0BAAU,IAAI,IAAI,EAAA,CAAG,IAAI,CAAC;CAElC,IAAI,UAAU,KAAA,GAAW,QAAQ,MAAM,IAAI,OAAO,MAAM,OAAO;CAC/D,MAAM,MAAM;CACZ,QAAQ,MAAO,IAAI,MAAM,MAAM,OAAO,IAAI,IAAI,IAAI,CAAC;AACrD;AAEA,MAAM,gBAAgB,MAA8C;CAClE,IAAI,UAAU,WAAW,CAAC,GAExB,OAAO;CAET,IAAI,MAAM,QAAQ,CAAC,GAAG;EACpB,MAAM,MAAM,IAAI,IAAI,CAAC;EACrB,QAAQ,MAAM,IAAI,IAAI,CAAC;CACzB;CACA,QAAQ,MAAM,MAAM;AACtB;;;;;;AAOA,MAAM,qBAAkD,qBAAO,IAAI,iCAAiC;;;;;;AAOpG,MAAa,kBAA+C,qBAAO,IAAI,8BAA8B;;;;;AAMrG,MAAa,sBACX,MACA,GACA,WACM;CACN,OAAO,eAAe,GAAG,QAAQ,EAAE,OAAO,KAAK,CAAC;CAEhD,MAAM,SAAS;CAIf,OAAO,sBAAsB;CAC7B,IAAI,WAAW,KAAA,GAAW,OAAO,mBAAmB;CACpD,OAAO;AACT;;;;;;AAOA,MAAa,WAAW,KAAc,OAA0B,WAAoB;CAClF,MAAM,cAAc,YAAY,GAAG;CACnC,IAAI;CACJ,IAAI,UAAU,WAAW,GAAG,KAAK,SAAS,YAAY,EAAE,sBAAsB,MAAM;EAElF,MAAM,OAAO;EACb,QAAQ,MAAM,KAAK,OAAO,CAAC,CAAC;CAC9B,OACE,OAAO,gBAAgB,KAAK,IAAI;CAElC,OAAO;EAAE;EAAM,OAAO,aAAa,GAAG;EAAG;CAAY;AACvD;AAEA,MAAM,mBAAmB,KAAc,SAAyD;CAC9F,IAAI,MAAM,QAAQ,GAAG,KAAK,SAAS,UAAU;EAE3C,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,IAAI;EAClD,QAAQ,MAAM;GACZ,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,GAAG,OAAO;GAC/D,OAAO;EACT;CACF;CACA,OAAO,OAAO,UACZ,OAAO,UAAU,YAAY,GAAG,CAAC,eACQ,KAC3C;AACF;;;;;;;;AAmBA,MAAM,UAAa,OAAuB,KAAa,UAAiC;CACtF,IAAI,IAAI,MAAM,IAAI,GAAG;CACrB,IAAI,MAAM,KAAA,GAAW;EACnB,IAAI,MAAM,QAAQ,MAAM,MAAM,MAAM;EACpC,IAAI,MAAM,GAAG;EACb,MAAM,IAAI,KAAK,CAAC;CAClB;CACA,OAAO;AACT;AAEA,MAAM,oCAAoC,IAAI,IAAoB;;AAGlE,MAAa,mBAAmB,QAC9B,UAAU,SAAS,GAAG,IAClB,OAAO,qBAAqB,KAAK,YAAY,IAC7C,eAAe,aACb,cAAc,GAAG,IACjB,IAAI,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;AAEzD,MAAM,+BAA+B,IAAI,IAAwB;AAEjE,MAAa,cAAc,QAEzB,UAAU,SAAS,GAAG,IAAI,OAAO,gBAAgB,KAAK,cAAc,IAAI,eAAe,GAAG;AAE5F,MAAM,kBAAkB,QAA6B;CACnD,MAAM,UAAU,QAAQ,KAAK,MAAM;CAEnC,OAAO;EACL,WAFkB,UAAU,WAAW,GAAG,KAAK,MAAM,QAAQ,GAAG,IAEvC,QAAQ,KAAK,QAAQ,IAAI;EAClD;EACA,aAAa,QAAQ;CACvB;AACF;;;;;;AAOA,MAAa,kBAAkB,OAAqB,MAAuB;CACzE,IAAI,CAAC,MAAM,WAAW,MAAM,MAAM,MAAM,GAAG,OAAO;CAElD,MAAM,IAAK,MAAM,MAAiB,WAAW,CAAC;CAC9C,OAAO,KAAK,SAAU,KAAK;AAC7B;;AAGA,MAAM,eAAe,GAAW,MAAsB;CACpD,MAAM,IAAI,EAAE,WAAW,CAAC;CACxB,IAAI,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,EAAE,QAAQ;EAClD,MAAM,IAAI,EAAE,WAAW,IAAI,CAAC;EAC5B,IAAI,KAAK,SAAU,KAAK,OAAQ,QAAS,IAAI,SAAW,OAAO,IAAI,SAAU;CAC/E;CACA,OAAO;AACT;;;;;AAMA,MAAa,UAAuC,qBAAO,SAAS;AACpE,MAAa,MAAmC,qBAAO,KAAK;AAE5D,MAAa,UAAU,OAAqB,GAAe,WAA6B;CACtF,MAAM,MAAM,MAAM;CAClB,IAAI,OAAO,MAAM,KAAK,OAAO;CAC7B,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GAEN,MAAM,IAAI,MAAM;GAChB,IAAI,eAAe,OAAO,GAAG,GAAG,OAAO;GACvC,MAAM,KAAK,YAAY,GAAG,GAAG;GAC7B,IAAI,EAAE,UAAU,KAAK,EAAE,MAAM,QAAQ,OAAO;GAC5C,MAAM,MAAM,KAAK,QAAS,IAAI;GAC9B,MAAM,MAAM,MAAM;GAClB,OAAO,QAAQ,IAAI,EAAE,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC;EAClD;EACA,KAAK,GAAG;GAEN,MAAM,IAAK,MAAM,MAAqB;GACtC,IAAI,EAAE,QAAQ,KAAK,CAAC,MAAM,QAAQ,OAAO;GACzC,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;EACA,SAAS;GAEP,MAAM,IAAK,MAAM,MAAiC;GAClD,IAAI,EAAE,QAAQ,MAAM,CAAC,MAAM,QAAQ,OAAO;GAC1C,MAAM,MAAM,MAAM;GAClB,OAAO;EACT;CACF;AACF;;AASA,IAAM,aAAN,MAAoC;CAClC,SAAS;CACT,QAAQ;CACR,SAAS;AACX;AAEA,MAAM,wBAAwB,IAAI,WAAW;;AAG7C,MAAM,aAAa,QAAgB,OAAe,WAA6B;CAC7E,QAAQ,SAAS;CACjB,QAAQ,QAAQ;CAChB,QAAQ,SAAS;CACjB,OAAO;AACT;;;;;;;;;;;AAYA,MAAa,QAAQ,OAAqB,GAAe,QAAiB,QAAyB;CACjG,IAAI,IAAI,MAAM;CACd,MAAM,MAAM,MAAM;CAClB,IAAI,QAAQ;CACZ,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GAEN,MAAM,IAAI,MAAM;GAChB,MAAM,OAAO,EAAE,UAAU;GACzB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,MAAM,IAAI,EAAE,WAAW,CAAC;IACxB,IAAI,IAAI,SAAU,IAAI,OAAQ;KAC5B,IAAI,KAAK,CAAC,MAAM,QAAQ;KACxB;IACF,OAAO;KACL,IAAI,eAAe,OAAO,CAAC,GAAG,OAAO,UAAU,GAAG,OAAO,IAAI;KAC7D,MAAM,KAAK,YAAY,GAAG,CAAC;KAC3B,IAAI,KAAK,EAAE,MAAM,QAAQ;KACzB,KAAK,KAAK,QAAS,IAAI;IACzB;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;EACA,KAAK,GAAG;GAEN,MAAM,QAAQ,MAAM;GACpB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,IAAI,KAAK,MAAM,EAAE,MAAM,QAAQ;IAC/B;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;EACA,SAAS;GAEP,MAAM,MAAM,MAAM;GAClB,MAAM,OAAO,EAAE,QAAQ;GACvB,OAAO,QAAQ,KAAK;IAClB,IAAI,KAAK,KAAK,OAAO,UAAU,GAAG,OAAO,IAAI;IAC7C,IAAI,KAAK,IAAI,EAAE,MAAM,QAAQ;IAC7B;IACA;GACF;GACA,OAAO,UAAU,GAAG,OAAO,KAAK;EAClC;CACF;AACF;;AASA,MAAa,WAAW,OAAqB,OAAe,MAAwB;CAClF,IAAI,MAAM,cAAc,GAAG;EACzB,MAAM,SAAS,KAAK,IAAI,MAAM,KAAK,QAAQ,CAAC;EAC5C,OAAO;GAAE;GAAQ,OAAO,SAAS;EAAM;CACzC;CAEA,MAAM,IAAI,MAAM;CAChB,IAAI,IAAI;CACR,IAAI,QAAQ;CACZ,OAAO,QAAQ,KAAK,IAAI,MAAM,KAAK;EACjC,IAAI,eAAe,OAAO,CAAC,GAAG;EAC9B,MAAM,IAAI,EAAE,WAAW,CAAC;EACxB,KAAK,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,EAAE,WAAW,EAAE,WAAW,IAAI,CAAC,IAAI,WAAY,QAAS,IAAI;EACvG;CACF;CACA,OAAO;EAAE,QAAQ;EAAG;CAAM;AAC5B;;AAGA,MAAa,eAAe,OAAqB,OAAe,QAAwB;CACtF,IAAI,MAAM,cAAc,GAAG,OAAO,MAAM;CAExC,MAAM,IAAI,MAAM;CAChB,IAAI,QAAQ;CACZ,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAAK;EAChC,MAAM,IAAI,EAAE,WAAW,CAAC;EACxB,IAAI,KAAK,SAAU,KAAK,SAAU,IAAI,IAAI,QAAQ,EAAE,WAAW,IAAI,CAAC,IAAI,WAAY,OAAQ;EAC5F;CACF;CACA,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,MAAa,cAAc,OAAqB,SAA+B,SAAyB;CACtG,MAAM,WAAY,MAAM,6BAAa,IAAI,IAAI;CAC7C,IAAI,OAAO,SAAS,IAAI,OAAO;CAC/B,IAAI,SAAS,KAAA,GAAW;EACtB,OAAO,QAAQ,cAAc;GAAC;GAAI;GAAI;EAAE,CAAC;EACzC,SAAS,IAAI,SAAS,IAAI;CAC5B;CACA,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;EACvC,MAAM,QAAQ,KAAK,IAAI,MAAM;EAC7B,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM;EAC5B,MAAM,aAAa,KAAK,IAAI,IAAI,MAAM;EACtC,MAAM,SAAS,QAAQ,MAAM;EAG7B,IADE,QAAQ,KAAK,OAAO,UAAU,MAAM,IAAI,KAAK,QAAQ,KAAK,MAAM,MAAM,OAAO,SAAS,MAAM,MAAM,aACzF;GACT,KAAK,QAAQ,OAAO,QAAQ,IAAI;GAChC,KAAK,IAAI,KAAK;GACd,KAAK,IAAI,IAAI,KAAK;GAClB,KAAK,IAAI,IAAI,KAAK,MAAM;EAC1B;EACA,IAAI,MAAM,MAAM,OAAO,KAAK,KAAK,OAAO,OAAO;CACjD;CACA,OAAO;AACT;;AAGA,MAAa,WAAW,OAAqB,QAAe,SAAyB;CAEnF,MAAM,OAAO,MAAM,MAAM,OAAO;CAChC,IAAI,OAAO,MAAM,OAAO;CACxB,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GAEN,MAAM,IAAK,MAAM,MAAiB,QAAQ,QAAkB,IAAI;GAChE,OAAO,KAAK,OAAO,IAAI;EACzB;EACA,KAAK,GAAG;GAEN,MAAM,MAAM,MAAM;GAElB,MAAM,IAAI;GACV,IAAI,EAAE,eAAe,GAAG,OAAO;GAC/B,MAAM,QAAQ,EAAE;GAChB,IAAI,IAAI,IAAI,QAAQ,OAAO,IAAI;GAC/B,OAAO,MAAM,MAAM,KAAK,MAAM;IAC5B,IAAI,IAAI;IACR,OAAO,IAAI,EAAE,UAAU,IAAI,IAAI,OAAO,EAAE,IAAI;IAC5C,IAAI,MAAM,EAAE,QAAQ,OAAO;IAC3B,IAAI,IAAI,QAAQ,OAAO,IAAI,CAAC;GAC9B;GACA,OAAO;EACT;EACA,SAAS;GAEP,MAAM,MAAM,MAAM;GAElB,MAAM,IAAI;GACV,OAAO,KAAK,IAAI,IAAI,MAAM,KAAK,MAAM,KAAK;IACxC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,IAAI,IAAI,IAAI,OAAO,EAAE,IAAI,SAAS;IACrE,OAAO;GACT;GACA,OAAO;EACT;CACF;AACF;;;;;;AAOA,MAAa,gBAAgB,OAAqB,KAAY,aAA8B;CAC1F,MAAM,IAAI,MAAM,OAAO,KAAK,QAAQ;CAEpC,IAAI,IAAI,KAAK,MAAM,WAAW,KAAA,GAAW,MAAM,OAAO,KAAK,MAAM,MAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,MAAM,MAAM,GAAG,CAAC;CAClH,OAAO;AACT;AAEA,MAAM,SAAS,OAAqB,KAAY,aAA8B;CAC5E,MAAM,MAAM,MAAM;CAClB,MAAM,MAAM,IAAI;CAChB,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,IAAI,KAAK,IAAI,KAAK,KAAK;CAC7B,QAAQ,MAAM,WAAd;EACE,KAAK,GAAG;GAEN,MAAM,IAAI,MAAM;GAEhB,MAAM,IAAI;GACV,IAAI,CAAC,UAAU;IACb,IAAI,SAAS,KAAK,OAAO,EAAE,WAAW,GAAG,GAAG,IAAI,MAAM;IACtD,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,CAAC,IAAI,KAAK;GAC3C;GACA,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KACrB,IAAI,WAAW,EAAE,WAAW,MAAM,CAAC,CAAC,MAAM,WAAW,EAAE,WAAW,CAAC,CAAC,GAAG,OAAO;GAEhF,OAAO,MAAM,MAAM,MAAM;EAC3B;EACA,KAAK,GAAG;GAEN,MAAM,IAAI,MAAM;GAEhB,MAAM,IAAI;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;IAC1B,MAAM,IAAI,EAAE,MAAM;IAClB,MAAM,IAAI,EAAE;IACZ,IAAI,WAAW,WAAW,CAAC,MAAM,WAAW,CAAC,IAAI,MAAM,GAAG,OAAO;GACnE;GACA,OAAO,MAAM,MAAM,MAAM;EAC3B;EACA,SAAS;GAEP,MAAM,IAAI,MAAM;GAEhB,MAAM,IAAI;GACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,EAAE,MAAM,OAAO,EAAE,IAAI,OAAO;GAC5D,OAAO,MAAM,MAAM,MAAM;EAC3B;CACF;AACF;AAEA,MAAM,cAAc,MAAuB,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Fail, State } from "../Input.js";
|
|
2
|
+
type Step = (state: State<any>) => unknown;
|
|
3
|
+
/** A step that runs `steps` in order and returns their outputs as an array, or {@link Fail}. */
|
|
4
|
+
export declare const tupleStep: (steps: ReadonlyArray<Step>) => ((state: State<any>) => Array<unknown> | Fail);
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=tuple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tuple.d.ts","names":[],"sources":["../../src/internal/tuple.ts"],"mappings":";KAcK,QAAQ,OAAO;;qBAMP,YAAa,OAAO,cAAc,YAAU,OAAO,eAAe,iBAAiB"}
|
|
@@ -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":";;;;;;;;;;;;;;AAiBA,MAAM,aAAa;;AAGnB,MAAa,aAAa,UAA+E;CACvG,MAAM,IAAI,MAAM;CAChB,IAAI,KAAK,YAAY,OAAO,SAAS,EAAE,CAAC,KAAK;CAC7C,QAAQ,UAAU;EAChB,MAAM,MAAM,IAAI,MAAe,CAAC;EAChC,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC1B,MAAM,IAAI,MAAM,EAAE,CAAC,KAAK;GACxB,IAAI,MAAM,MAAM,OAAO;GACvB,IAAI,KAAK;EACX;EACA,OAAO;CACT;AACF;AAEA,MAAM,WAAwG;aAChG,CAAC;EACZ,CAAC,SACC,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO,CAAC,EAAE;CACZ;EACD,CAAC,IAAI,SACH,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO,CAAC,IAAI,EAAE;CAChB;EACD,CAAC,IAAI,IAAI,SACP,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;EAAE;CACpB;EACD,CAAC,IAAI,IAAI,IAAI,SACX,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;GAAI;EAAE;CACxB;EACD,CAAC,IAAI,IAAI,IAAI,IAAI,SACf,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;GAAI;GAAI;EAAE;CAC5B;EACD,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,SACnB,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;GAAI;GAAI;GAAI;EAAE;CAChC;EACD,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,SACvB,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;EAAE;CACpC;EACD,CAAC,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,SAC3B,UAAU;EACT,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,MAAM,KAAK,GAAG,KAAK;EACnB,IAAI,OAAO,MAAM,OAAO;EACxB,OAAO;GAAC;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;GAAI;EAAE;CACxC;AACJ"}
|
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,18 +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/
|
|
106
|
-
"@
|
|
106
|
+
"@effect/platform-node-shared": "4.1.4",
|
|
107
|
+
"@effect/tsgo": "0.67.7",
|
|
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",
|
|
107
115
|
"@types/node": "^26.6.5",
|
|
108
116
|
"@typescript/native": "npm:typescript@7.0.2",
|
|
109
|
-
"@vitest/coverage-istanbul": "5.0
|
|
110
|
-
"effect": "4.1.
|
|
111
|
-
"fallow": "3.
|
|
117
|
+
"@vitest/coverage-istanbul": "5.1.0",
|
|
118
|
+
"effect": "4.1.4",
|
|
119
|
+
"fallow": "3.42.0",
|
|
112
120
|
"rolldown": "^1.2.14",
|
|
113
121
|
"typescript": "npm:@typescript/typescript6@6.0.2",
|
|
114
|
-
"vite": "npm:@voidzero-dev/vite-plus-core@1.
|
|
115
|
-
"vite-plus": "1.
|
|
116
|
-
"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"
|
|
117
125
|
},
|
|
118
126
|
"peerDependencies": {
|
|
119
127
|
"effect": "^4.0.0"
|