@thomasfosterau/effect-parse 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +37 -13
  2. package/dist/Ascii.d.ts +11 -4
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +7 -1
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts.map +1 -1
  7. package/dist/Binary.js +64 -35
  8. package/dist/Binary.js.map +1 -1
  9. package/dist/Bits.d.ts.map +1 -1
  10. package/dist/Bits.js +7 -4
  11. package/dist/Bits.js.map +1 -1
  12. package/dist/Compiler.d.ts +74 -2
  13. package/dist/Compiler.d.ts.map +1 -1
  14. package/dist/Compiler.js +78 -1
  15. package/dist/Compiler.js.map +1 -1
  16. package/dist/Expression.d.ts.map +1 -1
  17. package/dist/Expression.js +86 -74
  18. package/dist/Expression.js.map +1 -1
  19. package/dist/Input.d.ts +37 -4
  20. package/dist/Input.d.ts.map +1 -1
  21. package/dist/Input.js +42 -0
  22. package/dist/Input.js.map +1 -1
  23. package/dist/Nom.d.ts +5 -15
  24. package/dist/Nom.d.ts.map +1 -1
  25. package/dist/Nom.js.map +1 -1
  26. package/dist/ParseError.d.ts.map +1 -1
  27. package/dist/ParseError.js.map +1 -1
  28. package/dist/Parser.d.ts +366 -26
  29. package/dist/Parser.d.ts.map +1 -1
  30. package/dist/Parser.js +390 -19
  31. package/dist/Parser.js.map +1 -1
  32. package/dist/ParserSchema.js +1 -1
  33. package/dist/ParserStream.d.ts +3 -2
  34. package/dist/ParserStream.d.ts.map +1 -1
  35. package/dist/ParserStream.js +13 -9
  36. package/dist/ParserStream.js.map +1 -1
  37. package/dist/Syntax.d.ts +23 -5
  38. package/dist/Syntax.d.ts.map +1 -1
  39. package/dist/Syntax.js.map +1 -1
  40. package/dist/Text.d.ts.map +1 -1
  41. package/dist/Text.js +9 -9
  42. package/dist/Text.js.map +1 -1
  43. package/dist/Token.d.ts +55 -10
  44. package/dist/Token.d.ts.map +1 -1
  45. package/dist/Token.js +59 -21
  46. package/dist/Token.js.map +1 -1
  47. package/dist/internal/compiler/closure.d.ts.map +1 -1
  48. package/dist/internal/compiler/closure.js +257 -97
  49. package/dist/internal/compiler/closure.js.map +1 -1
  50. package/dist/internal/compiler/entries.d.ts +3 -1
  51. package/dist/internal/compiler/entries.d.ts.map +1 -1
  52. package/dist/internal/compiler/entries.js +3 -2
  53. package/dist/internal/compiler/entries.js.map +1 -1
  54. package/dist/internal/compiler/first.d.ts.map +1 -1
  55. package/dist/internal/compiler/first.js +7 -1
  56. package/dist/internal/compiler/first.js.map +1 -1
  57. package/dist/internal/compiler/graph.d.ts +17 -0
  58. package/dist/internal/compiler/graph.d.ts.map +1 -0
  59. package/dist/internal/compiler/graph.js +56 -0
  60. package/dist/internal/compiler/graph.js.map +1 -0
  61. package/dist/internal/compiler/jit.d.ts +5 -0
  62. package/dist/internal/compiler/jit.d.ts.map +1 -1
  63. package/dist/internal/compiler/jit.js +185 -96
  64. package/dist/internal/compiler/jit.js.map +1 -1
  65. package/dist/internal/compiler/registry.d.ts +10 -2
  66. package/dist/internal/compiler/registry.d.ts.map +1 -1
  67. package/dist/internal/compiler/registry.js.map +1 -1
  68. package/dist/internal/compiler/search.d.ts +32 -0
  69. package/dist/internal/compiler/search.d.ts.map +1 -0
  70. package/dist/internal/compiler/search.js +68 -0
  71. package/dist/internal/compiler/search.js.map +1 -0
  72. package/dist/internal/compiler/sets.d.ts.map +1 -1
  73. package/dist/internal/compiler/sets.js +1 -1
  74. package/dist/internal/compiler/sets.js.map +1 -1
  75. package/dist/internal/compiler/wasm.d.ts +8 -0
  76. package/dist/internal/compiler/wasm.d.ts.map +1 -0
  77. package/dist/internal/compiler/wasm.js +2769 -0
  78. package/dist/internal/compiler/wasm.js.map +1 -0
  79. package/dist/internal/compiler/wasmAsm.d.ts +199 -0
  80. package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
  81. package/dist/internal/compiler/wasmAsm.js +427 -0
  82. package/dist/internal/compiler/wasmAsm.js.map +1 -0
  83. package/dist/internal/entries.d.ts +3 -1
  84. package/dist/internal/entries.d.ts.map +1 -1
  85. package/dist/internal/entries.js.map +1 -1
  86. package/dist/internal/node.d.ts +58 -2
  87. package/dist/internal/node.d.ts.map +1 -1
  88. package/dist/internal/node.js +13 -3
  89. package/dist/internal/node.js.map +1 -1
  90. package/dist/internal/numbers.d.ts.map +1 -1
  91. package/dist/internal/numbers.js.map +1 -1
  92. package/dist/internal/run.d.ts +12 -0
  93. package/dist/internal/run.d.ts.map +1 -1
  94. package/dist/internal/run.js +51 -11
  95. package/dist/internal/run.js.map +1 -1
  96. package/dist/internal/stack.d.ts +6 -0
  97. package/dist/internal/stack.d.ts.map +1 -1
  98. package/dist/internal/stack.js +8 -2
  99. package/dist/internal/stack.js.map +1 -1
  100. package/dist/internal/syntax.d.ts +4 -4
  101. package/dist/internal/syntax.d.ts.map +1 -1
  102. package/dist/internal/syntax.js +18 -10
  103. package/dist/internal/syntax.js.map +1 -1
  104. package/dist/internal/text.d.ts +32 -0
  105. package/dist/internal/text.d.ts.map +1 -1
  106. package/dist/internal/text.js +68 -14
  107. package/dist/internal/text.js.map +1 -1
  108. package/dist/internal/tokens.d.ts +13 -0
  109. package/dist/internal/tokens.d.ts.map +1 -1
  110. package/dist/internal/tokens.js +59 -39
  111. package/dist/internal/tokens.js.map +1 -1
  112. package/package.json +5 -4
  113. package/src/Ascii.ts +42 -9
  114. package/src/Binary.ts +151 -71
  115. package/src/Bits.ts +12 -6
  116. package/src/Compiler.ts +101 -10
  117. package/src/Expression.ts +94 -81
  118. package/src/Input.ts +65 -6
  119. package/src/Nom.ts +15 -5
  120. package/src/ParseError.ts +3 -0
  121. package/src/Parser.ts +678 -127
  122. package/src/ParserStream.ts +37 -18
  123. package/src/Syntax.ts +60 -36
  124. package/src/Text.ts +16 -15
  125. package/src/Token.ts +138 -29
  126. package/src/internal/compiler/closure.ts +362 -135
  127. package/src/internal/compiler/entries.ts +4 -2
  128. package/src/internal/compiler/first.ts +10 -0
  129. package/src/internal/compiler/graph.ts +68 -0
  130. package/src/internal/compiler/jit.ts +284 -154
  131. package/src/internal/compiler/registry.ts +10 -2
  132. package/src/internal/compiler/search.ts +68 -0
  133. package/src/internal/compiler/sets.ts +7 -3
  134. package/src/internal/compiler/wasm.ts +3203 -0
  135. package/src/internal/compiler/wasmAsm.ts +484 -0
  136. package/src/internal/entries.ts +8 -2
  137. package/src/internal/node.ts +54 -4
  138. package/src/internal/numbers.ts +3 -1
  139. package/src/internal/run.ts +71 -12
  140. package/src/internal/stack.ts +8 -1
  141. package/src/internal/syntax.ts +39 -18
  142. package/src/internal/text.ts +97 -9
  143. package/src/internal/tokens.ts +96 -14
@@ -84,24 +84,30 @@ const errorKind = "ERROR";
84
84
  const rebase = (f, start) => new Failure(f.offset - start, f.kind, f.expected, f.context, f.hasCause, f.cause, f.message, f.needed);
85
85
  /** Moves a failure stored relative to a node back to absolute offsets. */
86
86
  const absolute = (f, start) => rebase(f, -start);
87
+ /** The children, and their offsets, of every leaf: one shared empty array. */
88
+ const none = [];
87
89
  /**
88
90
  * Builds a green node over `[start, end)` from the children waiting on the
89
- * stack.
91
+ * stack, `entries` from index `from` on (which the caller then removes):
92
+ * slicing them off first would allocate an array per node.
90
93
  */
91
- const build = (kind, named, key, start, end, lookahead, entries, value, error, diagnostics) => {
92
- const n = entries.length;
94
+ const build = (kind, named, key, start, end, lookahead, entries, from, value, error, diagnostics) => {
95
+ const n = entries.length - from;
96
+ const width = end - start;
97
+ const looked = Math.max(lookahead, end) - start;
98
+ if (n === 0) return new Green(kind, named, key, width, looked, none, none, void 0, value, error, error !== void 0, diagnostics);
93
99
  const children = new Array(n);
94
100
  const offsets = new Array(n);
95
101
  let fields;
96
102
  let hasError = error !== void 0;
97
103
  for (let i = 0; i < n; i++) {
98
- const e = entries[i];
104
+ const e = entries[from + i];
99
105
  children[i] = e.green;
100
106
  offsets[i] = e.start - start;
101
107
  if (e.green.hasError) hasError = true;
102
108
  if (e.field !== void 0) (fields ??= new Array(n).fill(void 0))[i] = e.field;
103
109
  }
104
- return new Green(kind, named, key, end - start, Math.max(lookahead, end) - start, children, offsets, fields, value, error, hasError, diagnostics);
110
+ return new Green(kind, named, key, width, looked, children, offsets, fields, value, error, hasError, diagnostics);
105
111
  };
106
112
  /**
107
113
  * The tree builder of a `Syntax` parse, reached through `state.syntax`. It
@@ -190,8 +196,9 @@ var SyntaxBuilder = class {
190
196
  hintOffset: this.state.hintOffset - start,
191
197
  hintExpected: hinted ? this.state.hintExpected : void 0
192
198
  };
193
- const entries = stack.splice(mark);
194
- stack.push(new Child(build(kind, named, key, start, end, looked, entries, a, void 0, diagnostics), start, end, void 0));
199
+ const green = build(kind, named, key, start, end, looked, stack, mark, a, void 0, diagnostics);
200
+ stack.length = mark;
201
+ stack.push(new Child(green, start, end, void 0));
195
202
  return a;
196
203
  }
197
204
  read(end) {
@@ -213,10 +220,11 @@ var SyntaxBuilder = class {
213
220
  let i = stack.length;
214
221
  while (i > 0 && stack[i - 1].start >= start && stack[i - 1].end > start) i--;
215
222
  const end = this.state.pos;
216
- const green = build(errorKind, true, void 0, start, end, this.looked(), stack.splice(i), void 0, {
223
+ const green = build(errorKind, true, void 0, start, end, this.looked(), stack, i, void 0, {
217
224
  failure: rebase(failure, start),
218
225
  mode
219
226
  });
227
+ stack.length = i;
220
228
  stack.push(new Child(green, start, end, void 0));
221
229
  }
222
230
  /**
@@ -230,13 +238,13 @@ var SyntaxBuilder = class {
230
238
  if (fatal !== void 0) {
231
239
  const last = Arr.isArrayNonEmpty(entries) ? Arr.lastNonEmpty(entries).end : 0;
232
240
  const start = Math.max(Math.min(errorStart, end), last);
233
- const error = build(errorKind, true, void 0, start, end, end, [], void 0, {
241
+ const error = build(errorKind, true, void 0, start, end, end, none, 0, void 0, {
234
242
  failure: rebase(fatal.failure, start),
235
243
  mode: fatal.mode
236
244
  });
237
245
  entries.push(new Child(error, start, end, void 0));
238
246
  }
239
- return build(kind, true, void 0, 0, end, Math.max(end, this.looked()), entries, value, void 0);
247
+ return build(kind, true, void 0, 0, end, Math.max(end, this.looked()), entries, 0, value, void 0);
240
248
  }
241
249
  /**
242
250
  * The outermost node of the previous tree built by `key` that starts at
@@ -1 +1 @@
1
- {"version":3,"file":"syntax.js","names":[],"sources":["../../src/internal/syntax.ts"],"sourcesContent":["/**\n * The tree builder behind the `Syntax` module (see `docs/DESIGN.md`,\n * \"Syntax trees\").\n *\n * Trees are stored as *green* nodes, as in Roslyn and rust-analyzer: a green\n * node knows its kind, its width and its children's offsets relative to its\n * own start, but not where it is in the input or who its parent is. A subtree\n * that an edit doesn't touch can therefore be shared, unchanged, by the tree\n * before the edit and the tree after it. `Syntax.SyntaxNode` is the *red*\n * view: a green node, its absolute start and its parent, built lazily while\n * navigating.\n *\n * While parsing, completed nodes wait on a stack until the node around them\n * completes and adopts them. Nodes built by an attempt that is later\n * abandoned must not end up in the tree. Every combinator that abandons an\n * attempt moves the cursor back to (or before) where the attempt started,\n * with `State.rewind`, and every node has a positive width, so the nodes of\n * an abandoned attempt are exactly those that end after the position the\n * cursor moves back to: {@link SyntaxBuilder} drops them when told of the rewind. This also\n * covers lookahead (`peek`, `not`) and custom parsers written with\n * `Parser.make`, which rewind the same way.\n *\n * `pos` stays a plain field, not an accessor that would watch every move: a\n * `pos` accessor on this subclass made every parser's cursor accesses\n * polymorphic, slowing ordinary parses by about a fifth in any program that\n * also built a syntax tree, and the syntax parse itself about twofold.\n *\n * For incremental parsing, every node records how far its parse looked: the\n * furthest position the cursor reached and the furthest failure recorded\n * while it was being parsed (its *lookahead*). The cursor only moves forward\n * between rewinds, so the furthest position is where it was at a rewind, or\n * where it is now. A node from the previous tree\n * is reused at a position when it was built by the same `Syntax.node`, and\n * the input it looked at, plus a margin for the tokens that read a little\n * past where they stop, is unchanged.\n */\nimport * as Arr from \"effect/Array\"\nimport * as Predicate from \"effect/Predicate\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { ErrMode, Input } from \"../Input.js\"\nimport { Fail, Failure, State } from \"../Input.js\"\nimport type { Key } from \"./key.js\"\n\n/** What a failure inside an `ERROR` node was. Offsets are relative to the node. */\nexport interface ErrorInfo {\n readonly failure: Failure\n readonly mode: ErrMode\n}\n\n/** A position-independent syntax tree node. */\nexport class Green {\n constructor(\n readonly kind: string,\n readonly named: boolean,\n /** The `Syntax.node` that built it; `undefined` for roots and errors, which are never reused alone. */\n readonly key: Key | undefined,\n readonly width: number,\n /** How far its parse looked, relative to its start (at least `width`). */\n readonly lookahead: number,\n readonly children: ReadonlyArray<Green>,\n /** The children's starts, relative to this node's start. */\n readonly offsets: ReadonlyArray<number>,\n /** The children's field names, when any child has one. */\n readonly fields: ReadonlyArray<string | undefined> | undefined,\n readonly value: unknown,\n /** Set on `ERROR` nodes. */\n readonly error: ErrorInfo | undefined,\n /** Whether this node or a descendant is an `ERROR` node. */\n readonly hasError: boolean,\n /** What its parse left behind for error reporting, replayed when it is reused. */\n readonly diagnostics: Diagnostics | undefined\n ) {}\n}\n\n/**\n * The error-reporting state a node's parse leaves behind (see\n * `State.deepest` and `State.setHint`). A reused node replays it, so that\n * a reparse reports the errors a fresh parse does.\n */\nexport interface Diagnostics {\n /** The furthest failure, at its offset in the parse that built the node... */\n readonly deepest: Failure | undefined\n /** ...which started the node at `base`. */\n readonly base: number\n /** Relative to the node's start. */\n readonly hintOffset: number\n readonly hintExpected: ReadonlyArray<string> | undefined\n}\n\n/** A completed node waiting for its parent, at an absolute position. */\nclass Child {\n constructor(\n readonly green: Green,\n readonly start: number,\n readonly end: number,\n public field: string | undefined\n ) {}\n}\n\nexport const errorKind = \"ERROR\"\n\nconst rebase = (f: Failure, start: number): Failure =>\n new Failure(f.offset - start, f.kind, f.expected, f.context, f.hasCause, f.cause, f.message, f.needed)\n\n/** Moves a failure stored relative to a node back to absolute offsets. */\nexport const absolute = (f: Failure, start: number): Failure => rebase(f, -start)\n\n/**\n * Builds a green node over `[start, end)` from the children waiting on the\n * stack.\n */\nconst build = (\n kind: string,\n named: boolean,\n key: Key | undefined,\n start: number,\n end: number,\n lookahead: number,\n entries: ReadonlyArray<Child>,\n value: unknown,\n error: ErrorInfo | undefined,\n diagnostics?: Diagnostics\n): Green => {\n const n = entries.length\n const children = new Array<Green>(n)\n const offsets = new Array<number>(n)\n let fields: Array<string | undefined> | undefined\n let hasError = error !== undefined\n for (let i = 0; i < n; i++) {\n const e = entries[i]\n children[i] = e.green\n offsets[i] = e.start - start\n if (e.green.hasError) hasError = true\n if (e.field !== undefined) (fields ??= new Array(n).fill(undefined))[i] = e.field\n }\n const width = end - start\n const looked = Math.max(lookahead, end) - start\n return new Green(kind, named, key, width, looked, children, offsets, fields, value, error, hasError, diagnostics)\n}\n\n/**\n * A stretch of the new input copied unchanged from the previous one:\n * `[newStart, newStart + length)` is `[oldStart, oldStart + length)`.\n */\nexport interface Segment {\n readonly newStart: number\n readonly oldStart: number\n readonly length: number\n}\n\n/** What a reparse may reuse. */\nexport interface Previous {\n readonly root: Green\n readonly oldLength: number\n readonly newLength: number\n readonly segments: ReadonlyArray<Segment>\n readonly input: Input\n /** How far past its lookahead a parser may have read, besides a token at the lookahead. */\n readonly extra: number\n readonly encoding: Encoding<any> | undefined\n}\n\n/** The hooks that `Syntax` combinators and `Parser.resumeAfter`/`retryAfter` call. */\nexport interface Builder {\n node(state: State<any>, step: (state: State<any>) => unknown, key: Key, kind: string, named: boolean): unknown\n field(state: State<any>, step: (state: State<any>) => unknown, name: string): unknown\n /** After error recovery: `[start, pos)` was skipped after `failure`. */\n skipped(start: number, failure: Failure, mode: ErrMode): void\n /**\n * Called by token parsers that read input up to `end` (exclusive) beyond\n * where they leave the cursor or record a failure.\n */\n read(end: number): void\n /** A failure or hint was recorded at `offset`. */\n reach(offset: number): void\n /** The cursor moved back from `from` to `to` (see `State.rewind`). */\n rewound(from: number, to: number): void\n}\n\n/**\n * The tree builder of a `Syntax` parse, reached through `state.syntax`. It\n * is not a `State` subclass: one class of state keeps every parser's cursor\n * and failure accesses monomorphic, whether or not the program also builds\n * syntax trees. `State` calls {@link reach} and {@link rewound} itself.\n */\nexport class SyntaxBuilder implements Builder {\n /**\n * The furthest position the cursor reached before a rewind, or failure\n * recorded, since the innermost open node started; {@link looked} adds\n * where the cursor is now.\n */\n highWater: number\n /** Completed nodes waiting for their parent, in input order. */\n readonly stack: Array<Child> = []\n /** How many nodes were reused from the previous tree. */\n reused = 0\n /** Where {@link find} found the last node it found. */\n lastParent: Green | undefined = undefined\n lastParentStart = 0\n\n constructor(\n readonly state: State<any>,\n readonly previous: Previous | undefined\n ) {\n this.highWater = state.pos\n state.syntax = this\n // Error recovery is always on: like Tree-sitter, a syntax parse always produces a tree\n state.recovered = []\n }\n\n reach(offset: number): void {\n if (offset > this.highWater) this.highWater = offset\n }\n\n rewound(from: number, to: number): void {\n if (from > this.highWater) this.highWater = from\n // An attempt was abandoned (or a lookahead finished): drop its nodes\n const stack = this.stack\n while (Arr.isArrayNonEmpty(stack) && Arr.lastNonEmpty(stack).end > to) stack.pop()\n }\n\n /** How far the parse looked: {@link highWater}, or the cursor if it is further. */\n private looked(): number {\n return this.state.pos > this.highWater ? this.state.pos : this.highWater\n }\n\n node(state: State<any>, step: (state: State<any>) => unknown, key: Key, kind: string, named: boolean): unknown {\n const start = this.state.pos\n const stack = this.stack\n if (this.previous !== undefined) {\n const green = this.reusable(this.previous, key, start)\n if (green !== undefined) {\n this.reused++\n const end = start + green.width\n state.pos = end\n const looked = start + green.lookahead\n if (looked > this.highWater) this.highWater = looked\n const d = green.diagnostics\n if (d !== undefined) {\n if (d.deepest !== undefined) this.deepen(start === d.base ? d.deepest : rebase(d.deepest, d.base - start))\n if (d.hintExpected !== undefined) this.state.setHint(start + d.hintOffset, d.hintExpected)\n }\n stack.push(new Child(green, start, end, undefined))\n return green.value\n }\n }\n const mark = stack.length\n const outer = this.highWater\n const outerDeepest = this.state.deepest\n const hintOffset = this.state.hintOffset\n const hintExpected = this.state.hintExpected\n this.highWater = start\n // Collect the furthest failure of this node alone, then merge it as `failWith` would have\n this.state.deepest = undefined\n const a = step(state)\n const looked = this.looked()\n this.highWater = outer > looked ? outer : looked\n const deepest = this.state.deepest as Failure | undefined\n this.state.deepest = outerDeepest\n if (deepest !== undefined) this.deepen(deepest)\n if (a === Fail) {\n if (stack.length > mark) stack.length = mark\n return a\n }\n const end = this.state.pos\n // Like Tree-sitter's rules, nodes are never empty: an empty match adds nothing to the tree\n if (end === start) return a\n const hinted = this.state.hintOffset !== hintOffset || this.state.hintExpected !== hintExpected\n const diagnostics: Diagnostics | undefined =\n deepest === undefined && !hinted\n ? undefined\n : {\n deepest,\n base: start,\n hintOffset: this.state.hintOffset - start,\n hintExpected: hinted ? this.state.hintExpected : undefined\n }\n const entries = stack.splice(mark)\n stack.push(\n new Child(build(kind, named, key, start, end, looked, entries, a, undefined, diagnostics), start, end, undefined)\n )\n return a\n }\n\n read(end: number): void {\n // `highWater` is the last position looked at, `end` is exclusive\n if (end - 1 > this.highWater) this.highWater = end - 1\n }\n\n /** Records `failure` as the furthest failure if it is, as `failWith` does. */\n private deepen(failure: Failure): void {\n if (this.state.deepest === undefined || failure.offset >= this.state.deepest.offset) this.state.deepest = failure\n }\n\n field(state: State<any>, step: (state: State<any>) => unknown, name: string): unknown {\n const stack = this.stack\n const mark = stack.length\n const a = step(state)\n if (a !== Fail) for (let i = mark; i < stack.length; i++) stack[i].field = name\n return a\n }\n\n skipped(start: number, failure: Failure, mode: ErrMode): void {\n const stack = this.stack\n let i = stack.length\n while (i > 0 && stack[i - 1].start >= start && stack[i - 1].end > start) i--\n const end = this.state.pos\n const green = build(errorKind, true, undefined, start, end, this.looked(), stack.splice(i), undefined, {\n failure: rebase(failure, start),\n mode\n })\n stack.push(new Child(green, start, end, undefined))\n }\n\n /**\n * Builds the root over the whole input from the nodes left on the stack.\n * When the parse failed, or stopped before the end, the rest of the input\n * becomes an `ERROR` node.\n */\n finish(kind: string, value: unknown, fatal: ErrorInfo | undefined, errorStart: number): Green {\n const entries = this.stack.splice(0)\n const end = this.state.end\n if (fatal !== undefined) {\n const last = Arr.isArrayNonEmpty(entries) ? Arr.lastNonEmpty(entries).end : 0\n const start = Math.max(Math.min(errorStart, end), last)\n const error = build(errorKind, true, undefined, start, end, end, [], undefined, {\n failure: rebase(fatal.failure, start),\n mode: fatal.mode\n })\n entries.push(new Child(error, start, end, undefined))\n }\n return build(kind, true, undefined, 0, end, Math.max(end, this.looked()), entries, value, undefined)\n }\n\n /**\n * The outermost node of the previous tree built by `key` that starts at\n * `offset`. Reused nodes are mostly siblings, found one after the other,\n * so the search starts from the parent of the last one found when\n * `offset` lies inside it: no ancestor of that parent can start there.\n */\n private find(root: Green, offset: number, key: Key): Green | undefined {\n let node = root\n let start = 0\n const last = this.lastParent\n if (last !== undefined && offset > this.lastParentStart && offset < this.lastParentStart + last.width) {\n node = last\n start = this.lastParentStart\n }\n while (true) {\n const offsets = node.offsets\n // The last child starting at or before `offset`\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 (start + offsets[mid] <= offset) {\n found = mid\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n if (found < 0) return undefined\n const child = node.children[found]\n const childStart = start + offsets[found]\n if (offset >= childStart + child.width) return undefined\n if (childStart === offset && child.key === key) {\n this.lastParent = node\n this.lastParentStart = start\n return child\n }\n node = child\n start = childStart\n }\n }\n\n /** The node of the previous tree built by `key` at `pos` (in the new input), if it can be reused. */\n private reusable(previous: Previous, key: Key, pos: number): Green | undefined {\n const segments = previous.segments\n // The segment containing `pos`\n let lo = 0\n let hi = segments.length - 1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const seg = segments[mid]\n if (pos < seg.newStart) hi = mid - 1\n else if (pos >= seg.newStart + seg.length) lo = mid + 1\n else {\n const old = seg.oldStart + (pos - seg.newStart)\n const green = this.find(previous.root, old, key)\n if (green === undefined) return undefined\n const segEnd = seg.oldStart + seg.length\n // The input it looked at must be unchanged; past the end of both inputs counts as unchanged\n if (old + green.lookahead + tokenWidth(previous.input, old + green.lookahead) + previous.extra <= segEnd) {\n return green\n }\n if (segEnd === previous.oldLength && seg.newStart + seg.length === previous.newLength) return green\n return undefined\n }\n }\n return undefined\n }\n}\n\n/**\n * How many units a token parser may read at `offset`, where a parse\n * stopped looking: one code point. Of a string, that is two units at a high\n * surrogate. Of bytes in an unknown encoding, up to four.\n */\nconst tokenWidth = (input: Input, offset: number): number => {\n if (Predicate.isString(input)) {\n const c = input.charCodeAt(offset)\n return c >= 0xd800 && c <= 0xdbff ? 2 : 1\n }\n return input instanceof Uint8Array ? 4 : 1\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"syntax.js","names":[],"sources":["../../src/internal/syntax.ts"],"sourcesContent":["/**\n * The tree builder behind the `Syntax` module (see `docs/DESIGN.md`,\n * \"Syntax trees\").\n *\n * Trees are stored as *green* nodes, as in Roslyn and rust-analyzer: a green\n * node knows its kind, its width and its children's offsets relative to its\n * own start, but not where it is in the input or who its parent is. A subtree\n * that an edit doesn't touch can therefore be shared, unchanged, by the tree\n * before the edit and the tree after it. `Syntax.SyntaxNode` is the *red*\n * view: a green node, its absolute start and its parent, built lazily while\n * navigating.\n *\n * While parsing, completed nodes wait on a stack until the node around them\n * completes and adopts them. Nodes built by an attempt that is later\n * abandoned must not end up in the tree. Every combinator that abandons an\n * attempt moves the cursor back to (or before) where the attempt started,\n * with `State.rewind`, and every node has a positive width, so the nodes of\n * an abandoned attempt are exactly those that end after the position the\n * cursor moves back to: {@link SyntaxBuilder} drops them when told of the rewind. This also\n * covers lookahead (`peek`, `not`) and custom parsers written with\n * `Parser.make`, which rewind the same way.\n *\n * `pos` stays a plain field, not an accessor that would watch every move: a\n * `pos` accessor on this subclass made every parser's cursor accesses\n * polymorphic, slowing ordinary parses by about a fifth in any program that\n * also built a syntax tree, and the syntax parse itself about twofold.\n *\n * For incremental parsing, every node records how far its parse looked: the\n * furthest position the cursor reached and the furthest failure recorded\n * while it was being parsed (its *lookahead*). The cursor only moves forward\n * between rewinds, so the furthest position is where it was at a rewind, or\n * where it is now. A node from the previous tree\n * is reused at a position when it was built by the same `Syntax.node`, and\n * the input it looked at, plus a margin for the tokens that read a little\n * past where they stop, is unchanged.\n */\nimport * as Arr from \"effect/Array\"\nimport * as Predicate from \"effect/Predicate\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { ErrMode, Input } from \"../Input.js\"\nimport { Fail, Failure, State } from \"../Input.js\"\nimport type { Key } from \"./key.js\"\n\n/** What a failure inside an `ERROR` node was. Offsets are relative to the node. */\nexport interface ErrorInfo {\n readonly failure: Failure\n readonly mode: ErrMode\n}\n\n/** A position-independent syntax tree node. */\nexport class Green {\n constructor(\n readonly kind: string,\n readonly named: boolean,\n /** The `Syntax.node` that built it; `undefined` for roots and errors, which are never reused alone. */\n readonly key: Key | undefined,\n readonly width: number,\n /** How far its parse looked, relative to its start (at least `width`). */\n readonly lookahead: number,\n readonly children: ReadonlyArray<Green>,\n /** The children's starts, relative to this node's start. */\n readonly offsets: ReadonlyArray<number>,\n /** The children's field names, when any child has one. */\n readonly fields: ReadonlyArray<string | undefined> | undefined,\n readonly value: unknown,\n /** Set on `ERROR` nodes. */\n readonly error: ErrorInfo | undefined,\n /** Whether this node or a descendant is an `ERROR` node. */\n readonly hasError: boolean,\n /** What its parse left behind for error reporting, replayed when it is reused. */\n readonly diagnostics: Diagnostics | undefined\n ) {}\n}\n\n/**\n * The error-reporting state a node's parse leaves behind (see\n * `State.deepest` and `State.setHint`). A reused node replays it, so that\n * a reparse reports the errors a fresh parse does.\n */\nexport interface Diagnostics {\n /** The furthest failure, at its offset in the parse that built the node... */\n readonly deepest: Failure | undefined\n /** ...which started the node at `base`. */\n readonly base: number\n /** Relative to the node's start. */\n readonly hintOffset: number\n readonly hintExpected: ReadonlyArray<string> | undefined\n}\n\n/** A completed node waiting for its parent, at an absolute position. */\nclass Child {\n constructor(\n readonly green: Green,\n readonly start: number,\n readonly end: number,\n public field: string | undefined\n ) {}\n}\n\nexport const errorKind = \"ERROR\"\n\nconst rebase = (f: Failure, start: number): Failure =>\n new Failure(f.offset - start, f.kind, f.expected, f.context, f.hasCause, f.cause, f.message, f.needed)\n\n/** Moves a failure stored relative to a node back to absolute offsets. */\nexport const absolute = (f: Failure, start: number): Failure => rebase(f, -start)\n\n/** The children, and their offsets, of every leaf: one shared empty array. */\nconst none: ReadonlyArray<never> = []\n\n/**\n * Builds a green node over `[start, end)` from the children waiting on the\n * stack, `entries` from index `from` on (which the caller then removes):\n * slicing them off first would allocate an array per node.\n */\nconst build = (\n kind: string,\n named: boolean,\n key: Key | undefined,\n start: number,\n end: number,\n lookahead: number,\n entries: ReadonlyArray<Child>,\n from: number,\n value: unknown,\n error: ErrorInfo | undefined,\n diagnostics?: Diagnostics\n): Green => {\n const n = entries.length - from\n const width = end - start\n const looked = Math.max(lookahead, end) - start\n if (n === 0)\n return new Green(\n kind,\n named,\n key,\n width,\n looked,\n none,\n none,\n undefined,\n value,\n error,\n error !== undefined,\n diagnostics\n )\n const children = new Array<Green>(n)\n const offsets = new Array<number>(n)\n let fields: Array<string | undefined> | undefined\n let hasError = error !== undefined\n for (let i = 0; i < n; i++) {\n const e = entries[from + i]\n children[i] = e.green\n offsets[i] = e.start - start\n if (e.green.hasError) hasError = true\n if (e.field !== undefined) (fields ??= new Array(n).fill(undefined))[i] = e.field\n }\n return new Green(kind, named, key, width, looked, children, offsets, fields, value, error, hasError, diagnostics)\n}\n\n/**\n * A stretch of the new input copied unchanged from the previous one:\n * `[newStart, newStart + length)` is `[oldStart, oldStart + length)`.\n */\nexport interface Segment {\n readonly newStart: number\n readonly oldStart: number\n readonly length: number\n}\n\n/** What a reparse may reuse. */\nexport interface Previous {\n readonly root: Green\n readonly oldLength: number\n readonly newLength: number\n readonly segments: ReadonlyArray<Segment>\n readonly input: Input\n /** How far past its lookahead a parser may have read, besides a token at the lookahead. */\n readonly extra: number\n readonly encoding: Encoding<any> | undefined\n}\n\n/** The hooks that `Syntax` combinators and `Parser.resumeAfter`/`retryAfter` call. */\nexport interface Builder {\n node<A>(state: State<any>, step: (state: State<any>) => A, key: Key, kind: string, named: boolean): A\n field<A>(state: State<any>, step: (state: State<any>) => A, name: string): A\n /** After error recovery: `[start, pos)` was skipped after `failure`. */\n skipped(start: number, failure: Failure, mode: ErrMode): void\n /**\n * Called by token parsers that read input up to `end` (exclusive) beyond\n * where they leave the cursor or record a failure.\n */\n read(end: number): void\n /** A failure or hint was recorded at `offset`. */\n reach(offset: number): void\n /** The cursor moved back from `from` to `to` (see `State.rewind`). */\n rewound(from: number, to: number): void\n}\n\n/**\n * The tree builder of a `Syntax` parse, reached through `state.syntax`. It\n * is not a `State` subclass: one class of state keeps every parser's cursor\n * and failure accesses monomorphic, whether or not the program also builds\n * syntax trees. `State` calls {@link reach} and {@link rewound} itself.\n */\nexport class SyntaxBuilder implements Builder {\n /**\n * The furthest position the cursor reached before a rewind, or failure\n * recorded, since the innermost open node started; {@link looked} adds\n * where the cursor is now.\n */\n highWater: number\n /** Completed nodes waiting for their parent, in input order. */\n readonly stack: Array<Child> = []\n /** How many nodes were reused from the previous tree. */\n reused = 0\n /** Where {@link find} found the last node it found. */\n lastParent: Green | undefined = undefined\n lastParentStart = 0\n\n constructor(\n readonly state: State<any>,\n readonly previous: Previous | undefined\n ) {\n this.highWater = state.pos\n state.syntax = this\n // Error recovery is always on: like Tree-sitter, a syntax parse always produces a tree\n state.recovered = []\n }\n\n reach(offset: number): void {\n if (offset > this.highWater) this.highWater = offset\n }\n\n rewound(from: number, to: number): void {\n if (from > this.highWater) this.highWater = from\n // An attempt was abandoned (or a lookahead finished): drop its nodes\n const stack = this.stack\n while (Arr.isArrayNonEmpty(stack) && Arr.lastNonEmpty(stack).end > to) stack.pop()\n }\n\n /** How far the parse looked: {@link highWater}, or the cursor if it is further. */\n private looked(): number {\n return this.state.pos > this.highWater ? this.state.pos : this.highWater\n }\n\n node<A>(state: State<any>, step: (state: State<any>) => A, key: Key, kind: string, named: boolean): A {\n const start = this.state.pos\n const stack = this.stack\n if (this.previous !== undefined) {\n const green = this.reusable(this.previous, key, start)\n if (green !== undefined) {\n this.reused++\n const end = start + green.width\n state.pos = end\n const looked = start + green.lookahead\n if (looked > this.highWater) this.highWater = looked\n const d = green.diagnostics\n if (d !== undefined) {\n if (d.deepest !== undefined) this.deepen(start === d.base ? d.deepest : rebase(d.deepest, d.base - start))\n if (d.hintExpected !== undefined) this.state.setHint(start + d.hintOffset, d.hintExpected)\n }\n stack.push(new Child(green, start, end, undefined))\n // SAFETY: `reusable` returns only a node built under this `key`, by this parser's `step`, whose value it holds\n return green.value as A\n }\n }\n const mark = stack.length\n const outer = this.highWater\n const outerDeepest = this.state.deepest\n const hintOffset = this.state.hintOffset\n const hintExpected = this.state.hintExpected\n this.highWater = start\n // Collect the furthest failure of this node alone, then merge it as `failWith` would have\n this.state.deepest = undefined\n const a = step(state)\n const looked = this.looked()\n this.highWater = outer > looked ? outer : looked\n const deepest = this.state.deepest\n this.state.deepest = outerDeepest\n if (deepest !== undefined) this.deepen(deepest)\n if (a === Fail) {\n if (stack.length > mark) stack.length = mark\n return a\n }\n const end = this.state.pos\n // Like Tree-sitter's rules, nodes are never empty: an empty match adds nothing to the tree\n if (end === start) return a\n const hinted = this.state.hintOffset !== hintOffset || this.state.hintExpected !== hintExpected\n const diagnostics: Diagnostics | undefined =\n deepest === undefined && !hinted\n ? undefined\n : {\n deepest,\n base: start,\n hintOffset: this.state.hintOffset - start,\n hintExpected: hinted ? this.state.hintExpected : undefined\n }\n const green = build(kind, named, key, start, end, looked, stack, mark, a, undefined, diagnostics)\n stack.length = mark\n stack.push(new Child(green, start, end, undefined))\n return a\n }\n\n read(end: number): void {\n // `highWater` is the last position looked at, `end` is exclusive\n if (end - 1 > this.highWater) this.highWater = end - 1\n }\n\n /** Records `failure` as the furthest failure if it is, as `failWith` does. */\n private deepen(failure: Failure): void {\n if (this.state.deepest === undefined || failure.offset >= this.state.deepest.offset) this.state.deepest = failure\n }\n\n field<A>(state: State<any>, step: (state: State<any>) => A, name: string): A {\n const stack = this.stack\n const mark = stack.length\n const a = step(state)\n if (a !== Fail) for (let i = mark; i < stack.length; i++) stack[i].field = name\n return a\n }\n\n skipped(start: number, failure: Failure, mode: ErrMode): void {\n const stack = this.stack\n let i = stack.length\n while (i > 0 && stack[i - 1].start >= start && stack[i - 1].end > start) i--\n const end = this.state.pos\n const green = build(errorKind, true, undefined, start, end, this.looked(), stack, i, undefined, {\n failure: rebase(failure, start),\n mode\n })\n stack.length = i\n stack.push(new Child(green, start, end, undefined))\n }\n\n /**\n * Builds the root over the whole input from the nodes left on the stack.\n * When the parse failed, or stopped before the end, the rest of the input\n * becomes an `ERROR` node.\n */\n finish(kind: string, value: unknown, fatal: ErrorInfo | undefined, errorStart: number): Green {\n const entries = this.stack.splice(0)\n const end = this.state.end\n if (fatal !== undefined) {\n const last = Arr.isArrayNonEmpty(entries) ? Arr.lastNonEmpty(entries).end : 0\n const start = Math.max(Math.min(errorStart, end), last)\n const error = build(errorKind, true, undefined, start, end, end, none, 0, undefined, {\n failure: rebase(fatal.failure, start),\n mode: fatal.mode\n })\n entries.push(new Child(error, start, end, undefined))\n }\n return build(kind, true, undefined, 0, end, Math.max(end, this.looked()), entries, 0, value, undefined)\n }\n\n /**\n * The outermost node of the previous tree built by `key` that starts at\n * `offset`. Reused nodes are mostly siblings, found one after the other,\n * so the search starts from the parent of the last one found when\n * `offset` lies inside it: no ancestor of that parent can start there.\n */\n private find(root: Green, offset: number, key: Key): Green | undefined {\n let node = root\n let start = 0\n const last = this.lastParent\n if (last !== undefined && offset > this.lastParentStart && offset < this.lastParentStart + last.width) {\n node = last\n start = this.lastParentStart\n }\n while (true) {\n const offsets = node.offsets\n // The last child starting at or before `offset`\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 (start + offsets[mid] <= offset) {\n found = mid\n lo = mid + 1\n } else {\n hi = mid - 1\n }\n }\n if (found < 0) return undefined\n const child = node.children[found]\n const childStart = start + offsets[found]\n if (offset >= childStart + child.width) return undefined\n if (childStart === offset && child.key === key) {\n this.lastParent = node\n this.lastParentStart = start\n return child\n }\n node = child\n start = childStart\n }\n }\n\n /** The node of the previous tree built by `key` at `pos` (in the new input), if it can be reused. */\n private reusable(previous: Previous, key: Key, pos: number): Green | undefined {\n const segments = previous.segments\n // The segment containing `pos`\n let lo = 0\n let hi = segments.length - 1\n while (lo <= hi) {\n const mid = (lo + hi) >> 1\n const seg = segments[mid]\n if (pos < seg.newStart) hi = mid - 1\n else if (pos >= seg.newStart + seg.length) lo = mid + 1\n else {\n const old = seg.oldStart + (pos - seg.newStart)\n const green = this.find(previous.root, old, key)\n if (green === undefined) return undefined\n const segEnd = seg.oldStart + seg.length\n // The input it looked at must be unchanged; past the end of both inputs counts as unchanged\n if (old + green.lookahead + tokenWidth(previous.input, old + green.lookahead) + previous.extra <= segEnd) {\n return green\n }\n if (segEnd === previous.oldLength && seg.newStart + seg.length === previous.newLength) return green\n return undefined\n }\n }\n return undefined\n }\n}\n\n/**\n * How many units a token parser may read at `offset`, where a parse\n * stopped looking: one code point. Of a string, that is two units at a high\n * surrogate. Of bytes in an unknown encoding, up to four.\n */\nconst tokenWidth = (input: Input, offset: number): number => {\n if (Predicate.isString(input)) {\n const c = input.charCodeAt(offset)\n return c >= 0xd800 && c <= 0xdbff ? 2 : 1\n }\n return input instanceof Uint8Array ? 4 : 1\n}\n"],"mappings":"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"}
@@ -13,6 +13,14 @@ export declare const End = -3;
13
13
  export declare const isEmptyUnits: (units: string | Uint8Array | ReadonlyArray<unknown>) => boolean;
14
14
  /** @internal */
15
15
  export declare const fastLimit: (enc: Encoding<any>) => number;
16
+ /**
17
+ * `String.fromCharCode`, seen as taking its argument list through `apply` as
18
+ * any array-like (which `Function.prototype.apply` accepts), such as a view of
19
+ * bytes.
20
+ */
21
+ export interface FromCharCodes {
22
+ readonly apply: (thisArg: null, codes: ArrayLike<number>) => string;
23
+ }
16
24
  /**
17
25
  * The code point that starts `s`: for a string known to hold one, such as
18
26
  * one element of `Array.from(string)`. On an empty string it is `NaN`, which,
@@ -26,6 +34,30 @@ export declare const charOf: (cp: number) => string;
26
34
  * slices are `String.prototype.slice`s, so no decoding is needed.
27
35
  */
28
36
  export declare const string: Encoding<string>;
37
+ /**
38
+ * The longest UTF-8 range built by hand: built eight ASCII bytes at a
39
+ * time, shorter ones are faster than a `TextDecoder` call, which costs
40
+ * about 120 ns whatever the length. Raising it past about 50 would also
41
+ * keep typical strings from {@link utf8Text}'s ASCII runs.
42
+ */
43
+ export declare const ShortText = 40;
44
+ /** A run of ASCII bytes, `[start, end)` of a state's input, and its text. */
45
+ export interface AsciiRun {
46
+ readonly start: number;
47
+ readonly end: number;
48
+ readonly text: string;
49
+ }
50
+ /**
51
+ * Decodes `[start, end)` of a state's UTF-8 input, as `utf8.text` does.
52
+ * Each `TextDecoder` call has a fixed cost of about 120 ns, more than
53
+ * slicing a string, so a long string inside a run of ASCII bytes (where a
54
+ * byte offset is a character offset) is sliced from the text of the whole
55
+ * run, decoded once and kept on the state; short strings, and those the run
56
+ * doesn't cover, are decoded as `utf8.text` decodes them.
57
+ */
58
+ export declare const utf8Text: (s: State<any>, start: number, end: number) => string;
59
+ /** Decodes `[start, end)` of a state's input in `enc`, through {@link utf8Text} for UTF-8. */
60
+ export declare const textIn: (enc: Encoding<any>, s: State<any>, start: number, end: number) => string;
29
61
  /** UTF-8 bytes. */
30
62
  export declare const utf8: Encoding<Uint8Array>;
31
63
  /** UTF-16 bytes, little endian. */
@@ -1 +1 @@
1
- {"version":3,"file":"text.d.ts","names":[],"sources":["../../src/internal/text.ts"],"mappings":";;;qBAWa;;qBAEA;;qBAEA;;;;;qBAgBA,eAAgB,gBAAgB,aAAa;;qBAQ7C,YAAa,KAAK;;;;;;qBAUlB,iBAAkB;;qBAGlB,SAAU;;;;;qBAkBV,QAAQ;;qBA8DR,MAAM,SAAS;;qBAuEf,SAAS,SAAS;;qBAGlB,SAAS,SAAS;;qBAGlB,QAAQ,SAAS;;mBA8BnB;;;;;;;qBAQE,OAAQ,KAAK,eAAe,OAAO,YAAY;;;;;qBAe/C,SACX,OAAO,YACP,YACA,MAAM,WAAW,wBACjB,UAAU,uBACV,oBACC;;mBAQQ;;mBAEA;;;;;mBAKA;;;;;qBAME,OACX,KAAK,eACL,OAAO,YACP,OAAO,wBACP,iBACA,aACA,cACA;;;;;qBA+DW,WAAY,KAAK,eAAe,OAAO,YAAY,eAAe;;;;;;qBA2BlE,OAAQ;;;;;qBAsBR,OACX,KAAK,eACL,gBAAgB,YAChB,eACA,aACA,IAAI,YAAY,gBAAgB;;qBAkBrB,cAAe,KAAK,eAAe,gBAAgB,YAAY,eAAe"}
1
+ {"version":3,"file":"text.d.ts","names":[],"sources":["../../src/internal/text.ts"],"mappings":";;;qBAWa;;qBAEA;;qBAEA;;;;;qBAgBA,eAAgB,gBAAgB,aAAa;;qBAQ7C,YAAa,KAAK;;;;;;iBAUd;WACN,QAAQ,eAAe,OAAO;;;;;;;qBAU5B,iBAAkB;;qBAGlB,SAAU;;;;;qBAmBV,QAAQ;;;;;;;qBA2ER;;iBAeI;WACN;WACA;WACA;;;;;;;;;;qBAcE,WAAY,GAAG,YAAY,eAAe;;qBAmB1C,SAAU,KAAK,eAAe,GAAG,YAAY,eAAe;;qBAK5D,MAAM,SAAS;;qBA0Ef,SAAS,SAAS;;qBAGlB,SAAS,SAAS;;qBAIlB,QAAQ,SAAS;;mBA+BnB;;;;;;;qBAQE,OAAQ,KAAK,eAAe,OAAO,YAAY;;;;;qBAe/C,SACX,OAAO,YACP,YACA,MAAM,WAAW,wBACjB,UAAU,uBACV,oBACC;;mBAQQ;;mBAEA;;;;;mBAKA;;;;;qBAME,OACX,KAAK,eACL,OAAO,YACP,OAAO,wBACP,iBACA,aACA,cACA;;;;;qBAiEW,WAAY,KAAK,eAAe,OAAO,YAAY,eAAe;;;;;;qBA2BlE,OAAQ;;;;;qBAsBR,OACX,KAAK,eACL,gBAAgB,YAChB,eACA,aACA,IAAI,YAAY,gBAAgB;;qBAkBrB,cAAe,KAAK,eAAe,gBAAgB,YAAY,eAAe"}
@@ -83,7 +83,34 @@ const decodeUtf8 = (b, i, end) => {
83
83
  }
84
84
  return -1;
85
85
  };
86
- const SHORT = 24;
86
+ const fromCharCode = String.fromCharCode;
87
+ /** How many of the (up to eight) bytes from `i` are ASCII; at least one, as `b[i]` is. */
88
+ const asciiPrefix = (b, i, end) => {
89
+ const n = end - i < 8 ? end - i : 8;
90
+ let k = 1;
91
+ while (k < n && b[i + k] < 128) k++;
92
+ return k;
93
+ };
94
+ /** The `n` (1 to 8) ASCII bytes from `i`, as a string. */
95
+ const asciiText = (b, i, n) => {
96
+ if (n === 8) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6], b[i + 7]);
97
+ if (n === 1) return asciiChars[b[i]];
98
+ if (n === 2) return fromCharCode(b[i], b[i + 1]);
99
+ if (n === 3) return fromCharCode(b[i], b[i + 1], b[i + 2]);
100
+ if (n === 4) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3]);
101
+ if (n === 5) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4]);
102
+ if (n === 6) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5]);
103
+ return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6]);
104
+ };
105
+ /** The longest UTF-16 range, in bytes, built by hand rather than by a `TextDecoder` call. */
106
+ const ShortUtf16 = 48;
107
+ /**
108
+ * The longest UTF-8 range built by hand: built eight ASCII bytes at a
109
+ * time, shorter ones are faster than a `TextDecoder` call, which costs
110
+ * about 120 ns whatever the length. Raising it past about 50 would also
111
+ * keep typical strings from {@link utf8Text}'s ASCII runs.
112
+ */
113
+ const ShortText = 40;
87
114
  const utf8Decoder = /*#__PURE__*/ new TextDecoder("utf-8", { ignoreBOM: true });
88
115
  /**
89
116
  * Decodes `b[start, end)`. Some platforms' `TextDecoder` rejects views of a
@@ -94,6 +121,35 @@ const decodeRange = (decoder, b, start, end) => {
94
121
  return decoder.decode(b.buffer instanceof ArrayBuffer ? view : view.slice());
95
122
  };
96
123
  const utf8Encoder = /*#__PURE__*/ new TextEncoder();
124
+ /** How far past a string {@link utf8Text} looks for the end of its ASCII run. */
125
+ const RunWindow = 16384;
126
+ /**
127
+ * Decodes `[start, end)` of a state's UTF-8 input, as `utf8.text` does.
128
+ * Each `TextDecoder` call has a fixed cost of about 120 ns, more than
129
+ * slicing a string, so a long string inside a run of ASCII bytes (where a
130
+ * byte offset is a character offset) is sliced from the text of the whole
131
+ * run, decoded once and kept on the state; short strings, and those the run
132
+ * doesn't cover, are decoded as `utf8.text` decodes them.
133
+ */
134
+ const utf8Text = (s, start, end) => {
135
+ const b = s.input;
136
+ if (end - start <= 40) return utf8.text(b, start, end);
137
+ const run = s.asciiRun;
138
+ if (run !== void 0 && start >= run.start && end <= run.end) return run.text.slice(start - run.start, end - run.start);
139
+ let e = start;
140
+ const limit = Math.min(s.end, end + RunWindow);
141
+ while (e < limit && b[e] < 128) e++;
142
+ if (e < end || e - start < 4 * (end - start)) return decodeRange(utf8Decoder, b, start, end);
143
+ const text = decodeRange(utf8Decoder, b, start, e);
144
+ s.asciiRun = {
145
+ start,
146
+ end: e,
147
+ text
148
+ };
149
+ return text.slice(0, end - start);
150
+ };
151
+ /** Decodes `[start, end)` of a state's input in `enc`, through {@link utf8Text} for UTF-8. */
152
+ const textIn = (enc, s, start, end) => enc === utf8 && end - start > 40 ? utf8Text(s, start, end) : enc.text(s.input, start, end);
97
153
  /** UTF-8 bytes. */
98
154
  const utf8 = {
99
155
  name: "UTF-8",
@@ -103,18 +159,16 @@ const utf8 = {
103
159
  width: (cp) => cp < 128 ? 1 : cp < 2048 ? 2 : cp < 65536 ? 3 : 4,
104
160
  encode: (text) => utf8Encoder.encode(text),
105
161
  text: (b, start, end) => {
106
- if (end - start > SHORT) return decodeRange(utf8Decoder, b, start, end);
162
+ if (end - start > 40) return decodeRange(utf8Decoder, b, start, end);
107
163
  let out = "";
108
- for (let i = start; i < end;) {
109
- const c = b[i];
110
- if (c < 128) {
111
- out += asciiChars[c];
112
- i++;
113
- } else {
114
- const cp = decodeUtf8(b, i, end);
115
- out += cp < 65536 ? String.fromCharCode(cp) : String.fromCodePoint(cp);
116
- i += cp < 2048 ? 2 : cp < 65536 ? 3 : 4;
117
- }
164
+ for (let i = start; i < end;) if (b[i] < 128) {
165
+ const n = asciiPrefix(b, i, end);
166
+ out += asciiText(b, i, n);
167
+ i += n;
168
+ } else {
169
+ const cp = decodeUtf8(b, i, end);
170
+ out += cp < 65536 ? String.fromCharCode(cp) : String.fromCodePoint(cp);
171
+ i += cp < 2048 ? 2 : cp < 65536 ? 3 : 4;
118
172
  }
119
173
  return out;
120
174
  },
@@ -148,7 +202,7 @@ const makeUtf16 = (littleEndian) => {
148
202
  return out;
149
203
  },
150
204
  text: (b, start, end) => {
151
- if (end - start <= 48) {
205
+ if (end - start <= ShortUtf16) {
152
206
  let out = "";
153
207
  for (let i = start; i < end; i += 2) out += String.fromCharCode(b[i + lo] | b[i + hi] << 8);
154
208
  return out;
@@ -345,6 +399,6 @@ const lenientText = (enc, input, start, end) => {
345
399
  });
346
400
  return out;
347
401
  };
348
- export { End, Invalid, Truncated, charOf, failAt, fastLimit, firstCodePoint, fold, isEmptyUnits, latin1, lenientText, next, scan, scanCount, scanOffset, scanStop, string, utf16be, utf16le, utf8, validate, walk, width };
402
+ export { End, Invalid, ShortText, Truncated, charOf, failAt, fastLimit, firstCodePoint, fold, isEmptyUnits, latin1, lenientText, next, scan, scanCount, scanOffset, scanStop, string, textIn, utf16be, utf16le, utf8, utf8Text, validate, walk, width };
349
403
 
350
404
  //# sourceMappingURL=text.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","names":[],"sources":["../../src/internal/text.ts"],"sourcesContent":["import * as Arr from \"effect/Array\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Str from \"effect/String\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { Fail, State } from \"../Input.js\"\n\n// -----------------------------------------------------------------------------\n// Decoding results\n// -----------------------------------------------------------------------------\n\n/** `Encoding.decode`: the input is malformed. */\nexport const Invalid = -1\n/** `Encoding.decode`: the input ends inside a sequence. */\nexport const Truncated = -2\n/** `next`: the input has ended. */\nexport const End = -3\n\n// -----------------------------------------------------------------------------\n// Encodings\n// -----------------------------------------------------------------------------\n\n/**\n * Units below this value decode to themselves with width 1, so hot loops can\n * skip `decode`. Defaults to 0x80 for ASCII compatible encodings.\n */\nconst FastLimit: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Encoding/FastLimit\")\n\n/**\n * Whether an input, a literal or a chunk has no units (characters, bytes or\n * tokens).\n */\nexport const isEmptyUnits = (units: string | Uint8Array | ReadonlyArray<unknown>): boolean =>\n Predicate.isString(units)\n ? Str.isEmpty(units)\n : units instanceof Uint8Array\n ? units.byteLength === 0\n : Arr.isReadonlyArrayEmpty(units)\n\n/** @internal */\nexport const fastLimit = (enc: Encoding<any>): number =>\n (enc as any)[FastLimit] ?? (enc.asciiCompatible && enc.unit === 1 ? 0x80 : 0)\n\nconst asciiChars: ReadonlyArray<string> = /*#__PURE__*/ Array.from({ length: 128 }, (_, i) => String.fromCharCode(i))\n\n/**\n * The code point that starts `s`: for a string known to hold one, such as\n * one element of `Array.from(string)`. On an empty string it is `NaN`, which,\n * like the `undefined` of `codePointAt(0)`, matches no code point.\n */\nexport const firstCodePoint = (s: string): number => s.codePointAt(0) ?? Number.NaN\n\n/** `String.fromCodePoint`, with the ASCII characters cached. */\nexport const charOf = (cp: number): string =>\n cp < 128 ? asciiChars[cp] : cp < 0x10000 ? String.fromCharCode(cp) : String.fromCodePoint(cp)\n\nconst decodeString = (s: string, i: number, end: number): number => {\n const c = s.charCodeAt(i)\n if ((c & 0xf800) !== 0xd800) return c\n if (c <= 0xdbff) {\n if (i + 1 >= end) return Truncated\n const d = s.charCodeAt(i + 1)\n if ((d & 0xfc00) === 0xdc00) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return Invalid\n}\n\n/**\n * JavaScript strings: UTF-16 code units. Offsets are code-unit indices and\n * slices are `String.prototype.slice`s, so no decoding is needed.\n */\nexport const string: Encoding<string> = {\n name: \"UTF-16\",\n unit: 1,\n asciiCompatible: true,\n decode: decodeString,\n width: (cp) => (cp > 0xffff ? 2 : 1),\n encode: (text) => text,\n text: (s, start, end) => s.slice(start, end),\n [FastLimit]: 0xd800\n} as Encoding<string>\n\nconst decodeUtf8 = (b: Uint8Array, i: number, end: number): number => {\n const c = b[i]\n if (c < 0x80) return c\n if (c < 0xc2) return Invalid\n if (c < 0xe0) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n return (d & 0xc0) === 0x80 ? ((c & 0x1f) << 6) | (d & 0x3f) : Invalid\n }\n if (c < 0xf0) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n // Reject overlong encodings (E0 80..9F) and surrogates (ED A0..BF)\n if (c === 0xe0 ? d < 0xa0 || d > 0xbf : c === 0xed ? d < 0x80 || d > 0x9f : (d & 0xc0) !== 0x80) return Invalid\n if (i + 2 >= end) return Truncated\n const e = b[i + 2]\n return (e & 0xc0) === 0x80 ? ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (e & 0x3f) : Invalid\n }\n if (c < 0xf5) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n // Reject overlong encodings (F0 80..8F) and code points above U+10FFFF (F4 90..BF)\n if (c === 0xf0 ? d < 0x90 || d > 0xbf : c === 0xf4 ? d < 0x80 || d > 0x8f : (d & 0xc0) !== 0x80) return Invalid\n if (i + 2 >= end) return Truncated\n const e = b[i + 2]\n if ((e & 0xc0) !== 0x80) return Invalid\n if (i + 3 >= end) return Truncated\n const f = b[i + 3]\n return (f & 0xc0) === 0x80 ? ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((e & 0x3f) << 6) | (f & 0x3f) : Invalid\n }\n return Invalid\n}\n\n// Building short strings by hand is several times faster than a\n// `TextDecoder` call, which has a high fixed cost.\nconst SHORT = 24\n\nconst utf8Decoder = /*#__PURE__*/ new TextDecoder(\"utf-8\", { ignoreBOM: true })\n\n/**\n * Decodes `b[start, end)`. Some platforms' `TextDecoder` rejects views of a\n * `SharedArrayBuffer`, so those are copied first.\n */\nconst decodeRange = (decoder: TextDecoder, b: Uint8Array, start: number, end: number): string => {\n const view = b.subarray(start, end)\n return decoder.decode(b.buffer instanceof ArrayBuffer ? view : view.slice())\n}\nconst utf8Encoder = /*#__PURE__*/ new TextEncoder()\n\n/** UTF-8 bytes. */\n// SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\nexport const utf8: Encoding<Uint8Array> = {\n name: \"UTF-8\",\n unit: 1,\n asciiCompatible: true,\n decode: decodeUtf8,\n width: (cp) => (cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4),\n encode: (text) => utf8Encoder.encode(text),\n text: (b, start, end) => {\n if (end - start > SHORT) return decodeRange(utf8Decoder, b, start, end)\n let out = \"\"\n for (let i = start; i < end;) {\n const c = b[i]\n if (c < 0x80) {\n out += asciiChars[c]\n i++\n } else {\n const cp = decodeUtf8(b, i, end)\n out += cp < 0x10000 ? String.fromCharCode(cp) : String.fromCodePoint(cp)\n i += cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4\n }\n }\n return out\n },\n // Every built-in encoding has the same keys in the same order, so code\n // reading them sees one object shape\n [FastLimit]: 0x80\n} as Encoding<Uint8Array>\n\nconst makeUtf16 = (littleEndian: boolean): Encoding<Uint8Array> => {\n const lo = littleEndian ? 0 : 1\n const hi = 1 - lo\n let decoder: TextDecoder | undefined\n // SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\n return {\n name: littleEndian ? \"UTF-16LE\" : \"UTF-16BE\",\n unit: 2,\n asciiCompatible: false,\n decode: (b, i, end) => {\n if (i + 1 >= end) return Truncated\n const c = b[i + lo] | (b[i + hi] << 8)\n if ((c & 0xf800) !== 0xd800) return c\n if (c > 0xdbff) return Invalid\n if (i + 3 >= end) return Truncated\n const d = b[i + 2 + lo] | (b[i + 2 + hi] << 8)\n return (d & 0xfc00) === 0xdc00 ? ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000 : Invalid\n },\n width: (cp) => (cp > 0xffff ? 4 : 2),\n encode: (text) => {\n const out = new Uint8Array(text.length * 2)\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i)\n out[2 * i + lo] = c & 0xff\n out[2 * i + hi] = c >> 8\n }\n return out\n },\n text: (b, start, end) => {\n if (end - start <= SHORT * 2) {\n // The range is well formed, so surrogate pairs can be copied unit by unit\n let out = \"\"\n for (let i = start; i < end; i += 2) out += String.fromCharCode(b[i + lo] | (b[i + hi] << 8))\n return out\n }\n decoder ??= new TextDecoder(littleEndian ? \"utf-16le\" : \"utf-16be\", { ignoreBOM: true })\n return decodeRange(decoder, b, start, end)\n },\n [FastLimit]: 0\n } as Encoding<Uint8Array>\n}\n\n/** UTF-16 bytes, little endian. */\nexport const utf16le: Encoding<Uint8Array> = /*#__PURE__*/ makeUtf16(true)\n\n/** UTF-16 bytes, big endian. */\nexport const utf16be: Encoding<Uint8Array> = /*#__PURE__*/ makeUtf16(false)\n\n/** ISO-8859-1: every byte is the code point of the same value. */\nexport const latin1: Encoding<Uint8Array> = {\n name: \"ISO-8859-1\",\n unit: 1,\n asciiCompatible: true,\n decode: (b, i) => b[i],\n width: () => 1,\n encode: (text) => {\n const out = new Uint8Array(text.length)\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i)\n if (c > 0xff) throw new RangeError(`${JSON.stringify(text[i])} can't be encoded as ISO-8859-1`)\n out[i] = c\n }\n return out\n },\n text: (b, start, end) => {\n let out = \"\"\n for (let i = start; i < end; i += 8192) {\n out += String.fromCharCode.apply(null, b.subarray(i, Math.min(end, i + 8192)) as unknown as Array<number>)\n }\n return out\n },\n [FastLimit]: 0x100\n} as Encoding<Uint8Array>\n\n// -----------------------------------------------------------------------------\n// Reading code points from a State\n// -----------------------------------------------------------------------------\n\n/** The width of the code point returned by the latest {@link next}. */\nexport let width = 0\n\n/**\n * Decodes the code point at the cursor without consuming it. Returns the\n * code point (setting {@link width}), {@link End}, {@link Invalid}, or\n * {@link Truncated} (only for partial input; on complete input a truncated\n * sequence is {@link Invalid}).\n */\nexport const next = (enc: Encoding<any>, state: State<any>, pos: number = state.pos): number => {\n const end = state.end\n if (pos >= end) return End\n const cp = enc.decode(state.input, pos, end)\n if (cp >= 0) {\n width = enc.width(cp)\n return cp\n }\n return cp === Truncated && !state.partial ? Invalid : cp\n}\n\n/**\n * Fails a parser that expected a code point but found `cp` (one of the\n * negative results of {@link next}, or a code point that did not match).\n */\nexport const failAt = (\n state: State<any>,\n cp: number,\n kind: Parameters<State[\"backtrack\"]>[0],\n expected: ReadonlyArray<string>,\n offset: number = state.pos\n): Fail => {\n if (cp === End) return state.eoi(kind, expected, 1)\n if (cp === Truncated) return state.incomplete(1, expected)\n return state.backtrack(kind, expected, offset)\n}\n\n// Results of `scan`, kept in module variables to avoid allocating\n/** Offset reached by the latest {@link scan}. */\nexport let scanOffset = 0\n/** Number of code points matched by the latest {@link scan}. */\nexport let scanCount = 0\n/**\n * Why the latest {@link scan} stopped: 0 = a non-matching code point or the\n * maximum count, or one of {@link End}, {@link Invalid}, {@link Truncated}.\n */\nexport let scanStop = 0\n\n/**\n * Scans code points from `pos` while `test(cp) !== negate`, up to `max`\n * code points. `fast` is `fastLimit(enc)`, which callers can precompute.\n */\nexport const scan = (\n enc: Encoding<any>,\n state: State<any>,\n test: (cp: number) => boolean,\n negate: boolean,\n max: number,\n pos: number = state.pos,\n fast: number = fastLimit(enc)\n): void => {\n const end = state.end\n const decode = enc.decode\n let i = pos\n let count = 0\n let stop = 0\n if (state.inputKind === 0) {\n const s = state.input as string\n while (count < max) {\n if (i >= end) {\n stop = End\n break\n }\n const c = s.charCodeAt(i)\n if (c < fast) {\n if (test(c) === negate) break\n i++\n } else {\n const cp = decode(s, i, end)\n if (cp < 0) {\n stop = cp === Truncated && state.partial ? Truncated : Invalid\n break\n }\n if (test(cp) === negate) break\n i += enc.width(cp)\n }\n count++\n }\n } else {\n const b = state.input as Uint8Array\n while (count < max) {\n if (i >= end) {\n stop = End\n break\n }\n const c = b[i]\n if (c < fast) {\n if (test(c) === negate) break\n i++\n } else {\n const cp = decode(b, i, end)\n if (cp < 0) {\n stop = cp === Truncated && state.partial ? Truncated : Invalid\n break\n }\n if (test(cp) === negate) break\n i += enc.width(cp)\n }\n count++\n }\n }\n scanOffset = i\n scanCount = count\n scanStop = stop\n}\n\nconst always = () => true\n\n/**\n * Checks that `[start, end)` is well formed, counting its code points.\n * Returns the count, or `-1 - offset` of the first malformed sequence.\n */\nexport const validate = (enc: Encoding<any>, state: State<any>, start: number, end: number): number => {\n const savedEnd = state.end\n const savedPartial = state.partial\n state.end = end\n state.partial = false\n scan(enc, state, always, false, Infinity, start)\n state.end = savedEnd\n state.partial = savedPartial\n return scanStop === Invalid ? -1 - scanOffset : scanCount\n}\n\n// -----------------------------------------------------------------------------\n// Case folding\n// -----------------------------------------------------------------------------\n\nconst foldCache = /*#__PURE__*/ new Map<number, number>()\n\nconst single = (s: string): number => {\n const cp = firstCodePoint(s)\n return s.length === (cp > 0xffff ? 2 : 1) ? cp : -1\n}\n\n/**\n * Simple case folding of a code point: the lowercase of its uppercase, when\n * both map to a single code point (so `\"K\"` (Kelvin) and `\"ſ\"` fold to `\"k\"`\n * and `\"s\"`), otherwise the code point itself.\n */\nexport const fold = (cp: number): number => {\n if (cp < 128) return cp >= 65 && cp <= 90 ? cp + 32 : cp\n let f = foldCache.get(cp)\n if (f === undefined) {\n const c = String.fromCodePoint(cp)\n const upper = c.toUpperCase()\n const viaUpper = single(upper) >= 0 ? single(upper.toLowerCase()) : -1\n f = viaUpper >= 0 ? viaUpper : single(c.toLowerCase())\n if (f < 0) f = cp\n foldCache.set(cp, f)\n }\n return f\n}\n\n// -----------------------------------------------------------------------------\n// Error rendering\n// -----------------------------------------------------------------------------\n\n/**\n * Walks the code points of `[start, end)` leniently: malformed sequences\n * are reported as `-1` and skipped one code unit at a time.\n */\nexport const walk = (\n enc: Encoding<any>,\n input: string | Uint8Array,\n start: number,\n end: number,\n f: (cp: number, offset: number, width: number) => boolean | void\n): void => {\n let i = start\n while (i < end) {\n let cp = enc.decode(input, i, end)\n let w: number\n if (cp >= 0) {\n w = enc.width(cp)\n } else {\n cp = -1\n w = Math.min(enc.unit, end - i)\n }\n if (f(cp, i, w) === false) return\n i += w\n }\n}\n\n/** Decodes `[start, end)`, replacing malformed sequences with U+FFFD. */\nexport const lenientText = (enc: Encoding<any>, input: string | Uint8Array, start: number, end: number): string => {\n let out = \"\"\n walk(enc, input, start, end, (cp) => {\n out += cp < 0 ? \"�\" : charOf(cp)\n })\n return out\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"text.js","names":[],"sources":["../../src/internal/text.ts"],"sourcesContent":["import * as Arr from \"effect/Array\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Str from \"effect/String\"\nimport type { Encoding } from \"../Encoding.js\"\nimport type { Fail, State } from \"../Input.js\"\n\n// -----------------------------------------------------------------------------\n// Decoding results\n// -----------------------------------------------------------------------------\n\n/** `Encoding.decode`: the input is malformed. */\nexport const Invalid = -1\n/** `Encoding.decode`: the input ends inside a sequence. */\nexport const Truncated = -2\n/** `next`: the input has ended. */\nexport const End = -3\n\n// -----------------------------------------------------------------------------\n// Encodings\n// -----------------------------------------------------------------------------\n\n/**\n * Units below this value decode to themselves with width 1, so hot loops can\n * skip `decode`. Defaults to 0x80 for ASCII compatible encodings.\n */\nconst FastLimit: unique symbol = /*#__PURE__*/ Symbol.for(\"effect-parse/Encoding/FastLimit\")\n\n/**\n * Whether an input, a literal or a chunk has no units (characters, bytes or\n * tokens).\n */\nexport const isEmptyUnits = (units: string | Uint8Array | ReadonlyArray<unknown>): boolean =>\n Predicate.isString(units)\n ? Str.isEmpty(units)\n : units instanceof Uint8Array\n ? units.byteLength === 0\n : Arr.isReadonlyArrayEmpty(units)\n\n/** @internal */\nexport const fastLimit = (enc: Encoding<any>): number =>\n // SAFETY: the built-in encodings carry the internal `FastLimit` key; on any other encoding it reads `undefined`\n (enc as Encoding<any> & { readonly [FastLimit]?: number })[FastLimit] ??\n (enc.asciiCompatible && enc.unit === 1 ? 0x80 : 0)\n\n/**\n * `String.fromCharCode`, seen as taking its argument list through `apply` as\n * any array-like (which `Function.prototype.apply` accepts), such as a view of\n * bytes.\n */\nexport interface FromCharCodes {\n readonly apply: (thisArg: null, codes: ArrayLike<number>) => string\n}\n\nconst asciiChars: ReadonlyArray<string> = /*#__PURE__*/ Array.from({ length: 128 }, (_, i) => String.fromCharCode(i))\n\n/**\n * The code point that starts `s`: for a string known to hold one, such as\n * one element of `Array.from(string)`. On an empty string it is `NaN`, which,\n * like the `undefined` of `codePointAt(0)`, matches no code point.\n */\nexport const firstCodePoint = (s: string): number => s.codePointAt(0) ?? Number.NaN\n\n/** `String.fromCodePoint`, with the ASCII characters cached. */\nexport const charOf = (cp: number): string =>\n cp < 128 ? asciiChars[cp] : cp < 0x10000 ? String.fromCharCode(cp) : String.fromCodePoint(cp)\n\nconst decodeString = (s: string, i: number, end: number): number => {\n const c = s.charCodeAt(i)\n if ((c & 0xf800) !== 0xd800) return c\n if (c <= 0xdbff) {\n if (i + 1 >= end) return Truncated\n const d = s.charCodeAt(i + 1)\n if ((d & 0xfc00) === 0xdc00) return ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000\n }\n return Invalid\n}\n\n/**\n * JavaScript strings: UTF-16 code units. Offsets are code-unit indices and\n * slices are `String.prototype.slice`s, so no decoding is needed.\n */\n// SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\nexport const string: Encoding<string> = {\n name: \"UTF-16\",\n unit: 1,\n asciiCompatible: true,\n decode: decodeString,\n width: (cp) => (cp > 0xffff ? 2 : 1),\n encode: (text) => text,\n text: (s, start, end) => s.slice(start, end),\n [FastLimit]: 0xd800\n} as Encoding<string>\n\nconst decodeUtf8 = (b: Uint8Array, i: number, end: number): number => {\n const c = b[i]\n if (c < 0x80) return c\n if (c < 0xc2) return Invalid\n if (c < 0xe0) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n return (d & 0xc0) === 0x80 ? ((c & 0x1f) << 6) | (d & 0x3f) : Invalid\n }\n if (c < 0xf0) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n // Reject overlong encodings (E0 80..9F) and surrogates (ED A0..BF)\n if (c === 0xe0 ? d < 0xa0 || d > 0xbf : c === 0xed ? d < 0x80 || d > 0x9f : (d & 0xc0) !== 0x80) return Invalid\n if (i + 2 >= end) return Truncated\n const e = b[i + 2]\n return (e & 0xc0) === 0x80 ? ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (e & 0x3f) : Invalid\n }\n if (c < 0xf5) {\n if (i + 1 >= end) return Truncated\n const d = b[i + 1]\n // Reject overlong encodings (F0 80..8F) and code points above U+10FFFF (F4 90..BF)\n if (c === 0xf0 ? d < 0x90 || d > 0xbf : c === 0xf4 ? d < 0x80 || d > 0x8f : (d & 0xc0) !== 0x80) return Invalid\n if (i + 2 >= end) return Truncated\n const e = b[i + 2]\n if ((e & 0xc0) !== 0x80) return Invalid\n if (i + 3 >= end) return Truncated\n const f = b[i + 3]\n return (f & 0xc0) === 0x80 ? ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((e & 0x3f) << 6) | (f & 0x3f) : Invalid\n }\n return Invalid\n}\n\nconst fromCharCode = String.fromCharCode\n\n/** How many of the (up to eight) bytes from `i` are ASCII; at least one, as `b[i]` is. */\nconst asciiPrefix = (b: Uint8Array, i: number, end: number): number => {\n const n = end - i < 8 ? end - i : 8\n let k = 1\n while (k < n && b[i + k] < 0x80) k++\n return k\n}\n\n/** The `n` (1 to 8) ASCII bytes from `i`, as a string. */\nconst asciiText = (b: Uint8Array, i: number, n: number): string => {\n if (n === 8) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6], b[i + 7])\n if (n === 1) return asciiChars[b[i]]\n if (n === 2) return fromCharCode(b[i], b[i + 1])\n if (n === 3) return fromCharCode(b[i], b[i + 1], b[i + 2])\n if (n === 4) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3])\n if (n === 5) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4])\n if (n === 6) return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5])\n return fromCharCode(b[i], b[i + 1], b[i + 2], b[i + 3], b[i + 4], b[i + 5], b[i + 6])\n}\n\n/** The longest UTF-16 range, in bytes, built by hand rather than by a `TextDecoder` call. */\nconst ShortUtf16 = 48\n\n/**\n * The longest UTF-8 range built by hand: built eight ASCII bytes at a\n * time, shorter ones are faster than a `TextDecoder` call, which costs\n * about 120 ns whatever the length. Raising it past about 50 would also\n * keep typical strings from {@link utf8Text}'s ASCII runs.\n */\nexport const ShortText = 40\n\nconst utf8Decoder = /*#__PURE__*/ new TextDecoder(\"utf-8\", { ignoreBOM: true })\n\n/**\n * Decodes `b[start, end)`. Some platforms' `TextDecoder` rejects views of a\n * `SharedArrayBuffer`, so those are copied first.\n */\nconst decodeRange = (decoder: TextDecoder, b: Uint8Array, start: number, end: number): string => {\n const view = b.subarray(start, end)\n return decoder.decode(b.buffer instanceof ArrayBuffer ? view : view.slice())\n}\nconst utf8Encoder = /*#__PURE__*/ new TextEncoder()\n\n/** A run of ASCII bytes, `[start, end)` of a state's input, and its text. */\nexport interface AsciiRun {\n readonly start: number\n readonly end: number\n readonly text: string\n}\n\n/** How far past a string {@link utf8Text} looks for the end of its ASCII run. */\nconst RunWindow = 16384\n\n/**\n * Decodes `[start, end)` of a state's UTF-8 input, as `utf8.text` does.\n * Each `TextDecoder` call has a fixed cost of about 120 ns, more than\n * slicing a string, so a long string inside a run of ASCII bytes (where a\n * byte offset is a character offset) is sliced from the text of the whole\n * run, decoded once and kept on the state; short strings, and those the run\n * doesn't cover, are decoded as `utf8.text` decodes them.\n */\nexport const utf8Text = (s: State<any>, start: number, end: number): string => {\n // SAFETY: called only by `Text.utf8` parsers, whose input is bytes\n const b = s.input as Uint8Array\n // `textIn` and the JIT check this themselves before calling\n if (end - start <= ShortText) return utf8.text(b, start, end)\n const run = s.asciiRun\n if (run !== undefined && start >= run.start && end <= run.end)\n return run.text.slice(start - run.start, end - run.start)\n let e = start\n const limit = Math.min(s.end, end + RunWindow)\n while (e < limit && b[e] < 0x80) e++\n // Only worth it when the run holds more than this string\n if (e < end || e - start < 4 * (end - start)) return decodeRange(utf8Decoder, b, start, end)\n const text = decodeRange(utf8Decoder, b, start, e)\n s.asciiRun = { start, end: e, text }\n return text.slice(0, end - start)\n}\n\n/** Decodes `[start, end)` of a state's input in `enc`, through {@link utf8Text} for UTF-8. */\nexport const textIn = (enc: Encoding<any>, s: State<any>, start: number, end: number): string =>\n enc === utf8 && end - start > ShortText ? utf8Text(s, start, end) : enc.text(s.input, start, end)\n\n/** UTF-8 bytes. */\n// SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\nexport const utf8: Encoding<Uint8Array> = {\n name: \"UTF-8\",\n unit: 1,\n asciiCompatible: true,\n decode: decodeUtf8,\n width: (cp) => (cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4),\n encode: (text) => utf8Encoder.encode(text),\n text: (b, start, end) => {\n if (end - start > ShortText) return decodeRange(utf8Decoder, b, start, end)\n let out = \"\"\n for (let i = start; i < end;) {\n const c = b[i]\n if (c < 0x80) {\n // Up to eight ASCII bytes in one call: a string a character at a\n // time costs about 8 ns a character, eight in one call about 20 ns\n const n = asciiPrefix(b, i, end)\n out += asciiText(b, i, n)\n i += n\n } else {\n const cp = decodeUtf8(b, i, end)\n out += cp < 0x10000 ? String.fromCharCode(cp) : String.fromCodePoint(cp)\n i += cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4\n }\n }\n return out\n },\n // Every built-in encoding has the same keys in the same order, so code\n // reading them sees one object shape\n [FastLimit]: 0x80\n} as Encoding<Uint8Array>\n\nconst makeUtf16 = (littleEndian: boolean): Encoding<Uint8Array> => {\n const lo = littleEndian ? 0 : 1\n const hi = 1 - lo\n let decoder: TextDecoder | undefined\n // SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\n return {\n name: littleEndian ? \"UTF-16LE\" : \"UTF-16BE\",\n unit: 2,\n asciiCompatible: false,\n decode: (b, i, end) => {\n if (i + 1 >= end) return Truncated\n const c = b[i + lo] | (b[i + hi] << 8)\n if ((c & 0xf800) !== 0xd800) return c\n if (c > 0xdbff) return Invalid\n if (i + 3 >= end) return Truncated\n const d = b[i + 2 + lo] | (b[i + 2 + hi] << 8)\n return (d & 0xfc00) === 0xdc00 ? ((c - 0xd800) << 10) + (d - 0xdc00) + 0x10000 : Invalid\n },\n width: (cp) => (cp > 0xffff ? 4 : 2),\n encode: (text) => {\n const out = new Uint8Array(text.length * 2)\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i)\n out[2 * i + lo] = c & 0xff\n out[2 * i + hi] = c >> 8\n }\n return out\n },\n text: (b, start, end) => {\n if (end - start <= ShortUtf16) {\n // The range is well formed, so surrogate pairs can be copied unit by unit\n let out = \"\"\n for (let i = start; i < end; i += 2) out += String.fromCharCode(b[i + lo] | (b[i + hi] << 8))\n return out\n }\n decoder ??= new TextDecoder(littleEndian ? \"utf-16le\" : \"utf-16be\", { ignoreBOM: true })\n return decodeRange(decoder, b, start, end)\n },\n [FastLimit]: 0\n } as Encoding<Uint8Array>\n}\n\n/** UTF-16 bytes, little endian. */\nexport const utf16le: Encoding<Uint8Array> = /*#__PURE__*/ makeUtf16(true)\n\n/** UTF-16 bytes, big endian. */\nexport const utf16be: Encoding<Uint8Array> = /*#__PURE__*/ makeUtf16(false)\n\n/** ISO-8859-1: every byte is the code point of the same value. */\n// SAFETY: an `Encoding` with the internal `FastLimit` key, which its type doesn't declare\nexport const latin1: Encoding<Uint8Array> = {\n name: \"ISO-8859-1\",\n unit: 1,\n asciiCompatible: true,\n decode: (b, i) => b[i],\n width: () => 1,\n encode: (text) => {\n const out = new Uint8Array(text.length)\n for (let i = 0; i < text.length; i++) {\n const c = text.charCodeAt(i)\n if (c > 0xff) throw new RangeError(`${JSON.stringify(text[i])} can't be encoded as ISO-8859-1`)\n out[i] = c\n }\n return out\n },\n text: (b, start, end) => {\n let out = \"\"\n for (let i = start; i < end; i += 8192) {\n // SAFETY: `apply` takes any array-like argument list, so each byte of the view is passed as a char code\n out += (String.fromCharCode as FromCharCodes).apply(null, b.subarray(i, Math.min(end, i + 8192)))\n }\n return out\n },\n [FastLimit]: 0x100\n} as Encoding<Uint8Array>\n\n// -----------------------------------------------------------------------------\n// Reading code points from a State\n// -----------------------------------------------------------------------------\n\n/** The width of the code point returned by the latest {@link next}. */\nexport let width = 0\n\n/**\n * Decodes the code point at the cursor without consuming it. Returns the\n * code point (setting {@link width}), {@link End}, {@link Invalid}, or\n * {@link Truncated} (only for partial input; on complete input a truncated\n * sequence is {@link Invalid}).\n */\nexport const next = (enc: Encoding<any>, state: State<any>, pos: number = state.pos): number => {\n const end = state.end\n if (pos >= end) return End\n const cp = enc.decode(state.input, pos, end)\n if (cp >= 0) {\n width = enc.width(cp)\n return cp\n }\n return cp === Truncated && !state.partial ? Invalid : cp\n}\n\n/**\n * Fails a parser that expected a code point but found `cp` (one of the\n * negative results of {@link next}, or a code point that did not match).\n */\nexport const failAt = (\n state: State<any>,\n cp: number,\n kind: Parameters<State[\"backtrack\"]>[0],\n expected: ReadonlyArray<string>,\n offset: number = state.pos\n): Fail => {\n if (cp === End) return state.eoi(kind, expected, 1)\n if (cp === Truncated) return state.incomplete(1, expected)\n return state.backtrack(kind, expected, offset)\n}\n\n// Results of `scan`, kept in module variables to avoid allocating\n/** Offset reached by the latest {@link scan}. */\nexport let scanOffset = 0\n/** Number of code points matched by the latest {@link scan}. */\nexport let scanCount = 0\n/**\n * Why the latest {@link scan} stopped: 0 = a non-matching code point or the\n * maximum count, or one of {@link End}, {@link Invalid}, {@link Truncated}.\n */\nexport let scanStop = 0\n\n/**\n * Scans code points from `pos` while `test(cp) !== negate`, up to `max`\n * code points. `fast` is `fastLimit(enc)`, which callers can precompute.\n */\nexport const scan = (\n enc: Encoding<any>,\n state: State<any>,\n test: (cp: number) => boolean,\n negate: boolean,\n max: number,\n pos: number = state.pos,\n fast: number = fastLimit(enc)\n): void => {\n const end = state.end\n const decode = enc.decode\n let i = pos\n let count = 0\n let stop = 0\n if (state.inputKind === 0) {\n // SAFETY: `inputKind` 0 is set only for a string input\n const s = state.input as string\n while (count < max) {\n if (i >= end) {\n stop = End\n break\n }\n const c = s.charCodeAt(i)\n if (c < fast) {\n if (test(c) === negate) break\n i++\n } else {\n const cp = decode(s, i, end)\n if (cp < 0) {\n stop = cp === Truncated && state.partial ? Truncated : Invalid\n break\n }\n if (test(cp) === negate) break\n i += enc.width(cp)\n }\n count++\n }\n } else {\n // SAFETY: an encoding's input is a string or a `Uint8Array`, and `inputKind` is not 0, so a `Uint8Array`\n const b = state.input as Uint8Array\n while (count < max) {\n if (i >= end) {\n stop = End\n break\n }\n const c = b[i]\n if (c < fast) {\n if (test(c) === negate) break\n i++\n } else {\n const cp = decode(b, i, end)\n if (cp < 0) {\n stop = cp === Truncated && state.partial ? Truncated : Invalid\n break\n }\n if (test(cp) === negate) break\n i += enc.width(cp)\n }\n count++\n }\n }\n scanOffset = i\n scanCount = count\n scanStop = stop\n}\n\nconst always = () => true\n\n/**\n * Checks that `[start, end)` is well formed, counting its code points.\n * Returns the count, or `-1 - offset` of the first malformed sequence.\n */\nexport const validate = (enc: Encoding<any>, state: State<any>, start: number, end: number): number => {\n const savedEnd = state.end\n const savedPartial = state.partial\n state.end = end\n state.partial = false\n scan(enc, state, always, false, Infinity, start)\n state.end = savedEnd\n state.partial = savedPartial\n return scanStop === Invalid ? -1 - scanOffset : scanCount\n}\n\n// -----------------------------------------------------------------------------\n// Case folding\n// -----------------------------------------------------------------------------\n\nconst foldCache = /*#__PURE__*/ new Map<number, number>()\n\nconst single = (s: string): number => {\n const cp = firstCodePoint(s)\n return s.length === (cp > 0xffff ? 2 : 1) ? cp : -1\n}\n\n/**\n * Simple case folding of a code point: the lowercase of its uppercase, when\n * both map to a single code point (so `\"K\"` (Kelvin) and `\"ſ\"` fold to `\"k\"`\n * and `\"s\"`), otherwise the code point itself.\n */\nexport const fold = (cp: number): number => {\n if (cp < 128) return cp >= 65 && cp <= 90 ? cp + 32 : cp\n let f = foldCache.get(cp)\n if (f === undefined) {\n const c = String.fromCodePoint(cp)\n const upper = c.toUpperCase()\n const viaUpper = single(upper) >= 0 ? single(upper.toLowerCase()) : -1\n f = viaUpper >= 0 ? viaUpper : single(c.toLowerCase())\n if (f < 0) f = cp\n foldCache.set(cp, f)\n }\n return f\n}\n\n// -----------------------------------------------------------------------------\n// Error rendering\n// -----------------------------------------------------------------------------\n\n/**\n * Walks the code points of `[start, end)` leniently: malformed sequences\n * are reported as `-1` and skipped one code unit at a time.\n */\nexport const walk = (\n enc: Encoding<any>,\n input: string | Uint8Array,\n start: number,\n end: number,\n f: (cp: number, offset: number, width: number) => boolean | void\n): void => {\n let i = start\n while (i < end) {\n let cp = enc.decode(input, i, end)\n let w: number\n if (cp >= 0) {\n w = enc.width(cp)\n } else {\n cp = -1\n w = Math.min(enc.unit, end - i)\n }\n if (f(cp, i, w) === false) return\n i += w\n }\n}\n\n/** Decodes `[start, end)`, replacing malformed sequences with U+FFFD. */\nexport const lenientText = (enc: Encoding<any>, input: string | Uint8Array, start: number, end: number): string => {\n let out = \"\"\n walk(enc, input, start, end, (cp) => {\n out += cp < 0 ? \"�\" : charOf(cp)\n })\n return out\n}\n"],"mappings":"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"}
@@ -67,6 +67,11 @@ export interface Scanned extends Advanced {
67
67
  * Scans forward while tokens satisfy the matcher (xor `negate`), up to `max`
68
68
  * tokens. Returns the offset reached, the number of tokens matched, and
69
69
  * whether the end of input was hit before `max` tokens.
70
+ *
71
+ * The result is one shared record, overwritten by the next scan: read it
72
+ * before running anything else. Allocating one per call cost the
73
+ * interpreter a record per token, since `scan` (shared by every `takeWhile`)
74
+ * is too polymorphic for V8 to inline and remove it.
70
75
  */
71
76
  export declare const scan: (state: State<Input>, m: AnyMatcher, negate: boolean, max: number) => Scanned;
72
77
  /** The offset reached and the number of tokens passed. */
@@ -78,6 +83,14 @@ export interface Advanced {
78
83
  export declare const advance: (state: State<Input>, start: number, n: number) => Advanced;
79
84
  /** Counts tokens between two offsets. */
80
85
  export declare const countTokens: (state: State<Input>, start: number, end: number) => number;
86
+ /**
87
+ * The first index at or after `from` of any of `needles` within
88
+ * `[from, state.end)`, or -1. The state remembers, under `needles`, where
89
+ * each one next occurs (`[from, at]` at `2 * i`), so successive searches
90
+ * forwards over one input search each needle once per occurrence rather
91
+ * than once per call (as `nextStop` does for `takeTill`).
92
+ */
93
+ export declare const indexOfAny: (state: State<Input>, needles: ReadonlyArray<Input>, from: number) => number;
81
94
  /** Finds `needle` within `[from, state.end)`; returns -1 if absent. */
82
95
  export declare const indexOf: (state: State<Input>, needle: Input, from: number) => number;
83
96
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.d.ts","names":[],"sources":["../../src/internal/tokens.ts"],"mappings":";;iBAQiB;;WAEN,OAAO;;WAEP,QAAQ;;WAER;;;iBAIM;WACN;WACA;WACA;;;qBAQE,eAAgB;;;;;;qBA2FhB;;;;;qBAMA,qBAAsB,WAAW,sBAC5C,cACA,GAAG,GACH,SAAS,6CACR;;;;;;qBAYU,UAAW,cAAc,6BAAmC;;;;;iBA+BxD;WACN,WAAW;WACX,SAAS;WACT;;;qBAuBE,kBAAmB,KAAK;qBASxB,aAAc,iBAAe;;;;;;qBAmB7B,iBAAkB,OAAO,MAAM,QAAQ;;;;;qBAoBvC;qBACA;qBAEA,SAAU,OAAO,MAAM,QAAQ,GAAG,YAAY;;iBA6B1C,gBAAgB;;WAEtB;;;;;;;qBAQE,OAAQ,OAAO,MAAM,QAAQ,GAAG,YAAY,iBAAiB,gBAAc;;iBAkDvE;WACN;WACA;;;qBAIE,UAAW,OAAO,MAAM,QAAQ,eAAe,cAAY;;qBAkB3D,cAAe,OAAO,MAAM,QAAQ,eAAe;;qBAanD,UAAW,OAAO,MAAM,QAAQ,QAAQ,OAAO;;;;;;qBAwC/C,eAAgB,OAAO,MAAM,QAAQ,KAAK,OAAO"}
1
+ {"version":3,"file":"tokens.d.ts","names":[],"sources":["../../src/internal/tokens.ts"],"mappings":";;iBAMiB;;WAEN,OAAO;;WAEP,QAAQ;;WAER;;;iBAIM;WACN;WACA;WACA;;;qBAQE,eAAgB;;;;;;qBAiGhB;;;;;qBAMA,qBAAsB,WAAW,sBAC5C,cACA,GAAG,GACH,SAAS,6CACR;;;;;;qBAiBU,UAAW,cAAc,6BAAmC;;;;;iBAgCxD;WACN,WAAW;WACX,SAAS;WACT;;;qBAuBE,kBAAmB,KAAK;qBASxB,aAAc,iBAAe;;;;;;qBAmB7B,iBAAkB,OAAO,MAAM,QAAQ;;;;;qBAqBvC;qBACA;qBAEA,SAAU,OAAO,MAAM,QAAQ,GAAG,YAAY;;iBAgC1C,gBAAgB;;WAEtB;;;;;;;;;;;;qBA8BE,OAAQ,OAAO,MAAM,QAAQ,GAAG,YAAY,iBAAiB,gBAAc;;iBAqDvE;WACN;WACA;;;qBAIE,UAAW,OAAO,MAAM,QAAQ,eAAe,cAAY;;qBAmB3D,cAAe,OAAO,MAAM,QAAQ,eAAe;;;;;;;;qBAoBnD,aAAc,OAAO,MAAM,QAAQ,SAAS,cAAc,QAAQ;;qBAwBlE,UAAW,OAAO,MAAM,QAAQ,QAAQ,OAAO;;;;;;qBA6C/C,eAAgB,OAAO,MAAM,QAAQ,KAAK,OAAO"}