@thomasfosterau/effect-parse 0.2.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 (144) hide show
  1. package/README.md +44 -1
  2. package/dist/Ascii.d.ts +0 -2
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +6 -6
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts +0 -2
  7. package/dist/Binary.d.ts.map +1 -1
  8. package/dist/Binary.js +1 -2
  9. package/dist/Bits.d.ts +0 -2
  10. package/dist/Bits.d.ts.map +1 -1
  11. package/dist/Bits.js +2 -3
  12. package/dist/Bits.js.map +1 -1
  13. package/dist/Compiler.d.ts +0 -2
  14. package/dist/Compiler.d.ts.map +1 -1
  15. package/dist/Compiler.js +1 -2
  16. package/dist/Encoding.d.ts +0 -2
  17. package/dist/Encoding.d.ts.map +1 -1
  18. package/dist/Encoding.js +1 -2
  19. package/dist/Expression.d.ts +0 -2
  20. package/dist/Expression.d.ts.map +1 -1
  21. package/dist/Expression.js +61 -18
  22. package/dist/Expression.js.map +1 -1
  23. package/dist/Input.d.ts +80 -7
  24. package/dist/Input.d.ts.map +1 -1
  25. package/dist/Input.js +149 -18
  26. package/dist/Input.js.map +1 -1
  27. package/dist/Nom.d.ts +1 -3
  28. package/dist/Nom.d.ts.map +1 -1
  29. package/dist/Nom.js +1 -2
  30. package/dist/ParseError.d.ts +0 -2
  31. package/dist/ParseError.d.ts.map +1 -1
  32. package/dist/ParseError.js +6 -10
  33. package/dist/ParseError.js.map +1 -1
  34. package/dist/Parser.d.ts +2 -2
  35. package/dist/Parser.d.ts.map +1 -1
  36. package/dist/Parser.js +58 -32
  37. package/dist/Parser.js.map +1 -1
  38. package/dist/ParserSchema.d.ts +198 -2
  39. package/dist/ParserSchema.d.ts.map +1 -1
  40. package/dist/ParserSchema.js +646 -18
  41. package/dist/ParserSchema.js.map +1 -1
  42. package/dist/ParserStream.d.ts +0 -2
  43. package/dist/ParserStream.d.ts.map +1 -1
  44. package/dist/ParserStream.js +15 -9
  45. package/dist/ParserStream.js.map +1 -1
  46. package/dist/Syntax.d.ts +0 -2
  47. package/dist/Syntax.d.ts.map +1 -1
  48. package/dist/Syntax.js +13 -11
  49. package/dist/Syntax.js.map +1 -1
  50. package/dist/Text.d.ts +0 -2
  51. package/dist/Text.d.ts.map +1 -1
  52. package/dist/Text.js +1 -2
  53. package/dist/Token.d.ts +0 -2
  54. package/dist/Token.d.ts.map +1 -1
  55. package/dist/Token.js +1 -2
  56. package/dist/internal/compiler/closure.d.ts +5 -2
  57. package/dist/internal/compiler/closure.d.ts.map +1 -1
  58. package/dist/internal/compiler/closure.js +160 -92
  59. package/dist/internal/compiler/closure.js.map +1 -1
  60. package/dist/internal/compiler/entries.d.ts +0 -2
  61. package/dist/internal/compiler/entries.d.ts.map +1 -1
  62. package/dist/internal/compiler/entries.js +6 -7
  63. package/dist/internal/compiler/entries.js.map +1 -1
  64. package/dist/internal/compiler/first.d.ts +0 -2
  65. package/dist/internal/compiler/first.d.ts.map +1 -1
  66. package/dist/internal/compiler/first.js +10 -10
  67. package/dist/internal/compiler/first.js.map +1 -1
  68. package/dist/internal/compiler/jit.d.ts +0 -2
  69. package/dist/internal/compiler/jit.d.ts.map +1 -1
  70. package/dist/internal/compiler/jit.js +52 -51
  71. package/dist/internal/compiler/jit.js.map +1 -1
  72. package/dist/internal/compiler/registry.d.ts +0 -2
  73. package/dist/internal/compiler/registry.d.ts.map +1 -1
  74. package/dist/internal/compiler/registry.js +1 -2
  75. package/dist/internal/compiler/sets.d.ts +2 -2
  76. package/dist/internal/compiler/sets.d.ts.map +1 -1
  77. package/dist/internal/compiler/sets.js +8 -3
  78. package/dist/internal/compiler/sets.js.map +1 -1
  79. package/dist/internal/entries.d.ts +0 -2
  80. package/dist/internal/entries.d.ts.map +1 -1
  81. package/dist/internal/entries.js +1 -2
  82. package/dist/internal/key.d.ts +10 -0
  83. package/dist/internal/key.d.ts.map +1 -0
  84. package/dist/internal/key.js +11 -0
  85. package/dist/internal/key.js.map +1 -0
  86. package/dist/internal/node.d.ts +11 -4
  87. package/dist/internal/node.d.ts.map +1 -1
  88. package/dist/internal/node.js +15 -3
  89. package/dist/internal/node.js.map +1 -1
  90. package/dist/internal/numbers.d.ts +0 -2
  91. package/dist/internal/numbers.d.ts.map +1 -1
  92. package/dist/internal/numbers.js +1 -2
  93. package/dist/internal/resume.d.ts +5 -6
  94. package/dist/internal/resume.d.ts.map +1 -1
  95. package/dist/internal/resume.js +1 -2
  96. package/dist/internal/resume.js.map +1 -1
  97. package/dist/internal/run.d.ts +0 -2
  98. package/dist/internal/run.d.ts.map +1 -1
  99. package/dist/internal/run.js +2 -3
  100. package/dist/internal/run.js.map +1 -1
  101. package/dist/internal/stack.d.ts +0 -2
  102. package/dist/internal/stack.d.ts.map +1 -1
  103. package/dist/internal/stack.js +12 -3
  104. package/dist/internal/stack.js.map +1 -1
  105. package/dist/internal/syntax.d.ts +30 -19
  106. package/dist/internal/syntax.d.ts.map +1 -1
  107. package/dist/internal/syntax.js +74 -63
  108. package/dist/internal/syntax.js.map +1 -1
  109. package/dist/internal/text.d.ts +5 -2
  110. package/dist/internal/text.d.ts.map +1 -1
  111. package/dist/internal/text.js +14 -5
  112. package/dist/internal/text.js.map +1 -1
  113. package/dist/internal/ties.d.ts +28 -0
  114. package/dist/internal/ties.d.ts.map +1 -0
  115. package/dist/internal/ties.js +66 -0
  116. package/dist/internal/ties.js.map +1 -0
  117. package/dist/internal/tokens.d.ts +10 -9
  118. package/dist/internal/tokens.d.ts.map +1 -1
  119. package/dist/internal/tokens.js +4 -8
  120. package/dist/internal/tokens.js.map +1 -1
  121. package/package.json +6 -6
  122. package/src/Ascii.ts +6 -5
  123. package/src/Bits.ts +1 -1
  124. package/src/Expression.ts +27 -23
  125. package/src/Input.ts +157 -21
  126. package/src/ParseError.ts +10 -8
  127. package/src/Parser.ts +67 -32
  128. package/src/ParserSchema.ts +982 -23
  129. package/src/ParserStream.ts +20 -8
  130. package/src/Syntax.ts +12 -9
  131. package/src/internal/compiler/closure.ts +202 -90
  132. package/src/internal/compiler/entries.ts +14 -11
  133. package/src/internal/compiler/first.ts +9 -8
  134. package/src/internal/compiler/jit.ts +95 -74
  135. package/src/internal/compiler/sets.ts +7 -0
  136. package/src/internal/key.ts +11 -0
  137. package/src/internal/node.ts +19 -2
  138. package/src/internal/resume.ts +5 -4
  139. package/src/internal/run.ts +1 -1
  140. package/src/internal/stack.ts +6 -1
  141. package/src/internal/syntax.ts +80 -84
  142. package/src/internal/text.ts +24 -4
  143. package/src/internal/ties.ts +83 -0
  144. package/src/internal/tokens.ts +20 -13
package/dist/Parser.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import * as Predicate from "effect/Predicate";
2
2
  import * as Result from "effect/Result";
3
- import { Fail, Failure, State, mergeExpected, mergeFailures } from "./Input.js";
3
+ import { Fail, Failure, State, mergeExpected, mergeFailures, mergeTiedFailures } from "./Input.js";
4
+ import { Key } from "./internal/key.js";
4
5
  import * as Resume from "./internal/resume.js";
5
6
  import * as Registry from "./internal/compiler/registry.js";
6
7
  import * as Option from "effect/Option";
8
+ import { TiedFailures } from "./internal/ties.js";
7
9
  import * as Context from "effect/Context";
8
10
  import * as Effect from "effect/Effect";
9
11
  import { dual } from "effect/Function";
@@ -14,7 +16,7 @@ import * as Entries from "./internal/entries.js";
14
16
  import * as Run from "./internal/run.js";
15
17
  import * as Stack from "./internal/stack.js";
16
18
  import { NodeId, bounds } from "./internal/node.js";
17
- //#region src/Parser.ts
19
+ // src/Parser.ts
18
20
  /**
19
21
  * The `Parser` data type and its general-purpose combinators.
20
22
  *
@@ -134,6 +136,8 @@ const isTwoParserArgs = (args) => isParser(args[0]) && isParser(args[1]);
134
136
  * The step function must either return the parsed value, having advanced
135
137
  * `state.pos` past the consumed input, or return the result of one of
136
138
  * `state.backtrack`, `state.cut`, `state.incomplete`, ... to signal failure.
139
+ * A step that moves the cursor backwards (to retry, or after a lookahead)
140
+ * calls `state.rewind(offset)` rather than assigning `state.pos`.
137
141
  *
138
142
  * @example
139
143
  * ```ts
@@ -460,7 +464,7 @@ const tryMap = /*#__PURE__*/ dual(2, (self, f) => {
460
464
  if (a === Fail) return Fail;
461
465
  const r = f(a);
462
466
  if (Result.isSuccess(r)) return r.success;
463
- state.pos = start;
467
+ state.rewind(start);
464
468
  return state.failCause("Backtrack", "Verify", r.failure);
465
469
  }, self.name, {
466
470
  _tag: "TryMap",
@@ -499,7 +503,7 @@ const filterMap = /*#__PURE__*/ dual(2, (self, f) => {
499
503
  if (a === Fail) return Fail;
500
504
  const o = f(a);
501
505
  if (Option.isSome(o)) return o.value;
502
- state.pos = start;
506
+ state.rewind(start);
503
507
  return state.backtrack("Verify");
504
508
  }, self.name, {
505
509
  _tag: "FilterMap",
@@ -521,7 +525,7 @@ const filter = /*#__PURE__*/ dual(2, (self, predicate) => {
521
525
  const a = step(state);
522
526
  if (a === Fail) return Fail;
523
527
  if (predicate(a)) return a;
524
- state.pos = start;
528
+ state.rewind(start);
525
529
  return state.backtrack("Verify");
526
530
  }, self.name, {
527
531
  _tag: "Filter",
@@ -543,7 +547,7 @@ const filterOrFail = /*#__PURE__*/ dual(3, (self, predicate, orFailWith) => {
543
547
  const a = step(state);
544
548
  if (a === Fail) return Fail;
545
549
  if (predicate(a)) return a;
546
- state.pos = start;
550
+ state.rewind(start);
547
551
  return state.failCause("Backtrack", "Verify", orFailWith(a));
548
552
  }, self.name, {
549
553
  _tag: "Filter",
@@ -698,7 +702,7 @@ const complete = (self) => {
698
702
  const start = state.pos;
699
703
  const a = step(state);
700
704
  if (a === Fail && state.mode === "Incomplete") {
701
- state.pos = start;
705
+ state.rewind(start);
702
706
  return state.backtrack("Complete");
703
707
  }
704
708
  return a;
@@ -835,7 +839,7 @@ const orElseSucceed = /*#__PURE__*/ dual(2, (self, value) => {
835
839
  });
836
840
  /** Rewinds after a recoverable failure, remembering it as a hint. */
837
841
  const recover = (state, start) => {
838
- state.pos = start;
842
+ state.rewind(start);
839
843
  const f = state.failure;
840
844
  if (f.offset === start) {
841
845
  state.hintOffset = start;
@@ -893,7 +897,7 @@ const peek = (self) => {
893
897
  const deepest = state.deepest;
894
898
  const a = step(state);
895
899
  if (a !== Fail) {
896
- state.pos = start;
900
+ state.rewind(start);
897
901
  state.hintOffset = hintOffset;
898
902
  state.hintExpected = hintExpected;
899
903
  state.deepest = deepest;
@@ -919,12 +923,12 @@ const not = (self) => {
919
923
  const hintExpected = state.hintExpected;
920
924
  const deepest = state.deepest;
921
925
  if (step(state) !== Fail) {
922
- state.pos = start;
926
+ state.rewind(start);
923
927
  state.deepest = deepest;
924
928
  return state.backtrack("Not");
925
929
  }
926
930
  if (state.mode !== "Backtrack") return Fail;
927
- state.pos = start;
931
+ state.rewind(start);
928
932
  state.hintOffset = hintOffset;
929
933
  state.hintExpected = hintExpected;
930
934
  state.deepest = deepest;
@@ -1230,17 +1234,39 @@ const alt = (...parsers) => {
1230
1234
  return described((state) => {
1231
1235
  const start = state.pos;
1232
1236
  let failure;
1237
+ let tie1;
1238
+ let tie2;
1233
1239
  for (let i = 0; i < n; i++) {
1234
1240
  const a = steps[i](state);
1235
1241
  if (a !== Fail) {
1236
- if (failure !== void 0 && failure.offset === state.pos) state.setHint(failure.offset, failure.expected);
1242
+ if (failure !== void 0 && failure.offset === state.pos) {
1243
+ let expected = failure.expected;
1244
+ if (tie1 !== void 0) expected = mergeExpected(expected, tie1.expected);
1245
+ if (tie2 !== void 0) expected = mergeExpected(expected, tie2.expected);
1246
+ state.setHint(failure.offset, expected);
1247
+ }
1237
1248
  return a;
1238
1249
  }
1239
1250
  if (state.mode !== "Backtrack") return Fail;
1240
- failure = failure === void 0 ? state.failure : mergeFailures(failure, state.failure);
1241
- state.pos = start;
1251
+ state.rewind(start);
1252
+ const head = state.failureHead;
1253
+ if (failure === void 0 || head.offset > failure.offset) {
1254
+ failure = head;
1255
+ tie1 = state.failureTie1;
1256
+ tie2 = state.failureTie2;
1257
+ } else if (head.offset === failure.offset) {
1258
+ const f = state.failure;
1259
+ if (tie1 === void 0) tie1 = f;
1260
+ else if (tie2 === void 0) tie2 = f;
1261
+ else {
1262
+ failure = mergeTiedFailures(failure, tie1, mergeExpected(failure.expected, tie1.expected));
1263
+ tie1 = tie2;
1264
+ tie2 = f;
1265
+ }
1266
+ }
1242
1267
  }
1243
- return state.failWith("Backtrack", failure ?? state.failure);
1268
+ if (failure === void 0) return state.failWith("Backtrack", state.failure);
1269
+ return tie1 === void 0 ? state.failWith("Backtrack", failure) : state.failTies(failure, tie1, tie2);
1244
1270
  }, "alt", {
1245
1271
  _tag: "Alt",
1246
1272
  parsers
@@ -1289,7 +1315,7 @@ const dispatch = (selector, cases, otherwise) => {
1289
1315
  if (key === Fail) return Fail;
1290
1316
  const parser = choose(key);
1291
1317
  if (parser === void 0) {
1292
- state.pos = start;
1318
+ state.rewind(start);
1293
1319
  return state.backtrack("Dispatch");
1294
1320
  }
1295
1321
  return parser.step(state);
@@ -1313,11 +1339,12 @@ const permutation = (...parsers) => {
1313
1339
  const steps = parsers.map((p) => p.step);
1314
1340
  const n = steps.length;
1315
1341
  return make((state) => {
1316
- const out = new Array(n);
1342
+ const ties = new TiedFailures();
1317
1343
  const done = new Array(n).fill(false);
1344
+ const out = new Array(n);
1318
1345
  let remaining = n;
1319
1346
  while (remaining > 0) {
1320
- let failure;
1347
+ ties.clear();
1321
1348
  let matched = false;
1322
1349
  for (let i = 0; i < n; i++) {
1323
1350
  if (done[i]) continue;
@@ -1331,10 +1358,10 @@ const permutation = (...parsers) => {
1331
1358
  break;
1332
1359
  }
1333
1360
  if (state.mode !== "Backtrack") return Fail;
1334
- failure = failure === void 0 ? state.failure : mergeFailures(failure, state.failure);
1335
- state.pos = start;
1361
+ state.rewind(start);
1362
+ ties.add(state);
1336
1363
  }
1337
- if (!matched) return state.failWith("Backtrack", failure ?? state.failure);
1364
+ if (!matched) return ties.fail(state);
1338
1365
  }
1339
1366
  return out;
1340
1367
  }, "permutation");
@@ -1357,7 +1384,7 @@ const foldImpl = (self, range, init, f, name, node, cond) => {
1357
1384
  const [min, max] = normalizeRange(range);
1358
1385
  const step = self.step;
1359
1386
  const checkLoop = max === Infinity;
1360
- const key = {};
1387
+ const key = new Key();
1361
1388
  return described((state) => {
1362
1389
  const entry = state.pos;
1363
1390
  let acc;
@@ -1480,7 +1507,7 @@ const repeatTill = /*#__PURE__*/ dual(isTwoParserArgs, (self, end, range) => {
1480
1507
  if (b !== Fail) return [acc, b];
1481
1508
  if (state.mode !== "Backtrack") return Fail;
1482
1509
  endFailure = state.failure;
1483
- state.pos = start;
1510
+ state.rewind(start);
1484
1511
  if (acc.length >= max) return Fail;
1485
1512
  }
1486
1513
  const a = step(state);
@@ -1519,7 +1546,7 @@ const separated = /*#__PURE__*/ dual(isTwoParserArgs, (self, separator, range) =
1519
1546
  const step = self.step;
1520
1547
  const sepStep = separator.step;
1521
1548
  const checkLoop = max === Infinity;
1522
- const key = {};
1549
+ const key = new Key();
1523
1550
  return described((state) => {
1524
1551
  const entry = state.pos;
1525
1552
  let acc;
@@ -1562,7 +1589,7 @@ const separated = /*#__PURE__*/ dual(isTwoParserArgs, (self, separator, range) =
1562
1589
  pos: start
1563
1590
  });
1564
1591
  if (state.mode !== "Backtrack" || acc.length < min) return Fail;
1565
- state.pos = start;
1592
+ state.rewind(start);
1566
1593
  return Resume.done(state, key, entry, resumed !== void 0, acc);
1567
1594
  }
1568
1595
  acc.push(a);
@@ -1599,7 +1626,7 @@ const separated = /*#__PURE__*/ dual(isTwoParserArgs, (self, separator, range) =
1599
1626
  const separatedFoldl1 = (self, separator, op) => {
1600
1627
  const step = self.step;
1601
1628
  const sepStep = separator.step;
1602
- const key = {};
1629
+ const key = new Key();
1603
1630
  return described((state) => {
1604
1631
  const entry = state.pos;
1605
1632
  const resumed = state.resume === void 0 ? void 0 : Resume.take(state, key, entry);
@@ -1629,7 +1656,7 @@ const separatedFoldl1 = (self, separator, op) => {
1629
1656
  if (a === Fail) {
1630
1657
  if (state.mode === "Incomplete" && state.resume !== void 0) saveFold(state, key, entry, acc, start);
1631
1658
  if (state.mode !== "Backtrack") return Fail;
1632
- state.pos = start;
1659
+ state.rewind(start);
1633
1660
  return Resume.done(state, key, entry, resumed !== void 0, acc);
1634
1661
  }
1635
1662
  acc = op(acc, s, a);
@@ -1671,7 +1698,7 @@ const separatedFoldr1 = (self, separator, op) => {
1671
1698
  const a = step(state);
1672
1699
  if (a === Fail) {
1673
1700
  if (state.mode !== "Backtrack") return Fail;
1674
- state.pos = start;
1701
+ state.rewind(start);
1675
1702
  break;
1676
1703
  }
1677
1704
  seps.push(s);
@@ -1783,7 +1810,7 @@ const resumeAfter = /*#__PURE__*/ dual(2, (self, recover) => {
1783
1810
  if (state.recovered === void 0 || state.mode === "Incomplete") return Fail;
1784
1811
  const failure = state.failure;
1785
1812
  const mode = state.mode;
1786
- state.pos = start;
1813
+ state.rewind(start);
1787
1814
  if (recoverStep(state) === Fail) return state.failWith(mode, failure);
1788
1815
  state.recovered.push(failure);
1789
1816
  state.syntax?.skipped(start, failure, mode);
@@ -1815,7 +1842,7 @@ const retryAfter = /*#__PURE__*/ dual(2, (self, recover) => {
1815
1842
  if (state.recovered === void 0 || state.mode === "Incomplete") return Fail;
1816
1843
  const failure = state.failure;
1817
1844
  const mode = state.mode;
1818
- state.pos = start;
1845
+ state.rewind(start);
1819
1846
  if (recoverStep(state) === Fail || state.pos === start) return state.failWith(mode, failure);
1820
1847
  state.recovered.push(failure);
1821
1848
  state.syntax?.skipped(start, failure, mode);
@@ -1886,7 +1913,7 @@ const preview = (state, offset) => {
1886
1913
  */
1887
1914
  const consoleTracer = (event) => {
1888
1915
  const indent = " ".repeat(event.depth);
1889
- if (event._tag === "Enter") console.log(`${indent}> ${event.name} @${event.offset} | ${preview(event.state, event.offset)}`);
1916
+ if (Predicate.isTagged(event, "Enter")) console.log(`${indent}> ${event.name} @${event.offset} | ${preview(event.state, event.offset)}`);
1890
1917
  else {
1891
1918
  const consumed = (event.endOffset ?? event.offset) - event.offset;
1892
1919
  console.log(`${indent}< ${event.name} | ${event.result === "Ok" ? `+${consumed}` : event.result}`);
@@ -2138,7 +2165,6 @@ const parseRecoverable = (self, input, options) => {
2138
2165
  errors
2139
2166
  };
2140
2167
  };
2141
- //#endregion
2142
2168
  export { Do, TypeId, allConsuming, alt, as, asSome, asVoid, backtrack, bind, bindTo, complete, cond, consoleTracer, context, cut, delimited, described, dispatch, empty, eof, expected, fail, failMessage, filter, filterMap, filterOrFail, flatMap, fold, fromEntries, gen, isParser, let_ as let, location, make, map, mapError, mapParser, named, not, opt, optional, orElse, orElseSucceed, orFail, parse, parseEffect, parsePartial, parsePeek, parseRecoverable, parseSync, peek, permutation, preceded, provide, provideService, reject, repeat, repeatTill, resumeAfter, retryAfter, run, separated, separatedFoldl1, separatedFoldr1, separatedPair, seq, service, span, struct, succeed, suspend, sync, taken, tap, terminated, todo, trace, tryMap, tryMapUnknown, void_ as void, void_, withSpan, withTaken, zip, zipLeft, zipRight, zipWith };
2143
2169
 
2144
2170
  //# sourceMappingURL=Parser.js.map