functionalscript 0.44.0 → 0.46.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 (571) hide show
  1. package/README.md +5 -3
  2. package/fjs/asn.1/module.f.mjs +8 -1
  3. package/fjs/asn.1/proof.f.d.mts +15 -0
  4. package/fjs/asn.1/proof.f.mjs +31 -3
  5. package/fjs/asserts/module.f.d.mts +14 -0
  6. package/fjs/asserts/module.f.mjs +20 -0
  7. package/fjs/asserts/proof.f.d.mts +3 -0
  8. package/fjs/asserts/proof.f.mjs +15 -1
  9. package/fjs/basen/base128/module.f.mjs +22 -5
  10. package/fjs/basen/base128/proof.f.d.mts +3 -1
  11. package/fjs/basen/base128/proof.f.mjs +3 -1
  12. package/fjs/basen/base64/module.f.mjs +7 -3
  13. package/fjs/basen/base64/proof.f.d.mts +3 -1
  14. package/fjs/basen/base64/proof.f.mjs +7 -4
  15. package/fjs/basen/cbase32/proof.f.d.mts +3 -1
  16. package/fjs/basen/cbase32/proof.f.mjs +3 -1
  17. package/fjs/bnf/data/module.f.d.mts +32 -6
  18. package/fjs/bnf/data/module.f.mjs +112 -7
  19. package/fjs/bnf/data/proof.f.d.mts +2 -0
  20. package/fjs/bnf/data/proof.f.mjs +74 -4
  21. package/fjs/bnf/data/types.d.ts +20 -2
  22. package/fjs/bnf/descent/module.f.d.mts +34 -5
  23. package/fjs/bnf/descent/module.f.mjs +176 -54
  24. package/fjs/bnf/descent/proof.f.d.mts +3 -0
  25. package/fjs/bnf/descent/proof.f.mjs +189 -27
  26. package/fjs/bnf/descent/types.d.ts +24 -18
  27. package/fjs/bnf/ll1/module.f.d.mts +74 -6
  28. package/fjs/bnf/ll1/module.f.mjs +297 -95
  29. package/fjs/bnf/ll1/proof.f.d.mts +17 -2
  30. package/fjs/bnf/ll1/proof.f.mjs +372 -137
  31. package/fjs/bnf/ll1/types.d.ts +25 -27
  32. package/fjs/bnf/matcher/module.f.d.mts +66 -0
  33. package/fjs/bnf/matcher/module.f.mjs +81 -0
  34. package/fjs/bnf/matcher/proof.f.d.mts +10 -0
  35. package/fjs/bnf/matcher/proof.f.mjs +79 -0
  36. package/fjs/bnf/matcher/types.d.ts +54 -0
  37. package/fjs/bnf/module.f.d.mts +15 -6
  38. package/fjs/bnf/module.f.mjs +52 -11
  39. package/fjs/bnf/proof.f.d.mts +2 -0
  40. package/fjs/bnf/proof.f.mjs +79 -3
  41. package/fjs/bnf/testlib.f.d.mts +31 -0
  42. package/fjs/bnf/testlib.f.mjs +80 -0
  43. package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
  44. package/fjs/bnf/token_symbol/module.f.mjs +7 -6
  45. package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
  46. package/fjs/bnf/token_symbol/types.d.ts +2 -2
  47. package/fjs/bnf/types.d.ts +10 -3
  48. package/fjs/cas/cli/module.f.d.mts +1 -1
  49. package/fjs/cas/cli/module.f.mjs +14 -20
  50. package/fjs/cas/cli/proof.f.d.mts +4 -4
  51. package/fjs/cas/cli/proof.f.mjs +47 -34
  52. package/fjs/cas/evo/module.f.d.mts +71 -31
  53. package/fjs/cas/evo/module.f.mjs +223 -138
  54. package/fjs/cas/evo/proof.f.d.mts +10 -1
  55. package/fjs/cas/evo/proof.f.mjs +311 -226
  56. package/fjs/cas/evo/types.d.ts +45 -9
  57. package/fjs/cas/module.f.d.mts +18 -32
  58. package/fjs/cas/module.f.mjs +164 -176
  59. package/fjs/cas/proof.f.d.mts +11 -8
  60. package/fjs/cas/proof.f.mjs +259 -147
  61. package/fjs/cas/types.d.ts +24 -10
  62. package/fjs/ci/common/module.f.d.mts +1 -1
  63. package/fjs/ci/common/module.f.mjs +1 -0
  64. package/fjs/ci/config/module.f.d.mts +3 -3
  65. package/fjs/ci/config/module.f.mjs +3 -3
  66. package/fjs/ci/module.f.d.mts +5 -5
  67. package/fjs/ci/module.f.mjs +8 -7
  68. package/fjs/ci/nix/module.f.d.mts +7 -5
  69. package/fjs/ci/nix/module.f.mjs +13 -12
  70. package/fjs/ci/nix/proof.f.d.mts +2 -0
  71. package/fjs/ci/nix/proof.f.mjs +4 -4
  72. package/fjs/ci/proof.f.d.mts +4 -2
  73. package/fjs/ci/proof.f.mjs +13 -8
  74. package/fjs/cli/module.f.d.mts +4 -6
  75. package/fjs/cli/module.f.mjs +4 -8
  76. package/fjs/cli/proof.f.d.mts +4 -2
  77. package/fjs/cli/proof.f.mjs +21 -18
  78. package/fjs/cli/types.d.ts +2 -3
  79. package/fjs/common/monoid/module.f.d.mts +70 -12
  80. package/fjs/common/monoid/module.f.mjs +177 -14
  81. package/fjs/common/monoid/proof.f.d.mts +12 -1
  82. package/fjs/common/monoid/proof.f.mjs +88 -4
  83. package/fjs/common/monoid/types.d.ts +23 -0
  84. package/fjs/crypto/hmac/module.f.mjs +2 -2
  85. package/fjs/crypto/secp/proof.f.d.mts +3 -1
  86. package/fjs/crypto/secp/proof.f.mjs +3 -1
  87. package/fjs/crypto/sha2/module.f.mjs +3 -1
  88. package/fjs/crypto/sha2/proof.f.d.mts +4 -1
  89. package/fjs/crypto/sha2/proof.f.mjs +27 -1
  90. package/fjs/crypto/sha2/types.d.ts +11 -0
  91. package/fjs/crypto/sign/module.f.mjs +2 -2
  92. package/fjs/crypto/vdf/module.f.d.mts +23 -4
  93. package/fjs/crypto/vdf/module.f.mjs +6 -4
  94. package/fjs/dev/module.f.d.mts +17 -5
  95. package/fjs/dev/module.f.mjs +60 -30
  96. package/fjs/dev/update/module.f.d.mts +11 -3
  97. package/fjs/dev/update/module.f.mjs +16 -11
  98. package/fjs/dev/update/proof.f.d.mts +4 -3
  99. package/fjs/dev/update/proof.f.mjs +11 -7
  100. package/fjs/djs/module.f.d.mts +13 -5
  101. package/fjs/djs/module.f.mjs +31 -16
  102. package/fjs/djs/parser/module.f.d.mts +16 -3
  103. package/fjs/djs/parser/module.f.mjs +135 -16
  104. package/fjs/djs/parser/proof.f.d.mts +8 -1
  105. package/fjs/djs/parser/proof.f.mjs +287 -13
  106. package/fjs/djs/parser/types.d.ts +7 -1
  107. package/fjs/djs/proof.f.d.mts +20 -1
  108. package/fjs/djs/proof.f.mjs +190 -12
  109. package/fjs/djs/serializer/module.f.d.mts +25 -8
  110. package/fjs/djs/serializer/module.f.mjs +66 -19
  111. package/fjs/djs/serializer/proof.f.d.mts +5 -0
  112. package/fjs/djs/serializer/proof.f.mjs +23 -1
  113. package/fjs/djs/tokenizer/module.f.d.mts +17 -5
  114. package/fjs/djs/tokenizer/module.f.mjs +120 -73
  115. package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
  116. package/fjs/djs/tokenizer/proof.f.mjs +86 -67
  117. package/fjs/djs/transpiler/module.f.d.mts +13 -19
  118. package/fjs/djs/transpiler/module.f.mjs +79 -72
  119. package/fjs/djs/transpiler/types.d.ts +29 -0
  120. package/fjs/djs/types.d.ts +7 -1
  121. package/fjs/effects/list/module.f.d.mts +23 -12
  122. package/fjs/effects/list/module.f.mjs +16 -12
  123. package/fjs/effects/list/types.d.ts +27 -7
  124. package/fjs/effects/memory/module.f.d.mts +6 -3
  125. package/fjs/effects/memory/module.f.mjs +7 -7
  126. package/fjs/effects/memory/proof.f.d.mts +4 -0
  127. package/fjs/effects/memory/proof.f.mjs +18 -9
  128. package/fjs/effects/memory/types.d.ts +4 -3
  129. package/fjs/effects/mock/module.f.d.mts +28 -4
  130. package/fjs/effects/mock/module.f.mjs +39 -5
  131. package/fjs/effects/mock/types.d.ts +10 -1
  132. package/fjs/effects/module.d.mts +12 -2
  133. package/fjs/effects/module.f.d.mts +469 -281
  134. package/fjs/effects/module.f.mjs +538 -299
  135. package/fjs/effects/module.mjs +11 -2
  136. package/fjs/effects/node/memory/module.d.mts +7 -2
  137. package/fjs/effects/node/memory/module.mjs +9 -5
  138. package/fjs/effects/node/memory/proof.d.mts +2 -0
  139. package/fjs/effects/node/memory/proof.mjs +12 -5
  140. package/fjs/effects/node/module.d.mts +8 -2
  141. package/fjs/effects/node/module.f.d.mts +183 -43
  142. package/fjs/effects/node/module.f.mjs +260 -62
  143. package/fjs/effects/node/module.mjs +61 -50
  144. package/fjs/effects/node/proof.f.d.mts +28 -2
  145. package/fjs/effects/node/proof.f.mjs +161 -42
  146. package/fjs/effects/node/types.d.ts +106 -18
  147. package/fjs/effects/node/virtual/module.f.d.mts +21 -4
  148. package/fjs/effects/node/virtual/module.f.mjs +113 -70
  149. package/fjs/effects/node/virtual/proof.f.d.mts +31 -2
  150. package/fjs/effects/node/virtual/proof.f.mjs +201 -8
  151. package/fjs/effects/proof.f.d.mts +69 -34
  152. package/fjs/effects/proof.f.mjs +413 -130
  153. package/fjs/effects/types.d.ts +161 -33
  154. package/fjs/emergent_testing/all.test.d.mts +8 -0
  155. package/fjs/emergent_testing/all.test.mjs +14 -0
  156. package/fjs/emergent_testing/module.f.d.mts +22 -10
  157. package/fjs/emergent_testing/module.f.mjs +119 -85
  158. package/fjs/emergent_testing/proof.f.d.mts +21 -7
  159. package/fjs/emergent_testing/proof.f.mjs +169 -35
  160. package/fjs/emergent_testing/types.d.ts +22 -4
  161. package/fjs/fsc/bnf.f.d.mts +3 -0
  162. package/fjs/fsc/bnf.f.mjs +4 -1
  163. package/fjs/fsc/json.f.d.mts +3 -0
  164. package/fjs/fsc/json.f.mjs +4 -1
  165. package/fjs/fsc/module.f.d.mts +9 -0
  166. package/fjs/fsc/module.f.mjs +5 -3
  167. package/fjs/fsm/module.f.d.mts +14 -4
  168. package/fjs/fsm/module.f.mjs +54 -37
  169. package/fjs/fsm/proof.f.d.mts +5 -0
  170. package/fjs/fsm/proof.f.mjs +87 -115
  171. package/fjs/js/keywords/module.f.d.mts +52 -0
  172. package/fjs/js/keywords/module.f.mjs +72 -0
  173. package/fjs/{emergent_testing/scenarios/return-value.pass.d.ts → js/keywords/proof.f.d.mts} +1 -1
  174. package/fjs/js/keywords/proof.f.mjs +13 -0
  175. package/fjs/js/tokenizer/module.f.d.mts +30 -3
  176. package/fjs/js/tokenizer/module.f.mjs +161 -211
  177. package/fjs/js/tokenizer/proof.f.d.mts +1 -0
  178. package/fjs/js/tokenizer/proof.f.mjs +54 -24
  179. package/fjs/js/tokenizer/types.d.ts +33 -24
  180. package/fjs/mcp/cas/module.f.d.mts +1 -6
  181. package/fjs/mcp/cas/module.f.mjs +55 -51
  182. package/fjs/mcp/cas/proof.f.d.mts +15 -0
  183. package/fjs/mcp/cas/proof.f.mjs +174 -0
  184. package/fjs/mcp/evo/module.f.d.mts +19 -10
  185. package/fjs/mcp/evo/module.f.mjs +48 -27
  186. package/fjs/mcp/evo/proof.f.d.mts +6 -1
  187. package/fjs/mcp/evo/proof.f.mjs +115 -31
  188. package/fjs/mcp/module.f.d.mts +39 -4
  189. package/fjs/mcp/module.f.mjs +14 -12
  190. package/fjs/mcp/proof.f.d.mts +13 -1
  191. package/fjs/mcp/proof.f.mjs +120 -61
  192. package/fjs/media/html/module.f.d.mts +12 -0
  193. package/fjs/media/html/module.f.mjs +7 -5
  194. package/fjs/media/html/proof.f.d.mts +3 -0
  195. package/fjs/media/html/proof.f.mjs +4 -1
  196. package/fjs/media/json/extended/module.f.d.mts +82 -0
  197. package/fjs/media/json/extended/module.f.mjs +153 -0
  198. package/fjs/media/json/extended/proof.f.d.mts +42 -0
  199. package/fjs/media/json/extended/proof.f.mjs +127 -0
  200. package/fjs/media/json/extended/types.d.ts +23 -0
  201. package/fjs/media/json/module.f.d.mts +8 -2
  202. package/fjs/media/json/module.f.mjs +43 -41
  203. package/fjs/media/json/number/module.f.d.mts +59 -0
  204. package/fjs/media/json/number/module.f.mjs +136 -0
  205. package/fjs/media/json/number/proof.f.d.mts +24 -0
  206. package/fjs/media/json/number/proof.f.mjs +86 -0
  207. package/fjs/media/json/number/types.d.ts +28 -0
  208. package/fjs/media/json/parser/module.f.d.mts +25 -13
  209. package/fjs/media/json/parser/module.f.mjs +133 -72
  210. package/fjs/media/json/parser/proof.f.d.mts +5 -0
  211. package/fjs/media/json/parser/proof.f.mjs +31 -1
  212. package/fjs/media/json/parser/types.d.ts +38 -14
  213. package/fjs/media/json/rtti/module.f.d.mts +1 -1
  214. package/fjs/media/json/rtti/module.f.mjs +1 -1
  215. package/fjs/media/json/rtti/proof.f.d.mts +3 -0
  216. package/fjs/media/json/rtti/proof.f.mjs +12 -12
  217. package/fjs/media/json/schema/module.f.d.mts +61 -27
  218. package/fjs/media/json/schema/module.f.mjs +218 -63
  219. package/fjs/media/json/schema/proof.f.d.mts +41 -1
  220. package/fjs/media/json/schema/proof.f.mjs +220 -9
  221. package/fjs/media/json/serializer/module.f.d.mts +44 -0
  222. package/fjs/media/json/serializer/module.f.mjs +71 -9
  223. package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
  224. package/fjs/media/json/tokenizer/module.f.mjs +31 -8
  225. package/fjs/media/json/tokenizer/proof.f.d.mts +6 -0
  226. package/fjs/media/json/tokenizer/proof.f.mjs +62 -21
  227. package/fjs/media/json/types.d.ts +36 -10
  228. package/fjs/media/lock/module.f.d.mts +100 -0
  229. package/fjs/media/lock/module.f.mjs +125 -0
  230. package/fjs/media/lock/proof.f.d.mts +33 -0
  231. package/fjs/media/lock/proof.f.mjs +196 -0
  232. package/fjs/media/lock/types.d.ts +15 -0
  233. package/fjs/media/module.f.d.mts +6 -5
  234. package/fjs/media/module.f.mjs +8 -7
  235. package/fjs/media/nix/module.f.d.mts +13 -0
  236. package/fjs/media/nix/module.f.mjs +4 -2
  237. package/fjs/media/nix/proof.f.d.mts +3 -0
  238. package/fjs/media/nix/proof.f.mjs +4 -1
  239. package/fjs/media/note/module.f.d.mts +121 -0
  240. package/fjs/media/note/module.f.mjs +131 -0
  241. package/fjs/media/note/proof.f.d.mts +29 -0
  242. package/fjs/media/note/proof.f.mjs +150 -0
  243. package/fjs/media/note/types.d.ts +10 -0
  244. package/fjs/media/proof.f.d.mts +4 -1
  245. package/fjs/media/proof.f.mjs +40 -21
  246. package/fjs/media/revision/module.f.d.mts +83 -7
  247. package/fjs/media/revision/module.f.mjs +127 -23
  248. package/fjs/media/revision/proof.f.d.mts +14 -0
  249. package/fjs/media/revision/proof.f.mjs +93 -2
  250. package/fjs/media/revision/types.d.ts +34 -5
  251. package/fjs/media/type/module.f.d.mts +53 -18
  252. package/fjs/media/type/module.f.mjs +87 -97
  253. package/fjs/media/type/proof.f.d.mts +17 -0
  254. package/fjs/media/type/proof.f.mjs +73 -13
  255. package/fjs/module.d.mts +5 -0
  256. package/fjs/module.f.d.mts +8 -0
  257. package/fjs/module.f.mjs +33 -10
  258. package/fjs/module.mjs +6 -0
  259. package/fjs/nanvm/proof.f.mjs +3 -3
  260. package/fjs/nanvm/rust/module.f.mjs +1 -1
  261. package/fjs/nanvm/update/module.f.d.mts +4 -4
  262. package/fjs/nanvm/update/module.f.mjs +8 -9
  263. package/fjs/nanvm/update/proof.f.mjs +4 -3
  264. package/fjs/path/module.f.d.mts +8 -0
  265. package/fjs/path/module.f.mjs +4 -2
  266. package/fjs/proof.f.d.mts +7 -3
  267. package/fjs/proof.f.mjs +41 -12
  268. package/fjs/protocol/json_rpc/module.f.d.mts +3 -3
  269. package/fjs/protocol/json_rpc/module.f.mjs +10 -7
  270. package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
  271. package/fjs/protocol/json_rpc/proof.f.mjs +26 -5
  272. package/fjs/protocol/mcp/module.f.d.mts +10 -13
  273. package/fjs/protocol/mcp/module.f.mjs +74 -58
  274. package/fjs/protocol/mcp/proof.f.d.mts +16 -3
  275. package/fjs/protocol/mcp/proof.f.mjs +224 -69
  276. package/fjs/protocol/mcp/stdio/module.f.d.mts +17 -11
  277. package/fjs/protocol/mcp/stdio/module.f.mjs +39 -33
  278. package/fjs/protocol/mcp/stdio/proof.f.d.mts +5 -3
  279. package/fjs/protocol/mcp/stdio/proof.f.mjs +46 -13
  280. package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
  281. package/fjs/protocol/mcp/types.d.ts +17 -6
  282. package/fjs/sul/id/module.f.d.mts +4 -0
  283. package/fjs/sul/id/module.f.mjs +6 -6
  284. package/fjs/sul/level/hash/module.f.d.mts +4 -1
  285. package/fjs/sul/level/hash/module.f.mjs +6 -4
  286. package/fjs/sul/level/hash/proof.f.d.mts +4 -0
  287. package/fjs/sul/level/hash/proof.f.mjs +7 -4
  288. package/fjs/sul/level/literal/module.f.d.mts +4 -1
  289. package/fjs/sul/level/literal/module.f.mjs +4 -3
  290. package/fjs/sul/level/literal/proof.f.d.mts +3 -0
  291. package/fjs/sul/level/literal/proof.f.mjs +4 -1
  292. package/fjs/sul/module.f.d.mts +5 -3
  293. package/fjs/sul/module.f.mjs +23 -17
  294. package/fjs/sul/proof.f.d.mts +4 -0
  295. package/fjs/sul/proof.f.mjs +5 -2
  296. package/fjs/text/ascii/module.f.d.mts +26 -0
  297. package/fjs/text/ascii/module.f.mjs +49 -1
  298. package/fjs/text/ascii/proof.f.d.mts +10 -0
  299. package/fjs/text/ascii/proof.f.mjs +33 -1
  300. package/fjs/text/code_point/module.f.d.mts +29 -3
  301. package/fjs/text/code_point/module.f.mjs +32 -9
  302. package/fjs/text/code_point/proof.f.d.mts +2 -0
  303. package/fjs/text/code_point/proof.f.mjs +39 -0
  304. package/fjs/text/module.f.d.mts +4 -2
  305. package/fjs/text/module.f.mjs +4 -3
  306. package/fjs/text/proof.f.d.mts +3 -0
  307. package/fjs/text/proof.f.mjs +4 -1
  308. package/fjs/text/sgr/module.f.d.mts +6 -5
  309. package/fjs/text/sgr/module.f.mjs +8 -8
  310. package/fjs/text/sgr/proof.f.d.mts +3 -0
  311. package/fjs/text/sgr/proof.f.mjs +4 -1
  312. package/fjs/text/utf16/module.f.d.mts +5 -1
  313. package/fjs/text/utf16/module.f.mjs +38 -35
  314. package/fjs/text/utf16/proof.f.d.mts +3 -1
  315. package/fjs/text/utf16/proof.f.mjs +19 -2
  316. package/fjs/text/utf8/module.f.d.mts +9 -5
  317. package/fjs/text/utf8/module.f.mjs +20 -20
  318. package/fjs/types/array/module.f.d.mts +2 -1
  319. package/fjs/types/array/module.f.mjs +16 -4
  320. package/fjs/types/bigfloat/module.f.d.mts +21 -1
  321. package/fjs/types/bigfloat/module.f.mjs +33 -7
  322. package/fjs/types/bigfloat/proof.f.d.mts +1 -0
  323. package/fjs/types/bigfloat/proof.f.mjs +46 -0
  324. package/fjs/types/bigint/module.f.d.mts +4 -0
  325. package/fjs/types/bigint/module.f.mjs +4 -3
  326. package/fjs/types/bit_vec/module.f.d.mts +10 -16
  327. package/fjs/types/bit_vec/module.f.mjs +99 -95
  328. package/fjs/types/bit_vec/proof.f.d.mts +6 -0
  329. package/fjs/types/bit_vec/proof.f.mjs +31 -5
  330. package/fjs/types/btree/find/module.f.d.mts +5 -1
  331. package/fjs/types/btree/find/module.f.mjs +5 -5
  332. package/fjs/types/btree/find/proof.f.d.mts +5 -1
  333. package/fjs/types/btree/find/proof.f.mjs +5 -3
  334. package/fjs/types/btree/module.f.d.mts +3 -0
  335. package/fjs/types/btree/module.f.mjs +3 -2
  336. package/fjs/types/btree/proof.f.d.mts +5 -1
  337. package/fjs/types/btree/proof.f.mjs +5 -3
  338. package/fjs/types/btree/remove/module.f.d.mts +11 -0
  339. package/fjs/types/btree/remove/module.f.mjs +10 -10
  340. package/fjs/types/btree/remove/proof.f.d.mts +3 -0
  341. package/fjs/types/btree/remove/proof.f.mjs +4 -1
  342. package/fjs/types/btree/set/module.f.d.mts +9 -0
  343. package/fjs/types/btree/set/module.f.mjs +14 -17
  344. package/fjs/types/btree/set/proof.f.d.mts +3 -0
  345. package/fjs/types/btree/set/proof.f.mjs +16 -1
  346. package/fjs/types/btree/types/module.f.d.mts +2 -1
  347. package/fjs/types/btree/types/module.f.mjs +2 -1
  348. package/fjs/types/byte_set/module.f.d.mts +20 -4
  349. package/fjs/types/byte_set/module.f.mjs +18 -8
  350. package/fjs/types/byte_set/proof.f.d.mts +3 -1
  351. package/fjs/types/byte_set/proof.f.mjs +10 -8
  352. package/fjs/types/function/compare/module.f.d.mts +3 -2
  353. package/fjs/types/function/compare/module.f.mjs +13 -5
  354. package/fjs/types/function/module.f.d.mts +8 -1
  355. package/fjs/types/function/module.f.mjs +8 -1
  356. package/fjs/types/function/operator/module.f.d.mts +2 -1
  357. package/fjs/types/function/operator/module.f.mjs +2 -2
  358. package/fjs/types/list/module.f.d.mts +10 -3
  359. package/fjs/types/list/module.f.mjs +6 -4
  360. package/fjs/types/list/proof.f.d.mts +4 -1
  361. package/fjs/types/list/proof.f.mjs +4 -2
  362. package/fjs/types/nibble_set/module.f.d.mts +2 -1
  363. package/fjs/types/nibble_set/module.f.mjs +2 -2
  364. package/fjs/types/nominal/module.f.d.mts +2 -1
  365. package/fjs/types/nominal/module.f.mjs +2 -1
  366. package/fjs/types/nullable/module.f.d.mts +26 -6
  367. package/fjs/types/nullable/module.f.mjs +25 -6
  368. package/fjs/types/nullable/proof.f.d.mts +4 -0
  369. package/fjs/types/nullable/proof.f.mjs +15 -0
  370. package/fjs/types/number/module.f.d.mts +4 -0
  371. package/fjs/types/number/module.f.mjs +4 -3
  372. package/fjs/types/object/module.f.d.mts +26 -4
  373. package/fjs/types/object/module.f.mjs +26 -7
  374. package/fjs/types/object/proof.f.d.mts +5 -2
  375. package/fjs/types/object/proof.f.mjs +6 -3
  376. package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
  377. package/fjs/types/object/structurally_same/module.f.mjs +59 -0
  378. package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
  379. package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
  380. package/fjs/types/ordered_map/module.f.d.mts +5 -0
  381. package/fjs/types/ordered_map/module.f.mjs +5 -4
  382. package/fjs/types/ordered_map/proof.f.d.mts +3 -0
  383. package/fjs/types/ordered_map/proof.f.mjs +4 -1
  384. package/fjs/types/patricia_trie/module.f.d.mts +2 -1
  385. package/fjs/types/patricia_trie/module.f.mjs +27 -12
  386. package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
  387. package/fjs/types/patricia_trie/proof.f.mjs +4 -1
  388. package/fjs/types/prime_field/module.f.d.mts +3 -1
  389. package/fjs/types/prime_field/module.f.mjs +3 -2
  390. package/fjs/types/range/module.f.d.mts +2 -1
  391. package/fjs/types/range/module.f.mjs +2 -2
  392. package/fjs/types/range_map/module.f.d.mts +6 -0
  393. package/fjs/types/range_map/module.f.mjs +6 -9
  394. package/fjs/types/range_map/proof.f.d.mts +5 -1
  395. package/fjs/types/range_map/proof.f.mjs +5 -3
  396. package/fjs/types/range_set/module.f.d.mts +5 -0
  397. package/fjs/types/range_set/module.f.mjs +1 -0
  398. package/fjs/types/range_set/proof.f.d.mts +3 -0
  399. package/fjs/types/range_set/proof.f.mjs +4 -1
  400. package/fjs/types/result/module.d.mts +8 -0
  401. package/fjs/types/result/module.f.d.mts +37 -7
  402. package/fjs/types/result/module.f.mjs +38 -8
  403. package/fjs/types/result/module.mjs +9 -1
  404. package/fjs/types/result/proof.f.d.mts +5 -0
  405. package/fjs/types/result/proof.f.mjs +22 -2
  406. package/fjs/types/rtti/common/module.f.d.mts +44 -14
  407. package/fjs/types/rtti/common/module.f.mjs +42 -36
  408. package/fjs/types/rtti/common/proof.f.d.mts +4 -0
  409. package/fjs/types/rtti/common/proof.f.mjs +10 -7
  410. package/fjs/types/rtti/data/module.f.d.mts +134 -0
  411. package/fjs/types/rtti/data/module.f.mjs +1053 -0
  412. package/fjs/types/rtti/data/proof.f.d.mts +76 -0
  413. package/fjs/types/rtti/data/proof.f.mjs +589 -0
  414. package/fjs/types/rtti/data/types.d.ts +83 -0
  415. package/fjs/types/rtti/module.f.d.mts +12 -5
  416. package/fjs/types/rtti/module.f.mjs +7 -5
  417. package/fjs/types/rtti/parse/module.f.d.mts +48 -0
  418. package/fjs/types/rtti/parse/module.f.mjs +45 -34
  419. package/fjs/types/rtti/parse/proof.f.d.mts +3 -2
  420. package/fjs/types/rtti/parse/proof.f.mjs +51 -52
  421. package/fjs/types/rtti/proof.f.d.mts +3 -1
  422. package/fjs/types/rtti/proof.f.mjs +6 -2
  423. package/fjs/types/rtti/ts/module.f.d.mts +68 -9
  424. package/fjs/types/rtti/ts/module.f.mjs +258 -30
  425. package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
  426. package/fjs/types/rtti/ts/proof.f.mjs +152 -4
  427. package/fjs/types/rtti/ts/types.d.ts +25 -1
  428. package/fjs/types/rtti/types.d.ts +40 -0
  429. package/fjs/types/sorted_list/module.f.d.mts +4 -1
  430. package/fjs/types/sorted_list/module.f.mjs +21 -12
  431. package/fjs/types/sorted_list/proof.f.d.mts +3 -1
  432. package/fjs/types/sorted_list/proof.f.mjs +3 -1
  433. package/fjs/types/sorted_set/module.f.d.mts +49 -1
  434. package/fjs/types/sorted_set/module.f.mjs +26 -2
  435. package/fjs/types/sorted_set/proof.f.d.mts +4 -1
  436. package/fjs/types/sorted_set/proof.f.mjs +19 -2
  437. package/fjs/types/string/module.f.d.mts +4 -0
  438. package/fjs/types/string/module.f.mjs +4 -3
  439. package/fjs/types/string_set/module.f.d.mts +3 -1
  440. package/fjs/types/string_set/module.f.mjs +3 -2
  441. package/fjs/types/ts/module.f.d.mts +2 -0
  442. package/fjs/types/ts/module.f.mjs +3 -3
  443. package/fjs/types/ts/proof.f.d.mts +1 -0
  444. package/fjs/types/ts/proof.f.mjs +5 -0
  445. package/fjs/types/ts/types.d.ts +6 -1
  446. package/fjs/types/uint8array/module.f.d.mts +13 -2
  447. package/fjs/types/uint8array/module.f.mjs +20 -15
  448. package/fjs/website/module.f.d.mts +5 -2
  449. package/fjs/website/module.f.mjs +6 -8
  450. package/fjs/website/proof.f.mjs +2 -1
  451. package/package.json +3 -3
  452. package/fjs/asn.1/types.js +0 -6
  453. package/fjs/asserts/types.js +0 -6
  454. package/fjs/basen/types.js +0 -6
  455. package/fjs/bnf/data/types.js +0 -6
  456. package/fjs/bnf/descent/types.js +0 -6
  457. package/fjs/bnf/ll1/types.js +0 -6
  458. package/fjs/bnf/token_symbol/types.js +0 -6
  459. package/fjs/bnf/types.js +0 -6
  460. package/fjs/cas/evo/types.js +0 -7
  461. package/fjs/cas/types.js +0 -6
  462. package/fjs/ci/common/types.js +0 -1
  463. package/fjs/ci/nix/types.js +0 -6
  464. package/fjs/ci/types.js +0 -6
  465. package/fjs/cli/types.js +0 -6
  466. package/fjs/common/monoid/types.js +0 -6
  467. package/fjs/crypto/pow/types.js +0 -6
  468. package/fjs/crypto/secp/types.js +0 -6
  469. package/fjs/crypto/sha2/types.js +0 -6
  470. package/fjs/crypto/sign/types.js +0 -6
  471. package/fjs/crypto/vdf/types.js +0 -6
  472. package/fjs/dev/package_json/module.f.d.mts +0 -32
  473. package/fjs/dev/package_json/module.f.mjs +0 -37
  474. package/fjs/dev/package_json/proof.f.d.mts +0 -6
  475. package/fjs/dev/package_json/proof.f.mjs +0 -32
  476. package/fjs/dev/types.js +0 -6
  477. package/fjs/djs/ast/types.js +0 -8
  478. package/fjs/djs/parser/types.js +0 -7
  479. package/fjs/djs/tokenizer/types.js +0 -7
  480. package/fjs/djs/types.js +0 -7
  481. package/fjs/effects/eff/module.f.d.mts +0 -10
  482. package/fjs/effects/eff/module.f.mjs +0 -68
  483. package/fjs/effects/eff/proof.f.d.mts +0 -12
  484. package/fjs/effects/eff/proof.f.mjs +0 -66
  485. package/fjs/effects/eff/types.d.ts +0 -71
  486. package/fjs/effects/eff/types.js +0 -6
  487. package/fjs/effects/list/types.js +0 -6
  488. package/fjs/effects/memory/types.js +0 -6
  489. package/fjs/effects/mock/types.js +0 -6
  490. package/fjs/effects/node/types.js +0 -6
  491. package/fjs/effects/node/virtual/types.js +0 -7
  492. package/fjs/effects/types.js +0 -6
  493. package/fjs/emergent_testing/all.test.d.ts +0 -1
  494. package/fjs/emergent_testing/all.test.js +0 -5
  495. package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
  496. package/fjs/emergent_testing/scenarios/all.js +0 -1
  497. package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
  498. package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
  499. package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
  500. package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
  501. package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
  502. package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
  503. package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
  504. package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
  505. package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
  506. package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
  507. package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
  508. package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
  509. package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
  510. package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
  511. package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
  512. package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
  513. package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
  514. package/fjs/emergent_testing/types.js +0 -6
  515. package/fjs/js/tokenizer/types.js +0 -6
  516. package/fjs/media/html/types.js +0 -6
  517. package/fjs/media/json/parser/types.js +0 -6
  518. package/fjs/media/json/tokenizer/types.js +0 -6
  519. package/fjs/media/json/types.js +0 -13
  520. package/fjs/media/nix/types.js +0 -6
  521. package/fjs/media/revision/types.js +0 -8
  522. package/fjs/media/type/types.js +0 -6
  523. package/fjs/media/types.js +0 -7
  524. package/fjs/nanvm/types.js +0 -11
  525. package/fjs/protocol/json_rpc/types.js +0 -8
  526. package/fjs/protocol/mcp/types.js +0 -8
  527. package/fjs/sul/id/types.js +0 -6
  528. package/fjs/sul/level/hash/types.js +0 -6
  529. package/fjs/sul/level/literal/types.js +0 -6
  530. package/fjs/sul/types.js +0 -6
  531. package/fjs/text/sgr/types.js +0 -6
  532. package/fjs/text/types.js +0 -6
  533. package/fjs/text/utf16/types.js +0 -6
  534. package/fjs/text/utf8/types.js +0 -6
  535. package/fjs/types/array/types.js +0 -6
  536. package/fjs/types/bigfloat/types.js +0 -6
  537. package/fjs/types/bigint/types.js +0 -6
  538. package/fjs/types/bit_vec/types.js +0 -6
  539. package/fjs/types/btree/find/types.js +0 -6
  540. package/fjs/types/btree/types/types.js +0 -6
  541. package/fjs/types/byte_set/types.js +0 -6
  542. package/fjs/types/function/compare/types.js +0 -6
  543. package/fjs/types/function/operator/types.js +0 -6
  544. package/fjs/types/function/types.js +0 -6
  545. package/fjs/types/list/types.js +0 -6
  546. package/fjs/types/nibble_set/types.js +0 -6
  547. package/fjs/types/nominal/types.js +0 -6
  548. package/fjs/types/nullable/types.js +0 -6
  549. package/fjs/types/object/types.js +0 -8
  550. package/fjs/types/option/types.js +0 -6
  551. package/fjs/types/ordered_map/types.js +0 -6
  552. package/fjs/types/patricia_trie/types.js +0 -6
  553. package/fjs/types/phantom/types.js +0 -11
  554. package/fjs/types/prime_field/types.js +0 -6
  555. package/fjs/types/range/types.js +0 -6
  556. package/fjs/types/range_map/types.js +0 -6
  557. package/fjs/types/result/types.js +0 -6
  558. package/fjs/types/rtti/common/types.js +0 -1
  559. package/fjs/types/rtti/parse/types.js +0 -1
  560. package/fjs/types/rtti/ts/types.js +0 -1
  561. package/fjs/types/rtti/types.js +0 -1
  562. package/fjs/types/rtti/validate/module.f.d.mts +0 -6
  563. package/fjs/types/rtti/validate/module.f.mjs +0 -169
  564. package/fjs/types/rtti/validate/proof.f.d.mts +0 -125
  565. package/fjs/types/rtti/validate/proof.f.mjs +0 -437
  566. package/fjs/types/rtti/validate/types.d.ts +0 -6
  567. package/fjs/types/rtti/validate/types.js +0 -1
  568. package/fjs/types/sorted_list/types.js +0 -6
  569. package/fjs/types/sorted_set/types.js +0 -6
  570. package/fjs/types/string_set/types.js +0 -6
  571. package/fjs/types/ts/types.js +0 -8
@@ -1,20 +1,28 @@
1
1
  /**
2
2
  * JavaScript tokenizer built as a range-map state machine over code points,
3
3
  * producing tokens for keywords, identifiers, punctuators, comments, strings,
4
- * and numeric literals (including `BigFloat`).
4
+ * and numeric literals.
5
+ *
6
+ * Numeric scanning is lexeme-first: a `number` token carries the exact source
7
+ * text and no derived numeric value, so tokenization stays bounded by the
8
+ * input and never fails because a coefficient or exponent is too large for a
9
+ * runtime numeric type.
5
10
  *
6
11
  * @module
12
+ *
13
+ * @import { Reduce, Scan, StateScan } from '../../types/function/operator/types.ts'
14
+ * @import { RangeMerge } from '../../types/range_map/types.ts'
15
+ * @import { List } from '../../types/list/types.ts'
16
+ * @import { Entry } from '../../types/ordered_map/types.ts'
17
+ * @import { Range as NumberRange } from '../../types/range/types.ts'
18
+ * @import { JsToken, TokenMetadata, JsTokenWithMetadata, _TokenizerStateWithMetadata, _TokenizerState, _ErrorMessage, _InitialState, _ParseIdState, _ParseWhitespaceState, _ParseNewLineState, _ParseStringState, _ParseEscapeCharState, _ParseOperatorState, _ParseCommentState, _ParseUnicodeCharState, _ParseNumberState, _InvalidNumberState, _EofState, _CharCodeOrEof, _ToToken, _CreateToToken, _RangeFunc, _RangeMapToToken, TriviaKind, } from './types.ts'
7
19
  */
8
20
 
9
- /** @import { Scan, StateScan } from '../../types/function/operator/types.ts' */
10
21
  import { strictEqual } from '../../types/function/operator/module.f.mjs'
11
- /** @import { RangeMapArray, RangeMerge } from '../../types/range_map/types.ts' */
12
22
  import { merge, fromRange, get } from '../../types/range_map/module.f.mjs'
13
- /** @import { List } from '../../types/list/types.ts' */
14
23
  import { empty, stateScan, flat, toArray, reduce as listReduce, scan, map as listMap } from '../../types/list/module.f.mjs'
24
+ import { keywords } from '../keywords/module.f.mjs'
15
25
  import { at, fromEntries } from '../../types/ordered_map/module.f.mjs'
16
- /** @import { Entry } from '../../types/ordered_map/types.ts' */
17
- /** @import { Range as NumberRange } from '../../types/range/types.ts' */
18
26
  import { one } from '../../types/range/module.f.mjs'
19
27
  import {
20
28
  range,
@@ -51,8 +59,9 @@ import {
51
59
  digit0,
52
60
  colon,
53
61
  //
62
+ hexDigitValue,
63
+ //
54
64
  latinCapitalLetterRange,
55
- latinCapitalLetterA,
56
65
  latinCapitalLetterE,
57
66
  //
58
67
  leftSquareBracket,
@@ -61,7 +70,6 @@ import {
61
70
  lowLine,
62
71
  //
63
72
  latinSmallLetterRange,
64
- latinSmallLetterA,
65
73
  latinSmallLetterB,
66
74
  latinSmallLetterE,
67
75
  latinSmallLetterF,
@@ -74,42 +82,7 @@ import {
74
82
  rightCurlyBracket,
75
83
  dollarSign
76
84
  } from '../../text/ascii/module.f.mjs'
77
- import { todo, assertEq } from '../../asserts/module.f.mjs'
78
- /** @import {
79
- StringToken,
80
- NumberToken,
81
- BigIntToken,
82
- ErrorToken,
83
- WhitespaceToken,
84
- NewLineToken,
85
- IdToken,
86
- CommentToken,
87
- EofToken,
88
- JsToken,
89
- TokenMetadata,
90
- JsTokenWithMetadata,
91
- _TokenizerStateWithMetadata,
92
- _TokenizerState,
93
- _ErrorMessage,
94
- _InitialState,
95
- _ParseIdState,
96
- _ParseWhitespaceState,
97
- _ParseNewLineState,
98
- _ParseStringState,
99
- _ParseEscapeCharState,
100
- _ParseOperatorState,
101
- _ParseCommentState,
102
- _ParseUnicodeCharState,
103
- _ParseNumberState,
104
- _ParseNumberBuffer,
105
- _InvalidNumberState,
106
- _EofState,
107
- _CharCodeOrEof,
108
- _ToToken,
109
- _CreateToToken,
110
- _RangeFunc,
111
- _RangeMapToToken,
112
- } from './types.ts' */
85
+ import { todo, assertEq, assertStructurallySame } from '../../asserts/module.f.mjs'
113
86
 
114
87
  const { fromCharCode } = String
115
88
 
@@ -150,9 +123,6 @@ const rangeSetTerminalForNumber = [
150
123
  one(tilde),
151
124
  ]
152
125
 
153
- const rangeSmallAF = range('af')
154
- const rangeCapitalAF = range('AF')
155
-
156
126
  const rangeIdStart = [
157
127
  latinSmallLetterRange,
158
128
  latinCapitalLetterRange,
@@ -192,16 +162,19 @@ const rangeId = [digitRange, ...rangeIdStart]
192
162
  const appendChar = old => input => `${old}${fromCharCode(input)}`
193
163
 
194
164
  /**
195
- * @template T
196
- * @param {_CreateToToken<T>} def
197
- * @returns {(a: _CreateToToken<T>) => (b: _CreateToToken<T>) => _CreateToToken<T>}
165
+ * @type {<T>(a: T) => Reduce<T>}
198
166
  */
199
- const union = def => a => b => {
167
+ const unionX = def => a => b => {
200
168
  if (a === def || a === b) { return b }
201
169
  if (b === def) { return a }
202
170
  throw [a, b]
203
171
  }
204
172
 
173
+ /**
174
+ * @type {<T>(a: _CreateToToken<T>) => Reduce<_CreateToToken<T>>}
175
+ */
176
+ const union = unionX
177
+
205
178
  /**
206
179
  * @template T
207
180
  * @param {_CreateToToken<T>} def
@@ -264,83 +237,32 @@ const create = def => a => {
264
237
  return v => c => x(c)(v)(c)
265
238
  }
266
239
 
267
- /** @type {(digit: number) => bigint} */
268
- const digitToBigInt = d => BigInt(d - digit0)
269
-
270
- /** @type {(digit: number) => _ParseNumberBuffer} */
271
- const startNumber = digit => ({ s: 1n, m: digitToBigInt(digit), f: 0, es: 1, e: 0 })
272
-
273
- /** @type {(digit: number) => (b: _ParseNumberBuffer) => _ParseNumberBuffer} */
274
- const addIntDigit = digit => b => ({ ...b, m: b.m * 10n + digitToBigInt(digit) })
275
-
276
- /** @type {(digit: number) => (b: _ParseNumberBuffer) => _ParseNumberBuffer} */
277
- const addFracDigit = digit => b => ({ ...b, m: b.m * 10n + digitToBigInt(digit), f: b.f - 1 })
278
-
279
- /** @type {(digit: number) => (b: _ParseNumberBuffer) => _ParseNumberBuffer} */
280
- const addExpDigit = digit => b => ({ ...b, e: b.e * 10 + digit - digit0 })
281
-
282
- /** @type {(s: _ParseNumberState) => JsToken} */
283
- const bufferToNumberToken = ({ numberKind, value, b }) => {
284
- if (numberKind === 'bigint')
285
- return { kind: 'bigint', value: b.s * b.m }
286
- return { kind: 'number', value: value, bf: [b.s * b.m, b.f + b.es * b.e] }
287
- }
240
+ /**
241
+ * Turns a completed numeric scanning state into its token.
242
+ *
243
+ * A `number` token carries the lexeme and nothing else — deriving a numeric
244
+ * value is each consumer's own policy, so no valid literal can fail to
245
+ * tokenize because its coefficient or exponent exceeds a runtime numeric
246
+ * limit. A `bigint` literal is the one case where the value *is* the token:
247
+ * `123n` means that bigint, so it is constructed here from the same lexeme.
248
+ *
249
+ * @type {(s: _ParseNumberState) => JsToken}
250
+ */
251
+ const stateToNumberToken = ({ numberKind, value }) =>
252
+ numberKind === 'bigint'
253
+ ? { kind: 'bigint', value: BigInt(value) }
254
+ : { kind: 'number', value }
288
255
 
289
256
  /**
290
- * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords
257
+ * Derived from the one source of truth for JavaScript keywords,
258
+ * `fjs/js/keywords` — FunctionalScript is a strict subset of JavaScript, so
259
+ * the tokenizer recognizes exactly that module's `keywords`.
291
260
  */
292
261
  /** @type {List<Entry<JsToken>>} */
293
- const keywordEntries = [
294
- ['arguments', { kind: 'arguments' }],
295
- ['await', { kind: 'await' }],
296
- ['break', { kind: 'break' }],
297
- ['case', { kind: 'case' }],
298
- ['catch', { kind: 'catch' }],
299
- ['class', { kind: 'class' }],
300
- ['const', { kind: 'const' }],
301
- ['continue', { kind: 'continue' }],
302
- ['debugger', { kind: 'debugger' }],
303
- ['default', { kind: 'default' }],
304
- ['delete', { kind: 'delete' }],
305
- ['do', { kind: 'do' }],
306
- ['else', { kind: 'else' }],
307
- ['enum', { kind: 'enum' }],
308
- ['eval', { kind: 'eval' }],
309
- ['export', { kind: 'export' }],
310
- ['extends', { kind: 'extends' }],
311
- ['false', { kind: 'false' }],
312
- ['finally', { kind: 'finally' }],
313
- ['for', { kind: 'for' }],
314
- ['function', { kind: 'function' }],
315
- ['if', { kind: 'if' }],
316
- ['implements', { kind: 'implements' }],
317
- ['import', { kind: 'import' }],
318
- ['in', { kind: 'in' }],
319
- ['instanceof', { kind: 'instanceof' }],
320
- ['interface', { kind: 'interface' }],
321
- ['let', { kind: 'let' }],
322
- ['new', { kind: 'new' }],
323
- ['null', { kind: 'null' }],
324
- ['package', { kind: 'package' }],
325
- ['private', { kind: 'private' }],
326
- ['protected', { kind: 'protected' }],
327
- ['public', { kind: 'public' }],
328
- ['return', { kind: 'return' }],
329
- ['static', { kind: 'static' }],
330
- ['super', { kind: 'super' }],
331
- ['switch', { kind: 'switch' }],
332
- ['this', { kind: 'this' }],
333
- ['throw', { kind: 'throw' }],
334
- ['true', { kind: 'true' }],
335
- ['try', { kind: 'try' }],
336
- ['typeof', { kind: 'typeof' }],
337
- ['undefined', { kind: 'undefined' }],
338
- ['var', { kind: 'var' }],
339
- ['void', { kind: 'void' }],
340
- ['while', { kind: 'while' }],
341
- ['with', { kind: 'with' }],
342
- ['yield', { kind: 'yield' }],
343
- ]
262
+ const keywordEntries = keywords.map(kind =>
263
+ // every keyword kind is a `JsToken` kind by construction: `_KeywordToken`
264
+ // derives its kinds from this same `keywords` list
265
+ [kind, /** @type {JsToken} */ ({ kind })])
344
266
 
345
267
  const keywordMap = fromEntries(keywordEntries)
346
268
 
@@ -419,20 +341,20 @@ const hasOperatorToken = op => at(op)(operatorMap) !== null
419
341
 
420
342
  /** @type {(state: _InitialState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
421
343
  const initialStateOp = create(
422
- /** @type {_CreateToToken<_TokenizerState>} */ (state => () => [[{ kind: 'error', message: 'unexpected character' }], state])
344
+ state => () => [[{ kind: 'error', message: 'unexpected character' }], state]
423
345
  )([
424
- rangeFunc(rangeOneNine)(/** @type {_CreateToToken<_TokenizerState>} */ (() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: 'int' }])),
425
- rangeSetFunc(rangeIdStart)(/** @type {_CreateToToken<_TokenizerState>} */ (() => input => [empty, { kind: 'id', value: fromCharCode(input) }])),
426
- rangeSetFunc(rangeSetWhiteSpace)(/** @type {_CreateToToken<_TokenizerState>} */ (() => () => [empty, { kind: 'ws' }])),
427
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_TokenizerState>} */ (() => () => [empty, { kind: 'nl' }])),
428
- rangeFunc(one(quotationMark))(/** @type {_CreateToToken<_TokenizerState>} */ (() => () => [empty, { kind: 'string', value: '' }])),
429
- rangeFunc(one(digit0))(/** @type {_CreateToToken<_TokenizerState>} */ (() => input => [empty, { kind: 'number', value: fromCharCode(input), b: startNumber(input), numberKind: '0' }])),
430
- rangeSetFunc(rangeOpStart)(/** @type {_CreateToToken<_TokenizerState>} */ (() => input => [empty, { kind: 'op', value: fromCharCode(input) }]))
346
+ rangeFunc(rangeOneNine)(() => input => [empty, { kind: 'number', value: fromCharCode(input), numberKind: 'int' }]),
347
+ rangeSetFunc(rangeIdStart)(() => input => [empty, { kind: 'id', value: fromCharCode(input) }]),
348
+ rangeSetFunc(rangeSetWhiteSpace)(() => () => [empty, { kind: 'ws' }]),
349
+ rangeSetFunc(rangeSetNewLine)(() => () => [empty, { kind: 'nl' }]),
350
+ rangeFunc(one(quotationMark))(() => () => [empty, { kind: 'string', value: '' }]),
351
+ rangeFunc(one(digit0))(() => input => [empty, { kind: 'number', value: fromCharCode(input), numberKind: '0' }]),
352
+ rangeSetFunc(rangeOpStart)(() => input => [empty, { kind: 'op', value: fromCharCode(input) }])
431
353
  ])
432
354
 
433
355
  /** @type {_CreateToToken<_ParseNumberState>} */
434
356
  const invalidNumberToToken = () => input => {
435
- const next = tokenizeOp(input, { kind: 'initial' })
357
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
436
358
  return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
437
359
  }
438
360
 
@@ -440,36 +362,36 @@ const invalidNumberToToken = () => input => {
440
362
  const fullStopToToken = state => input => {
441
363
  switch (state.numberKind) {
442
364
  case '0':
443
- case 'int': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: '.' }]
444
- default: return tokenizeOp(input, { kind: 'invalidNumber' })
365
+ case 'int': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: '.' }]
366
+ default: return tokenizeCharCodeOp(input, { kind: 'invalidNumber' })
445
367
  }
446
368
  }
447
369
 
448
370
  /** @type {_CreateToToken<_ParseNumberState>} */
449
371
  const digit0ToToken = state => input => {
450
372
  switch (state.numberKind) {
451
- case '0': return tokenizeOp(input, { kind: 'invalidNumber' })
373
+ case '0': return tokenizeCharCodeOp(input, { kind: 'invalidNumber' })
452
374
  case '.':
453
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addFracDigit(input)(state.b), numberKind: 'fractional' }]
375
+ case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'fractional' }]
454
376
  case 'e':
455
377
  case 'e+':
456
378
  case 'e-':
457
- case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addExpDigit(input)(state.b), numberKind: 'expDigits' }]
458
- default: return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addIntDigit(input)(state.b), numberKind: state.numberKind }]
379
+ case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'expDigits' }]
380
+ default: return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: state.numberKind }]
459
381
  }
460
382
  }
461
383
 
462
384
  /** @type {_CreateToToken<_ParseNumberState>} */
463
385
  const digit19ToToken = state => input => {
464
386
  switch (state.numberKind) {
465
- case '0': return tokenizeOp(input, { kind: 'invalidNumber' })
387
+ case '0': return tokenizeCharCodeOp(input, { kind: 'invalidNumber' })
466
388
  case '.':
467
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addFracDigit(input)(state.b), numberKind: 'fractional' }]
389
+ case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'fractional' }]
468
390
  case 'e':
469
391
  case 'e+':
470
392
  case 'e-':
471
- case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addExpDigit(input)(state.b), numberKind: 'expDigits' }]
472
- default: return [empty, { kind: 'number', value: appendChar(state.value)(input), b: addIntDigit(input)(state.b), numberKind: 'int' }]
393
+ case 'expDigits': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'expDigits' }]
394
+ default: return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'int' }]
473
395
  }
474
396
  }
475
397
 
@@ -478,15 +400,15 @@ const expToToken = state => input => {
478
400
  switch (state.numberKind) {
479
401
  case '0':
480
402
  case 'int':
481
- case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e' }]
482
- default: return tokenizeOp(input, { kind: 'invalidNumber' })
403
+ case 'fractional': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'e' }]
404
+ default: return tokenizeCharCodeOp(input, { kind: 'invalidNumber' })
483
405
  }
484
406
  }
485
407
 
486
408
  /** @type {_CreateToToken<_ParseNumberState>} */
487
409
  const hyphenMinusToToken = state => input => {
488
410
  switch (state.numberKind) {
489
- case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: { ...state.b, es: -1 }, numberKind: 'e-' }]
411
+ case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'e-' }]
490
412
  default: return terminalToToken(state)(input)
491
413
  }
492
414
  }
@@ -494,8 +416,8 @@ const hyphenMinusToToken = state => input => {
494
416
  /** @type {_CreateToToken<_ParseNumberState>} */
495
417
  const plusSignToToken = state => input => {
496
418
  switch (state.numberKind) {
497
- case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), b: state.b, numberKind: 'e+' }]
498
- default: return tokenizeOp(input, { kind: 'invalidNumber' })
419
+ case 'e': return [empty, { kind: 'number', value: appendChar(state.value)(input), numberKind: 'e+' }]
420
+ default: return tokenizeCharCodeOp(input, { kind: 'invalidNumber' })
499
421
  }
500
422
  }
501
423
 
@@ -507,13 +429,13 @@ const terminalToToken = state => input => {
507
429
  case 'e+':
508
430
  case 'e-':
509
431
  {
510
- const next = tokenizeOp(input, { kind: 'initial' })
432
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
511
433
  return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
512
434
  }
513
435
  default:
514
436
  {
515
- const next = tokenizeOp(input, { kind: 'initial' })
516
- return [{ first: bufferToNumberToken(state), tail: next[0] }, next[1]]
437
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
438
+ return [{ first: stateToNumberToken(state), tail: next[0] }, next[1]]
517
439
  }
518
440
  }
519
441
  }
@@ -524,11 +446,11 @@ const bigintToToken = state => input => {
524
446
  case '0':
525
447
  case 'int':
526
448
  {
527
- return [empty, { kind: 'number', value: state.value, b: state.b, numberKind: 'bigint' }]
449
+ return [empty, { kind: 'number', value: state.value, numberKind: 'bigint' }]
528
450
  }
529
451
  default:
530
452
  {
531
- const next = tokenizeOp(input, { kind: 'initial' })
453
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
532
454
  return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
533
455
  }
534
456
  }
@@ -548,12 +470,12 @@ const parseNumberStateOp = create(invalidNumberToToken)([
548
470
 
549
471
  /** @type {(state: _InvalidNumberState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
550
472
  const invalidNumberStateOp = create(
551
- /** @type {_CreateToToken<_InvalidNumberState>} */ (() => () => [empty, { kind: 'invalidNumber' }])
473
+ () => () => [empty, { kind: 'invalidNumber' }]
552
474
  )([
553
- rangeSetFunc(rangeSetTerminalForNumber)(/** @type {_CreateToToken<_InvalidNumberState>} */ (() => input => {
554
- const next = tokenizeOp(input, { kind: 'initial' })
475
+ rangeSetFunc(rangeSetTerminalForNumber)(() => input => {
476
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
555
477
  return [{ first: { kind: 'error', message: 'invalid number' }, tail: next[0] }, next[1]]
556
- }))
478
+ })
557
479
  ])
558
480
 
559
481
  /** @type {readonly NumberRange[]} */
@@ -565,66 +487,66 @@ const rangeSetStringControl = [
565
487
 
566
488
  /** @type {(state: _ParseStringState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
567
489
  const parseStringStateOp = create(
568
- /** @type {_CreateToToken<_ParseStringState>} */ (state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }])
490
+ state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }]
569
491
  )([
570
- rangeFunc(one(quotationMark))(/** @type {_CreateToToken<_ParseStringState>} */ (state => () => [[{ kind: 'string', value: state.value }], { kind: 'initial' }])),
571
- rangeFunc(one(reverseSolidus))(/** @type {_CreateToToken<_ParseStringState>} */ (state => () => [empty, { kind: 'escapeChar', value: state.value }])),
572
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseStringState>} */ (() => () => [[{ kind: 'error', message: 'unterminated string literal' }], { kind: 'nl' }])),
573
- rangeSetFunc(rangeSetStringControl)(/** @type {_CreateToToken<_ParseStringState>} */ (state => () => [[{ kind: 'error', message: 'unescaped control character in string' }], { kind: 'string', value: state.value }]))
492
+ rangeFunc(one(quotationMark))(state => () => [[{ kind: 'string', value: state.value }], { kind: 'initial' }]),
493
+ rangeFunc(one(reverseSolidus))(state => () => [empty, { kind: 'escapeChar', value: state.value }]),
494
+ rangeSetFunc(rangeSetNewLine)(() => () => [[{ kind: 'error', message: 'unterminated string literal' }], { kind: 'nl' }]),
495
+ rangeSetFunc(rangeSetStringControl)(state => () => [[{ kind: 'error', message: 'unescaped control character in string' }], { kind: 'string', value: state.value }])
574
496
  ])
575
497
 
576
498
  /** @type {_CreateToToken<_ParseEscapeCharState>} */
577
499
  const parseEscapeDefault = state => input => {
578
- const next = tokenizeOp(input, { kind: 'string', value: state.value })
500
+ const next = tokenizeCharCodeOp(input, { kind: 'string', value: state.value })
579
501
  return [{ first: { kind: 'error', message: 'unescaped character' }, tail: next[0] }, next[1]]
580
502
  }
581
503
 
582
504
  /** @type {(state: _ParseEscapeCharState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
583
505
  const parseEscapeCharStateOp = create(parseEscapeDefault)([
584
- rangeSetFunc([one(quotationMark), one(reverseSolidus), one(solidus)])(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }])),
585
- rangeFunc(one(latinSmallLetterB))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'string', value: appendChar(state.value)(backspace) }])),
586
- rangeFunc(one(latinSmallLetterF))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'string', value: appendChar(state.value)(ff) }])),
587
- rangeFunc(one(latinSmallLetterN))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'string', value: appendChar(state.value)(lf) }])),
588
- rangeFunc(one(latinSmallLetterR))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'string', value: appendChar(state.value)(cr) }])),
589
- rangeFunc(one(latinSmallLetterT))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'string', value: appendChar(state.value)(ht) }])),
590
- rangeFunc(one(latinSmallLetterU))(/** @type {_CreateToToken<_ParseEscapeCharState>} */ (state => () => [empty, { kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0 }])),
506
+ rangeSetFunc([one(quotationMark), one(reverseSolidus), one(solidus)])(state => input => [empty, { kind: 'string', value: appendChar(state.value)(input) }]),
507
+ rangeFunc(one(latinSmallLetterB))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(backspace) }]),
508
+ rangeFunc(one(latinSmallLetterF))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(ff) }]),
509
+ rangeFunc(one(latinSmallLetterN))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(lf) }]),
510
+ rangeFunc(one(latinSmallLetterR))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(cr) }]),
511
+ rangeFunc(one(latinSmallLetterT))(state => () => [empty, { kind: 'string', value: appendChar(state.value)(ht) }]),
512
+ rangeFunc(one(latinSmallLetterU))(state => () => [empty, { kind: 'unicodeChar', value: state.value, unicode: 0, hexIndex: 0 }]),
591
513
  ])
592
514
 
593
515
  /** @type {_CreateToToken<_ParseUnicodeCharState>} */
594
516
  const parseUnicodeCharDefault = state => input => {
595
- const next = tokenizeOp(input, { kind: 'string', value: state.value })
517
+ const next = tokenizeCharCodeOp(input, { kind: 'string', value: state.value })
596
518
  return [{ first: { kind: 'error', message: 'invalid hex value' }, tail: next[0] }, next[1]]
597
519
  }
598
520
 
599
- /** @type {(offset: number) => _CreateToToken<_ParseUnicodeCharState>} */
600
- const parseUnicodeCharHex = offset => state => input => {
601
- const hexValue = input - offset
521
+ /**
522
+ * `hexDigitValue` classifies the code point and decodes it in one step, so this
523
+ * state needs no range-map dispatch: a `null` value is exactly the non-hex
524
+ * input the default handler rejects.
525
+ *
526
+ * @type {(state: _ParseUnicodeCharState) => (input: number) => readonly [List<JsToken>, _TokenizerState]}
527
+ */
528
+ const parseUnicodeCharStateOp = state => input => {
529
+ const hexValue = hexDigitValue(input)
530
+ if (hexValue === null) { return parseUnicodeCharDefault(state)(input) }
602
531
  const newUnicode = state.unicode | (hexValue << (3 - state.hexIndex) * 4)
603
532
  return [empty, state.hexIndex === 3 ?
604
533
  { kind: 'string', value: appendChar(state.value)(newUnicode) } :
605
534
  { kind: 'unicodeChar', value: state.value, unicode: newUnicode, hexIndex: state.hexIndex + 1 }]
606
535
  }
607
536
 
608
- /** @type {(state: _ParseUnicodeCharState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
609
- const parseUnicodeCharStateOp = create(parseUnicodeCharDefault)([
610
- rangeFunc(digitRange)(parseUnicodeCharHex(digit0)),
611
- rangeFunc(rangeSmallAF)(parseUnicodeCharHex(latinSmallLetterA - 10)),
612
- rangeFunc(rangeCapitalAF)(parseUnicodeCharHex(latinCapitalLetterA - 10))
613
- ])
614
-
615
537
  /** @type {(s: string) => JsToken} */
616
538
  const idToToken = s => at(s)(keywordMap) ?? { kind: 'id', value: s }
617
539
 
618
540
  /** @type {_CreateToToken<_ParseIdState>} */
619
541
  const parseIdDefault = state => input => {
620
542
  const keyWordToken = idToToken(state.value)
621
- const next = tokenizeOp(input, { kind: 'initial' })
543
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
622
544
  return [{ first: keyWordToken, tail: next[0] }, next[1]]
623
545
  }
624
546
 
625
547
  /** @type {(state: _ParseIdState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
626
548
  const parseIdStateOp = create(parseIdDefault)([
627
- rangeSetFunc(rangeId)(/** @type {_CreateToToken<_ParseIdState>} */ (state => input => [empty, { kind: 'id', value: appendChar(state.value)(input) }]))
549
+ rangeSetFunc(rangeId)(state => input => [empty, { kind: 'id', value: appendChar(state.value)(input) }])
628
550
  ])
629
551
 
630
552
  /** @type {(state: _ParseOperatorState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
@@ -636,7 +558,7 @@ const parseOperatorStateOp = state => input => {
636
558
  default: {
637
559
  if (hasOperatorToken(nextStateValue))
638
560
  return [empty, { kind: 'op', value: nextStateValue }]
639
- const next = tokenizeOp(input, { kind: 'initial' })
561
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
640
562
  return [{ first: getOperatorToken(state.value), tail: next[0] }, next[1]]
641
563
  }
642
564
  }
@@ -644,59 +566,81 @@ const parseOperatorStateOp = state => input => {
644
566
 
645
567
  /** @type {(state: _ParseCommentState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
646
568
  const parseSinglelineCommentStateOp = create(
647
- /** @type {_CreateToToken<_ParseCommentState>} */ (state => input => [empty, { ...state, value: appendChar(state.value)(input) }])
569
+ state => input => [empty, { ...state, value: appendChar(state.value)(input) }]
648
570
  )([
649
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseCommentState>} */ (state => () => [[{ kind: '//', value: state.value }], { kind: 'nl' }]))
571
+ rangeSetFunc(rangeSetNewLine)(state => () => [[{ kind: '//', value: state.value }], { kind: 'nl' }])
650
572
  ])
651
573
 
652
574
  /** @type {(state: _ParseCommentState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
653
575
  const parseMultilineCommentStateOp = create(
654
- /** @type {_CreateToToken<_ParseCommentState>} */ (state => input => [empty, { ...state, value: appendChar(state.value)(input) }])
576
+ state => input => [empty, { ...state, value: appendChar(state.value)(input) }]
655
577
  )([
656
- rangeFunc(one(asterisk))(/** @type {_CreateToToken<_ParseCommentState>} */ (state => () => [empty, { ...state, kind: '/**' }])),
657
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseCommentState>} */ (state => input => [empty, { ...state, value: appendChar(state.value)(input), newLine: true }])),
578
+ rangeFunc(one(asterisk))(state => () => [empty, { ...state, kind: '/**' }]),
579
+ rangeSetFunc(rangeSetNewLine)(state => input => [empty, { ...state, value: appendChar(state.value)(input), newLine: true }]),
658
580
  ])
659
581
 
660
582
  /** @type {(state: _ParseCommentState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
661
583
  const parseMultilineCommentAsteriskStateOp = create(
662
- /** @type {_CreateToToken<_ParseCommentState>} */ (state => input => [empty, { ...state, kind: '/*', value: appendChar(appendChar(state.value)(asterisk))(input) }])
584
+ state => input => [empty, { ...state, kind: '/*', value: appendChar(appendChar(state.value)(asterisk))(input) }]
663
585
  )([
664
- rangeFunc(one(asterisk))(/** @type {_CreateToToken<_ParseCommentState>} */ (state => () => [empty, { ...state, value: appendChar(state.value)(asterisk) }])),
665
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseCommentState>} */ (state => input => [empty, { kind: '/*', value: appendChar(appendChar(state.value)(asterisk))(input), newLine: true }])),
666
- rangeFunc(one(solidus))(/** @type {_CreateToToken<_ParseCommentState>} */ (state => () => {
586
+ rangeFunc(one(asterisk))(state => () => [empty, { ...state, value: appendChar(state.value)(asterisk) }]),
587
+ rangeSetFunc(rangeSetNewLine)(state => input => [empty, { kind: '/*', value: appendChar(appendChar(state.value)(asterisk))(input), newLine: true }]),
588
+ rangeFunc(one(solidus))(state => () => {
667
589
  /** @type {List<JsToken>} */
668
590
  const tokens = state.newLine ? [{ kind: '/*', value: state.value }, { kind: 'nl' }] : [{ kind: '/*', value: state.value }]
669
591
  return [tokens, { kind: 'initial' }]
670
- }))
592
+ })
671
593
  ])
672
594
 
595
+ /**
596
+ * The coalescing rule for whitespace/newline trivia: a maximal run collapses
597
+ * to a single token, and a run containing any newline is an `nl`. Equal kinds
598
+ * coalesce; `nl` absorbs `ws`.
599
+ *
600
+ * Exported because `fjs/djs/tokenizer` produces the same token stream and must
601
+ * agree byte for byte — its scanner reaches the same four decisions from
602
+ * grammar tags. This module defines `JsToken`, so the rule is stated here once
603
+ * rather than re-derived on each side with only the proofs to catch a drift.
604
+ *
605
+ * @type {(a: TriviaKind, b: TriviaKind) => TriviaKind}
606
+ */
607
+ export const mergeTrivia = (a, b) => a === 'nl' || b === 'nl' ? 'nl' : 'ws'
608
+
609
+ /**
610
+ * The two trivia states, shared rather than rebuilt, so a run of trivia
611
+ * allocates nothing per character.
612
+ *
613
+ * @type {{ readonly ws: _ParseWhitespaceState, readonly nl: _ParseNewLineState }}
614
+ */
615
+ const triviaState = { ws: { kind: 'ws' }, nl: { kind: 'nl' } }
616
+
673
617
  /** @type {_CreateToToken<_ParseWhitespaceState>} */
674
618
  const parseWhitespaceDefault = () => input => {
675
- const next = tokenizeOp(input, { kind: 'initial' })
619
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
676
620
  return [{ first: { kind: 'ws' }, tail: next[0] }, next[1]]
677
621
  }
678
622
 
679
623
  /** @type {(state: _ParseWhitespaceState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
680
624
  const parseWhitespaceStateOp = create(parseWhitespaceDefault)([
681
- rangeSetFunc(rangeSetWhiteSpace)(/** @type {_CreateToToken<_ParseWhitespaceState>} */ (state => () => [empty, state])),
682
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseWhitespaceState>} */ (() => () => [empty, { kind: 'nl' }]))
625
+ rangeSetFunc(rangeSetWhiteSpace)(({ kind }) => () => [empty, triviaState[mergeTrivia(kind, 'ws')]]),
626
+ rangeSetFunc(rangeSetNewLine)(({ kind }) => () => [empty, triviaState[mergeTrivia(kind, 'nl')]])
683
627
  ])
684
628
 
685
629
  /** @type {_CreateToToken<_ParseNewLineState>} */
686
630
  const parseNewLineDefault = () => input => {
687
- const next = tokenizeOp(input, { kind: 'initial' })
631
+ const next = tokenizeCharCodeOp(input, { kind: 'initial' })
688
632
  return [{ first: { kind: 'nl' }, tail: next[0] }, next[1]]
689
633
  }
690
634
 
691
635
  /** @type {(state: _ParseNewLineState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
692
636
  const parseNewLineStateOp = create(parseNewLineDefault)([
693
- rangeSetFunc(rangeSetWhiteSpace)(/** @type {_CreateToToken<_ParseNewLineState>} */ (state => () => [empty, state])),
694
- rangeSetFunc(rangeSetNewLine)(/** @type {_CreateToToken<_ParseNewLineState>} */ (state => () => [empty, state]))
637
+ rangeSetFunc(rangeSetWhiteSpace)(({ kind }) => () => [empty, triviaState[mergeTrivia(kind, 'ws')]]),
638
+ rangeSetFunc(rangeSetNewLine)(({ kind }) => () => [empty, triviaState[mergeTrivia(kind, 'nl')]])
695
639
  ])
696
640
 
697
641
  /** @type {(state: _EofState) => (input: number) => readonly [List<JsToken>, _TokenizerState]} */
698
642
  const eofStateOp = create(
699
- /** @type {_CreateToToken<_EofState>} */ (state => () => [[{ kind: 'error', message: 'eof' }], state])
643
+ state => () => [[{ kind: 'error', message: 'eof' }], state]
700
644
  )([])
701
645
 
702
646
  /** @type {StateScan<number, _TokenizerState, List<JsToken>>} */
@@ -735,7 +679,7 @@ const tokenizeEofOp = state => {
735
679
  case 'e+':
736
680
  case 'e-': return [[{ kind: 'error', message: 'invalid number' }, { kind: 'eof' }], { kind: 'eof', }]
737
681
  }
738
- return [[bufferToNumberToken(state), { kind: 'eof' }], { kind: 'eof' }]
682
+ return [[stateToNumberToken(state), { kind: 'eof' }], { kind: 'eof' }]
739
683
  case 'op': return [[getOperatorToken(state.value), { kind: 'eof' }], { kind: 'eof' }]
740
684
  case '//': return [[{ kind: '//', value: state.value }, { kind: 'eof' }], { kind: 'eof' }]
741
685
  case '/*':
@@ -746,9 +690,6 @@ const tokenizeEofOp = state => {
746
690
  }
747
691
  }
748
692
 
749
- /** @type {StateScan<_CharCodeOrEof, _TokenizerState, List<JsToken>>} */
750
- const tokenizeOp = (input, state) => input === null ? tokenizeEofOp(state) : tokenizeCharCodeOp(input, state)
751
-
752
693
  /** @type {(metadata: TokenMetadata) => (token: JsToken) => JsTokenWithMetadata} */
753
694
  const mapTokenWithMetadata = metadata => token => { return { token, metadata } }
754
695
 
@@ -782,14 +723,23 @@ export const proof = {
782
723
  const result = getOperatorToken('@')
783
724
  assertEq(result.kind, 'error')
784
725
  },
726
+ // `tokenize` appends exactly one trailing `null` after its input, so the
727
+ // scan reaches `{ kind: 'eof' }` only on that final step — nothing ever
728
+ // runs tokenizeCharCodeOp/tokenizeEofOp again afterward with that state.
729
+ // Call each directly to cover their otherwise-unreachable `'eof'` arms.
730
+ tokenizeCharCodeOpAfterEof: () => {
731
+ const [tokens, state] = tokenizeCharCodeOp('a'.charCodeAt(0), { kind: 'eof' })
732
+ assertStructurallySame(toArray(tokens), [{ kind: 'error', message: 'eof' }])
733
+ assertStructurallySame(state, { kind: 'eof' })
734
+ },
735
+ tokenizeEofOpAfterEof: () => {
736
+ const [tokens, state] = tokenizeEofOp({ kind: 'eof' })
737
+ assertStructurallySame(toArray(tokens), [{ kind: 'error', message: 'eof' }, { kind: 'eof' }])
738
+ assertStructurallySame(state, { kind: 'eof' })
739
+ },
785
740
  throw: {
786
741
  // union throws when two distinct non-default handlers are merged for the same range;
787
742
  // this path is unreachable through the public API (no overlapping ranges in practice).
788
- unionConflict: () => {
789
- const def = (/** @type {undefined} */ _) => todo
790
- const a = (/** @type {undefined} */ _) => todo
791
- const b = (/** @type {undefined} */ _) => todo
792
- union(def)(a)(b)
793
- }
743
+ unionConflict: () => unionX(0)(1)(2)
794
744
  }
795
745
  }