@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.
Files changed (137) hide show
  1. package/dist/Ascii.d.ts +0 -2
  2. package/dist/Ascii.d.ts.map +1 -1
  3. package/dist/Ascii.js +6 -6
  4. package/dist/Ascii.js.map +1 -1
  5. package/dist/Binary.d.ts +0 -2
  6. package/dist/Binary.d.ts.map +1 -1
  7. package/dist/Binary.js +1 -2
  8. package/dist/Bits.d.ts +0 -2
  9. package/dist/Bits.d.ts.map +1 -1
  10. package/dist/Bits.js +2 -3
  11. package/dist/Bits.js.map +1 -1
  12. package/dist/Compiler.d.ts +0 -2
  13. package/dist/Compiler.d.ts.map +1 -1
  14. package/dist/Compiler.js +1 -2
  15. package/dist/Encoding.d.ts +0 -2
  16. package/dist/Encoding.d.ts.map +1 -1
  17. package/dist/Encoding.js +1 -2
  18. package/dist/Expression.d.ts +0 -2
  19. package/dist/Expression.d.ts.map +1 -1
  20. package/dist/Expression.js +44 -8
  21. package/dist/Expression.js.map +1 -1
  22. package/dist/Input.d.ts +32 -4
  23. package/dist/Input.d.ts.map +1 -1
  24. package/dist/Input.js +47 -8
  25. package/dist/Input.js.map +1 -1
  26. package/dist/Nom.d.ts +0 -2
  27. package/dist/Nom.d.ts.map +1 -1
  28. package/dist/Nom.js +1 -2
  29. package/dist/ParseError.d.ts +0 -2
  30. package/dist/ParseError.d.ts.map +1 -1
  31. package/dist/ParseError.js +6 -9
  32. package/dist/ParseError.js.map +1 -1
  33. package/dist/Parser.d.ts +2 -2
  34. package/dist/Parser.d.ts.map +1 -1
  35. package/dist/Parser.js +26 -24
  36. package/dist/Parser.js.map +1 -1
  37. package/dist/ParserSchema.d.ts +0 -2
  38. package/dist/ParserSchema.d.ts.map +1 -1
  39. package/dist/ParserSchema.js +2 -3
  40. package/dist/ParserStream.d.ts +0 -2
  41. package/dist/ParserStream.d.ts.map +1 -1
  42. package/dist/ParserStream.js +15 -9
  43. package/dist/ParserStream.js.map +1 -1
  44. package/dist/Syntax.d.ts +0 -2
  45. package/dist/Syntax.d.ts.map +1 -1
  46. package/dist/Syntax.js +13 -11
  47. package/dist/Syntax.js.map +1 -1
  48. package/dist/Text.d.ts +0 -2
  49. package/dist/Text.d.ts.map +1 -1
  50. package/dist/Text.js +1 -2
  51. package/dist/Token.d.ts +0 -2
  52. package/dist/Token.d.ts.map +1 -1
  53. package/dist/Token.js +1 -2
  54. package/dist/internal/compiler/closure.d.ts +5 -2
  55. package/dist/internal/compiler/closure.d.ts.map +1 -1
  56. package/dist/internal/compiler/closure.js +160 -92
  57. package/dist/internal/compiler/closure.js.map +1 -1
  58. package/dist/internal/compiler/entries.d.ts +0 -2
  59. package/dist/internal/compiler/entries.d.ts.map +1 -1
  60. package/dist/internal/compiler/entries.js +6 -7
  61. package/dist/internal/compiler/entries.js.map +1 -1
  62. package/dist/internal/compiler/first.d.ts +0 -2
  63. package/dist/internal/compiler/first.d.ts.map +1 -1
  64. package/dist/internal/compiler/first.js +10 -10
  65. package/dist/internal/compiler/first.js.map +1 -1
  66. package/dist/internal/compiler/jit.d.ts +0 -2
  67. package/dist/internal/compiler/jit.d.ts.map +1 -1
  68. package/dist/internal/compiler/jit.js +52 -51
  69. package/dist/internal/compiler/jit.js.map +1 -1
  70. package/dist/internal/compiler/registry.d.ts +0 -2
  71. package/dist/internal/compiler/registry.d.ts.map +1 -1
  72. package/dist/internal/compiler/registry.js +1 -2
  73. package/dist/internal/compiler/sets.d.ts +2 -2
  74. package/dist/internal/compiler/sets.d.ts.map +1 -1
  75. package/dist/internal/compiler/sets.js +8 -3
  76. package/dist/internal/compiler/sets.js.map +1 -1
  77. package/dist/internal/entries.d.ts +0 -2
  78. package/dist/internal/entries.d.ts.map +1 -1
  79. package/dist/internal/entries.js +1 -2
  80. package/dist/internal/key.d.ts +10 -0
  81. package/dist/internal/key.d.ts.map +1 -0
  82. package/dist/internal/key.js +11 -0
  83. package/dist/internal/key.js.map +1 -0
  84. package/dist/internal/node.d.ts +11 -4
  85. package/dist/internal/node.d.ts.map +1 -1
  86. package/dist/internal/node.js +15 -3
  87. package/dist/internal/node.js.map +1 -1
  88. package/dist/internal/numbers.d.ts +0 -2
  89. package/dist/internal/numbers.d.ts.map +1 -1
  90. package/dist/internal/numbers.js +1 -2
  91. package/dist/internal/resume.d.ts +5 -6
  92. package/dist/internal/resume.d.ts.map +1 -1
  93. package/dist/internal/resume.js +1 -2
  94. package/dist/internal/resume.js.map +1 -1
  95. package/dist/internal/run.d.ts +0 -2
  96. package/dist/internal/run.d.ts.map +1 -1
  97. package/dist/internal/run.js +2 -3
  98. package/dist/internal/run.js.map +1 -1
  99. package/dist/internal/stack.d.ts +0 -2
  100. package/dist/internal/stack.d.ts.map +1 -1
  101. package/dist/internal/stack.js +1 -2
  102. package/dist/internal/syntax.d.ts +30 -20
  103. package/dist/internal/syntax.d.ts.map +1 -1
  104. package/dist/internal/syntax.js +73 -66
  105. package/dist/internal/syntax.js.map +1 -1
  106. package/dist/internal/text.d.ts +5 -2
  107. package/dist/internal/text.d.ts.map +1 -1
  108. package/dist/internal/text.js +14 -5
  109. package/dist/internal/text.js.map +1 -1
  110. package/dist/internal/ties.d.ts +0 -2
  111. package/dist/internal/ties.d.ts.map +1 -1
  112. package/dist/internal/ties.js +1 -2
  113. package/dist/internal/tokens.d.ts +10 -9
  114. package/dist/internal/tokens.d.ts.map +1 -1
  115. package/dist/internal/tokens.js +4 -8
  116. package/dist/internal/tokens.js.map +1 -1
  117. package/package.json +6 -6
  118. package/src/Ascii.ts +6 -5
  119. package/src/Bits.ts +1 -1
  120. package/src/Expression.ts +7 -6
  121. package/src/Input.ts +50 -11
  122. package/src/ParseError.ts +9 -7
  123. package/src/Parser.ts +26 -23
  124. package/src/ParserStream.ts +20 -8
  125. package/src/Syntax.ts +12 -9
  126. package/src/internal/compiler/closure.ts +202 -90
  127. package/src/internal/compiler/entries.ts +14 -11
  128. package/src/internal/compiler/first.ts +9 -8
  129. package/src/internal/compiler/jit.ts +95 -74
  130. package/src/internal/compiler/sets.ts +7 -0
  131. package/src/internal/key.ts +11 -0
  132. package/src/internal/node.ts +19 -2
  133. package/src/internal/resume.ts +5 -4
  134. package/src/internal/run.ts +1 -1
  135. package/src/internal/syntax.ts +78 -87
  136. package/src/internal/text.ts +24 -4
  137. package/src/internal/tokens.ts +20 -13
@@ -1 +1 @@
1
- {"version":3,"file":"first.js","names":[],"sources":["../../../src/internal/compiler/first.ts"],"sourcesContent":["/**\n * First sets: which input units can start a match of a parser.\n *\n * A first set has a mode:\n *\n * - `Strict`: when the next unit is not in `units` (or the input has\n * ended), the parser fails with `Backtrack`.\n * - `Optional`: in that case, the parser either fails with `Backtrack` or\n * succeeds without consuming input.\n * - `Unknown`: no guarantee.\n *\n * Units are UTF-16 code units for strings and bytes for byte inputs; units\n * from `TableSize` up are summarized by `high`. Array inputs have no units.\n *\n * Skipping a parser that is certain to fail also skips the callbacks it\n * would have run before failing, which is why callbacks must be pure.\n */\nimport * as Predicate from \"effect/Predicate\"\nimport type { Encoding } from \"../../Encoding.js\"\nimport type { Node, ParserLike } from \"../node.js\"\nimport { nodeOf } from \"../node.js\"\nimport { fastLimit } from \"../text.js\"\nimport type { CharSet } from \"./sets.js\"\nimport { kindOfEncoding, reachesAbove, TableSize, textSet, tokenSet } from \"./sets.js\"\n\nexport const Strict = 0\nconst Optional = 1\nconst Unknown = 2\n\nexport interface First {\n readonly mode: 0 | 1 | 2\n readonly units: Uint8Array\n readonly high: boolean\n}\n\nconst none = /*#__PURE__*/ new Uint8Array(TableSize)\nconst all = /*#__PURE__*/ new Uint8Array(TableSize).fill(1)\n\nconst unknown: First = { mode: Unknown, units: all, high: true }\nconst emptyOptional: First = { mode: Optional, units: none, high: false }\nconst failing: First = { mode: Strict, units: none, high: false }\nconst anyUnit: First = { mode: Strict, units: all, high: true }\n\nconst union = (a: First, b: First, mode: 0 | 1 | 2): First => {\n const units = new Uint8Array(TableSize)\n for (let i = 0; i < TableSize; i++) units[i] = a.units[i] | b.units[i]\n return { mode, units, high: a.high || b.high }\n}\n\nconst withMode = (f: First, mode: 0 | 1 | 2): First => (f.mode === mode ? f : { ...f, mode })\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\nconst upperAscii = (c: number): number => (c >= 97 && c <= 122 ? c - 32 : c)\n\nconst ofUnits = (codes: ReadonlyArray<number>, mode: 0 | 1 | 2 = Strict): First => {\n const units = new Uint8Array(TableSize)\n let high = false\n for (const c of codes) {\n if (c < TableSize) units[c] = 1\n else high = true\n }\n return { mode, units, high }\n}\n\nexport class FirstSets {\n private readonly memo = new Map<ParserLike, First | undefined>()\n constructor(readonly kind: 0 | 1 | 2) {}\n\n of(p: ParserLike): First {\n if (this.kind === 2) return unknown\n if (this.memo.has(p)) return this.memo.get(p) ?? unknown // in progress: a cycle\n this.memo.set(p, undefined)\n const f = this.compute(nodeOf(p))\n this.memo.set(p, f)\n return f\n }\n\n /** Units of the code points of a set, as an encoding (or `Token`) reads them. */\n private setUnits(set: CharSet, enc: Encoding<any> | undefined, mode: 0 | 1): First | undefined {\n if (enc === undefined || kindOfEncoding(enc) === 0) {\n if (this.kind === 1) return { mode, units: set.table, high: false }\n return { mode, units: set.table, high: reachesAbove(set, TableSize) }\n }\n if (enc.unit !== 1) return undefined\n const fast = fastLimit(enc)\n if (fast === 0) return undefined\n const units = set.table.slice()\n // Multi-unit sequences start with a unit at or above `fast`\n if (fast < TableSize) units.fill(reachesAbove(set, fast) ? 1 : 0, fast)\n return { mode, units, high: false }\n }\n\n private compute(node: Node): First {\n const kind = this.kind as 0 | 1\n switch (node._tag) {\n case \"Succeed\":\n case \"Sync\":\n case \"Location\":\n case \"RestLen\":\n case \"Eof\":\n return emptyOptional\n case \"Fail\":\n return node.mode === \"Backtrack\" ? failing : unknown\n case \"Any\":\n return node.encoding !== undefined && kindOfEncoding(node.encoding) !== kind ? unknown : anyUnit\n case \"Take\":\n return node.count === 0 ? emptyOptional : anyUnit\n case \"Literal\": {\n const lit = node.literal\n if (node.encoding !== undefined) {\n if (kindOfEncoding(node.encoding) !== kind) return unknown\n if (node.caseless) return lit.length === 0 ? unknown : anyUnit\n const encoded = node.encoding.encode(lit as string)\n if (encoded.length === 0) return emptyOptional\n return ofUnits([Predicate.isString(encoded) ? encoded.charCodeAt(0) : encoded[0]])\n }\n if (lit.length === 0) return emptyOptional\n let first: number\n if (Predicate.isString(lit)) {\n first = kind === 0 ? lit.charCodeAt(0) : new TextEncoder().encode(lit)[0]\n } else if (lit instanceof Uint8Array && kind === 1) {\n first = lit[0]\n } else {\n return unknown\n }\n return ofUnits(node.caseless ? [first, lowerAscii(first), upperAscii(first)] : [first])\n }\n case \"OneOf\":\n case \"TakeWhile\": {\n if (node.encoding !== undefined && kindOfEncoding(node.encoding) !== kind) return unknown\n const min = node._tag === \"OneOf\" ? 1 : node.min\n if (node._tag === \"TakeWhile\" && node.max === 0) return emptyOptional\n const mode = min > 0 ? Strict : Optional\n if (node.negate) return mode === Strict ? anyUnit : withMode(anyUnit, Optional)\n const set = node.encoding === undefined ? tokenSet(node.set, kind) : textSet(node.set)\n return this.setUnits(set, node.encoding, mode) ?? (mode === Strict ? anyUnit : unknown)\n }\n case \"Map\":\n case \"As\":\n case \"Tap\":\n case \"TryMap\":\n case \"FilterMap\":\n case \"Filter\":\n case \"Taken\":\n case \"WithTaken\":\n case \"Span\":\n case \"WithSpan\":\n case \"Context\":\n case \"Expected\":\n case \"MapError\":\n case \"OrFail\":\n case \"Peek\":\n case \"Trace\":\n case \"Syntax\":\n case \"ResumeAfter\":\n case \"RetryAfter\":\n return this.of(node.self)\n case \"FlatMap\":\n case \"SeparatedFold\":\n case \"Dispatch\": {\n const f = this.of(node._tag === \"Dispatch\" ? node.selector : node.self)\n return f.mode === Strict ? f : unknown\n }\n case \"Mode\": {\n const f = this.of(node.self)\n return node.from === \"Backtrack\" ? (f.mode === Unknown ? f : unknown) : f\n }\n case \"Opt\":\n case \"OrElseSucceed\": {\n const f = this.of(node.self)\n return f.mode === Unknown ? f : withMode(f, Optional)\n }\n case \"Seq\":\n case \"Struct\":\n return this.sequence(node.parsers)\n case \"ZipWith\":\n return this.sequence([node.self, node.that])\n case \"Alt\": {\n if (node.parsers.length === 0) return failing\n let acc: First | undefined\n let mode: 0 | 1 | 2 = Strict\n for (const p of node.parsers) {\n const f = this.of(p)\n if (f.mode === Unknown) return unknown\n if (f.mode === Optional) mode = Optional\n acc = acc === undefined ? f : union(acc, f, mode)\n }\n return acc === undefined ? failing : withMode(acc, mode)\n }\n case \"Repeat\":\n case \"Fold\":\n case \"Separated\": {\n if (node.max === 0) return emptyOptional\n const f = this.of(node.self)\n if (f.mode !== Strict) return unknown\n return node.min === 0 ? withMode(f, Optional) : f\n }\n case \"Suspend\":\n return this.of(node.resolve())\n default:\n return unknown\n }\n }\n\n private sequence(parsers: ReadonlyArray<ParserLike>): First {\n let acc: First | undefined\n for (const p of parsers) {\n const f = this.of(p)\n if (f.mode === Unknown) return unknown\n acc = acc === undefined ? f : union(acc, f, f.mode)\n if (f.mode === Strict) return acc\n }\n return acc ?? emptyOptional\n }\n}\n\n/**\n * For an `Alt`: the branches worth trying for each next unit, each next\n * high unit, and at the end of the input, or `undefined` when pruning\n * would never skip a branch.\n */\nexport interface AltPlan {\n /** Indexed by unit: indexes into `lists`. */\n readonly byUnit: Uint8Array\n readonly high: number\n readonly end: number\n readonly lists: ReadonlyArray<ReadonlyArray<number>>\n}\n\nexport const planAlt = (firsts: ReadonlyArray<First>): AltPlan | undefined => {\n const n = firsts.length\n if (n < 2 || n > 64) return undefined\n const lists: Array<ReadonlyArray<number>> = []\n const index = new Map<string, number>()\n const listOf = (keep: (f: First) => boolean): number => {\n const list: Array<number> = []\n for (let i = 0; i < n; i++) if (keep(firsts[i])) list.push(i)\n const key = list.join(\",\")\n let k = index.get(key)\n if (k === undefined) {\n k = lists.length\n lists.push(list)\n index.set(key, k)\n }\n return k\n }\n const byUnit = new Uint8Array(TableSize)\n for (let u = 0; u < TableSize; u++) byUnit[u] = listOf((f) => f.mode !== Strict || f.units[u] === 1)\n const high = listOf((f) => f.mode !== Strict || f.high)\n const end = listOf((f) => f.mode !== Strict)\n if (lists.length === 1 && lists[0].length === n) return undefined\n if (lists.length > 255) return undefined\n return { byUnit, high, end, lists }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,SAAS;AACtB,MAAM,WAAW;AACjB,MAAM,UAAU;AAQhB,MAAM,qBAAqB,IAAI,WAAW,SAAS;AACnD,MAAM,MAAoB,kBAAI,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC;AAE1D,MAAM,UAAiB;CAAE,MAAM;CAAS,OAAO;CAAK,MAAM;AAAK;AAC/D,MAAM,gBAAuB;CAAE,MAAM;CAAU,OAAO;CAAM,MAAM;AAAM;AACxE,MAAM,UAAiB;CAAE,MAAA;CAAc,OAAO;CAAM,MAAM;AAAM;AAChE,MAAM,UAAiB;CAAE,MAAA;CAAc,OAAO;CAAK,MAAM;AAAK;AAE9D,MAAM,SAAS,GAAU,GAAU,SAA2B;CAC5D,MAAM,QAAQ,IAAI,WAAW,SAAS;CACtC,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK,MAAM,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM;CACpE,OAAO;EAAE;EAAM;EAAO,MAAM,EAAE,QAAQ,EAAE;CAAK;AAC/C;AAEA,MAAM,YAAY,GAAU,SAA4B,EAAE,SAAS,OAAO,IAAI;CAAE,GAAG;CAAG;AAAK;AAE3F,MAAM,cAAc,MAAuB,KAAK,MAAM,KAAK,KAAK,IAAI,KAAK;AACzE,MAAM,cAAc,MAAuB,KAAK,MAAM,KAAK,MAAM,IAAI,KAAK;AAE1E,MAAM,WAAW,OAA8B,OAAA,MAAoC;CACjF,MAAM,QAAQ,IAAI,WAAW,SAAS;CACtC,IAAI,OAAO;CACX,KAAK,MAAM,KAAK,OACd,IAAI,IAAI,WAAW,MAAM,KAAK;MACzB,OAAO;CAEd,OAAO;EAAE;EAAM;EAAO;CAAK;AAC7B;AAEA,IAAa,YAAb,MAAuB;CAEA;CADrB,uBAAwB,IAAI,IAAmC;CAC/D,YAAY,MAA0B;EAAjB,KAAA,OAAA;CAAkB;CAEvC,GAAG,GAAsB;EACvB,IAAI,KAAK,SAAS,GAAG,OAAO;EAC5B,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,IAAI,CAAC,KAAK;EACjD,KAAK,KAAK,IAAI,GAAG,KAAA,CAAS;EAC1B,MAAM,IAAI,KAAK,QAAQ,OAAO,CAAC,CAAC;EAChC,KAAK,KAAK,IAAI,GAAG,CAAC;EAClB,OAAO;CACT;;CAGA,SAAiB,KAAc,KAAgC,MAAgC;EAC7F,IAAI,QAAQ,KAAA,KAAa,eAAe,GAAG,MAAM,GAAG;GAClD,IAAI,KAAK,SAAS,GAAG,OAAO;IAAE;IAAM,OAAO,IAAI;IAAO,MAAM;GAAM;GAClE,OAAO;IAAE;IAAM,OAAO,IAAI;IAAO,MAAM,aAAa,KAAK,SAAS;GAAE;EACtE;EACA,IAAI,IAAI,SAAS,GAAG,OAAO,KAAA;EAC3B,MAAM,OAAO,UAAU,GAAG;EAC1B,IAAI,SAAS,GAAG,OAAO,KAAA;EACvB,MAAM,QAAQ,IAAI,MAAM,MAAM;EAE9B,IAAI,OAAO,WAAW,MAAM,KAAK,aAAa,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI;EACtE,OAAO;GAAE;GAAM;GAAO,MAAM;EAAM;CACpC;CAEA,QAAgB,MAAmB;EACjC,MAAM,OAAO,KAAK;EAClB,QAAQ,KAAK,MAAb;GACE,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,OACH,OAAO;GACT,KAAK,QACH,OAAO,KAAK,SAAS,cAAc,UAAU;GAC/C,KAAK,OACH,OAAO,KAAK,aAAa,KAAA,KAAa,eAAe,KAAK,QAAQ,MAAM,OAAO,UAAU;GAC3F,KAAK,QACH,OAAO,KAAK,UAAU,IAAI,gBAAgB;GAC5C,KAAK,WAAW;IACd,MAAM,MAAM,KAAK;IACjB,IAAI,KAAK,aAAa,KAAA,GAAW;KAC/B,IAAI,eAAe,KAAK,QAAQ,MAAM,MAAM,OAAO;KACnD,IAAI,KAAK,UAAU,OAAO,IAAI,WAAW,IAAI,UAAU;KACvD,MAAM,UAAU,KAAK,SAAS,OAAO,GAAa;KAClD,IAAI,QAAQ,WAAW,GAAG,OAAO;KACjC,OAAO,QAAQ,CAAC,UAAU,SAAS,OAAO,IAAI,QAAQ,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAC;IACnF;IACA,IAAI,IAAI,WAAW,GAAG,OAAO;IAC7B,IAAI;IACJ,IAAI,UAAU,SAAS,GAAG,GACxB,QAAQ,SAAS,IAAI,IAAI,WAAW,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC;SAClE,IAAI,eAAe,cAAc,SAAS,GAC/C,QAAQ,IAAI;SAEZ,OAAO;IAET,OAAO,QAAQ,KAAK,WAAW;KAAC;KAAO,WAAW,KAAK;KAAG,WAAW,KAAK;IAAC,IAAI,CAAC,KAAK,CAAC;GACxF;GACA,KAAK;GACL,KAAK,aAAa;IAChB,IAAI,KAAK,aAAa,KAAA,KAAa,eAAe,KAAK,QAAQ,MAAM,MAAM,OAAO;IAClF,MAAM,MAAM,KAAK,SAAS,UAAU,IAAI,KAAK;IAC7C,IAAI,KAAK,SAAS,eAAe,KAAK,QAAQ,GAAG,OAAO;IACxD,MAAM,OAAO,MAAM,IAAA,IAAa;IAChC,IAAI,KAAK,QAAQ,OAAO,SAAA,IAAkB,UAAU,SAAS,SAAS,QAAQ;IAC9E,MAAM,MAAM,KAAK,aAAa,KAAA,IAAY,SAAS,KAAK,KAAK,IAAI,IAAI,QAAQ,KAAK,GAAG;IACrF,OAAO,KAAK,SAAS,KAAK,KAAK,UAAU,IAAI,MAAM,SAAA,IAAkB,UAAU;GACjF;GACA,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,cACH,OAAO,KAAK,GAAG,KAAK,IAAI;GAC1B,KAAK;GACL,KAAK;GACL,KAAK,YAAY;IACf,MAAM,IAAI,KAAK,GAAG,KAAK,SAAS,aAAa,KAAK,WAAW,KAAK,IAAI;IACtE,OAAO,EAAE,SAAA,IAAkB,IAAI;GACjC;GACA,KAAK,QAAQ;IACX,MAAM,IAAI,KAAK,GAAG,KAAK,IAAI;IAC3B,OAAO,KAAK,SAAS,cAAe,EAAE,SAAS,UAAU,IAAI,UAAW;GAC1E;GACA,KAAK;GACL,KAAK,iBAAiB;IACpB,MAAM,IAAI,KAAK,GAAG,KAAK,IAAI;IAC3B,OAAO,EAAE,SAAS,UAAU,IAAI,SAAS,GAAG,QAAQ;GACtD;GACA,KAAK;GACL,KAAK,UACH,OAAO,KAAK,SAAS,KAAK,OAAO;GACnC,KAAK,WACH,OAAO,KAAK,SAAS,CAAC,KAAK,MAAM,KAAK,IAAI,CAAC;GAC7C,KAAK,OAAO;IACV,IAAI,KAAK,QAAQ,WAAW,GAAG,OAAO;IACtC,IAAI;IACJ,IAAI,OAAA;IACJ,KAAK,MAAM,KAAK,KAAK,SAAS;KAC5B,MAAM,IAAI,KAAK,GAAG,CAAC;KACnB,IAAI,EAAE,SAAS,SAAS,OAAO;KAC/B,IAAI,EAAE,SAAS,UAAU,OAAO;KAChC,MAAM,QAAQ,KAAA,IAAY,IAAI,MAAM,KAAK,GAAG,IAAI;IAClD;IACA,OAAO,QAAQ,KAAA,IAAY,UAAU,SAAS,KAAK,IAAI;GACzD;GACA,KAAK;GACL,KAAK;GACL,KAAK,aAAa;IAChB,IAAI,KAAK,QAAQ,GAAG,OAAO;IAC3B,MAAM,IAAI,KAAK,GAAG,KAAK,IAAI;IAC3B,IAAI,EAAE,SAAA,GAAiB,OAAO;IAC9B,OAAO,KAAK,QAAQ,IAAI,SAAS,GAAG,QAAQ,IAAI;GAClD;GACA,KAAK,WACH,OAAO,KAAK,GAAG,KAAK,QAAQ,CAAC;GAC/B,SACE,OAAO;EACX;CACF;CAEA,SAAiB,SAA2C;EAC1D,IAAI;EACJ,KAAK,MAAM,KAAK,SAAS;GACvB,MAAM,IAAI,KAAK,GAAG,CAAC;GACnB,IAAI,EAAE,SAAS,SAAS,OAAO;GAC/B,MAAM,QAAQ,KAAA,IAAY,IAAI,MAAM,KAAK,GAAG,EAAE,IAAI;GAClD,IAAI,EAAE,SAAA,GAAiB,OAAO;EAChC;EACA,OAAO,OAAO;CAChB;AACF;AAeA,MAAa,WAAW,WAAsD;CAC5E,MAAM,IAAI,OAAO;CACjB,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,KAAA;CAC5B,MAAM,QAAsC,CAAC;CAC7C,MAAM,wBAAQ,IAAI,IAAoB;CACtC,MAAM,UAAU,SAAwC;EACtD,MAAM,OAAsB,CAAC;EAC7B,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,CAAC;EAC5D,MAAM,MAAM,KAAK,KAAK,GAAG;EACzB,IAAI,IAAI,MAAM,IAAI,GAAG;EACrB,IAAI,MAAM,KAAA,GAAW;GACnB,IAAI,MAAM;GACV,MAAM,KAAK,IAAI;GACf,MAAM,IAAI,KAAK,CAAC;EAClB;EACA,OAAO;CACT;CACA,MAAM,SAAS,IAAI,WAAW,SAAS;CACvC,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,KAAK,OAAO,KAAK,QAAQ,MAAM,EAAE,SAAA,KAAmB,EAAE,MAAM,OAAO,CAAC;CACnG,MAAM,OAAO,QAAQ,MAAM,EAAE,SAAA,KAAmB,EAAE,IAAI;CACtD,MAAM,MAAM,QAAQ,MAAM,EAAE,SAAA,CAAe;CAC3C,IAAI,MAAM,WAAW,KAAK,MAAM,EAAE,CAAC,WAAW,GAAG,OAAO,KAAA;CACxD,IAAI,MAAM,SAAS,KAAK,OAAO,KAAA;CAC/B,OAAO;EAAE;EAAQ;EAAM;EAAK;CAAM;AACpC"}
1
+ {"version":3,"file":"first.js","names":[],"sources":["../../../src/internal/compiler/first.ts"],"sourcesContent":["/**\n * First sets: which input units can start a match of a parser.\n *\n * A first set has a mode:\n *\n * - `Strict`: when the next unit is not in `units` (or the input has\n * ended), the parser fails with `Backtrack`.\n * - `Optional`: in that case, the parser either fails with `Backtrack` or\n * succeeds without consuming input.\n * - `Unknown`: no guarantee.\n *\n * Units are UTF-16 code units for strings and bytes for byte inputs; units\n * from `TableSize` up are summarized by `high`. Array inputs have no units.\n *\n * Skipping a parser that is certain to fail also skips the callbacks it\n * would have run before failing, which is why callbacks must be pure.\n */\nimport * as Arr from \"effect/Array\"\nimport * as Predicate from \"effect/Predicate\"\nimport type { Encoding } from \"../../Encoding.js\"\nimport type { Node, ParserLike } from \"../node.js\"\nimport { nodeOf } from \"../node.js\"\nimport { fastLimit, isEmptyUnits } from \"../text.js\"\nimport type { CharSet } from \"./sets.js\"\nimport { kindOfEncoding, reachesAbove, TableSize, textSet, tokenSet } from \"./sets.js\"\n\nexport const Strict = 0\nconst Optional = 1\nconst Unknown = 2\n\nexport interface First {\n readonly mode: 0 | 1 | 2\n readonly units: Uint8Array\n readonly high: boolean\n}\n\nconst none = /*#__PURE__*/ new Uint8Array(TableSize)\nconst all = /*#__PURE__*/ new Uint8Array(TableSize).fill(1)\n\nconst unknown: First = { mode: Unknown, units: all, high: true }\nconst emptyOptional: First = { mode: Optional, units: none, high: false }\nconst failing: First = { mode: Strict, units: none, high: false }\nconst anyUnit: First = { mode: Strict, units: all, high: true }\n\nconst union = (a: First, b: First, mode: 0 | 1 | 2): First => {\n const units = new Uint8Array(TableSize)\n for (let i = 0; i < TableSize; i++) units[i] = a.units[i] | b.units[i]\n return { mode, units, high: a.high || b.high }\n}\n\nconst withMode = (f: First, mode: 0 | 1 | 2): First => (f.mode === mode ? f : { ...f, mode })\n\nconst lowerAscii = (c: number): number => (c >= 65 && c <= 90 ? c + 32 : c)\nconst upperAscii = (c: number): number => (c >= 97 && c <= 122 ? c - 32 : c)\n\nconst ofUnits = (codes: ReadonlyArray<number>, mode: 0 | 1 | 2 = Strict): First => {\n const units = new Uint8Array(TableSize)\n let high = false\n for (const c of codes) {\n if (c < TableSize) units[c] = 1\n else high = true\n }\n return { mode, units, high }\n}\n\nexport class FirstSets {\n private readonly memo = new Map<ParserLike, First | undefined>()\n constructor(readonly kind: 0 | 1 | 2) {}\n\n of(p: ParserLike): First {\n if (this.kind === 2) return unknown\n if (this.memo.has(p)) return this.memo.get(p) ?? unknown // in progress: a cycle\n this.memo.set(p, undefined)\n const f = this.compute(nodeOf(p))\n this.memo.set(p, f)\n return f\n }\n\n /** Units of the code points of a set, as an encoding (or `Token`) reads them. */\n private setUnits(set: CharSet, enc: Encoding<any> | undefined, mode: 0 | 1): First | undefined {\n if (enc === undefined || kindOfEncoding(enc) === 0) {\n if (this.kind === 1) return { mode, units: set.table, high: false }\n return { mode, units: set.table, high: reachesAbove(set, TableSize) }\n }\n if (enc.unit !== 1) return undefined\n const fast = fastLimit(enc)\n if (fast === 0) return undefined\n const units = set.table.slice()\n // Multi-unit sequences start with a unit at or above `fast`\n if (fast < TableSize) units.fill(reachesAbove(set, fast) ? 1 : 0, fast)\n return { mode, units, high: false }\n }\n\n private compute(node: Node): First {\n const kind = this.kind as 0 | 1\n switch (node._tag) {\n case \"Succeed\":\n case \"Sync\":\n case \"Location\":\n case \"RestLen\":\n case \"Eof\":\n return emptyOptional\n case \"Fail\":\n return node.mode === \"Backtrack\" ? failing : unknown\n case \"Any\":\n return node.encoding !== undefined && kindOfEncoding(node.encoding) !== kind ? unknown : anyUnit\n case \"Take\":\n return node.count === 0 ? emptyOptional : anyUnit\n case \"Literal\": {\n const lit = node.literal\n if (node.encoding !== undefined) {\n if (kindOfEncoding(node.encoding) !== kind) return unknown\n if (node.caseless) return isEmptyUnits(lit) ? unknown : anyUnit\n const encoded = node.encoding.encode(lit as string)\n if (isEmptyUnits(encoded)) return emptyOptional\n return ofUnits([Predicate.isString(encoded) ? encoded.charCodeAt(0) : encoded[0]])\n }\n if (isEmptyUnits(lit)) return emptyOptional\n let first: number\n if (Predicate.isString(lit)) {\n first = kind === 0 ? lit.charCodeAt(0) : new TextEncoder().encode(lit)[0]\n } else if (lit instanceof Uint8Array && kind === 1) {\n first = lit[0]\n } else {\n return unknown\n }\n return ofUnits(node.caseless ? [first, lowerAscii(first), upperAscii(first)] : [first])\n }\n case \"OneOf\":\n case \"TakeWhile\": {\n if (node.encoding !== undefined && kindOfEncoding(node.encoding) !== kind) return unknown\n const min = Predicate.isTagged(node, \"OneOf\") ? 1 : node.min\n if (Predicate.isTagged(node, \"TakeWhile\") && node.max === 0) return emptyOptional\n const mode = min > 0 ? Strict : Optional\n if (node.negate) return mode === Strict ? anyUnit : withMode(anyUnit, Optional)\n const set = node.encoding === undefined ? tokenSet(node.set, kind) : textSet(node.set)\n return this.setUnits(set, node.encoding, mode) ?? (mode === Strict ? anyUnit : unknown)\n }\n case \"Map\":\n case \"As\":\n case \"Tap\":\n case \"TryMap\":\n case \"FilterMap\":\n case \"Filter\":\n case \"Taken\":\n case \"WithTaken\":\n case \"Span\":\n case \"WithSpan\":\n case \"Context\":\n case \"Expected\":\n case \"MapError\":\n case \"OrFail\":\n case \"Peek\":\n case \"Trace\":\n case \"Syntax\":\n case \"ResumeAfter\":\n case \"RetryAfter\":\n return this.of(node.self)\n case \"FlatMap\":\n case \"SeparatedFold\":\n case \"Dispatch\": {\n const f = this.of(Predicate.isTagged(node, \"Dispatch\") ? node.selector : node.self)\n return f.mode === Strict ? f : unknown\n }\n case \"Mode\": {\n const f = this.of(node.self)\n return node.from === \"Backtrack\" ? (f.mode === Unknown ? f : unknown) : f\n }\n case \"Opt\":\n case \"OrElseSucceed\": {\n const f = this.of(node.self)\n return f.mode === Unknown ? f : withMode(f, Optional)\n }\n case \"Seq\":\n case \"Struct\":\n return this.sequence(node.parsers)\n case \"ZipWith\":\n return this.sequence([node.self, node.that])\n case \"Alt\": {\n if (Arr.isReadonlyArrayEmpty(node.parsers)) return failing\n let acc: First | undefined\n let mode: 0 | 1 | 2 = Strict\n for (const p of node.parsers) {\n const f = this.of(p)\n if (f.mode === Unknown) return unknown\n if (f.mode === Optional) mode = Optional\n acc = acc === undefined ? f : union(acc, f, mode)\n }\n return acc === undefined ? failing : withMode(acc, mode)\n }\n case \"Repeat\":\n case \"Fold\":\n case \"Separated\": {\n if (node.max === 0) return emptyOptional\n const f = this.of(node.self)\n if (f.mode !== Strict) return unknown\n return node.min === 0 ? withMode(f, Optional) : f\n }\n case \"Suspend\":\n return this.of(node.resolve())\n default:\n return unknown\n }\n }\n\n private sequence(parsers: ReadonlyArray<ParserLike>): First {\n let acc: First | undefined\n for (const p of parsers) {\n const f = this.of(p)\n if (f.mode === Unknown) return unknown\n acc = acc === undefined ? f : union(acc, f, f.mode)\n if (f.mode === Strict) return acc\n }\n return acc ?? emptyOptional\n }\n}\n\n/**\n * For an `Alt`: the branches worth trying for each next unit, each next\n * high unit, and at the end of the input, or `undefined` when pruning\n * would never skip a branch.\n */\nexport interface AltPlan {\n /** Indexed by unit: indexes into `lists`. */\n readonly byUnit: Uint8Array\n readonly high: number\n readonly end: number\n readonly lists: ReadonlyArray<ReadonlyArray<number>>\n}\n\nexport const planAlt = (firsts: ReadonlyArray<First>): AltPlan | undefined => {\n const n = firsts.length\n if (n < 2 || n > 64) return undefined\n const lists: Array<ReadonlyArray<number>> = []\n const index = new Map<string, number>()\n const listOf = (keep: (f: First) => boolean): number => {\n const list: Array<number> = []\n for (let i = 0; i < n; i++) if (keep(firsts[i])) list.push(i)\n const key = list.join(\",\")\n let k = index.get(key)\n if (k === undefined) {\n k = lists.length\n lists.push(list)\n index.set(key, k)\n }\n return k\n }\n const byUnit = new Uint8Array(TableSize)\n for (let u = 0; u < TableSize; u++) byUnit[u] = listOf((f) => f.mode !== Strict || f.units[u] === 1)\n const high = listOf((f) => f.mode !== Strict || f.high)\n const end = listOf((f) => f.mode !== Strict)\n if (lists.length === 1 && lists[0].length === n) return undefined\n if (lists.length > 255) return undefined\n return { byUnit, high, end, lists }\n}\n"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
  import { Backend } from "./registry.js";
2
- //#region src/internal/compiler/jit.d.ts
3
2
  /**
4
3
  * The JIT as a backend: generated code where `new Function` is allowed,
5
4
  * otherwise (or if generating fails) the closure compiler.
6
5
  */
7
6
  export declare const backend: Backend;
8
- //#endregion
9
7
  //# sourceMappingURL=jit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jit.d.ts","names":[],"sources":["../../../src/internal/compiler/jit.ts"],"mappings":";;;;;;qBAkwCa,SAAS"}
1
+ {"version":3,"file":"jit.d.ts","names":[],"sources":["../../../src/internal/compiler/jit.ts"],"mappings":";;;;;qBAgxCa,SAAS"}
@@ -1,17 +1,20 @@
1
1
  import * as Predicate from "effect/Predicate";
2
+ import * as Result from "effect/Result";
2
3
  import { Fail } from "../../Input.js";
3
4
  import { floatScan, floatTexts, scanFloatBytes, scanFloatString, toFloat } from "../numbers.js";
5
+ import { Key } from "../key.js";
4
6
  import * as Resume from "../resume.js";
5
7
  import { compileAny } from "../tokens.js";
6
8
  import { backend as backend$1, createClosureCompiler } from "./closure.js";
7
9
  import * as Option from "effect/Option";
8
10
  import { charOf, fastLimit, latin1, string, utf16be, utf16le, utf8, validate } from "../text.js";
11
+ import * as Arr from "effect/Array";
9
12
  import { addEntry, flushEntries, fromEntries, isPlainKey } from "../entries.js";
10
- import { children, nodeOf } from "../node.js";
13
+ import { children, nodeOf, scansFloat } from "../node.js";
11
14
  import { buildsEntries, pairOf } from "./entries.js";
12
15
  import { Strict, planAlt } from "./first.js";
13
- import { TableSize, kindOfEncoding, reachesAbove, textSet, tokenSet } from "./sets.js";
14
- //#region src/internal/compiler/jit.ts
16
+ import { TableSize, acceptTable, kindOfEncoding, reachesAbove, textSet, tokenSet } from "./sets.js";
17
+ // src/internal/compiler/jit.ts
15
18
  /**
16
19
  * The JIT: emits JavaScript source for a parser's description and builds
17
20
  * it with `new Function`.
@@ -65,11 +68,8 @@ let supported = false;
65
68
  const jitSupported = () => {
66
69
  if (checked !== globalThis.Function) {
67
70
  checked = globalThis.Function;
68
- try {
69
- supported = checked("return true")() === true;
70
- } catch {
71
- supported = false;
72
- }
71
+ const fn = checked;
72
+ supported = Result.getOrElse(Result.try(() => fn("return true")() === true), () => false);
73
73
  }
74
74
  return supported;
75
75
  };
@@ -117,7 +117,7 @@ const runsOf = (table) => {
117
117
  };
118
118
  /** A JavaScript expression testing `v` against ranges, or `undefined` if too long. */
119
119
  const rangeTest = (runs, v) => {
120
- if (runs.length === 0) return "false";
120
+ if (Arr.isReadonlyArrayEmpty(runs)) return "false";
121
121
  if (runs.length > 4) return void 0;
122
122
  return runs.map(([a, b]) => a === b ? `${v}===${a}` : `(${v}>=${a}&&${v}<=${b})`).join("||");
123
123
  };
@@ -144,8 +144,8 @@ const runCost = ([a, b], size) => a === b || a === 0 || b === size - 1 ? 1 : 2;
144
144
  const tableTest = (table, v, size) => {
145
145
  const accept = runsWhere(table, size, 1);
146
146
  const reject = runsWhere(table, size, 0);
147
- if (accept.length === 0) return "false";
148
- if (reject.length === 0) return "true";
147
+ if (Arr.isReadonlyArrayEmpty(accept)) return "false";
148
+ if (Arr.isReadonlyArrayEmpty(reject)) return "true";
149
149
  const cost = (runs) => runs.reduce((n, r) => n + runCost(r, size), 0);
150
150
  const acceptCost = cost(accept);
151
151
  const rejectCost = cost(reject);
@@ -247,7 +247,7 @@ var Emitter = class {
247
247
  const out = used ? this.v(fn) : null;
248
248
  const done = this.label();
249
249
  const body = this.inline(p, used, out, `break ${done};`, fn, 0);
250
- this.functions.push(`function ${name}(p){const I=$I,E=$E;${fn.vars.length > 0 ? `let ${fn.vars.join(",")};` : ""}${done}:{${body}P=p;return ${out ?? "void 0"}}return F}`);
250
+ this.functions.push(`function ${name}(p){const I=$I,E=$E;${Arr.isArrayNonEmpty(fn.vars) ? `let ${fn.vars.join(",")};` : ""}${done}:{${body}P=p;return ${out ?? "void 0"}}return F}`);
251
251
  return name;
252
252
  }
253
253
  /**
@@ -256,7 +256,7 @@ var Emitter = class {
256
256
  */
257
257
  gen(p, used, out, fail, fn, depth) {
258
258
  const node = nodeOf(p);
259
- if (node._tag === "Suspend") return this.call(this.rule(node.resolve(), used), out, fail);
259
+ if (Predicate.isTagged(node, "Suspend")) return this.call(this.rule(node.resolve(), used), out, fail);
260
260
  if (!isLeaf(node) && ((this.refs.get(p) ?? 0) > 1 && !this.small(p) || depth > 32)) return this.call(this.rule(p, used), out, fail);
261
261
  return this.inline(p, used, out, fail, fn, depth);
262
262
  }
@@ -265,7 +265,7 @@ var Emitter = class {
265
265
  let budget = 6;
266
266
  const visit = (q) => {
267
267
  const node = nodeOf(q);
268
- if (--budget < 0 || node._tag === "Suspend" || node._tag === "Escaped" || node._tag === "Dispatch") return false;
268
+ if (--budget < 0 || Predicate.isTagged(node, "Suspend") || Predicate.isTagged(node, "Escaped") || Predicate.isTagged(node, "Dispatch")) return false;
269
269
  return children(node).every(visit);
270
270
  };
271
271
  return visit(p);
@@ -359,7 +359,7 @@ var Emitter = class {
359
359
  return this.leaf(p, node, used, out, fail, fn);
360
360
  case "Literal": return this.leaf(p, node, used, out, fail, fn, node.literal.length * 4);
361
361
  case "Escaped":
362
- if (!this.native(node.encoding) || this.resumable) return this.delegate(p, used, out, fail, fn);
362
+ if (!this.native(node.encoding)) return this.delegate(p, used, out, fail, fn);
363
363
  return this.escaped(p, node, out, fail, fn, d);
364
364
  case "Map": {
365
365
  if (!used) return this.gen(node.self, false, null, fail, fn, d);
@@ -380,7 +380,7 @@ var Emitter = class {
380
380
  case "FilterMap": {
381
381
  const t = this.v(fn);
382
382
  const r = this.v(fn);
383
- const [tag, field] = node._tag === "TryMap" ? ["Success", "success"] : ["Some", "value"];
383
+ const [tag, field] = Predicate.isTagged(node, "TryMap") ? ["Success", "success"] : ["Some", "value"];
384
384
  return this.gen(node.self, true, t, fail, fn, d) + `${r}=${this.const(node.f)}(${t});if(${r}._tag!=="${tag}"){${BT}${fail}}${set(`${r}.${field}`)}`;
385
385
  }
386
386
  case "Filter": {
@@ -406,7 +406,7 @@ var Emitter = class {
406
406
  case "WithSpan": {
407
407
  const st = this.v(fn);
408
408
  const t = this.v(fn);
409
- const extra = node._tag === "WithSpan" ? `{start:${st},end:p}` : `$S.slice(${st},p)`;
409
+ const extra = Predicate.isTagged(node, "WithSpan") ? `{start:${st},end:p}` : `$S.slice(${st},p)`;
410
410
  return `${st}=p;` + this.gen(node.self, true, t, fail, fn, d) + set(`[${t},${extra}]`);
411
411
  }
412
412
  case "Span": {
@@ -436,8 +436,8 @@ var Emitter = class {
436
436
  const ok = this.label();
437
437
  const bad = this.label();
438
438
  const t = out === null ? null : this.v(fn);
439
- const some = node._tag === "Opt" ? `R.some(${t})` : `${t}`;
440
- const orElse = node._tag === "Opt" ? "R.none()" : `${this.const(node.value)}()`;
439
+ const some = Predicate.isTagged(node, "Opt") ? `R.some(${t})` : `${t}`;
440
+ const orElse = Predicate.isTagged(node, "Opt") ? "R.none()" : `${this.const(node.value)}()`;
441
441
  return `${st}=p;${ok}:{${bad}:{${this.gen(node.self, used, t, `break ${bad};`, fn, d)}${set(some)}break ${ok};}if($S.mode!=="Backtrack"){${fail}}p=${st};${set(orElse)}}`;
442
442
  }
443
443
  case "Peek": {
@@ -481,11 +481,7 @@ var Emitter = class {
481
481
  */
482
482
  float(node, out, fail, fn, d) {
483
483
  if (!floatTexts.has(node.self) || this.kind === 2) return void 0;
484
- let taken = nodeOf(node.self);
485
- while (taken._tag === "Expected") taken = nodeOf(taken.self);
486
- if (taken._tag !== "Taken") return void 0;
487
- const enc = taken.encoding;
488
- if (enc !== void 0 && !(this.native(enc) && enc.unit === 1 && enc.asciiCompatible)) return void 0;
484
+ if (!scansFloat(node.self, (enc) => this.native(enc))) return void 0;
489
485
  const t = this.v(fn);
490
486
  const scan = this.const(floatScan);
491
487
  const near = this.resumable ? `||$S.partial&&${scan}.read+${Margin}>E` : "";
@@ -509,7 +505,7 @@ var Emitter = class {
509
505
  }
510
506
  alt(node, used, out, fail, fn, d) {
511
507
  const parsers = node.parsers;
512
- if (parsers.length === 0) return `${BT}${fail}`;
508
+ if (Arr.isReadonlyArrayEmpty(parsers)) return `${BT}${fail}`;
513
509
  if (parsers.length === 1) return this.gen(parsers[0], used, out, fail, fn, d);
514
510
  const firsts = this.kind === 2 ? void 0 : parsers.map((q) => this.closure.firsts.of(q));
515
511
  const prune = firsts !== void 0 && planAlt(firsts) !== void 0;
@@ -557,9 +553,9 @@ var Emitter = class {
557
553
  return code + `default:{$S.pos=p;${r}=${q}.step($S);if(${r}===F){${fail}}p=$S.pos;}}`;
558
554
  };
559
555
  let sel = nodeOf(node.selector);
560
- const peek = sel._tag === "Peek";
556
+ const peek = Predicate.isTagged(sel, "Peek");
561
557
  if (peek) sel = nodeOf(sel.self);
562
- if (sel._tag !== "Any" || !this.native(sel.encoding)) return general(true);
558
+ if (!Predicate.isTagged(sel, "Any") || !this.native(sel.encoding)) return general(true);
563
559
  const enc = sel.encoding;
564
560
  const r = enc === void 0 ? void 0 : this.reader(enc);
565
561
  const limit = r === void 0 ? this.kind === 0 ? 55296 : TableSize : Math.min(r.fast, 55296);
@@ -587,7 +583,7 @@ var Emitter = class {
587
583
  const bad = this.label();
588
584
  const n = this.v(fn);
589
585
  const st = this.v(fn);
590
- const isFold = node._tag === "Fold";
586
+ const isFold = Predicate.isTagged(node, "Fold");
591
587
  const cond = isFold ? node.while : void 0;
592
588
  const keep = out !== null && used && collect === void 0;
593
589
  const tracked = keep || cond !== void 0;
@@ -619,7 +615,7 @@ var Emitter = class {
619
615
  * of a `Done` one; a resumed repetition records its result when it ends.
620
616
  */
621
617
  resumePoint(fn) {
622
- const key = this.const({});
618
+ const key = this.const(new Key());
623
619
  const entry = this.v(fn);
624
620
  const resumed = this.v(fn);
625
621
  const done = this.label();
@@ -690,7 +686,7 @@ var Emitter = class {
690
686
  element: (f, check) => pair.parsers.map((q, j) => this.gen(q, j === pair.key || j === pair.value, j === pair.key ? key : j === pair.value ? value : null, f, fn, d)).join("") + check + `if(${deferred}===void 0&&R.isPlainKey(${key}))${out}[${key}]=${value};else ${deferred}=R.addEntry(${out},${deferred},${key},${value});`,
691
687
  finish: `if(${deferred}!==void 0)R.flushEntries(${out},${deferred});`
692
688
  };
693
- return node._tag === "Repeat" ? this.repeat(node, true, out, fail, fn, d, collect) : this.separated(node, true, out, fail, fn, d, collect);
689
+ return Predicate.isTagged(node, "Repeat") ? this.repeat(node, true, out, fail, fn, d, collect) : this.separated(node, true, out, fail, fn, d, collect);
694
690
  }
695
691
  default: return this.entries(node.self, out, fail, fn, d);
696
692
  }
@@ -823,35 +819,43 @@ var Emitter = class {
823
819
  const always = highTest(c) === "true";
824
820
  return `${head}if(${c}<${small}){if(!(${member}))break;p++}else ${never && !negate ? `break;` : always && !counted ? `p++;` : `if(${c}<${fast}||${c}>56319){if(!(${highTest(c)}))break ${loop};p++}else{${cp}=${c};if(p+1<I.length){const d=I.charCodeAt(p+1);if((d&64512)===56320)${cp}=((${c}-55296)<<10)+(d-56320)+65536}if(!(${highTest(cp)}))break ${loop};p+=${cp}>65535?2:1}`}${count}}${finish}`;
825
821
  }
822
+ /**
823
+ * `escaped`. In a resumable build it keeps the closure compiler's
824
+ * checkpoints: where the next segment starts and, unless raw, the text
825
+ * so far, saved when a segment or an escape runs out of input.
826
+ */
826
827
  escaped(p, node, out, fail, fn, d) {
827
828
  const enc = node.encoding;
828
829
  const ctrl = node.control;
829
- const r = enc === void 0 ? void 0 : this.reader(enc);
830
- if (r !== void 0 && !(ctrl < r.fast)) return this.delegate(p, !node.raw, out, fail, fn);
830
+ const rd = enc === void 0 ? void 0 : this.reader(enc);
831
+ if (rd !== void 0 && !(ctrl < rd.fast)) return this.delegate(p, !node.raw, out, fail, fn);
831
832
  const raw = node.raw;
833
+ const r = this.resumable ? this.resumePoint(fn) : void 0;
832
834
  const acc = raw ? null : out ?? this.v(fn);
833
835
  const x = raw ? null : this.v(fn);
834
836
  const b = this.v(fn);
835
- const st = this.v(fn);
837
+ const st = r?.entry ?? this.v(fn);
836
838
  const okv = this.v(fn);
837
839
  const loop = this.label();
838
840
  const bad = this.label();
841
+ /** Saves the checkpoint of a segment starting at `pos`, when the parse ran out of input. */
842
+ const save = (pos) => r === void 0 ? "" : `if($S.mode==="Incomplete"&&$S.resume!==void 0)R.save($S,${r.key},${r.entry},${raw ? pos : `{out:${acc},pos:${pos}}`});`;
839
843
  const normal = this.gen(node.normal, !raw, x, `break ${bad};`, fn, d);
840
- const escape = this.gen(node.escape, !raw, x, fail, fn, d);
844
+ const escape = this.gen(node.escape, !raw, x, `${save(b)}${fail}`, fn, d);
841
845
  const onNormal = raw ? `if(p===${b}){$S.mode="Cut";${fail}}continue ${loop};` : `if(p!==${b}){${acc}+=${x};continue ${loop}}`;
842
846
  const slice = enc !== void 0 ? `${this.const(enc.text)}(I,${st},p)` : this.kind === 0 ? `I.slice(${st},p)` : `I.subarray(${st},p)`;
843
- const ctrlTest = r === void 0 ? `p<E&&${this.unit("p")}===${ctrl}` : `${r.guard("p")}&&${r.unit("p")}===${ctrl}`;
844
- return `${raw ? `${st}=p;` : `${acc}="";`}${loop}:while(p<E){${b}=p;${okv}=false;${bad}:{${normal}${okv}=true;}if(${okv}){${onNormal}}else{if($S.mode!=="Backtrack"){${fail}}p=${b}}if(${ctrlTest}){p+=${r?.width ?? 1};${escape}${raw ? "" : `${acc}+=${x};`}}else break ${loop};}` + (raw && out !== null ? `${out}=${slice};` : "");
847
+ const ctrlTest = rd === void 0 ? `p<E&&${this.unit("p")}===${ctrl}` : `${rd.guard("p")}&&${rd.unit("p")}===${ctrl}`;
848
+ const stop = r === void 0 ? loop : this.label();
849
+ const loopCode = `${loop}:while(p<E){${b}=p;${okv}=false;${bad}:{${normal}${okv}=true;}if(${okv}){${onNormal}}else{if($S.mode!=="Backtrack"){${save(b)}${fail}}p=${b}}if(${ctrlTest}){p+=${rd?.width ?? 1};${escape}${raw ? "" : `${acc}+=${x};`}}else break ${stop};}`;
850
+ const body = r === void 0 ? loopCode : `${stop}:{${loopCode}if($S.partial){$S.mode="Incomplete";${save("p")}${fail}}}`;
851
+ if (r === void 0) return `${raw ? `${st}=p;` : `${acc}="";`}${body}${raw && out !== null ? `${out}=${slice};` : ""}`;
852
+ if (acc !== null) return r.wrap(acc, `${acc}=cp.out;p=cp.pos;`, `${acc}="";`, body);
853
+ const value = out ?? this.v(fn);
854
+ return r.wrap(value, "p=cp;", "", `${body}${value}=${out === null ? "void 0" : slice};`);
845
855
  }
846
856
  };
847
857
  /** The UTF-16 code units of a string. */
848
858
  const unitsOf = (s) => Array.from({ length: s.length }, (_, i) => s.charCodeAt(i));
849
- /** 1 where a small code is accepted (taking `negate` into account). */
850
- const acceptTable = (set, negate) => {
851
- const t = new Uint8Array(TableSize);
852
- for (let c = 0; c < TableSize; c++) t[c] = set.table[c] === 1 !== negate ? 1 : 0;
853
- return t;
854
- };
855
859
  /** Generates the source of a compiled parser, without building it. */
856
860
  const generate = (root, kind, resumable = false) => {
857
861
  const e = new Emitter(root, kind, resumable);
@@ -880,23 +884,20 @@ const compileJit = (root, kind, resumable = false) => {
880
884
  */
881
885
  const backend = { build: (p, kind, resumable) => {
882
886
  if (!jitSupported()) return backend$1.build(p, kind, resumable);
883
- try {
884
- const { fallbacks, source, step } = compileJit(p, kind, resumable);
885
- return {
887
+ return Result.match(Result.try(() => compileJit(p, kind, resumable)), {
888
+ onSuccess: ({ fallbacks, source, step }) => ({
886
889
  backend: "jit",
887
890
  step,
888
891
  fallbacks,
889
892
  error: void 0,
890
893
  source
891
- };
892
- } catch (error) {
893
- return {
894
+ }),
895
+ onFailure: (error) => ({
894
896
  ...backend$1.build(p, kind, resumable),
895
897
  jitError: error
896
- };
897
- }
898
+ })
899
+ });
898
900
  } };
899
- //#endregion
900
901
  export { backend };
901
902
 
902
903
  //# sourceMappingURL=jit.js.map