@thomasfosterau/effect-parse 0.3.0 → 0.4.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/dist/Ascii.d.ts +0 -2
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +6 -6
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +0 -2
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +1 -2
- package/dist/Bits.d.ts +0 -2
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +2 -3
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +0 -2
- package/dist/Compiler.d.ts.map +1 -1
- package/dist/Compiler.js +1 -2
- package/dist/Encoding.d.ts +0 -2
- package/dist/Encoding.d.ts.map +1 -1
- package/dist/Encoding.js +1 -2
- package/dist/Expression.d.ts +0 -2
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +44 -8
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +32 -4
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +47 -8
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +0 -2
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js +1 -2
- package/dist/ParseError.d.ts +0 -2
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +6 -9
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +2 -2
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +26 -24
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts +0 -2
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +2 -3
- package/dist/ParserStream.d.ts +0 -2
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +15 -9
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +0 -2
- package/dist/Syntax.d.ts.map +1 -1
- package/dist/Syntax.js +13 -11
- package/dist/Syntax.js.map +1 -1
- package/dist/Text.d.ts +0 -2
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +1 -2
- package/dist/Token.d.ts +0 -2
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +1 -2
- package/dist/internal/compiler/closure.d.ts +5 -2
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +160 -92
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +0 -2
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +6 -7
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts +0 -2
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +10 -10
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/jit.d.ts +0 -2
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +52 -51
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +0 -2
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js +1 -2
- package/dist/internal/compiler/sets.d.ts +2 -2
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +8 -3
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/entries.d.ts +0 -2
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js +1 -2
- package/dist/internal/key.d.ts +10 -0
- package/dist/internal/key.d.ts.map +1 -0
- package/dist/internal/key.js +11 -0
- package/dist/internal/key.js.map +1 -0
- package/dist/internal/node.d.ts +11 -4
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +15 -3
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts +0 -2
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js +1 -2
- package/dist/internal/resume.d.ts +5 -6
- package/dist/internal/resume.d.ts.map +1 -1
- package/dist/internal/resume.js +1 -2
- package/dist/internal/resume.js.map +1 -1
- package/dist/internal/run.d.ts +0 -2
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +2 -3
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +0 -2
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +1 -2
- package/dist/internal/syntax.d.ts +30 -20
- package/dist/internal/syntax.d.ts.map +1 -1
- package/dist/internal/syntax.js +73 -66
- package/dist/internal/syntax.js.map +1 -1
- package/dist/internal/text.d.ts +5 -2
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +14 -5
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/ties.d.ts +0 -2
- package/dist/internal/ties.d.ts.map +1 -1
- package/dist/internal/ties.js +1 -2
- package/dist/internal/tokens.d.ts +10 -9
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +4 -8
- package/dist/internal/tokens.js.map +1 -1
- package/package.json +6 -6
- package/src/Ascii.ts +6 -5
- package/src/Bits.ts +1 -1
- package/src/Expression.ts +7 -6
- package/src/Input.ts +50 -11
- package/src/ParseError.ts +9 -7
- package/src/Parser.ts +26 -23
- package/src/ParserStream.ts +20 -8
- package/src/Syntax.ts +12 -9
- package/src/internal/compiler/closure.ts +202 -90
- package/src/internal/compiler/entries.ts +14 -11
- package/src/internal/compiler/first.ts +9 -8
- package/src/internal/compiler/jit.ts +95 -74
- package/src/internal/compiler/sets.ts +7 -0
- package/src/internal/key.ts +11 -0
- package/src/internal/node.ts +19 -2
- package/src/internal/resume.ts +5 -4
- package/src/internal/run.ts +1 -1
- package/src/internal/syntax.ts +78 -87
- package/src/internal/text.ts +24 -4
- package/src/internal/tokens.ts +20 -13
package/dist/ParserSchema.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as Result from "effect/Result";
|
|
2
2
|
import { Parser } from "./Parser.js";
|
|
3
3
|
import * as Schema from "effect/Schema";
|
|
4
|
-
//#region src/ParserSchema.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* The key of the annotation that says how a schema is written as text
|
|
7
6
|
* ({@link Annotation}), namespaced to this package so it cannot collide with
|
|
@@ -226,5 +225,4 @@ export declare const toPrinter: <S extends Schema.ConstraintCodec<unknown, unkno
|
|
|
226
225
|
export declare const fromSchema: <S extends Schema.ConstraintCodec<unknown, unknown, never, never> & Schema.Top>(schema: S, options?: {
|
|
227
226
|
readonly encode?: ((value: S["Type"]) => string) | undefined;
|
|
228
227
|
}) => Schema.decodeTo<Schema.toType<S>, Schema.String>;
|
|
229
|
-
//#endregion
|
|
230
228
|
//# sourceMappingURL=ParserSchema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParserSchema.d.ts","names":[],"sources":["../src/ParserSchema.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ParserSchema.d.ts","names":[],"sources":["../src/ParserSchema.ts"],"mappings":";;;;;;;;;;;qBA4Da;;YAGD;cACE;;;;;;gBAME,iBAAiB;;;;;;;;;;iBAWhB,QAAQ;;WAEd,WAAW,OAAO;;WAElB;;;;;;;;iBASM,aAAa,WAAW,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO;;;;;;;;qBA0CtE,OAAQ,GAAG,GAAG,QAAQ,OAAO,GAAG,mBAAmB,UAAU,QAAQ,OAAK,aAAa;;;;;;;;;;iBAuBnF,QAAQ;;;;;;;WAOd,SAAS,OAAO;;WAEhB,UAAU,OAAO;;WAEjB;;WAEA;;WAEA;;;;;WAKA;;;;;;;WAOA;;;;;;;;;;YAWC,WAAW,eAAe,QAAQ,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;qBAqB7C;GAEV,WACC,YAAY,WAAW,MACrB,UAAU,OAAO,KAAK,MAAM,MAAM,YAAY,kCAAkC;GACnF,UAAU,OAAO,KAAK,MAAM,GAAG,YAAY,WAAW,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAsDzD,WAAY,UAAU,OAAO,4BACxC,QAAQ,MACP,OAAO,WAAW,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAmCf,YAAa,UAAU,OAAO,mDACzC,QAAQ,QACL,OAAO,cAAc,OAAO,eAAe,OAAO;;;;;;;;;;;;;;;;;;;;;;;;qBAmC1C,aAAc,UAAU,OAAO,kDAAkD,OAAO,KACnG,QAAQ,GACR;WAAqB,WAAW,OAAO;MACtC,OAAO,SAAS,OAAO,OAAO,IAAI,OAAO"}
|
package/dist/ParserSchema.js
CHANGED
|
@@ -4,10 +4,10 @@ import * as P from "./Parser.js";
|
|
|
4
4
|
import { describeLiteral } from "./internal/tokens.js";
|
|
5
5
|
import * as Token from "./Token.js";
|
|
6
6
|
import * as Option from "effect/Option";
|
|
7
|
+
import * as Arr from "effect/Array";
|
|
7
8
|
import * as Ascii from "./Ascii.js";
|
|
8
9
|
import * as Effect from "effect/Effect";
|
|
9
10
|
import { dual } from "effect/Function";
|
|
10
|
-
import * as Arr from "effect/Array";
|
|
11
11
|
import * as Match from "effect/Match";
|
|
12
12
|
import * as MutableHashMap from "effect/MutableHashMap";
|
|
13
13
|
import * as Order from "effect/Order";
|
|
@@ -16,7 +16,7 @@ import * as Schema from "effect/Schema";
|
|
|
16
16
|
import * as SchemaAST from "effect/SchemaAST";
|
|
17
17
|
import * as SchemaIssue from "effect/SchemaIssue";
|
|
18
18
|
import * as SchemaTransformation from "effect/SchemaTransformation";
|
|
19
|
-
|
|
19
|
+
// src/ParserSchema.ts
|
|
20
20
|
/**
|
|
21
21
|
* Effect `Schema`s and parsers, in both directions.
|
|
22
22
|
*
|
|
@@ -679,7 +679,6 @@ const unionPrinter = (ast, ctx) => {
|
|
|
679
679
|
return issue ?? unwritable(ctx, "No member of the union can write this value", value);
|
|
680
680
|
};
|
|
681
681
|
};
|
|
682
|
-
//#endregion
|
|
683
682
|
export { annotate, annotationKey, fromSchema, make, toParser, toPrinter };
|
|
684
683
|
|
|
685
684
|
//# sourceMappingURL=ParserSchema.js.map
|
package/dist/ParserStream.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { Parser } from "./Parser.js";
|
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
4
|
import * as ParseError from "./ParseError.js";
|
|
5
5
|
import * as Stream from "effect/Stream";
|
|
6
|
-
//#region src/ParserStream.d.ts
|
|
7
6
|
/**
|
|
8
7
|
* Input kinds that can be streamed in chunks.
|
|
9
8
|
*
|
|
@@ -128,6 +127,5 @@ export declare const parseResponse: {
|
|
|
128
127
|
<A, E, R>(parser: Parser<A, E, R, Uint8Array>): (self: Response) => Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>;
|
|
129
128
|
<A, E, R>(self: Response, parser: Parser<A, E, R, Uint8Array>): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>;
|
|
130
129
|
};
|
|
131
|
-
//#endregion
|
|
132
130
|
export {};
|
|
133
131
|
//# sourceMappingURL=ParserStream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParserStream.d.ts","names":[],"sources":["../src/ParserStream.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ParserStream.d.ts","names":[],"sources":["../src/ParserStream.ts"],"mappings":";;;;;;;;;;;YA+CY,qBAAqB,aAAa;;;;;;;iBA8B7B,iBAAiB;;WAEvB,QAAQ,OAAO;;;;;;;;;;;;;;;;;;qBAmBb;GACV,GAAG,GAAG,GAAG,UAAU,WAClB,QAAQ,OAAO,GAAG,GAAG,GAAG,IACxB,UAAU,iBAAiB,MACzB,IAAI,IAAI,MAAM,OAAO,OAAO,OAAO,IAAI,IAAI,QAAQ,OAAO,OAAO,GAAG,KAAK,WAAW,WAAW,IAAI,KAAK;GAC3G,UAAU,WAAW,IAAI,IAAI,GAAG,GAAG,GAClC,MAAM,OAAO,OAAO,OAAO,QAAQ,KAAK,IAAI,KAC5C,QAAQ,OAAO,GAAG,GAAG,GAAG,IACxB,UAAU,iBAAiB,KAC1B,OAAO,OAAO,GAAG,KAAK,WAAW,WAAW,IAAI,KAAK;;;;;;;;;;;;;;;;;;;;;;;;qBA4M7C;GACV,GAAG,GAAG,GAAG,UAAU,WAClB,QAAQ,OAAO,GAAG,GAAG,GAAG,IACxB,UAAU,iBAAiB,MACzB,IAAI,IAAI,MAAM,OAAO,OAAO,OAAO,IAAI,IAAI,QAAQ,OAAO,OAAO,GAAG,KAAK,WAAW,WAAW,IAAI,KAAK;GAC3G,UAAU,WAAW,IAAI,IAAI,GAAG,GAAG,GAClC,MAAM,OAAO,OAAO,OAAO,QAAQ,KAAK,IAAI,KAC5C,QAAQ,OAAO,GAAG,GAAG,GAAG,IACxB,UAAU,iBAAiB,KAC1B,OAAO,OAAO,GAAG,KAAK,WAAW,WAAW,IAAI,KAAK;;;;;;;;;;;;qBA2B7C,gCAAgC;WAAyC;;;;;;;;;;;;;;;;;;;;;;;qBAuBzE;GACV,GAAG,GAAG,GACL,QAAQ,OAAO,GAAG,GAAG,GAAG,eACtB,MAAM,eAAe,iBAAiB,OAAO,OAAO,GAAG,WAAW,WAAW,KAAK,WAAW;GAChG,GAAG,GAAG,GACL,MAAM,eAAe,cACrB,QAAQ,OAAO,GAAG,GAAG,GAAG,cACvB,OAAO,OAAO,GAAG,WAAW,WAAW,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;qBAiC/C;GACV,GAAG,GAAG,GACL,QAAQ,OAAO,GAAG,GAAG,GAAG,eACtB,MAAM,aAAa,OAAO,OAAO,GAAG,WAAW,WAAW,KAAK,WAAW;GAC7E,GAAG,GAAG,GACL,MAAM,UACN,QAAQ,OAAO,GAAG,GAAG,GAAG,cACvB,OAAO,OAAO,GAAG,WAAW,WAAW,KAAK,WAAW"}
|
package/dist/ParserStream.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Predicate from "effect/Predicate";
|
|
2
2
|
import { Fail, Failure, State, fromSource } from "./Input.js";
|
|
3
3
|
import * as Registry from "./internal/compiler/registry.js";
|
|
4
|
+
import { isEmptyUnits } from "./internal/text.js";
|
|
4
5
|
import * as Data from "effect/Data";
|
|
5
6
|
import * as Effect from "effect/Effect";
|
|
6
7
|
import { dual } from "effect/Function";
|
|
@@ -8,7 +9,7 @@ import * as ParseError from "./ParseError.js";
|
|
|
8
9
|
import * as Run from "./internal/run.js";
|
|
9
10
|
import * as Stack from "./internal/stack.js";
|
|
10
11
|
import * as Stream from "effect/Stream";
|
|
11
|
-
|
|
12
|
+
// src/ParserStream.ts
|
|
12
13
|
/**
|
|
13
14
|
* Running parsers over Effect `Stream`s of input chunks.
|
|
14
15
|
*
|
|
@@ -37,7 +38,7 @@ import * as Stream from "effect/Stream";
|
|
|
37
38
|
const concat = (a, b) => {
|
|
38
39
|
if (Predicate.isString(a)) return a + b;
|
|
39
40
|
if (a instanceof Uint8Array) {
|
|
40
|
-
if (a.
|
|
41
|
+
if (a.byteLength === 0) return b;
|
|
41
42
|
const out = new Uint8Array(a.length + b.length);
|
|
42
43
|
out.set(a);
|
|
43
44
|
out.set(b, a.length);
|
|
@@ -116,6 +117,7 @@ var Incremental = class {
|
|
|
116
117
|
/** The input length at the last attempt, and where that attempt ran out of input. */
|
|
117
118
|
attempted = 0;
|
|
118
119
|
restart = 0;
|
|
120
|
+
pushed = 0;
|
|
119
121
|
/** Set once an attempt settles: a success (with its end offset) or a definite failure. */
|
|
120
122
|
settled;
|
|
121
123
|
constructor(parser, context, empty) {
|
|
@@ -152,17 +154,21 @@ var Incremental = class {
|
|
|
152
154
|
}
|
|
153
155
|
}
|
|
154
156
|
push(chunk) {
|
|
155
|
-
if (chunk
|
|
157
|
+
if (isEmptyUnits(chunk)) return;
|
|
156
158
|
this.append(chunk);
|
|
157
159
|
if (this.settled !== void 0) return;
|
|
160
|
+
if (++this.pushed === 1) return;
|
|
158
161
|
const added = this.length - this.attempted;
|
|
159
162
|
if (added < (this.attempted - this.restart) / 2) return;
|
|
160
163
|
if (this.kind === 0 && added < this.attempted / 8) return;
|
|
161
164
|
this.attempt();
|
|
162
165
|
}
|
|
163
|
-
/**
|
|
164
|
-
step
|
|
165
|
-
|
|
166
|
+
/**
|
|
167
|
+
* The step attempts run: the parser's compiled code if it was compiled
|
|
168
|
+
* (the resumable build, unless `resumable` is false), else the interpreter.
|
|
169
|
+
*/
|
|
170
|
+
step(state, resumable = true) {
|
|
171
|
+
return Stack.run(Registry.stepFor(this.parser, state, resumable) ?? this.parser.step, state);
|
|
166
172
|
}
|
|
167
173
|
attempt() {
|
|
168
174
|
const state = new State(this.input(), {
|
|
@@ -185,8 +191,9 @@ var Incremental = class {
|
|
|
185
191
|
if (settled.pos === this.length) return Effect.succeed(settled.value);
|
|
186
192
|
} else if (settled === void 0) {
|
|
187
193
|
const state = new State(this.input(), { context: this.context });
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
const resumable = this.attempted > 0;
|
|
195
|
+
if (resumable) state.resume = this.resume;
|
|
196
|
+
const a = this.step(state, resumable);
|
|
190
197
|
if (a !== Fail && state.pos === state.end) return Effect.succeed(a);
|
|
191
198
|
}
|
|
192
199
|
const all = this.input();
|
|
@@ -276,7 +283,6 @@ const parseReadable = /*#__PURE__*/ dual(2, (self, parser) => parseAll(Stream.fr
|
|
|
276
283
|
* @category combinators
|
|
277
284
|
*/
|
|
278
285
|
const parseResponse = /*#__PURE__*/ dual(2, (self, parser) => parseReadable(self.body ?? new ReadableStream({ start: (c) => c.close() }), parser));
|
|
279
|
-
//#endregion
|
|
280
286
|
export { ReadError, parseAll, parseMany, parseReadable, parseResponse };
|
|
281
287
|
|
|
282
288
|
//# sourceMappingURL=ParserStream.js.map
|
package/dist/ParserStream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParserStream.js","names":[],"sources":["../src/ParserStream.ts"],"sourcesContent":["/**\n * Running parsers over Effect `Stream`s of input chunks.\n *\n * This is where nom's and winnow's *partial* (streaming) parsing meets\n * Effect: chunks are buffered and the parser runs in partial mode, so a\n * value split across chunk boundaries is reported as `Incomplete` and\n * retried once more data arrives. When the stream ends, the leftover input\n * is parsed in complete mode.\n *\n * @example\n * ```ts\n * import { Effect, Stream } from \"effect\"\n * import { Ascii, Parser, ParserStream, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const line = Parser.terminated(Ascii.decInt, Token.literal(\"\\n\"))\n *\n * const program = Stream.make(\"1\\n2\", \"3\\n\", \"4\\n\").pipe(\n * ParserStream.parseMany(line),\n * Stream.runCollect\n * )\n * // Effect.runSync(program) => [1, 23, 4]\n * ```\n *\n * @since 0.1.0\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Context from \"effect/Context\"\nimport * as Data from \"effect/Data\"\nimport * as Effect from \"effect/Effect\"\nimport { dual } from \"effect/Function\"\nimport * as Stream from \"effect/Stream\"\nimport type { BinaryInput, Input, Source } from \"./Input.js\"\nimport { Fail, Failure, fromSource, State } from \"./Input.js\"\nimport * as ParseError from \"./ParseError.js\"\nimport * as Registry from \"./internal/compiler/registry.js\"\nimport type * as Resume from \"./internal/resume.js\"\nimport * as Run from \"./internal/run.js\"\nimport * as Stack from \"./internal/stack.js\"\nimport type { Parser } from \"./Parser.js\"\n\n/**\n * Input kinds that can be streamed in chunks.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Chunkable = string | Uint8Array | ReadonlyArray<unknown>\n\nconst concat = <I extends Chunkable>(a: I, b: I): I => {\n if (Predicate.isString(a)) return (a + (b as string)) as I\n if (a instanceof Uint8Array) {\n if (a.length === 0) return b\n const out = new Uint8Array(a.length + (b as Uint8Array).length)\n out.set(a)\n out.set(b as Uint8Array, a.length)\n return out as I\n }\n return [...a, ...(b as ReadonlyArray<unknown>)] as unknown as I\n}\n\nconst sliceFrom = <I extends Chunkable>(input: I, offset: number): I =>\n (Predicate.isString(input) ? input.slice(offset) : input.slice(offset)) as I\n\nconst noProgress = (input: Input, offset: number) =>\n ParseError.fromFailure<never>(\n input,\n new Failure(offset, \"Assert\", [], [], false, undefined, \"`parseMany` parsers must always consume\", 0),\n \"Cut\"\n )\n\n/**\n * Options for {@link parseMany}.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface ParseManyOptions<I> {\n /** The empty input, used to initialise the buffer (inferred from the first chunk if omitted). */\n readonly empty?: Source<I> | undefined\n}\n\n/**\n * Transforms a stream of input chunks into a stream of parsed values by\n * applying `parser` repeatedly. Each application must consume input.\n *\n * Services required by the parser are taken from the stream's context.\n * Error offsets are relative to the internal buffer of unconsumed input,\n * which is also the `input` of the reported `ParseError`.\n *\n * A parser compiled with the `Compiler` module runs compiled, with the\n * build that handles partial input (see `Parser.run`); a value that fails\n * or needs more input is parsed again interpreted, so errors and\n * `Incomplete` are the interpreter's.\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseMany: {\n <A, E, R, I extends Chunkable>(\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): <E0, R0>(self: Stream.Stream<Source<I>, E0, R0>) => Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R>\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<NoInfer<I>>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R>\n} = /*#__PURE__*/ dual(\n (args) => Stream.isStream(args[0]),\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<I>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R> =>\n Stream.suspend(() => {\n const step = parser.step\n let buffer: I | undefined = options?.empty === undefined ? undefined : fromSource<I>(options.empty)\n\n const drain = (context: any, partial: boolean): Effect.Effect<Array<A>, ParseError.ParseError<E>> => {\n const out: Array<A> = []\n if (buffer === undefined) return Effect.succeed(out)\n const input = buffer\n // One state for the whole buffer, reset before each value\n const state = new State(input)\n let offset = 0\n while (offset < input.length) {\n state.reset(offset, { partial, context })\n const a = Run.runOn(parser, step, state)\n if (a === Fail) {\n if (partial && state.mode === \"Incomplete\") break\n return Effect.fail(ParseError.fromFailure<E>(input, state.reportedFailure(), state.mode, state.encoding))\n }\n if (state.pos === offset) return Effect.fail(noProgress(input, offset))\n out.push(a)\n offset = state.pos\n }\n buffer = sliceFrom(input, offset)\n return Effect.succeed(out)\n }\n\n const feed = (source: Source<I>) =>\n Effect.flatMap(Effect.context<R>(), (context) =>\n Effect.suspend(() => {\n const chunk = fromSource<I>(source)\n buffer = buffer === undefined ? chunk : concat(buffer, chunk)\n return drain(context, true)\n })\n )\n\n const finish = Effect.flatMap(Effect.context<R>(), (context) => Effect.suspend(() => drain(context, false)))\n\n return self.pipe(\n Stream.mapEffect(feed),\n Stream.flattenIterable,\n Stream.concat(Stream.unwrap(Effect.map(finish, Stream.fromIterable)))\n )\n })\n)\n\n/**\n * Parses a stream of chunks incrementally, as one input. Chunks are parsed\n * as they arrive, in partial mode; when the parser runs out of input, its\n * repetitions keep checkpoints (see `internal/resume.ts`), so the next\n * attempt carries on from where the last one stopped instead of starting\n * over.\n */\nclass Incremental<A, E, I extends Chunkable> {\n private kind: 0 | 1 | 2 | undefined\n private text = \"\"\n private bytes = new Uint8Array(0)\n private items: Array<unknown> = []\n private length = 0\n private readonly resume: Resume.Checkpoints = new Map()\n /** The input length at the last attempt, and where that attempt ran out of input. */\n private attempted = 0\n private restart = 0\n /** Set once an attempt settles: a success (with its end offset) or a definite failure. */\n private settled: { readonly value: A; readonly pos: number } | \"failed\" | undefined\n\n constructor(\n private readonly parser: Parser<A, E, any, I>,\n private readonly context: Context.Context<never>,\n empty: I | undefined\n ) {\n if (empty !== undefined) this.append(empty)\n }\n\n private append(chunk: I): void {\n if (Predicate.isString(chunk)) {\n this.kind ??= 0\n this.text += chunk\n this.length += chunk.length\n } else if (chunk instanceof Uint8Array) {\n this.kind ??= 1\n const needed = this.length + chunk.length\n if (needed > this.bytes.length) {\n // Grow geometrically, so appending costs amortized constant time per byte\n const grown = new Uint8Array(Math.max(needed, this.bytes.length * 2, 4096))\n grown.set(this.bytes.subarray(0, this.length))\n this.bytes = grown\n }\n this.bytes.set(chunk, this.length)\n this.length = needed\n } else {\n this.kind ??= 2\n for (let i = 0; i < chunk.length; i++) this.items.push(chunk[i])\n this.length = this.items.length\n }\n }\n\n private input(): I {\n switch (this.kind) {\n case 1:\n return this.bytes.subarray(0, this.length) as I\n case 2:\n // Items are only appended between attempts, after each state has read its `end`\n return this.items as unknown as I\n default:\n return this.text as I\n }\n }\n\n push(chunk: I): void {\n if (chunk.length === 0) return\n this.append(chunk)\n if (this.settled !== undefined) return\n // An attempt re-reads what the last one could not finish, from `restart`;\n // waiting until at least half as much new input has arrived keeps the\n // total work linear in the input. Strings are also copied when they are\n // flattened, so they wait for a fraction of the whole input too.\n const added = this.length - this.attempted\n if (added < (this.attempted - this.restart) / 2) return\n if (this.kind === 0 && added < this.attempted / 8) return\n this.attempt()\n }\n\n /** The step attempts run: the parser's resumable compiled code if it was compiled, else the interpreter. */\n private step(state: State<I>): unknown {\n return Stack.run(Registry.stepFor(this.parser, state, true) ?? this.parser.step, state)\n }\n\n private attempt(): void {\n const state = new State(this.input(), { partial: true, context: this.context })\n state.resume = this.resume\n const a = this.step(state)\n this.attempted = this.length\n if (a !== Fail) {\n this.settled = { value: a as A, pos: state.pos }\n } else if (state.mode === \"Incomplete\") {\n this.restart = state.failure.offset\n } else {\n this.settled = \"failed\"\n }\n }\n\n finish(): Effect.Effect<A, ParseError.ParseError<E>> {\n const settled = this.settled\n if (settled !== undefined && settled !== \"failed\") {\n if (settled.pos === this.length) return Effect.succeed(settled.value)\n } else if (settled === undefined) {\n // The last attempt, in complete mode, resumes from the checkpoints too\n const state = new State(this.input(), { context: this.context })\n state.resume = this.resume\n const a = this.step(state)\n if (a !== Fail && state.pos === state.end) return Effect.succeed(a as A)\n }\n // The error comes from an ordinary parse of the whole input, so it is the\n // same as if the input had been parsed in one go\n const all = this.input()\n const state = new State(all, { context: this.context })\n const a = Stack.run(this.parser.step, state)\n if (a !== Fail && state.pos === state.end) return Effect.succeed(a)\n if (a !== Fail) state.backtrack(\"Eof\", [\"end of input\"])\n return Effect.fail(ParseError.fromFailure<E>(all, state.reportedFailure(), state.mode, state.encoding))\n }\n}\n\n/**\n * Parses an entire stream of chunks as a single complete input.\n *\n * Parsing does not wait for the stream to end: each chunk is parsed as it\n * arrives, in partial mode, and when the parser runs out of input its\n * repetitions (`repeat`, `separated`, `fold`, `escaped`, ...) remember how\n * far they got, so that the next attempt resumes there rather than starting\n * over. A large document, such as the body of a `fetch` response, is\n * therefore parsed while it downloads, and is ready soon after its last\n * byte. Use {@link parseReadable} or {@link parseResponse} for web streams.\n *\n * The result and any `ParseError` are those of parsing the whole input at\n * once: errors are reported once the stream has ended, by an ordinary\n * interpreted parse of the whole input. A parser compiled with the\n * `Compiler` module streams compiled too (with a build that handles partial\n * input), which is several times faster. As with compiled parsers,\n * callbacks should be pure: the elements parsed before a checkpoint are\n * not parsed again, and on failure everything is parsed again.\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseAll: {\n <A, E, R, I extends Chunkable>(\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): <E0, R0>(self: Stream.Stream<Source<I>, E0, R0>) => Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R>\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<NoInfer<I>>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R>\n} = /*#__PURE__*/ dual(\n (args) => Stream.isStream(args[0]),\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<I>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R> =>\n Effect.flatMap(Effect.context<R>(), (context) =>\n Effect.suspend(() => {\n const empty = options?.empty === undefined ? undefined : fromSource<I>(options.empty)\n const incremental = new Incremental(parser, context as Context.Context<never>, empty)\n return Effect.flatMap(\n Stream.runForEach(self, (chunk) => Effect.sync(() => incremental.push(fromSource<I>(chunk)))),\n () => Effect.suspend(() => incremental.finish())\n )\n })\n )\n)\n\n/**\n * An error reading a `ReadableStream` given to {@link parseReadable} or\n * {@link parseResponse}.\n *\n * @since 0.1.0\n * @category errors\n */\nexport class ReadError extends /*#__PURE__*/ Data.TaggedError(\"ReadError\")<{ readonly cause: unknown }> {}\n\n/**\n * Parses a web `ReadableStream` of bytes, such as the body of a `fetch`\n * response, incrementally (see {@link parseAll}): the bytes are parsed as\n * they arrive, without waiting for the end of the stream or decoding them\n * first. Use a byte parser, e.g. one built from `Text.utf8`.\n *\n * @example\n * ```ts\n * import { Effect } from \"effect\"\n * import { Parser, ParserStream, Text } from \"@thomasfosterau/effect-parse\"\n *\n * const csvLine = Parser.separated(Text.utf8.takeTill(\",\\n\"), Text.utf8.literal(\",\"))\n * const csv = Parser.separated(csvLine, Text.utf8.literal(\"\\n\"))\n *\n * const response = await fetch(\"https://example.com/data.csv\")\n * const rows = await Effect.runPromise(ParserStream.parseReadable(response.body!, csv))\n * ```\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseReadable: {\n <A, E, R>(\n parser: Parser<A, E, R, Uint8Array>\n ): (self: ReadableStream<BinaryInput>) => Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n <A, E, R>(\n self: ReadableStream<BinaryInput>,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R>(\n self: ReadableStream<BinaryInput>,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R> =>\n parseAll(\n Stream.fromReadableStream({ evaluate: () => self, onError: (cause) => new ReadError({ cause }) }),\n parser,\n { empty: new Uint8Array(0) }\n )\n)\n\n/**\n * Parses the body of a `fetch` `Response` incrementally, as it downloads\n * (see {@link parseReadable}). A response without a body is parsed as empty\n * input. The status is not checked.\n *\n * @example\n * ```ts\n * import { Effect } from \"effect\"\n * import { Parser, ParserStream, Text } from \"@thomasfosterau/effect-parse\"\n *\n * const lines = Parser.separated(Text.utf8.tillLineEnding, Text.utf8.lineEnding)\n *\n * const response = await fetch(\"https://example.com/log.txt\")\n * const value = await Effect.runPromise(ParserStream.parseResponse(response, lines))\n * ```\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseResponse: {\n <A, E, R>(\n parser: Parser<A, E, R, Uint8Array>\n ): (self: Response) => Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n <A, E, R>(\n self: Response,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R>(\n self: Response,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R> =>\n parseReadable(self.body ?? new ReadableStream<Uint8Array>({ start: (c) => c.close() }), parser)\n)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,MAAM,UAA+B,GAAM,MAAY;CACrD,IAAI,UAAU,SAAS,CAAC,GAAG,OAAQ,IAAK;CACxC,IAAI,aAAa,YAAY;EAC3B,IAAI,EAAE,WAAW,GAAG,OAAO;EAC3B,MAAM,MAAM,IAAI,WAAW,EAAE,SAAU,EAAiB,MAAM;EAC9D,IAAI,IAAI,CAAC;EACT,IAAI,IAAI,GAAiB,EAAE,MAAM;EACjC,OAAO;CACT;CACA,OAAO,CAAC,GAAG,GAAG,GAAI,CAA4B;AAChD;AAEA,MAAM,aAAkC,OAAU,WAC/C,UAAU,SAAS,KAAK,IAAI,MAAM,MAAM,MAAM,IAAI,MAAM,MAAM,MAAM;AAEvE,MAAM,cAAc,OAAc,WAChC,WAAW,YACT,OACA,IAAI,QAAQ,QAAQ,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,KAAA,GAAW,2CAA2C,CAAC,GACpG,KACF;;;;;;;;;;;;;;;;;AA6BF,MAAa,YAUK,oBACf,SAAS,OAAO,SAAS,KAAK,EAAE,IAE/B,MACA,QACA,YAEA,OAAO,cAAc;CACnB,MAAM,OAAO,OAAO;CACpB,IAAI,SAAwB,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,WAAc,QAAQ,KAAK;CAElG,MAAM,SAAS,SAAc,YAAwE;EACnG,MAAM,MAAgB,CAAC;EACvB,IAAI,WAAW,KAAA,GAAW,OAAO,OAAO,QAAQ,GAAG;EACnD,MAAM,QAAQ;EAEd,MAAM,QAAQ,IAAI,MAAM,KAAK;EAC7B,IAAI,SAAS;EACb,OAAO,SAAS,MAAM,QAAQ;GAC5B,MAAM,MAAM,QAAQ;IAAE;IAAS;GAAQ,CAAC;GACxC,MAAM,IAAI,IAAI,MAAM,QAAQ,MAAM,KAAK;GACvC,IAAI,MAAM,MAAM;IACd,IAAI,WAAW,MAAM,SAAS,cAAc;IAC5C,OAAO,OAAO,KAAK,WAAW,YAAe,OAAO,MAAM,gBAAgB,GAAG,MAAM,MAAM,MAAM,QAAQ,CAAC;GAC1G;GACA,IAAI,MAAM,QAAQ,QAAQ,OAAO,OAAO,KAAK,WAAW,OAAO,MAAM,CAAC;GACtE,IAAI,KAAK,CAAC;GACV,SAAS,MAAM;EACjB;EACA,SAAS,UAAU,OAAO,MAAM;EAChC,OAAO,OAAO,QAAQ,GAAG;CAC3B;CAEA,MAAM,QAAQ,WACZ,OAAO,QAAQ,OAAO,QAAW,IAAI,YACnC,OAAO,cAAc;EACnB,MAAM,QAAQ,WAAc,MAAM;EAClC,SAAS,WAAW,KAAA,IAAY,QAAQ,OAAO,QAAQ,KAAK;EAC5D,OAAO,MAAM,SAAS,IAAI;CAC5B,CAAC,CACH;CAEF,MAAM,SAAS,OAAO,QAAQ,OAAO,QAAW,IAAI,YAAY,OAAO,cAAc,MAAM,SAAS,KAAK,CAAC,CAAC;CAE3G,OAAO,KAAK,KACV,OAAO,UAAU,IAAI,GACrB,OAAO,iBACP,OAAO,OAAO,OAAO,OAAO,OAAO,IAAI,QAAQ,OAAO,YAAY,CAAC,CAAC,CACtE;AACF,CAAC,CACL;;;;;;;;AASA,IAAM,cAAN,MAA6C;CAcxB;CACA;CAdnB;CACA,OAAe;CACf,wBAAgB,IAAI,WAAW,CAAC;CAChC,QAAgC,CAAC;CACjC,SAAiB;CACjB,yBAA8C,IAAI,IAAI;;CAEtD,YAAoB;CACpB,UAAkB;;CAElB;CAEA,YACE,QACA,SACA,OACA;EAHiB,KAAA,SAAA;EACA,KAAA,UAAA;EAGjB,IAAI,UAAU,KAAA,GAAW,KAAK,OAAO,KAAK;CAC5C;CAEA,OAAe,OAAgB;EAC7B,IAAI,UAAU,SAAS,KAAK,GAAG;GAC7B,KAAK,SAAS;GACd,KAAK,QAAQ;GACb,KAAK,UAAU,MAAM;EACvB,OAAO,IAAI,iBAAiB,YAAY;GACtC,KAAK,SAAS;GACd,MAAM,SAAS,KAAK,SAAS,MAAM;GACnC,IAAI,SAAS,KAAK,MAAM,QAAQ;IAE9B,MAAM,QAAQ,IAAI,WAAW,KAAK,IAAI,QAAQ,KAAK,MAAM,SAAS,GAAG,IAAI,CAAC;IAC1E,MAAM,IAAI,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM,CAAC;IAC7C,KAAK,QAAQ;GACf;GACA,KAAK,MAAM,IAAI,OAAO,KAAK,MAAM;GACjC,KAAK,SAAS;EAChB,OAAO;GACL,KAAK,SAAS;GACd,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,MAAM,EAAE;GAC/D,KAAK,SAAS,KAAK,MAAM;EAC3B;CACF;CAEA,QAAmB;EACjB,QAAQ,KAAK,MAAb;GACE,KAAK,GACH,OAAO,KAAK,MAAM,SAAS,GAAG,KAAK,MAAM;GAC3C,KAAK,GAEH,OAAO,KAAK;GACd,SACE,OAAO,KAAK;EAChB;CACF;CAEA,KAAK,OAAgB;EACnB,IAAI,MAAM,WAAW,GAAG;EACxB,KAAK,OAAO,KAAK;EACjB,IAAI,KAAK,YAAY,KAAA,GAAW;EAKhC,MAAM,QAAQ,KAAK,SAAS,KAAK;EACjC,IAAI,SAAS,KAAK,YAAY,KAAK,WAAW,GAAG;EACjD,IAAI,KAAK,SAAS,KAAK,QAAQ,KAAK,YAAY,GAAG;EACnD,KAAK,QAAQ;CACf;;CAGA,KAAa,OAA0B;EACrC,OAAO,MAAM,IAAI,SAAS,QAAQ,KAAK,QAAQ,OAAO,IAAI,KAAK,KAAK,OAAO,MAAM,KAAK;CACxF;CAEA,UAAwB;EACtB,MAAM,QAAQ,IAAI,MAAM,KAAK,MAAM,GAAG;GAAE,SAAS;GAAM,SAAS,KAAK;EAAQ,CAAC;EAC9E,MAAM,SAAS,KAAK;EACpB,MAAM,IAAI,KAAK,KAAK,KAAK;EACzB,KAAK,YAAY,KAAK;EACtB,IAAI,MAAM,MACR,KAAK,UAAU;GAAE,OAAO;GAAQ,KAAK,MAAM;EAAI;OAC1C,IAAI,MAAM,SAAS,cACxB,KAAK,UAAU,MAAM,QAAQ;OAE7B,KAAK,UAAU;CAEnB;CAEA,SAAqD;EACnD,MAAM,UAAU,KAAK;EACrB,IAAI,YAAY,KAAA,KAAa,YAAY,UACnC;OAAA,QAAQ,QAAQ,KAAK,QAAQ,OAAO,OAAO,QAAQ,QAAQ,KAAK;EAAA,OAC/D,IAAI,YAAY,KAAA,GAAW;GAEhC,MAAM,QAAQ,IAAI,MAAM,KAAK,MAAM,GAAG,EAAE,SAAS,KAAK,QAAQ,CAAC;GAC/D,MAAM,SAAS,KAAK;GACpB,MAAM,IAAI,KAAK,KAAK,KAAK;GACzB,IAAI,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,OAAO,OAAO,QAAQ,CAAM;EACzE;EAGA,MAAM,MAAM,KAAK,MAAM;EACvB,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,SAAS,KAAK,QAAQ,CAAC;EACtD,MAAM,IAAI,MAAM,IAAI,KAAK,OAAO,MAAM,KAAK;EAC3C,IAAI,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK,OAAO,OAAO,QAAQ,CAAC;EAClE,IAAI,MAAM,MAAM,MAAM,UAAU,OAAO,CAAC,cAAc,CAAC;EACvD,OAAO,OAAO,KAAK,WAAW,YAAe,KAAK,MAAM,gBAAgB,GAAG,MAAM,MAAM,MAAM,QAAQ,CAAC;CACxG;AACF;;;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,WAUK,oBACf,SAAS,OAAO,SAAS,KAAK,EAAE,IAE/B,MACA,QACA,YAEA,OAAO,QAAQ,OAAO,QAAW,IAAI,YACnC,OAAO,cAAc;CAEnB,MAAM,cAAc,IAAI,YAAY,QAAQ,SAD9B,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,WAAc,QAAQ,KAAK,CACA;CACpF,OAAO,OAAO,QACZ,OAAO,WAAW,OAAO,UAAU,OAAO,WAAW,YAAY,KAAK,WAAc,KAAK,CAAC,CAAC,CAAC,SACtF,OAAO,cAAc,YAAY,OAAO,CAAC,CACjD;AACF,CAAC,CACH,CACJ;;;;;;;;AASA,IAAa,YAAb,eAA6C,mBAAK,YAAY,WAAW,EAAA,CAA+B,CAAC;;;;;;;;;;;;;;;;;;;;;;AAuBzG,MAAa,gBAQK,mBAChB,IAEE,MACA,WAEA,SACE,OAAO,mBAAmB;CAAE,gBAAgB;CAAM,UAAU,UAAU,IAAI,UAAU,EAAE,MAAM,CAAC;AAAE,CAAC,GAChG,QACA,EAAE,uBAAO,IAAI,WAAW,CAAC,EAAE,CAC7B,CACJ;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,gBAQK,mBAChB,IAEE,MACA,WAEA,cAAc,KAAK,QAAQ,IAAI,eAA2B,EAAE,QAAQ,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAClG"}
|
|
1
|
+
{"version":3,"file":"ParserStream.js","names":[],"sources":["../src/ParserStream.ts"],"sourcesContent":["/**\n * Running parsers over Effect `Stream`s of input chunks.\n *\n * This is where nom's and winnow's *partial* (streaming) parsing meets\n * Effect: chunks are buffered and the parser runs in partial mode, so a\n * value split across chunk boundaries is reported as `Incomplete` and\n * retried once more data arrives. When the stream ends, the leftover input\n * is parsed in complete mode.\n *\n * @example\n * ```ts\n * import { Effect, Stream } from \"effect\"\n * import { Ascii, Parser, ParserStream, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const line = Parser.terminated(Ascii.decInt, Token.literal(\"\\n\"))\n *\n * const program = Stream.make(\"1\\n2\", \"3\\n\", \"4\\n\").pipe(\n * ParserStream.parseMany(line),\n * Stream.runCollect\n * )\n * // Effect.runSync(program) => [1, 23, 4]\n * ```\n *\n * @since 0.1.0\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Context from \"effect/Context\"\nimport * as Data from \"effect/Data\"\nimport * as Effect from \"effect/Effect\"\nimport { dual } from \"effect/Function\"\nimport * as Stream from \"effect/Stream\"\nimport type { BinaryInput, Input, Source } from \"./Input.js\"\nimport { Fail, Failure, fromSource, State } from \"./Input.js\"\nimport * as ParseError from \"./ParseError.js\"\nimport * as Registry from \"./internal/compiler/registry.js\"\nimport type * as Resume from \"./internal/resume.js\"\nimport * as Run from \"./internal/run.js\"\nimport * as Stack from \"./internal/stack.js\"\nimport { isEmptyUnits } from \"./internal/text.js\"\nimport type { Parser } from \"./Parser.js\"\n\n/**\n * Input kinds that can be streamed in chunks.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Chunkable = string | Uint8Array | ReadonlyArray<unknown>\n\nconst concat = <I extends Chunkable>(a: I, b: I): I => {\n if (Predicate.isString(a)) return (a + (b as string)) as I\n if (a instanceof Uint8Array) {\n if (a.byteLength === 0) return b\n const out = new Uint8Array(a.length + (b as Uint8Array).length)\n out.set(a)\n out.set(b as Uint8Array, a.length)\n return out as I\n }\n return [...a, ...(b as ReadonlyArray<unknown>)] as unknown as I\n}\n\nconst sliceFrom = <I extends Chunkable>(input: I, offset: number): I =>\n (Predicate.isString(input) ? input.slice(offset) : input.slice(offset)) as I\n\nconst noProgress = (input: Input, offset: number) =>\n ParseError.fromFailure<never>(\n input,\n new Failure(offset, \"Assert\", [], [], false, undefined, \"`parseMany` parsers must always consume\", 0),\n \"Cut\"\n )\n\n/**\n * Options for {@link parseMany}.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface ParseManyOptions<I> {\n /** The empty input, used to initialise the buffer (inferred from the first chunk if omitted). */\n readonly empty?: Source<I> | undefined\n}\n\n/**\n * Transforms a stream of input chunks into a stream of parsed values by\n * applying `parser` repeatedly. Each application must consume input.\n *\n * Services required by the parser are taken from the stream's context.\n * Error offsets are relative to the internal buffer of unconsumed input,\n * which is also the `input` of the reported `ParseError`.\n *\n * A parser compiled with the `Compiler` module runs compiled, with the\n * build that handles partial input (see `Parser.run`); a value that fails\n * or needs more input is parsed again interpreted, so errors and\n * `Incomplete` are the interpreter's.\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseMany: {\n <A, E, R, I extends Chunkable>(\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): <E0, R0>(self: Stream.Stream<Source<I>, E0, R0>) => Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R>\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<NoInfer<I>>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R>\n} = /*#__PURE__*/ dual(\n (args) => Stream.isStream(args[0]),\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<I>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Stream.Stream<A, E0 | ParseError.ParseError<E>, R0 | R> =>\n Stream.suspend(() => {\n const step = parser.step\n let buffer: I | undefined = options?.empty === undefined ? undefined : fromSource<I>(options.empty)\n\n const drain = (context: any, partial: boolean): Effect.Effect<Array<A>, ParseError.ParseError<E>> => {\n const out: Array<A> = []\n if (buffer === undefined) return Effect.succeed(out)\n const input = buffer\n // One state for the whole buffer, reset before each value\n const state = new State(input)\n let offset = 0\n while (offset < input.length) {\n state.reset(offset, { partial, context })\n const a = Run.runOn(parser, step, state)\n if (a === Fail) {\n if (partial && state.mode === \"Incomplete\") break\n return Effect.fail(ParseError.fromFailure<E>(input, state.reportedFailure(), state.mode, state.encoding))\n }\n if (state.pos === offset) return Effect.fail(noProgress(input, offset))\n out.push(a)\n offset = state.pos\n }\n buffer = sliceFrom(input, offset)\n return Effect.succeed(out)\n }\n\n const feed = (source: Source<I>) =>\n Effect.flatMap(Effect.context<R>(), (context) =>\n Effect.suspend(() => {\n const chunk = fromSource<I>(source)\n buffer = buffer === undefined ? chunk : concat(buffer, chunk)\n return drain(context, true)\n })\n )\n\n const finish = Effect.flatMap(Effect.context<R>(), (context) => Effect.suspend(() => drain(context, false)))\n\n return self.pipe(\n Stream.mapEffect(feed),\n Stream.flattenIterable,\n Stream.concat(Stream.unwrap(Effect.map(finish, Stream.fromIterable)))\n )\n })\n)\n\n/**\n * Parses a stream of chunks incrementally, as one input. Chunks are parsed\n * as they arrive, in partial mode; when the parser runs out of input, its\n * repetitions keep checkpoints (see `internal/resume.ts`), so the next\n * attempt carries on from where the last one stopped instead of starting\n * over.\n */\nclass Incremental<A, E, I extends Chunkable> {\n private kind: 0 | 1 | 2 | undefined\n private text = \"\"\n private bytes = new Uint8Array(0)\n private items: Array<unknown> = []\n private length = 0\n private readonly resume: Resume.Checkpoints = new Map()\n /** The input length at the last attempt, and where that attempt ran out of input. */\n private attempted = 0\n private restart = 0\n private pushed = 0\n /** Set once an attempt settles: a success (with its end offset) or a definite failure. */\n private settled: { readonly value: A; readonly pos: number } | \"failed\" | undefined\n\n constructor(\n private readonly parser: Parser<A, E, any, I>,\n private readonly context: Context.Context<never>,\n empty: I | undefined\n ) {\n if (empty !== undefined) this.append(empty)\n }\n\n private append(chunk: I): void {\n if (Predicate.isString(chunk)) {\n this.kind ??= 0\n this.text += chunk\n this.length += chunk.length\n } else if (chunk instanceof Uint8Array) {\n this.kind ??= 1\n const needed = this.length + chunk.length\n if (needed > this.bytes.length) {\n // Grow geometrically, so appending costs amortized constant time per byte\n const grown = new Uint8Array(Math.max(needed, this.bytes.length * 2, 4096))\n grown.set(this.bytes.subarray(0, this.length))\n this.bytes = grown\n }\n this.bytes.set(chunk, this.length)\n this.length = needed\n } else {\n this.kind ??= 2\n for (let i = 0; i < chunk.length; i++) this.items.push(chunk[i])\n this.length = this.items.length\n }\n }\n\n private input(): I {\n switch (this.kind) {\n case 1:\n return this.bytes.subarray(0, this.length) as I\n case 2:\n // Items are only appended between attempts, after each state has read its `end`\n return this.items as unknown as I\n default:\n return this.text as I\n }\n }\n\n push(chunk: I): void {\n if (isEmptyUnits(chunk)) return\n this.append(chunk)\n if (this.settled !== undefined) return\n // The first attempt waits for a second chunk: an input that arrives in\n // one chunk (most small responses) is parsed once, by `finish`, instead\n // of once in partial mode and again in complete mode, since a repetition\n // that completes without resuming keeps no checkpoint\n if (++this.pushed === 1) return\n // An attempt re-reads what the last one could not finish, from `restart`;\n // waiting until at least half as much new input has arrived keeps the\n // total work linear in the input. Strings are also copied when they are\n // flattened, so they wait for a fraction of the whole input too.\n const added = this.length - this.attempted\n if (added < (this.attempted - this.restart) / 2) return\n if (this.kind === 0 && added < this.attempted / 8) return\n this.attempt()\n }\n\n /**\n * The step attempts run: the parser's compiled code if it was compiled\n * (the resumable build, unless `resumable` is false), else the interpreter.\n */\n private step(state: State<I>, resumable = true): unknown {\n return Stack.run(Registry.stepFor(this.parser, state, resumable) ?? this.parser.step, state)\n }\n\n private attempt(): void {\n const state = new State(this.input(), { partial: true, context: this.context })\n state.resume = this.resume\n const a = this.step(state)\n this.attempted = this.length\n if (a !== Fail) {\n this.settled = { value: a as A, pos: state.pos }\n } else if (state.mode === \"Incomplete\") {\n this.restart = state.failure.offset\n } else {\n this.settled = \"failed\"\n }\n }\n\n finish(): Effect.Effect<A, ParseError.ParseError<E>> {\n const settled = this.settled\n if (settled !== undefined && settled !== \"failed\") {\n if (settled.pos === this.length) return Effect.succeed(settled.value)\n } else if (settled === undefined) {\n // The last attempt, in complete mode, resumes from the checkpoints too;\n // with no attempt before it, it is an ordinary parse\n const state = new State(this.input(), { context: this.context })\n const resumable = this.attempted > 0\n if (resumable) state.resume = this.resume\n const a = this.step(state, resumable)\n if (a !== Fail && state.pos === state.end) return Effect.succeed(a as A)\n }\n // The error comes from an ordinary parse of the whole input, so it is the\n // same as if the input had been parsed in one go\n const all = this.input()\n const state = new State(all, { context: this.context })\n const a = Stack.run(this.parser.step, state)\n if (a !== Fail && state.pos === state.end) return Effect.succeed(a)\n if (a !== Fail) state.backtrack(\"Eof\", [\"end of input\"])\n return Effect.fail(ParseError.fromFailure<E>(all, state.reportedFailure(), state.mode, state.encoding))\n }\n}\n\n/**\n * Parses an entire stream of chunks as a single complete input.\n *\n * Parsing does not wait for the stream to end: each chunk is parsed as it\n * arrives, in partial mode, and when the parser runs out of input its\n * repetitions (`repeat`, `separated`, `fold`, `escaped`, ...) remember how\n * far they got, so that the next attempt resumes there rather than starting\n * over. A large document, such as the body of a `fetch` response, is\n * therefore parsed while it downloads, and is ready soon after its last\n * byte. Use {@link parseReadable} or {@link parseResponse} for web streams.\n *\n * The result and any `ParseError` are those of parsing the whole input at\n * once: errors are reported once the stream has ended, by an ordinary\n * interpreted parse of the whole input. A parser compiled with the\n * `Compiler` module streams compiled too (with a build that handles partial\n * input), which is several times faster. As with compiled parsers,\n * callbacks should be pure: the elements parsed before a checkpoint are\n * not parsed again, and on failure everything is parsed again.\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseAll: {\n <A, E, R, I extends Chunkable>(\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): <E0, R0>(self: Stream.Stream<Source<I>, E0, R0>) => Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R>\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<NoInfer<I>>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R>\n} = /*#__PURE__*/ dual(\n (args) => Stream.isStream(args[0]),\n <I extends Chunkable, E0, R0, A, E, R>(\n self: Stream.Stream<Source<I>, E0, R0>,\n parser: Parser<A, E, R, I>,\n options?: ParseManyOptions<I>\n ): Effect.Effect<A, E0 | ParseError.ParseError<E>, R0 | R> =>\n Effect.flatMap(Effect.context<R>(), (context) =>\n Effect.suspend(() => {\n const empty = options?.empty === undefined ? undefined : fromSource<I>(options.empty)\n const incremental = new Incremental(parser, context as Context.Context<never>, empty)\n return Effect.flatMap(\n Stream.runForEach(self, (chunk) => Effect.sync(() => incremental.push(fromSource<I>(chunk)))),\n () => Effect.suspend(() => incremental.finish())\n )\n })\n )\n)\n\n/**\n * An error reading a `ReadableStream` given to {@link parseReadable} or\n * {@link parseResponse}.\n *\n * @since 0.1.0\n * @category errors\n */\nexport class ReadError extends /*#__PURE__*/ Data.TaggedError(\"ReadError\")<{ readonly cause: unknown }> {}\n\n/**\n * Parses a web `ReadableStream` of bytes, such as the body of a `fetch`\n * response, incrementally (see {@link parseAll}): the bytes are parsed as\n * they arrive, without waiting for the end of the stream or decoding them\n * first. Use a byte parser, e.g. one built from `Text.utf8`.\n *\n * @example\n * ```ts\n * import { Effect } from \"effect\"\n * import { Parser, ParserStream, Text } from \"@thomasfosterau/effect-parse\"\n *\n * const csvLine = Parser.separated(Text.utf8.takeTill(\",\\n\"), Text.utf8.literal(\",\"))\n * const csv = Parser.separated(csvLine, Text.utf8.literal(\"\\n\"))\n *\n * const response = await fetch(\"https://example.com/data.csv\")\n * const rows = await Effect.runPromise(ParserStream.parseReadable(response.body!, csv))\n * ```\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseReadable: {\n <A, E, R>(\n parser: Parser<A, E, R, Uint8Array>\n ): (self: ReadableStream<BinaryInput>) => Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n <A, E, R>(\n self: ReadableStream<BinaryInput>,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R>(\n self: ReadableStream<BinaryInput>,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R> =>\n parseAll(\n Stream.fromReadableStream({ evaluate: () => self, onError: (cause) => new ReadError({ cause }) }),\n parser,\n { empty: new Uint8Array(0) }\n )\n)\n\n/**\n * Parses the body of a `fetch` `Response` incrementally, as it downloads\n * (see {@link parseReadable}). A response without a body is parsed as empty\n * input. The status is not checked.\n *\n * @example\n * ```ts\n * import { Effect } from \"effect\"\n * import { Parser, ParserStream, Text } from \"@thomasfosterau/effect-parse\"\n *\n * const lines = Parser.separated(Text.utf8.tillLineEnding, Text.utf8.lineEnding)\n *\n * const response = await fetch(\"https://example.com/log.txt\")\n * const value = await Effect.runPromise(ParserStream.parseResponse(response, lines))\n * ```\n *\n * @since 0.1.0\n * @category combinators\n */\nexport const parseResponse: {\n <A, E, R>(\n parser: Parser<A, E, R, Uint8Array>\n ): (self: Response) => Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n <A, E, R>(\n self: Response,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R>(\n self: Response,\n parser: Parser<A, E, R, Uint8Array>\n ): Effect.Effect<A, ParseError.ParseError<E> | ReadError, R> =>\n parseReadable(self.body ?? new ReadableStream<Uint8Array>({ start: (c) => c.close() }), parser)\n)\n"],"mappings":"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"}
|
package/dist/Syntax.d.ts
CHANGED
|
@@ -4,7 +4,6 @@ import * as Option from "effect/Option";
|
|
|
4
4
|
import * as Context from "effect/Context";
|
|
5
5
|
import * as ParseError from "./ParseError.js";
|
|
6
6
|
import { ErrorInfo, Green } from "./internal/syntax.js";
|
|
7
|
-
//#region src/Syntax.d.ts
|
|
8
7
|
/**
|
|
9
8
|
* Marks a parser as a rule of the syntax tree: in a {@link parse}, each
|
|
10
9
|
* match becomes a named node of the given kind, spanning the input it
|
|
@@ -396,6 +395,5 @@ export declare const replace: <A, E>(tree: Tree<A, E, string>, start: number, en
|
|
|
396
395
|
* @category parsing
|
|
397
396
|
*/
|
|
398
397
|
export declare const diff: <I extends Input>(before: I, after: I) => Edit | undefined;
|
|
399
|
-
//#endregion
|
|
400
398
|
export {};
|
|
401
399
|
//# sourceMappingURL=Syntax.d.ts.map
|
package/dist/Syntax.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Syntax.d.ts","names":[],"sources":["../src/Syntax.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Syntax.d.ts","names":[],"sources":["../src/Syntax.ts"],"mappings":"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"}
|
package/dist/Syntax.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as Predicate from "effect/Predicate";
|
|
2
|
-
import { Fail, fromSource } from "./Input.js";
|
|
2
|
+
import { Fail, State, fromSource } from "./Input.js";
|
|
3
3
|
import { described, isParser } from "./Parser.js";
|
|
4
|
+
import { Key } from "./internal/key.js";
|
|
4
5
|
import * as Option from "effect/Option";
|
|
5
6
|
import { dual } from "effect/Function";
|
|
6
7
|
import * as ParseError from "./ParseError.js";
|
|
7
8
|
import * as Stack from "./internal/stack.js";
|
|
8
9
|
import { nodeOf } from "./internal/node.js";
|
|
9
|
-
import
|
|
10
|
-
|
|
10
|
+
import * as Str from "effect/String";
|
|
11
|
+
import { SyntaxBuilder, absolute, errorKind } from "./internal/syntax.js";
|
|
12
|
+
// src/Syntax.ts
|
|
11
13
|
/**
|
|
12
14
|
* Concrete syntax trees and incremental parsing, in the spirit of
|
|
13
15
|
* [Tree-sitter](https://tree-sitter.github.io).
|
|
@@ -58,7 +60,7 @@ import { SyntaxState, absolute, errorKind } from "./internal/syntax.js";
|
|
|
58
60
|
*/
|
|
59
61
|
const syntaxNode = (self, kind, named) => {
|
|
60
62
|
const step = self.step;
|
|
61
|
-
const key =
|
|
63
|
+
const key = new Key();
|
|
62
64
|
return described((state) => {
|
|
63
65
|
const builder = state.syntax;
|
|
64
66
|
return builder === void 0 ? step(state) : builder.node(state, step, key, kind, named);
|
|
@@ -108,7 +110,7 @@ const node = /*#__PURE__*/ dual(2, (self, kind) => syntaxNode(self, kind, true))
|
|
|
108
110
|
const token = /*#__PURE__*/ dual((args) => isParser(args[0]), (self, kind) => syntaxNode(self, kind ?? defaultTokenKind(self), false));
|
|
109
111
|
const defaultTokenKind = (self) => {
|
|
110
112
|
const n = nodeOf(self);
|
|
111
|
-
if (n
|
|
113
|
+
if (Predicate.isTagged(n, "Literal") && Predicate.isString(n.literal) && !n.caseless) return n.literal;
|
|
112
114
|
return self.name ?? "token";
|
|
113
115
|
};
|
|
114
116
|
/**
|
|
@@ -439,7 +441,7 @@ var SyntaxNode = class SyntaxNode {
|
|
|
439
441
|
let out = "";
|
|
440
442
|
const visit = (green, field) => {
|
|
441
443
|
if (green.named || green === this.green) {
|
|
442
|
-
if (out
|
|
444
|
+
if (Str.isNonEmpty(out)) out += " ";
|
|
443
445
|
if (field !== void 0) out += `${field}: `;
|
|
444
446
|
out += `(${green.kind}`;
|
|
445
447
|
for (let i = 0; i < green.children.length; i++) visit(green.children[i], green.fields?.[i]);
|
|
@@ -548,7 +550,8 @@ var TreeCursor = class {
|
|
|
548
550
|
};
|
|
549
551
|
const expectedEof = ["end of input"];
|
|
550
552
|
const run = (config, input, previous) => {
|
|
551
|
-
const state = new
|
|
553
|
+
const state = new State(input, { context: config.context });
|
|
554
|
+
const builder = new SyntaxBuilder(state, previous);
|
|
552
555
|
const a = Stack.run(config.inner.step, state);
|
|
553
556
|
if (state.encoding === void 0 && previous !== void 0) state.encoding = previous.encoding;
|
|
554
557
|
let fatal;
|
|
@@ -564,8 +567,8 @@ const run = (config, input, previous) => {
|
|
|
564
567
|
mode: "Backtrack"
|
|
565
568
|
};
|
|
566
569
|
} else value = Option.some(a);
|
|
567
|
-
const green =
|
|
568
|
-
return new Tree(input, value,
|
|
570
|
+
const green = builder.finish(config.kind, Option.getOrUndefined(value), fatal, state.pos);
|
|
571
|
+
return new Tree(input, value, builder.reused, green, config, state.encoding);
|
|
569
572
|
};
|
|
570
573
|
/**
|
|
571
574
|
* Parses an input into a syntax {@link Tree}. The grammar's output is the
|
|
@@ -582,7 +585,7 @@ const run = (config, input, previous) => {
|
|
|
582
585
|
*/
|
|
583
586
|
const parse = (grammar, input, options) => {
|
|
584
587
|
const n = nodeOf(grammar);
|
|
585
|
-
const isRoot = n
|
|
588
|
+
const isRoot = Predicate.isTagged(n, "Syntax") && n.kind !== void 0 && n.named;
|
|
586
589
|
const config = {
|
|
587
590
|
kind: isRoot ? n.kind : options?.kind ?? "document",
|
|
588
591
|
inner: isRoot ? n.self : grammar,
|
|
@@ -711,7 +714,6 @@ const segmentsOf = (oldLength, newLength, edits) => {
|
|
|
711
714
|
if (length !== newLength) throw new RangeError(`the edits give an input of length ${length}, but the new input has length ${newLength}`);
|
|
712
715
|
return segments;
|
|
713
716
|
};
|
|
714
|
-
//#endregion
|
|
715
717
|
export { ERROR, SyntaxNode, Tree, TreeCursor, diff, field, node, parse, reparse, replace, token };
|
|
716
718
|
|
|
717
719
|
//# sourceMappingURL=Syntax.js.map
|
package/dist/Syntax.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Syntax.js","names":[],"sources":["../src/Syntax.ts"],"sourcesContent":["/**\n * Concrete syntax trees and incremental parsing, in the spirit of\n * [Tree-sitter](https://tree-sitter.github.io).\n *\n * Mark the rules of a grammar that should appear in the tree with\n * {@link node} (and, optionally, {@link token} and {@link field}). Outside\n * this module the marks change nothing: `Parser.parse` returns the same\n * values, and compiled parsers compile them away. {@link parse} runs the\n * grammar and returns a {@link Tree}: a tree of {@link SyntaxNode}s with\n * spans, parents and siblings, to search by position (`descendantAt`) or walk\n * with a {@link TreeCursor}. Each node also carries the value its parser\n * returned.\n *\n * Like Tree-sitter, a syntax parse always produces a tree. Failures handled\n * by `Parser.resumeAfter` and `Parser.retryAfter` become `ERROR` nodes over\n * the input they skipped, and so does any input after a fatal failure.\n *\n * After an edit, {@link reparse} (or {@link replace}) parses the new input\n * reusing every node of the old tree whose input is unchanged: only the\n * nodes that enclose the edit, or looked at the edited input, are parsed\n * again, and each reused node is stepped over whole.\n *\n * @example\n * ```ts\n * import { Ascii, Parser, Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const ws = Ascii.multispace0\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const list = Syntax.node(\n * Parser.delimited(\n * Token.literal(\"[\"),\n * Parser.separated(Parser.delimited(ws, number, ws), Token.literal(\",\")),\n * Token.literal(\"]\")\n * ),\n * \"list\"\n * )\n *\n * const tree = Syntax.parse(list, \"[1, 2, 3]\")\n * String(tree.root) // \"(list (number) (number) (number))\"\n * tree.root.descendantAt(4)?.text // \"2\"\n *\n * const edited = Syntax.replace(tree, 4, 5, \"20\") // \"[1, 20, 3]\"\n * edited.root.namedChild(1)?.value // 20\n * edited.reused // 2: only \"20\" was parsed again\n * ```\n *\n * @since 0.2.0\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Context from \"effect/Context\"\nimport { dual } from \"effect/Function\"\nimport * as Option from \"effect/Option\"\nimport type { Input, Slice, Source } from \"./Input.js\"\nimport { Fail, fromSource } from \"./Input.js\"\nimport * as ParseError from \"./ParseError.js\"\nimport { nodeOf } from \"./internal/node.js\"\nimport * as Stack from \"./internal/stack.js\"\nimport type { ErrorInfo, Green, Previous, Segment } from \"./internal/syntax.js\"\nimport { absolute, errorKind, SyntaxState } from \"./internal/syntax.js\"\nimport type { Parser } from \"./Parser.js\"\nimport { described, isParser } from \"./Parser.js\"\n\n// -----------------------------------------------------------------------------\n// Grammar annotations\n// -----------------------------------------------------------------------------\n\nconst syntaxNode = (self: Parser.Any, kind: string, named: boolean): Parser.Any => {\n const step = self.step\n // Identifies the nodes this parser builds, so a reparse can reuse them\n const key = {}\n return described<unknown, unknown, unknown, Input>(\n (state) => {\n const builder = state.syntax\n return builder === undefined ? step(state) : builder.node(state, step, key, kind, named)\n },\n self.name,\n { _tag: \"Syntax\", self, kind, named }\n )\n}\n\n/**\n * Marks a parser as a rule of the syntax tree: in a {@link parse}, each\n * match becomes a named node of the given kind, spanning the input it\n * consumed, with the nodes built inside it as children and its output as\n * its `value`. Outside {@link parse}, the parser is unchanged.\n *\n * A match that consumes nothing adds no node (as in Tree-sitter, where rules\n * can't match the empty string).\n *\n * For {@link reparse} to reuse a node, its parser's output must depend only\n * on the input from where the node starts: not on services, on state kept\n * in closures, or on absolute offsets (`Parser.location`, `Parser.span`),\n * which are not updated when the node moves. Use the node's `start` and\n * `end` instead.\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const node: {\n (kind: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind: string): Parser<A, E, R, I> =>\n syntaxNode(self, kind, true) as Parser<A, E, R, I>\n)\n\n/**\n * Like {@link node}, but builds an *anonymous* node, Tree-sitter's name for\n * punctuation and keywords: anonymous nodes are left out of\n * `namedChildren` and of the tree's printed form. The kind defaults to the\n * literal for a `Token.literal` of a string, and to the parser's name\n * otherwise.\n *\n * @example\n * ```ts\n * import { Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const comma = Syntax.token(Token.literal(\",\")) // kind \",\"\n * ```\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const token: {\n (kind?: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind?: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(\n (args) => isParser(args[0]),\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind?: string): Parser<A, E, R, I> =>\n syntaxNode(self, kind ?? defaultTokenKind(self), false) as Parser<A, E, R, I>\n)\n\nconst defaultTokenKind = (self: Parser.Any): string => {\n const n = nodeOf(self)\n if (n._tag === \"Literal\" && Predicate.isString(n.literal) && !n.caseless) return n.literal\n return self.name ?? \"token\"\n}\n\n/**\n * Gives the nodes built by a parser a field name in their parent, like\n * Tree-sitter's `field(name, rule)`: find them with `childByField` and\n * `childrenByField`. Outside {@link parse}, the parser is unchanged.\n *\n * @example\n * ```ts\n * import { Ascii, Parser, Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const name = Syntax.node(Ascii.alpha1, \"name\")\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const pair = Syntax.node(\n * Parser.separatedPair(Syntax.field(name, \"key\"), Token.literal(\"=\"), Syntax.field(number, \"value\")),\n * \"pair\"\n * )\n * Syntax.parse(pair, \"x=1\").root.childByField(\"value\")?.value // 1\n * ```\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const field: {\n (name: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, name: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(2, <A, E, R, I extends Input>(self: Parser<A, E, R, I>, name: string): Parser<A, E, R, I> => {\n const step = self.step\n return described<A, E, R, I>(\n (state) => {\n const builder = state.syntax\n return (builder === undefined ? step(state) : builder.field(state, step, name)) as A | typeof Fail\n },\n self.name,\n { _tag: \"Syntax\", self, kind: undefined, named: false }\n )\n})\n\n// -----------------------------------------------------------------------------\n// Trees\n// -----------------------------------------------------------------------------\n\n/**\n * The kind of the nodes that stand for input that could not be parsed.\n *\n * @since 0.2.0\n * @category models\n */\nexport const ERROR: \"ERROR\" = errorKind\n\n/**\n * An edit to an input, as Tree-sitter's `TSInputEdit`: the input\n * `[start, oldEnd)` was replaced by `[start, newEnd)`. Offsets are in the\n * input's units (UTF-16 code units for strings, bytes, elements).\n *\n * @since 0.2.0\n * @category models\n */\nexport interface Edit {\n readonly start: number\n readonly oldEnd: number\n readonly newEnd: number\n}\n\n/**\n * Options for {@link parse}.\n *\n * @since 0.2.0\n * @category models\n */\nexport interface ParseOptions {\n /**\n * The kind of the root node, when the grammar itself is not a\n * {@link node}. Defaults to `\"document\"`.\n */\n readonly kind?: string | undefined\n /**\n * For {@link reparse}: how many input units custom parsers may read past\n * the furthest position they move the cursor to or record a failure at,\n * besides one token there. Defaults to 0, which is right for the built-in\n * parsers, and for custom parsers (`Parser.make`) that only read past\n * where they stop to see that the token there doesn't match.\n *\n * A node is reused only when the input its parse looked at is unchanged.\n * Built-in parsers that read further, such as a literal that fails part\n * way or `Token.takeUntil`, record how far they read.\n */\n readonly lookahead?: number | undefined\n}\n\n/**\n * Options for {@link parse} with a parser that requires services.\n *\n * @since 0.2.0\n * @category models\n */\nexport interface ParseOptionsWithContext<R> extends ParseOptions {\n readonly context: Context.Context<R>\n}\n\ninterface Config {\n readonly kind: string\n readonly inner: Parser.Any\n readonly lookahead: number\n readonly context: Context.Context<never> | undefined\n}\n\n/**\n * The result of a {@link parse}: a syntax tree over the whole input, the\n * grammar's output, and the errors met on the way.\n *\n * @since 0.2.0\n * @category models\n */\nexport class Tree<out A, out E = never, I extends Input = string> {\n /** The root node. It always spans the whole input. */\n readonly root: SyntaxNode<I>\n private lines: Array<number> | undefined\n private errorList: ReadonlyArray<ParseError.ParseError<E>> | undefined\n\n /** @internal */\n constructor(\n /** The input the tree was parsed from. */\n readonly input: I,\n /** The grammar's output: `none` when the parse failed. */\n readonly value: Option.Option<A>,\n /** How many nodes were reused from the previous tree by {@link reparse}. */\n readonly reused: number,\n /** @internal */\n readonly green: Green,\n /** @internal */\n readonly config: Config,\n /** @internal */\n readonly encoding: ParseError.ParseError<never>[\"encoding\"]\n ) {\n this.root = new SyntaxNode(this, green, 0, undefined, 0)\n }\n\n /**\n * Every error of the parse, in input order: the failures recovered by\n * `Parser.resumeAfter` and `Parser.retryAfter`, then the fatal one, if\n * the parse failed. Each one belongs to an `ERROR` node.\n */\n get errors(): ReadonlyArray<ParseError.ParseError<E>> {\n if (this.errorList === undefined) {\n const out: Array<ParseError.ParseError<E>> = []\n const visit = (green: Green, start: number) => {\n if (!green.hasError) return\n if (green.error !== undefined) out.push(this.toError(green.error, start))\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], start + green.offsets[i])\n }\n visit(this.green, 0)\n this.errorList = out\n }\n return this.errorList\n }\n\n /** Whether the tree has any `ERROR` node. */\n get hasErrors(): boolean {\n return this.green.hasError\n }\n\n /** The smallest node containing `[start, end)` (see {@link SyntaxNode.descendantAt}). */\n descendantAt(start: number, end?: number): SyntaxNode<I> {\n return this.root.descendantAt(start, end)\n }\n\n /** A cursor at the root. */\n walk(): TreeCursor<I> {\n return new TreeCursor(this.root)\n }\n\n /**\n * The 1-based line and column (in code points) of an offset, as in\n * `ParseError`. Lines of a string input are indexed once, so lookups take\n * logarithmic time.\n */\n lineColumn(offset: number): ParseError.LineColumn {\n const input = this.input\n if (!Predicate.isString(input)) return ParseError.lineColumn(input, offset, this.encoding)\n let lines = this.lines\n if (lines === undefined) {\n lines = [0]\n for (let i = input.indexOf(\"\\n\"); i >= 0; i = input.indexOf(\"\\n\", i + 1)) lines.push(i + 1)\n this.lines = lines\n }\n const at = Math.max(0, Math.min(offset, input.length))\n let lo = 0\n let hi = lines.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (lines[mid] <= at) lo = mid\n else hi = mid - 1\n }\n const lineStart = lines[lo]\n return { line: lo + 1, column: ParseError.lineColumn(input.slice(lineStart, at), at - lineStart).column }\n }\n\n /** The root's S-expression (see {@link SyntaxNode.toString}). */\n toString(): string {\n return this.root.toString()\n }\n\n /** @internal */\n toError(error: ErrorInfo, start: number): ParseError.ParseError<E> {\n return ParseError.fromFailure<E>(this.input, absolute(error.failure, start), error.mode, this.encoding)\n }\n}\n\n/**\n * A node of a syntax tree: its kind, span and value, and its place in the\n * tree. Nodes are views built on demand; two views of the same node are\n * different objects but have the same `start`, `end` and `kind`.\n *\n * @since 0.2.0\n * @category models\n */\nexport class SyntaxNode<I extends Input = string> {\n private childList: ReadonlyArray<SyntaxNode<I>> | undefined\n\n /** @internal */\n constructor(\n /** The tree this node belongs to. */\n readonly tree: Tree<unknown, unknown, I>,\n /** @internal */\n readonly green: Green,\n /** The offset where the node starts. */\n readonly start: number,\n /** The parent node; `undefined` for the root. */\n readonly parent: SyntaxNode<I> | undefined,\n /** The node's index among its parent's children. */\n readonly index: number\n ) {}\n\n /** The node's kind: the name given to {@link node} or {@link token}, or `\"ERROR\"`. */\n get kind(): string {\n return this.green.kind\n }\n\n /** `false` for the anonymous nodes built by {@link token}. */\n get named(): boolean {\n return this.green.named\n }\n\n /** The field name given by {@link field}, if any. */\n get field(): string | undefined {\n return this.parent?.green.fields?.[this.index]\n }\n\n /** The offset where the node ends (exclusive). */\n get end(): number {\n return this.start + this.green.width\n }\n\n /** The number of input units the node spans. */\n get length(): number {\n return this.green.width\n }\n\n /** The output of the node's parser (`undefined` for `ERROR` nodes, and for a root that failed). */\n get value(): unknown {\n return this.green.value\n }\n\n /** The input the node spans. */\n get text(): Slice<I> {\n const input = this.tree.input as any\n return input instanceof Uint8Array\n ? (input.subarray(this.start, this.end) as any)\n : input.slice(this.start, this.end)\n }\n\n /** Whether this is an `ERROR` node. */\n get isError(): boolean {\n return this.green.error !== undefined\n }\n\n /** Whether this node or a descendant is an `ERROR` node. */\n get hasError(): boolean {\n return this.green.hasError\n }\n\n /** For an `ERROR` node, the error it stands for. */\n get error(): ParseError.ParseError<unknown> | undefined {\n const error = this.green.error\n return error === undefined ? undefined : this.tree.toError(error, this.start)\n }\n\n /** The child nodes, named and anonymous, in input order. */\n get children(): ReadonlyArray<SyntaxNode<I>> {\n if (this.childList === undefined) {\n const green = this.green\n const out = new Array<SyntaxNode<I>>(green.children.length)\n for (let i = 0; i < out.length; i++) out[i] = this.makeChild(i)\n this.childList = out\n }\n return this.childList\n }\n\n /** The number of children. */\n get childCount(): number {\n return this.green.children.length\n }\n\n /** The child at `index` (negative indices count from the end). */\n child(index: number): SyntaxNode<I> | undefined {\n const n = this.green.children.length\n const i = index < 0 ? n + index : index\n return i >= 0 && i < n ? this.children[i] : undefined\n }\n\n /** The named children. */\n get namedChildren(): ReadonlyArray<SyntaxNode<I>> {\n return this.children.filter((c) => c.named)\n }\n\n /** The named child at `index`. */\n namedChild(index: number): SyntaxNode<I> | undefined {\n return this.namedChildren[index]\n }\n\n /** The first child with the given field name. */\n childByField(name: string): SyntaxNode<I> | undefined {\n const fields = this.green.fields\n if (fields === undefined) return undefined\n const i = fields.indexOf(name)\n return i < 0 ? undefined : this.children[i]\n }\n\n /** The children with the given field name. */\n childrenByField(name: string): ReadonlyArray<SyntaxNode<I>> {\n const fields = this.green.fields\n if (fields === undefined) return []\n return this.children.filter((_, i) => fields[i] === name)\n }\n\n /** The next sibling, named or anonymous. */\n get nextSibling(): SyntaxNode<I> | undefined {\n return this.parent?.children[this.index + 1]\n }\n\n /** The previous sibling, named or anonymous. */\n get previousSibling(): SyntaxNode<I> | undefined {\n return this.index > 0 ? this.parent?.children[this.index - 1] : undefined\n }\n\n /** The next named sibling. */\n get nextNamedSibling(): SyntaxNode<I> | undefined {\n const siblings = this.parent?.children\n if (siblings === undefined) return undefined\n for (let i = this.index + 1; i < siblings.length; i++) if (siblings[i].named) return siblings[i]\n return undefined\n }\n\n /** The previous named sibling. */\n get previousNamedSibling(): SyntaxNode<I> | undefined {\n const siblings = this.parent?.children\n if (siblings === undefined) return undefined\n for (let i = this.index - 1; i >= 0; i--) if (siblings[i].named) return siblings[i]\n return undefined\n }\n\n /**\n * The index of the child containing the input unit at `offset`, or -1.\n * Takes logarithmic time.\n */\n childIndexAt(offset: number): number {\n const green = this.green\n const offsets = green.offsets\n const rel = offset - this.start\n let lo = 0\n let hi = offsets.length - 1\n let found = -1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n if (offsets[mid] <= rel) {\n found = mid\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n // Skip back over empty `ERROR` nodes at `offset`\n while (found >= 0 && green.children[found].width === 0 && offsets[found] === rel) found--\n return found >= 0 && rel < offsets[found] + green.children[found].width ? found : -1\n }\n\n /** The child containing the input unit at `offset`. */\n childAt(offset: number): SyntaxNode<I> | undefined {\n const i = this.childIndexAt(offset)\n return i < 0 ? undefined : this.children[i]\n }\n\n /**\n * The smallest node, this one or a descendant, that contains\n * `[start, end)` (Tree-sitter's `descendant_for_byte_range`). With only\n * `start`, the deepest node containing the input unit at `start`. Takes\n * time proportional to the depth of the tree times the logarithm of the\n * number of children.\n */\n descendantAt(start: number, end: number = start + 1): SyntaxNode<I> {\n return descendantOf(this, start, end)\n }\n\n /** Like {@link descendantAt}, but only stops at named nodes. */\n namedDescendantAt(start: number, end: number = start + 1): SyntaxNode<I> {\n let node: SyntaxNode<I> = this.descendantAt(start, end)\n // Every node below `this` has a parent, so the walk stops at `this` at the latest\n while (!node.named && node !== this) node = node.parent ?? this\n return node\n }\n\n /** This node and its descendants, in pre-order. */\n *descendants(): Generator<SyntaxNode<I>, void, undefined> {\n const cursor = this.walk()\n while (true) {\n yield cursor.node\n if (cursor.gotoFirstChild()) continue\n while (!cursor.gotoNextSibling()) {\n if (!cursor.gotoParent()) return\n }\n }\n }\n\n /** The descendants of the given kind, in pre-order. */\n *descendantsOfKind(kind: string): Generator<SyntaxNode<I>, void, undefined> {\n for (const n of this.descendants()) if (n.kind === kind) yield n\n }\n\n /** A cursor at this node, which cannot move above it. */\n walk(): TreeCursor<I> {\n return new TreeCursor(this)\n }\n\n /**\n * The node as an S-expression of its named descendants, with field\n * names, as Tree-sitter prints it: `(pair key: (name) value: (number))`.\n */\n toString(): string {\n let out = \"\"\n const visit = (green: Green, field: string | undefined) => {\n if (green.named || green === this.green) {\n if (out.length > 0) out += \" \"\n if (field !== undefined) out += `${field}: `\n out += `(${green.kind}`\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], green.fields?.[i])\n out += \")\"\n } else {\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], green.fields?.[i])\n }\n }\n visit(this.green, this.field)\n return out\n }\n\n toJSON(): unknown {\n return { kind: this.kind, start: this.start, end: this.end }\n }\n\n private makeChild(i: number): SyntaxNode<I> {\n const green = this.green\n return new SyntaxNode(this.tree, green.children[i], this.start + green.offsets[i], this, i)\n }\n}\n\n/** The smallest node, `root` or a descendant, that contains `[start, end)` (see `SyntaxNode.descendantAt`). */\nconst descendantOf = <I extends Input>(root: SyntaxNode<I>, start: number, end: number): SyntaxNode<I> => {\n let node = root\n while (true) {\n const i = node.childIndexAt(start)\n if (i < 0) return node\n const child = node.children[i]\n if (end > child.end) return node\n node = child\n }\n}\n\n/**\n * A cursor for walking a tree, as Tree-sitter's `TreeCursor`. It starts at\n * a node and cannot move above it.\n *\n * @since 0.2.0\n * @category models\n */\nexport class TreeCursor<I extends Input = string> {\n private current: SyntaxNode<I>\n private depth = 0\n\n /** @internal */\n constructor(node: SyntaxNode<I>) {\n this.current = node\n }\n\n /** The node at the cursor. */\n get node(): SyntaxNode<I> {\n return this.current\n }\n\n /** The field name of the node at the cursor, if any. */\n get field(): string | undefined {\n return this.depth === 0 ? undefined : this.current.field\n }\n\n /** Moves to the first child; `false` if there is none. */\n gotoFirstChild(): boolean {\n return this.goto(this.current.child(0))\n }\n\n /** Moves to the last child; `false` if there is none. */\n gotoLastChild(): boolean {\n return this.goto(this.current.child(-1))\n }\n\n /** Moves to the child containing the input unit at `offset`; `false` if there is none. */\n gotoFirstChildForOffset(offset: number): boolean {\n return this.goto(this.current.childAt(offset))\n }\n\n /** Moves to the next sibling; `false` if there is none. */\n gotoNextSibling(): boolean {\n if (this.depth === 0) return false\n const next = this.current.nextSibling\n if (next === undefined) return false\n this.current = next\n return true\n }\n\n /** Moves to the previous sibling; `false` if there is none. */\n gotoPreviousSibling(): boolean {\n if (this.depth === 0) return false\n const previous = this.current.previousSibling\n if (previous === undefined) return false\n this.current = previous\n return true\n }\n\n /** Moves to the parent; `false` at the node the cursor started at. */\n gotoParent(): boolean {\n const parent = this.current.parent\n if (this.depth === 0 || parent === undefined) return false\n this.current = parent\n this.depth--\n return true\n }\n\n /** Moves to the deepest node containing the input unit at `offset`. */\n gotoDescendantAt(offset: number): void {\n while (this.gotoFirstChildForOffset(offset)) {\n // descend\n }\n }\n\n /** Starts again at `node`. */\n reset(node: SyntaxNode<I>): void {\n this.current = node\n this.depth = 0\n }\n\n private goto(node: SyntaxNode<I> | undefined): boolean {\n if (node === undefined) return false\n this.current = node\n this.depth++\n return true\n }\n}\n\n// -----------------------------------------------------------------------------\n// Parsing\n// -----------------------------------------------------------------------------\n\nconst expectedEof = [\"end of input\"]\n\nconst run = <A, E, I extends Input>(config: Config, input: I, previous: Previous | undefined): Tree<A, E, I> => {\n const state = new SyntaxState<I>(input, { context: config.context }, previous)\n const a = Stack.run(config.inner.step, state)\n // Text parsers record the encoding when they fail, which they may have done inside reused nodes\n if (state.encoding === undefined && previous !== undefined) state.encoding = previous.encoding\n let fatal: ErrorInfo | undefined\n let value: Option.Option<A> = Option.none()\n if (a === Fail) {\n fatal = { failure: state.reportedFailure(), mode: state.mode }\n } else if (state.pos < state.end) {\n state.backtrack(\"Eof\", expectedEof)\n fatal = { failure: state.reportedFailure(), mode: \"Backtrack\" }\n } else {\n value = Option.some(a as A)\n }\n const green = state.finish(config.kind, Option.getOrUndefined(value), fatal, state.pos)\n return new Tree<A, E, I>(input, value, state.reused, green, config, state.encoding)\n}\n\n/**\n * Parses an input into a syntax {@link Tree}. The grammar's output is the\n * tree's `value`, and its {@link node}s are the tree's nodes. When the\n * grammar is itself a {@link node}, that node is the root; otherwise the\n * root is a node of kind `options.kind` (by default `\"document\"`).\n *\n * The parse never fails: recovered failures (see `Parser.resumeAfter`), a\n * fatal failure and unparsed input at the end all become `ERROR` nodes, and\n * are listed in `tree.errors`. The parse is interpreted, never compiled.\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const parse: {\n <A, E, I extends Input>(\n grammar: Parser<A, E, never, I>,\n input: NoInfer<Source<I>>,\n options?: ParseOptions\n ): Tree<A, E, I>\n <A, E, R, I extends Input>(\n grammar: Parser<A, E, R, I>,\n input: NoInfer<Source<I>>,\n options: ParseOptionsWithContext<R>\n ): Tree<A, E, I>\n} = <A, E, R, I extends Input>(\n grammar: Parser<A, E, R, I>,\n input: I | Source<I>,\n options?: ParseOptions & { readonly context?: Context.Context<R> }\n): Tree<A, E, I> => {\n const n = nodeOf(grammar)\n const isRoot = n._tag === \"Syntax\" && n.kind !== undefined && n.named\n const config: Config = {\n kind: isRoot ? n.kind : (options?.kind ?? \"document\"),\n inner: isRoot ? (n.self as Parser.Any) : grammar,\n lookahead: options?.lookahead ?? 0,\n context: options?.context as Context.Context<never> | undefined\n }\n return run(config, fromSource(input as Input) as I, undefined)\n}\n\n/**\n * Parses the new version of a tree's input, reusing the nodes of the tree\n * that the edits leave unchanged (Tree-sitter's `ts_tree_edit` followed by\n * `ts_parser_parse` with the old tree). The result is the tree a fresh\n * {@link parse} of `input` would build, but only the parts of the tree\n * around the edits are parsed again. `tree.reused` says how many nodes were\n * reused.\n *\n * `edits` describe how the old input became the new one, applied in order,\n * each in the coordinates of the input as the previous edits left it. When\n * they are omitted, the edit is found by comparing the inputs (their common\n * prefix and suffix), which takes time linear in their length but much less\n * than parsing.\n *\n * Errors in the new tree are those a fresh parse reports, except that an\n * error just after a reused node may list fewer expected alternatives.\n *\n * @example\n * ```ts\n * import { Ascii, Syntax } from \"@thomasfosterau/effect-parse\"\n *\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const tree = Syntax.parse(number, \"12\")\n * Syntax.reparse(tree, \"123\", [{ start: 2, oldEnd: 2, newEnd: 3 }]).root.value // 123\n * ```\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const reparse = <A, E, I extends Input>(\n tree: Tree<A, E, I>,\n input: NoInfer<Source<I>>,\n edits?: Edit | ReadonlyArray<Edit>\n): Tree<A, E, I> => {\n const next = fromSource(input as Input) as I\n const list =\n edits === undefined\n ? diffList(tree.input, next)\n : \"start\" in edits\n ? [edits as Edit]\n : (edits as ReadonlyArray<Edit>)\n const previous: Previous = {\n root: tree.green,\n oldLength: tree.input.length,\n newLength: next.length,\n segments: segmentsOf(tree.input.length, next.length, list),\n input: tree.input,\n extra: tree.config.lookahead,\n encoding: tree.encoding\n }\n return run(tree.config, next, previous)\n}\n\n/**\n * Replaces `[start, end)` of a tree's string input with `text` and parses\n * the result incrementally (see {@link reparse}).\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const replace = <A, E>(\n tree: Tree<A, E, string>,\n start: number,\n end: number,\n text: string\n): Tree<A, E, string> => {\n const input = tree.input\n if (start < 0 || end < start || end > input.length) {\n throw new RangeError(`invalid range [${start}, ${end}) of an input of length ${input.length}`)\n }\n return reparse(tree, input.slice(0, start) + text + input.slice(end), {\n start,\n oldEnd: end,\n newEnd: start + text.length\n })\n}\n\n/**\n * Finds the edit that turns `before` into `after`: the part between their\n * longest common prefix and suffix. `undefined` when they are equal.\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const diff = <I extends Input>(before: I, after: I): Edit | undefined => {\n const a = before as any\n const b = after as any\n const at = Predicate.isString(a) ? (s: string, i: number) => s.charCodeAt(i) : (s: any, i: number) => s[i]\n const max = Math.min(a.length, b.length)\n let prefix = 0\n while (prefix < max && at(a, prefix) === at(b, prefix)) prefix++\n if (prefix === a.length && prefix === b.length) return undefined\n let suffix = 0\n while (suffix < max - prefix && at(a, a.length - 1 - suffix) === at(b, b.length - 1 - suffix)) suffix++\n return { start: prefix, oldEnd: a.length - suffix, newEnd: b.length - suffix }\n}\n\nconst diffList = (before: Input, after: Input): ReadonlyArray<Edit> => {\n const edit = diff(before, after)\n return edit === undefined ? [] : [edit]\n}\n\n/** The stretches of the new input copied unchanged from the old one. */\nconst segmentsOf = (oldLength: number, newLength: number, edits: ReadonlyArray<Edit>): Array<Segment> => {\n let segments: Array<Segment> = oldLength > 0 ? [{ newStart: 0, oldStart: 0, length: oldLength }] : []\n let length = oldLength\n for (const { newEnd, oldEnd, start } of edits) {\n if (!(start >= 0 && oldEnd >= start && oldEnd <= length && newEnd >= start)) {\n throw new RangeError(\n `invalid edit { start: ${start}, oldEnd: ${oldEnd}, newEnd: ${newEnd} } of an input of length ${length}`\n )\n }\n const delta = newEnd - oldEnd\n const out: Array<Segment> = []\n for (const s of segments) {\n const end = s.newStart + s.length\n if (s.newStart < start) {\n out.push({ newStart: s.newStart, oldStart: s.oldStart, length: Math.min(end, start) - s.newStart })\n }\n if (end > oldEnd) {\n const from = Math.max(s.newStart, oldEnd)\n out.push({ newStart: from + delta, oldStart: s.oldStart + (from - s.newStart), length: end - from })\n }\n }\n segments = out\n length += delta\n }\n if (length !== newLength) {\n throw new RangeError(`the edits give an input of length ${length}, but the new input has length ${newLength}`)\n }\n return segments\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Syntax.js","names":[],"sources":["../src/Syntax.ts"],"sourcesContent":["/**\n * Concrete syntax trees and incremental parsing, in the spirit of\n * [Tree-sitter](https://tree-sitter.github.io).\n *\n * Mark the rules of a grammar that should appear in the tree with\n * {@link node} (and, optionally, {@link token} and {@link field}). Outside\n * this module the marks change nothing: `Parser.parse` returns the same\n * values, and compiled parsers compile them away. {@link parse} runs the\n * grammar and returns a {@link Tree}: a tree of {@link SyntaxNode}s with\n * spans, parents and siblings, to search by position (`descendantAt`) or walk\n * with a {@link TreeCursor}. Each node also carries the value its parser\n * returned.\n *\n * Like Tree-sitter, a syntax parse always produces a tree. Failures handled\n * by `Parser.resumeAfter` and `Parser.retryAfter` become `ERROR` nodes over\n * the input they skipped, and so does any input after a fatal failure.\n *\n * After an edit, {@link reparse} (or {@link replace}) parses the new input\n * reusing every node of the old tree whose input is unchanged: only the\n * nodes that enclose the edit, or looked at the edited input, are parsed\n * again, and each reused node is stepped over whole.\n *\n * @example\n * ```ts\n * import { Ascii, Parser, Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const ws = Ascii.multispace0\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const list = Syntax.node(\n * Parser.delimited(\n * Token.literal(\"[\"),\n * Parser.separated(Parser.delimited(ws, number, ws), Token.literal(\",\")),\n * Token.literal(\"]\")\n * ),\n * \"list\"\n * )\n *\n * const tree = Syntax.parse(list, \"[1, 2, 3]\")\n * String(tree.root) // \"(list (number) (number) (number))\"\n * tree.root.descendantAt(4)?.text // \"2\"\n *\n * const edited = Syntax.replace(tree, 4, 5, \"20\") // \"[1, 20, 3]\"\n * edited.root.namedChild(1)?.value // 20\n * edited.reused // 2: only \"20\" was parsed again\n * ```\n *\n * @since 0.2.0\n */\nimport * as Str from \"effect/String\"\nimport * as Predicate from \"effect/Predicate\"\nimport type * as Context from \"effect/Context\"\nimport { dual } from \"effect/Function\"\nimport * as Option from \"effect/Option\"\nimport type { Input, Slice, Source } from \"./Input.js\"\nimport { Fail, fromSource, State } from \"./Input.js\"\nimport * as ParseError from \"./ParseError.js\"\nimport { nodeOf } from \"./internal/node.js\"\nimport { Key } from \"./internal/key.js\"\nimport * as Stack from \"./internal/stack.js\"\nimport type { ErrorInfo, Green, Previous, Segment } from \"./internal/syntax.js\"\nimport { absolute, errorKind, SyntaxBuilder } from \"./internal/syntax.js\"\nimport type { Parser } from \"./Parser.js\"\nimport { described, isParser } from \"./Parser.js\"\n\n// -----------------------------------------------------------------------------\n// Grammar annotations\n// -----------------------------------------------------------------------------\n\nconst syntaxNode = (self: Parser.Any, kind: string, named: boolean): Parser.Any => {\n const step = self.step\n // Identifies the nodes this parser builds, so a reparse can reuse them\n const key = new Key()\n return described<unknown, unknown, unknown, Input>(\n (state) => {\n const builder = state.syntax\n return builder === undefined ? step(state) : builder.node(state, step, key, kind, named)\n },\n self.name,\n { _tag: \"Syntax\", self, kind, named }\n )\n}\n\n/**\n * Marks a parser as a rule of the syntax tree: in a {@link parse}, each\n * match becomes a named node of the given kind, spanning the input it\n * consumed, with the nodes built inside it as children and its output as\n * its `value`. Outside {@link parse}, the parser is unchanged.\n *\n * A match that consumes nothing adds no node (as in Tree-sitter, where rules\n * can't match the empty string).\n *\n * For {@link reparse} to reuse a node, its parser's output must depend only\n * on the input from where the node starts: not on services, on state kept\n * in closures, or on absolute offsets (`Parser.location`, `Parser.span`),\n * which are not updated when the node moves. Use the node's `start` and\n * `end` instead.\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const node: {\n (kind: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(\n 2,\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind: string): Parser<A, E, R, I> =>\n syntaxNode(self, kind, true) as Parser<A, E, R, I>\n)\n\n/**\n * Like {@link node}, but builds an *anonymous* node, Tree-sitter's name for\n * punctuation and keywords: anonymous nodes are left out of\n * `namedChildren` and of the tree's printed form. The kind defaults to the\n * literal for a `Token.literal` of a string, and to the parser's name\n * otherwise.\n *\n * @example\n * ```ts\n * import { Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const comma = Syntax.token(Token.literal(\",\")) // kind \",\"\n * ```\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const token: {\n (kind?: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind?: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(\n (args) => isParser(args[0]),\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, kind?: string): Parser<A, E, R, I> =>\n syntaxNode(self, kind ?? defaultTokenKind(self), false) as Parser<A, E, R, I>\n)\n\nconst defaultTokenKind = (self: Parser.Any): string => {\n const n = nodeOf(self)\n if (Predicate.isTagged(n, \"Literal\") && Predicate.isString(n.literal) && !n.caseless) return n.literal\n return self.name ?? \"token\"\n}\n\n/**\n * Gives the nodes built by a parser a field name in their parent, like\n * Tree-sitter's `field(name, rule)`: find them with `childByField` and\n * `childrenByField`. Outside {@link parse}, the parser is unchanged.\n *\n * @example\n * ```ts\n * import { Ascii, Parser, Syntax, Token } from \"@thomasfosterau/effect-parse\"\n *\n * const name = Syntax.node(Ascii.alpha1, \"name\")\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const pair = Syntax.node(\n * Parser.separatedPair(Syntax.field(name, \"key\"), Token.literal(\"=\"), Syntax.field(number, \"value\")),\n * \"pair\"\n * )\n * Syntax.parse(pair, \"x=1\").root.childByField(\"value\")?.value // 1\n * ```\n *\n * @since 0.2.0\n * @category annotations\n */\nexport const field: {\n (name: string): <A, E, R, I extends Input>(self: Parser<A, E, R, I>) => Parser<A, E, R, I>\n <A, E, R, I extends Input>(self: Parser<A, E, R, I>, name: string): Parser<A, E, R, I>\n} = /*#__PURE__*/ dual(2, <A, E, R, I extends Input>(self: Parser<A, E, R, I>, name: string): Parser<A, E, R, I> => {\n const step = self.step\n return described<A, E, R, I>(\n (state) => {\n const builder = state.syntax\n return (builder === undefined ? step(state) : builder.field(state, step, name)) as A | typeof Fail\n },\n self.name,\n { _tag: \"Syntax\", self, kind: undefined, named: false }\n )\n})\n\n// -----------------------------------------------------------------------------\n// Trees\n// -----------------------------------------------------------------------------\n\n/**\n * The kind of the nodes that stand for input that could not be parsed.\n *\n * @since 0.2.0\n * @category models\n */\nexport const ERROR: \"ERROR\" = errorKind\n\n/**\n * An edit to an input, as Tree-sitter's `TSInputEdit`: the input\n * `[start, oldEnd)` was replaced by `[start, newEnd)`. Offsets are in the\n * input's units (UTF-16 code units for strings, bytes, elements).\n *\n * @since 0.2.0\n * @category models\n */\nexport interface Edit {\n readonly start: number\n readonly oldEnd: number\n readonly newEnd: number\n}\n\n/**\n * Options for {@link parse}.\n *\n * @since 0.2.0\n * @category models\n */\nexport interface ParseOptions {\n /**\n * The kind of the root node, when the grammar itself is not a\n * {@link node}. Defaults to `\"document\"`.\n */\n readonly kind?: string | undefined\n /**\n * For {@link reparse}: how many input units custom parsers may read past\n * the furthest position they move the cursor to or record a failure at,\n * besides one token there. Defaults to 0, which is right for the built-in\n * parsers, and for custom parsers (`Parser.make`) that only read past\n * where they stop to see that the token there doesn't match.\n *\n * A node is reused only when the input its parse looked at is unchanged.\n * Built-in parsers that read further, such as a literal that fails part\n * way or `Token.takeUntil`, record how far they read.\n */\n readonly lookahead?: number | undefined\n}\n\n/**\n * Options for {@link parse} with a parser that requires services.\n *\n * @since 0.2.0\n * @category models\n */\nexport interface ParseOptionsWithContext<R> extends ParseOptions {\n readonly context: Context.Context<R>\n}\n\ninterface Config {\n readonly kind: string\n readonly inner: Parser.Any\n readonly lookahead: number\n readonly context: Context.Context<never> | undefined\n}\n\n/**\n * The result of a {@link parse}: a syntax tree over the whole input, the\n * grammar's output, and the errors met on the way.\n *\n * @since 0.2.0\n * @category models\n */\nexport class Tree<out A, out E = never, I extends Input = string> {\n /** The root node. It always spans the whole input. */\n readonly root: SyntaxNode<I>\n private lines: Array<number> | undefined\n private errorList: ReadonlyArray<ParseError.ParseError<E>> | undefined\n\n /** @internal */\n constructor(\n /** The input the tree was parsed from. */\n readonly input: I,\n /** The grammar's output: `none` when the parse failed. */\n readonly value: Option.Option<A>,\n /** How many nodes were reused from the previous tree by {@link reparse}. */\n readonly reused: number,\n /** @internal */\n readonly green: Green,\n /** @internal */\n readonly config: Config,\n /** @internal */\n readonly encoding: ParseError.ParseError<never>[\"encoding\"]\n ) {\n this.root = new SyntaxNode(this, green, 0, undefined, 0)\n }\n\n /**\n * Every error of the parse, in input order: the failures recovered by\n * `Parser.resumeAfter` and `Parser.retryAfter`, then the fatal one, if\n * the parse failed. Each one belongs to an `ERROR` node.\n */\n get errors(): ReadonlyArray<ParseError.ParseError<E>> {\n if (this.errorList === undefined) {\n const out: Array<ParseError.ParseError<E>> = []\n const visit = (green: Green, start: number) => {\n if (!green.hasError) return\n if (green.error !== undefined) out.push(this.toError(green.error, start))\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], start + green.offsets[i])\n }\n visit(this.green, 0)\n this.errorList = out\n }\n return this.errorList\n }\n\n /** Whether the tree has any `ERROR` node. */\n get hasErrors(): boolean {\n return this.green.hasError\n }\n\n /** The smallest node containing `[start, end)` (see {@link SyntaxNode.descendantAt}). */\n descendantAt(start: number, end?: number): SyntaxNode<I> {\n return this.root.descendantAt(start, end)\n }\n\n /** A cursor at the root. */\n walk(): TreeCursor<I> {\n return new TreeCursor(this.root)\n }\n\n /**\n * The 1-based line and column (in code points) of an offset, as in\n * `ParseError`. Lines of a string input are indexed once, so lookups take\n * logarithmic time.\n */\n lineColumn(offset: number): ParseError.LineColumn {\n const input = this.input\n if (!Predicate.isString(input)) return ParseError.lineColumn(input, offset, this.encoding)\n let lines = this.lines\n if (lines === undefined) {\n lines = [0]\n for (let i = input.indexOf(\"\\n\"); i >= 0; i = input.indexOf(\"\\n\", i + 1)) lines.push(i + 1)\n this.lines = lines\n }\n const at = Math.max(0, Math.min(offset, input.length))\n let lo = 0\n let hi = lines.length - 1\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1\n if (lines[mid] <= at) lo = mid\n else hi = mid - 1\n }\n const lineStart = lines[lo]\n return { line: lo + 1, column: ParseError.lineColumn(input.slice(lineStart, at), at - lineStart).column }\n }\n\n /** The root's S-expression (see {@link SyntaxNode.toString}). */\n toString(): string {\n return this.root.toString()\n }\n\n /** @internal */\n toError(error: ErrorInfo, start: number): ParseError.ParseError<E> {\n return ParseError.fromFailure<E>(this.input, absolute(error.failure, start), error.mode, this.encoding)\n }\n}\n\n/**\n * A node of a syntax tree: its kind, span and value, and its place in the\n * tree. Nodes are views built on demand; two views of the same node are\n * different objects but have the same `start`, `end` and `kind`.\n *\n * @since 0.2.0\n * @category models\n */\nexport class SyntaxNode<I extends Input = string> {\n private childList: ReadonlyArray<SyntaxNode<I>> | undefined\n\n /** @internal */\n constructor(\n /** The tree this node belongs to. */\n readonly tree: Tree<unknown, unknown, I>,\n /** @internal */\n readonly green: Green,\n /** The offset where the node starts. */\n readonly start: number,\n /** The parent node; `undefined` for the root. */\n readonly parent: SyntaxNode<I> | undefined,\n /** The node's index among its parent's children. */\n readonly index: number\n ) {}\n\n /** The node's kind: the name given to {@link node} or {@link token}, or `\"ERROR\"`. */\n get kind(): string {\n return this.green.kind\n }\n\n /** `false` for the anonymous nodes built by {@link token}. */\n get named(): boolean {\n return this.green.named\n }\n\n /** The field name given by {@link field}, if any. */\n get field(): string | undefined {\n return this.parent?.green.fields?.[this.index]\n }\n\n /** The offset where the node ends (exclusive). */\n get end(): number {\n return this.start + this.green.width\n }\n\n /** The number of input units the node spans. */\n get length(): number {\n return this.green.width\n }\n\n /** The output of the node's parser (`undefined` for `ERROR` nodes, and for a root that failed). */\n get value(): unknown {\n return this.green.value\n }\n\n /** The input the node spans. */\n get text(): Slice<I> {\n const input = this.tree.input as any\n return input instanceof Uint8Array\n ? (input.subarray(this.start, this.end) as any)\n : input.slice(this.start, this.end)\n }\n\n /** Whether this is an `ERROR` node. */\n get isError(): boolean {\n return this.green.error !== undefined\n }\n\n /** Whether this node or a descendant is an `ERROR` node. */\n get hasError(): boolean {\n return this.green.hasError\n }\n\n /** For an `ERROR` node, the error it stands for. */\n get error(): ParseError.ParseError<unknown> | undefined {\n const error = this.green.error\n return error === undefined ? undefined : this.tree.toError(error, this.start)\n }\n\n /** The child nodes, named and anonymous, in input order. */\n get children(): ReadonlyArray<SyntaxNode<I>> {\n if (this.childList === undefined) {\n const green = this.green\n const out = new Array<SyntaxNode<I>>(green.children.length)\n for (let i = 0; i < out.length; i++) out[i] = this.makeChild(i)\n this.childList = out\n }\n return this.childList\n }\n\n /** The number of children. */\n get childCount(): number {\n return this.green.children.length\n }\n\n /** The child at `index` (negative indices count from the end). */\n child(index: number): SyntaxNode<I> | undefined {\n const n = this.green.children.length\n const i = index < 0 ? n + index : index\n return i >= 0 && i < n ? this.children[i] : undefined\n }\n\n /** The named children. */\n get namedChildren(): ReadonlyArray<SyntaxNode<I>> {\n return this.children.filter((c) => c.named)\n }\n\n /** The named child at `index`. */\n namedChild(index: number): SyntaxNode<I> | undefined {\n return this.namedChildren[index]\n }\n\n /** The first child with the given field name. */\n childByField(name: string): SyntaxNode<I> | undefined {\n const fields = this.green.fields\n if (fields === undefined) return undefined\n const i = fields.indexOf(name)\n return i < 0 ? undefined : this.children[i]\n }\n\n /** The children with the given field name. */\n childrenByField(name: string): ReadonlyArray<SyntaxNode<I>> {\n const fields = this.green.fields\n if (fields === undefined) return []\n return this.children.filter((_, i) => fields[i] === name)\n }\n\n /** The next sibling, named or anonymous. */\n get nextSibling(): SyntaxNode<I> | undefined {\n return this.parent?.children[this.index + 1]\n }\n\n /** The previous sibling, named or anonymous. */\n get previousSibling(): SyntaxNode<I> | undefined {\n return this.index > 0 ? this.parent?.children[this.index - 1] : undefined\n }\n\n /** The next named sibling. */\n get nextNamedSibling(): SyntaxNode<I> | undefined {\n const siblings = this.parent?.children\n if (siblings === undefined) return undefined\n for (let i = this.index + 1; i < siblings.length; i++) if (siblings[i].named) return siblings[i]\n return undefined\n }\n\n /** The previous named sibling. */\n get previousNamedSibling(): SyntaxNode<I> | undefined {\n const siblings = this.parent?.children\n if (siblings === undefined) return undefined\n for (let i = this.index - 1; i >= 0; i--) if (siblings[i].named) return siblings[i]\n return undefined\n }\n\n /**\n * The index of the child containing the input unit at `offset`, or -1.\n * Takes logarithmic time.\n */\n childIndexAt(offset: number): number {\n const green = this.green\n const offsets = green.offsets\n const rel = offset - this.start\n let lo = 0\n let hi = offsets.length - 1\n let found = -1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n if (offsets[mid] <= rel) {\n found = mid\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n // Skip back over empty `ERROR` nodes at `offset`\n while (found >= 0 && green.children[found].width === 0 && offsets[found] === rel) found--\n return found >= 0 && rel < offsets[found] + green.children[found].width ? found : -1\n }\n\n /** The child containing the input unit at `offset`. */\n childAt(offset: number): SyntaxNode<I> | undefined {\n const i = this.childIndexAt(offset)\n return i < 0 ? undefined : this.children[i]\n }\n\n /**\n * The smallest node, this one or a descendant, that contains\n * `[start, end)` (Tree-sitter's `descendant_for_byte_range`). With only\n * `start`, the deepest node containing the input unit at `start`. Takes\n * time proportional to the depth of the tree times the logarithm of the\n * number of children.\n */\n descendantAt(start: number, end: number = start + 1): SyntaxNode<I> {\n return descendantOf(this, start, end)\n }\n\n /** Like {@link descendantAt}, but only stops at named nodes. */\n namedDescendantAt(start: number, end: number = start + 1): SyntaxNode<I> {\n let node: SyntaxNode<I> = this.descendantAt(start, end)\n // Every node below `this` has a parent, so the walk stops at `this` at the latest\n while (!node.named && node !== this) node = node.parent ?? this\n return node\n }\n\n /** This node and its descendants, in pre-order. */\n *descendants(): Generator<SyntaxNode<I>, void, undefined> {\n const cursor = this.walk()\n while (true) {\n yield cursor.node\n if (cursor.gotoFirstChild()) continue\n while (!cursor.gotoNextSibling()) {\n if (!cursor.gotoParent()) return\n }\n }\n }\n\n /** The descendants of the given kind, in pre-order. */\n *descendantsOfKind(kind: string): Generator<SyntaxNode<I>, void, undefined> {\n for (const n of this.descendants()) if (n.kind === kind) yield n\n }\n\n /** A cursor at this node, which cannot move above it. */\n walk(): TreeCursor<I> {\n return new TreeCursor(this)\n }\n\n /**\n * The node as an S-expression of its named descendants, with field\n * names, as Tree-sitter prints it: `(pair key: (name) value: (number))`.\n */\n toString(): string {\n let out = \"\"\n const visit = (green: Green, field: string | undefined) => {\n if (green.named || green === this.green) {\n if (Str.isNonEmpty(out)) out += \" \"\n if (field !== undefined) out += `${field}: `\n out += `(${green.kind}`\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], green.fields?.[i])\n out += \")\"\n } else {\n for (let i = 0; i < green.children.length; i++) visit(green.children[i], green.fields?.[i])\n }\n }\n visit(this.green, this.field)\n return out\n }\n\n toJSON(): unknown {\n return { kind: this.kind, start: this.start, end: this.end }\n }\n\n private makeChild(i: number): SyntaxNode<I> {\n const green = this.green\n return new SyntaxNode(this.tree, green.children[i], this.start + green.offsets[i], this, i)\n }\n}\n\n/** The smallest node, `root` or a descendant, that contains `[start, end)` (see `SyntaxNode.descendantAt`). */\nconst descendantOf = <I extends Input>(root: SyntaxNode<I>, start: number, end: number): SyntaxNode<I> => {\n let node = root\n while (true) {\n const i = node.childIndexAt(start)\n if (i < 0) return node\n const child = node.children[i]\n if (end > child.end) return node\n node = child\n }\n}\n\n/**\n * A cursor for walking a tree, as Tree-sitter's `TreeCursor`. It starts at\n * a node and cannot move above it.\n *\n * @since 0.2.0\n * @category models\n */\nexport class TreeCursor<I extends Input = string> {\n private current: SyntaxNode<I>\n private depth = 0\n\n /** @internal */\n constructor(node: SyntaxNode<I>) {\n this.current = node\n }\n\n /** The node at the cursor. */\n get node(): SyntaxNode<I> {\n return this.current\n }\n\n /** The field name of the node at the cursor, if any. */\n get field(): string | undefined {\n return this.depth === 0 ? undefined : this.current.field\n }\n\n /** Moves to the first child; `false` if there is none. */\n gotoFirstChild(): boolean {\n return this.goto(this.current.child(0))\n }\n\n /** Moves to the last child; `false` if there is none. */\n gotoLastChild(): boolean {\n return this.goto(this.current.child(-1))\n }\n\n /** Moves to the child containing the input unit at `offset`; `false` if there is none. */\n gotoFirstChildForOffset(offset: number): boolean {\n return this.goto(this.current.childAt(offset))\n }\n\n /** Moves to the next sibling; `false` if there is none. */\n gotoNextSibling(): boolean {\n if (this.depth === 0) return false\n const next = this.current.nextSibling\n if (next === undefined) return false\n this.current = next\n return true\n }\n\n /** Moves to the previous sibling; `false` if there is none. */\n gotoPreviousSibling(): boolean {\n if (this.depth === 0) return false\n const previous = this.current.previousSibling\n if (previous === undefined) return false\n this.current = previous\n return true\n }\n\n /** Moves to the parent; `false` at the node the cursor started at. */\n gotoParent(): boolean {\n const parent = this.current.parent\n if (this.depth === 0 || parent === undefined) return false\n this.current = parent\n this.depth--\n return true\n }\n\n /** Moves to the deepest node containing the input unit at `offset`. */\n gotoDescendantAt(offset: number): void {\n while (this.gotoFirstChildForOffset(offset)) {\n // descend\n }\n }\n\n /** Starts again at `node`. */\n reset(node: SyntaxNode<I>): void {\n this.current = node\n this.depth = 0\n }\n\n private goto(node: SyntaxNode<I> | undefined): boolean {\n if (node === undefined) return false\n this.current = node\n this.depth++\n return true\n }\n}\n\n// -----------------------------------------------------------------------------\n// Parsing\n// -----------------------------------------------------------------------------\n\nconst expectedEof = [\"end of input\"]\n\nconst run = <A, E, I extends Input>(config: Config, input: I, previous: Previous | undefined): Tree<A, E, I> => {\n const state = new State<I>(input, { context: config.context })\n const builder = new SyntaxBuilder(state, previous)\n const a = Stack.run(config.inner.step, state)\n // Text parsers record the encoding when they fail, which they may have done inside reused nodes\n if (state.encoding === undefined && previous !== undefined) state.encoding = previous.encoding\n let fatal: ErrorInfo | undefined\n let value: Option.Option<A> = Option.none()\n if (a === Fail) {\n fatal = { failure: state.reportedFailure(), mode: state.mode }\n } else if (state.pos < state.end) {\n state.backtrack(\"Eof\", expectedEof)\n fatal = { failure: state.reportedFailure(), mode: \"Backtrack\" }\n } else {\n value = Option.some(a as A)\n }\n const green = builder.finish(config.kind, Option.getOrUndefined(value), fatal, state.pos)\n return new Tree<A, E, I>(input, value, builder.reused, green, config, state.encoding)\n}\n\n/**\n * Parses an input into a syntax {@link Tree}. The grammar's output is the\n * tree's `value`, and its {@link node}s are the tree's nodes. When the\n * grammar is itself a {@link node}, that node is the root; otherwise the\n * root is a node of kind `options.kind` (by default `\"document\"`).\n *\n * The parse never fails: recovered failures (see `Parser.resumeAfter`), a\n * fatal failure and unparsed input at the end all become `ERROR` nodes, and\n * are listed in `tree.errors`. The parse is interpreted, never compiled.\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const parse: {\n <A, E, I extends Input>(\n grammar: Parser<A, E, never, I>,\n input: NoInfer<Source<I>>,\n options?: ParseOptions\n ): Tree<A, E, I>\n <A, E, R, I extends Input>(\n grammar: Parser<A, E, R, I>,\n input: NoInfer<Source<I>>,\n options: ParseOptionsWithContext<R>\n ): Tree<A, E, I>\n} = <A, E, R, I extends Input>(\n grammar: Parser<A, E, R, I>,\n input: I | Source<I>,\n options?: ParseOptions & { readonly context?: Context.Context<R> }\n): Tree<A, E, I> => {\n const n = nodeOf(grammar)\n const isRoot = Predicate.isTagged(n, \"Syntax\") && n.kind !== undefined && n.named\n const config: Config = {\n kind: isRoot ? n.kind : (options?.kind ?? \"document\"),\n inner: isRoot ? (n.self as Parser.Any) : grammar,\n lookahead: options?.lookahead ?? 0,\n context: options?.context as Context.Context<never> | undefined\n }\n return run(config, fromSource(input as Input) as I, undefined)\n}\n\n/**\n * Parses the new version of a tree's input, reusing the nodes of the tree\n * that the edits leave unchanged (Tree-sitter's `ts_tree_edit` followed by\n * `ts_parser_parse` with the old tree). The result is the tree a fresh\n * {@link parse} of `input` would build, but only the parts of the tree\n * around the edits are parsed again. `tree.reused` says how many nodes were\n * reused.\n *\n * `edits` describe how the old input became the new one, applied in order,\n * each in the coordinates of the input as the previous edits left it. When\n * they are omitted, the edit is found by comparing the inputs (their common\n * prefix and suffix), which takes time linear in their length but much less\n * than parsing.\n *\n * Errors in the new tree are those a fresh parse reports, except that an\n * error just after a reused node may list fewer expected alternatives.\n *\n * @example\n * ```ts\n * import { Ascii, Syntax } from \"@thomasfosterau/effect-parse\"\n *\n * const number = Syntax.node(Ascii.decInt, \"number\")\n * const tree = Syntax.parse(number, \"12\")\n * Syntax.reparse(tree, \"123\", [{ start: 2, oldEnd: 2, newEnd: 3 }]).root.value // 123\n * ```\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const reparse = <A, E, I extends Input>(\n tree: Tree<A, E, I>,\n input: NoInfer<Source<I>>,\n edits?: Edit | ReadonlyArray<Edit>\n): Tree<A, E, I> => {\n const next = fromSource(input as Input) as I\n const list =\n edits === undefined\n ? diffList(tree.input, next)\n : \"start\" in edits\n ? [edits as Edit]\n : (edits as ReadonlyArray<Edit>)\n const previous: Previous = {\n root: tree.green,\n oldLength: tree.input.length,\n newLength: next.length,\n segments: segmentsOf(tree.input.length, next.length, list),\n input: tree.input,\n extra: tree.config.lookahead,\n encoding: tree.encoding\n }\n return run(tree.config, next, previous)\n}\n\n/**\n * Replaces `[start, end)` of a tree's string input with `text` and parses\n * the result incrementally (see {@link reparse}).\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const replace = <A, E>(\n tree: Tree<A, E, string>,\n start: number,\n end: number,\n text: string\n): Tree<A, E, string> => {\n const input = tree.input\n if (start < 0 || end < start || end > input.length) {\n throw new RangeError(`invalid range [${start}, ${end}) of an input of length ${input.length}`)\n }\n return reparse(tree, input.slice(0, start) + text + input.slice(end), {\n start,\n oldEnd: end,\n newEnd: start + text.length\n })\n}\n\n/**\n * Finds the edit that turns `before` into `after`: the part between their\n * longest common prefix and suffix. `undefined` when they are equal.\n *\n * @since 0.2.0\n * @category parsing\n */\nexport const diff = <I extends Input>(before: I, after: I): Edit | undefined => {\n const a = before as any\n const b = after as any\n const at = Predicate.isString(a) ? (s: string, i: number) => s.charCodeAt(i) : (s: any, i: number) => s[i]\n const max = Math.min(a.length, b.length)\n let prefix = 0\n while (prefix < max && at(a, prefix) === at(b, prefix)) prefix++\n if (prefix === a.length && prefix === b.length) return undefined\n let suffix = 0\n while (suffix < max - prefix && at(a, a.length - 1 - suffix) === at(b, b.length - 1 - suffix)) suffix++\n return { start: prefix, oldEnd: a.length - suffix, newEnd: b.length - suffix }\n}\n\nconst diffList = (before: Input, after: Input): ReadonlyArray<Edit> => {\n const edit = diff(before, after)\n return edit === undefined ? [] : [edit]\n}\n\n/** The stretches of the new input copied unchanged from the old one. */\nconst segmentsOf = (oldLength: number, newLength: number, edits: ReadonlyArray<Edit>): Array<Segment> => {\n let segments: Array<Segment> = oldLength > 0 ? [{ newStart: 0, oldStart: 0, length: oldLength }] : []\n let length = oldLength\n for (const { newEnd, oldEnd, start } of edits) {\n if (!(start >= 0 && oldEnd >= start && oldEnd <= length && newEnd >= start)) {\n throw new RangeError(\n `invalid edit { start: ${start}, oldEnd: ${oldEnd}, newEnd: ${newEnd} } of an input of length ${length}`\n )\n }\n const delta = newEnd - oldEnd\n const out: Array<Segment> = []\n for (const s of segments) {\n const end = s.newStart + s.length\n if (s.newStart < start) {\n out.push({ newStart: s.newStart, oldStart: s.oldStart, length: Math.min(end, start) - s.newStart })\n }\n if (end > oldEnd) {\n const from = Math.max(s.newStart, oldEnd)\n out.push({ newStart: from + delta, oldStart: s.oldStart + (from - s.newStart), length: end - from })\n }\n }\n segments = out\n length += delta\n }\n if (length !== newLength) {\n throw new RangeError(`the edits give an input of length ${length}, but the new input has length ${newLength}`)\n }\n return segments\n}\n"],"mappings":"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"}
|
package/dist/Text.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Parser, Range } from "./Parser.js";
|
|
2
2
|
import { StringTokenSet } from "./Token.js";
|
|
3
3
|
import { Encoding } from "./Encoding.js";
|
|
4
|
-
//#region src/Text.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* A predicate over characters. It accepts a one-character string or a code
|
|
7
6
|
* point.
|
|
@@ -290,5 +289,4 @@ export declare const utf16be: TextParsers<Uint8Array>;
|
|
|
290
289
|
* @category instances
|
|
291
290
|
*/
|
|
292
291
|
export declare const latin1: TextParsers<Uint8Array>;
|
|
293
|
-
//#endregion
|
|
294
292
|
//# sourceMappingURL=Text.d.ts.map
|