parseman 0.59.0 → 0.59.2

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 (65) hide show
  1. package/README.md +5 -4
  2. package/dist/analysis/diagnostics.js +19 -45
  3. package/dist/analysis/diagnostics.js.map +1 -1
  4. package/dist/cli/index.js +19 -45
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/combinators/choice.d.ts +0 -5
  7. package/dist/combinators/choice.d.ts.map +1 -1
  8. package/dist/combinators/scanTo.d.ts +1 -16
  9. package/dist/combinators/scanTo.d.ts.map +1 -1
  10. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  11. package/dist/compiler/linker.d.ts +0 -3
  12. package/dist/compiler/linker.d.ts.map +1 -1
  13. package/dist/compiler/token-alphabet.d.ts +5 -25
  14. package/dist/compiler/token-alphabet.d.ts.map +1 -1
  15. package/dist/compiler/token-capability.js.map +1 -1
  16. package/dist/compiler/token-dispatch.d.ts +8 -79
  17. package/dist/compiler/token-dispatch.d.ts.map +1 -1
  18. package/dist/cst/root-trivia-scope.d.ts +0 -3
  19. package/dist/cst/root-trivia-scope.d.ts.map +1 -1
  20. package/dist/cst/trivia-entries.d.ts +0 -2
  21. package/dist/cst/trivia-entries.d.ts.map +1 -1
  22. package/dist/cst/trivia-kinds.d.ts +0 -5
  23. package/dist/cst/trivia-kinds.d.ts.map +1 -1
  24. package/dist/index.js +20 -46
  25. package/dist/index.js.map +1 -1
  26. package/dist/language-service/index.js.map +1 -1
  27. package/dist/plugin/index.js +20 -46
  28. package/dist/plugin/index.js.map +1 -1
  29. package/dist/run/index.js.map +1 -1
  30. package/dist/spec/index.js.map +1 -1
  31. package/dist/spec/model.d.ts +0 -8
  32. package/dist/spec/model.d.ts.map +1 -1
  33. package/dist/table/encode.d.ts.map +1 -1
  34. package/dist/table/index.js +19 -45
  35. package/dist/table/index.js.map +1 -1
  36. package/dist/table/ops.d.ts +6 -6
  37. package/dist/table/ops.d.ts.map +1 -1
  38. package/dist/table/program.d.ts +0 -1
  39. package/dist/table/program.d.ts.map +1 -1
  40. package/dist/table/scalar-terminal.d.ts +0 -7
  41. package/dist/table/scalar-terminal.d.ts.map +1 -1
  42. package/dist/table/scan-shapes.d.ts +0 -8
  43. package/dist/table/scan-shapes.d.ts.map +1 -1
  44. package/dist/table/site-labels.d.ts +0 -2
  45. package/dist/table/site-labels.d.ts.map +1 -1
  46. package/dist/version.d.ts +1 -1
  47. package/package.json +1 -1
  48. package/src/combinators/choice.ts +1 -1
  49. package/src/combinators/scanTo.ts +1 -1
  50. package/src/compiler/ir-serialize.ts +2 -1
  51. package/src/compiler/linker.ts +1 -1
  52. package/src/compiler/token-alphabet.ts +14 -10
  53. package/src/compiler/token-dispatch.ts +10 -313
  54. package/src/compiler/token-scanner.ts +2 -2
  55. package/src/cst/root-trivia-scope.ts +1 -1
  56. package/src/cst/trivia-entries.ts +1 -1
  57. package/src/cst/trivia-kinds.ts +1 -1
  58. package/src/spec/model.ts +1 -1
  59. package/src/table/encode.ts +16 -39
  60. package/src/table/ops.ts +6 -6
  61. package/src/table/program.ts +1 -1
  62. package/src/table/scalar-terminal.ts +1 -1
  63. package/src/table/scan-shapes.ts +15 -46
  64. package/src/table/site-labels.ts +1 -1
  65. package/src/version.ts +1 -1
@@ -94,7 +94,7 @@ export type ScanShape =
94
94
  | { kind: 'alt'; arms: ScanShape[]; disjoint: boolean; firsts: Array<CharSet | null> }
95
95
 
96
96
  /** Backslash (`\`) code point — the escape lead char in string shapes. */
97
- export const BACKSLASH = 92
97
+ const BACKSLASH = 92
98
98
 
99
99
  const META = new Set('()[]{}*+?|^$.'.split(''))
100
100
 
@@ -1137,15 +1137,6 @@ function caseFoldLiteralOrAlt(source: string): ScanShape | null {
1137
1137
  return { kind: 'alt', arms: litArms, disjoint: false, firsts: litArms.map(() => null) }
1138
1138
  }
1139
1139
 
1140
- /**
1141
- * `PARSEMAN_SCANTO=indexof` swaps the single-stop-char `until` scan loop for
1142
- * `String.prototype.indexOf`. Defaults OFF so a baseline build is provably
1143
- * byte-identical to the unmodified compiler, which is what makes the A/B a
1144
- * toggle rather than two different compilers (docs/design/derived-tokenization.md
1145
- * §16.3: the gate is a byte-identical parse tree against a toggled baseline).
1146
- */
1147
- const scanToIndexOfEnabled = (): boolean => process.env.PARSEMAN_SCANTO === 'indexof'
1148
-
1149
1140
  export const classCond = (cVar: string, ranges: Array<[number, number]>): string =>
1150
1141
  ranges
1151
1142
  .map(([lo, hi]) => (lo === hi ? `${cVar} === ${lo}` : `(${cVar} >= ${lo} && ${cVar} <= ${hi})`))
@@ -1162,10 +1153,10 @@ export const litCond = (base: string, cps: number[], firstVar?: string): string
1162
1153
  .join(' && ')
1163
1154
 
1164
1155
  /** Line-terminator code points `.` does not match (`\n \r \u2028 \u2029`). */
1165
- export const LINE_TERMINATORS = [10, 13, 8232, 8233] as const
1156
+ const LINE_TERMINATORS = [10, 13, 8232, 8233] as const
1166
1157
 
1167
1158
  /** The body-stop chars that abort a string match (excluded set minus quote/backslash). */
1168
- export function stringHardStop(
1159
+ function stringHardStop(
1169
1160
  shape: Extract<ScanShape, { kind: 'string' }>,
1170
1161
  ): Array<[number, number]> {
1171
1162
  return shape.excluded.filter(
@@ -1467,24 +1458,12 @@ export function emitShapeMatch(
1467
1458
  const openChk = openLen === 1
1468
1459
  ? `${codeAt(start, firstChar)} === ${shape.open[0]}`
1469
1460
  : litCond(start, shape.open, firstChar)
1470
- // A SINGLE stop code point makes this scan a `memchr`, and V8 implements
1471
- // `String.prototype.indexOf` with a SIMD one. Measured 4.3x over the char
1472
- // loop on a 0.97 MiB corpus, 61 of 61 interleaved rounds
1473
- // (scratchpad/native-primitive-bakeoff/micro-scanto.mjs, regime (a)).
1474
- // Semantics are identical: the loop stops at the first stop char or at
1475
- // `input.length`, which is exactly `indexOf`'s hit / not-found pair.
1476
- // Multi-member stop sets stay on the loop — 3x indexOf + min measured at
1477
- // parity (0.992), because the min-reduce rescans the tail and discards it.
1478
- const stopCp =
1479
- shape.stop.length === 1 && shape.stop[0]![0] === shape.stop[0]![1] ? shape.stop[0]![0] : null
1461
+ // A char loop, not `String.prototype.indexOf`. An opt-in `indexOf` variant
1462
+ // (`PARSEMAN_SCANTO=indexof`) won 4.3x in a microbenchmark but was never
1463
+ // claimed as a win on real grammars (CHANGELOG), and nothing enabled it; it
1464
+ // last existed at `4a5d0341`.
1480
1465
  const scanLine =
1481
- stopCp !== null && stopCp <= 0xffff && scanToIndexOfEnabled()
1482
- ? // No temp is minted: a temp would renumber every later variable in the
1483
- // function and show up as an artifact-size delta that is counter
1484
- // renumbering rather than this change (the §9.1.4 / §9.2 effect).
1485
- `${ind} ${j} = input.indexOf(${JSON.stringify(String.fromCharCode(stopCp))}, ${j})` +
1486
- `; if (${j} < 0) ${j} = input.length`
1487
- : `${ind} while (${j} < input.length && !(${classCond(`input.charCodeAt(${j})`, shape.stop)})) ${j}++`
1466
+ `${ind} while (${j} < input.length && !(${classCond(`input.charCodeAt(${j})`, shape.stop)})) ${j}++`
1488
1467
  return {
1489
1468
  setup: [
1490
1469
  `${ind}let ${j} = ${start}`,
@@ -1549,23 +1528,13 @@ export function emitShapeMatch(
1549
1528
  ? `${codeAt(start, firstChar)} === ${shape.open[0]}`
1550
1529
  : litCond(start, shape.open, firstChar)
1551
1530
  const closeChk = litCond(j, shape.close)
1552
- // Scanning to a fixed close literal IS `indexOf`, and V8's is SIMD. The
1553
- // rewrite is exact: the loop stops at the first close literal at or after `j`,
1554
- // or runs out of room and leaves the token unterminated (no match). `indexOf`
1555
- // returns that same first index, or -1 for "never occurs" — mapped to
1556
- // `input.length`, which makes the `j + closeLen <= input.length` guard fail
1557
- // exactly where the loop's room check did. When it IS found the close literal
1558
- // matches by construction, so the guard's re-comparison is dropped.
1559
- const closeStr = String.fromCharCode(...shape.close)
1560
- const scanLines = scanToIndexOfEnabled()
1561
- ? [
1562
- `${ind} ${j} = input.indexOf(${JSON.stringify(closeStr)}, ${j}); if (${j} < 0) ${j} = input.length`,
1563
- `${ind} if (${j} + ${closeLen} <= input.length) ${endV} = ${j} + ${closeLen}`,
1564
- ]
1565
- : [
1566
- `${ind} while (${j} + ${closeLen - 1} < input.length && !(${closeChk})) ${j}++`,
1567
- `${ind} if (${j} + ${closeLen} <= input.length && (${closeChk})) ${endV} = ${j} + ${closeLen}`,
1568
- ]
1531
+ // The loop stops at the first close literal at or after `j`, or runs out of
1532
+ // room and leaves the token unterminated (no match). The same `indexOf`
1533
+ // variant as `until` above was removed with it.
1534
+ const scanLines = [
1535
+ `${ind} while (${j} + ${closeLen - 1} < input.length && !(${closeChk})) ${j}++`,
1536
+ `${ind} if (${j} + ${closeLen} <= input.length && (${closeChk})) ${endV} = ${j} + ${closeLen}`,
1537
+ ]
1569
1538
  return {
1570
1539
  setup: [
1571
1540
  `${ind}let ${j} = ${start}`,
@@ -81,7 +81,7 @@ export const CAP_OFF = 1
81
81
  export const CAP_ON = 2
82
82
 
83
83
  /** Buffer raw-entry mode is not provable at this site. */
84
- export const RAW_UNKNOWN = 0
84
+ const RAW_UNKNOWN = 0
85
85
  /** Buffer retains raw entry values. */
86
86
  export const RAW_CAPTURE = 1
87
87
  /** Buffer retains only a raw source-order count. */
package/src/version.ts CHANGED
@@ -13,4 +13,4 @@
13
13
  * Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
14
14
  * the build if this constant drifts from the published version.
15
15
  */
16
- export const PARSEMAN_VERSION = '0.59.0'
16
+ export const PARSEMAN_VERSION = '0.59.2'