functionalscript 0.44.0 → 0.45.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 (453) hide show
  1. package/fjs/asn.1/proof.f.d.mts +5 -0
  2. package/fjs/asn.1/proof.f.mjs +15 -3
  3. package/fjs/asserts/module.f.d.mts +14 -0
  4. package/fjs/asserts/module.f.mjs +20 -0
  5. package/fjs/asserts/proof.f.d.mts +3 -0
  6. package/fjs/asserts/proof.f.mjs +15 -1
  7. package/fjs/basen/base128/proof.f.d.mts +3 -1
  8. package/fjs/basen/base128/proof.f.mjs +3 -1
  9. package/fjs/basen/base64/module.f.mjs +7 -3
  10. package/fjs/basen/base64/proof.f.d.mts +3 -1
  11. package/fjs/basen/base64/proof.f.mjs +7 -4
  12. package/fjs/basen/cbase32/proof.f.d.mts +3 -1
  13. package/fjs/basen/cbase32/proof.f.mjs +3 -1
  14. package/fjs/bnf/data/proof.f.mjs +0 -1
  15. package/fjs/bnf/descent/module.f.d.mts +17 -2
  16. package/fjs/bnf/descent/module.f.mjs +118 -41
  17. package/fjs/bnf/descent/proof.f.d.mts +1 -0
  18. package/fjs/bnf/descent/proof.f.mjs +77 -1
  19. package/fjs/bnf/descent/types.d.ts +12 -4
  20. package/fjs/bnf/ll1/module.f.d.mts +28 -2
  21. package/fjs/bnf/ll1/module.f.mjs +180 -38
  22. package/fjs/bnf/ll1/proof.f.d.mts +2 -0
  23. package/fjs/bnf/ll1/proof.f.mjs +62 -1
  24. package/fjs/bnf/ll1/types.d.ts +14 -8
  25. package/fjs/bnf/module.f.d.mts +15 -6
  26. package/fjs/bnf/module.f.mjs +52 -11
  27. package/fjs/bnf/proof.f.d.mts +2 -0
  28. package/fjs/bnf/proof.f.mjs +79 -3
  29. package/fjs/bnf/token_symbol/module.f.d.mts +4 -3
  30. package/fjs/bnf/token_symbol/module.f.mjs +7 -6
  31. package/fjs/bnf/token_symbol/proof.f.mjs +5 -2
  32. package/fjs/bnf/token_symbol/types.d.ts +2 -2
  33. package/fjs/bnf/types.d.ts +10 -3
  34. package/fjs/cas/cli/proof.f.d.mts +3 -1
  35. package/fjs/cas/cli/proof.f.mjs +3 -1
  36. package/fjs/cas/evo/module.f.d.mts +7 -13
  37. package/fjs/cas/evo/module.f.mjs +103 -96
  38. package/fjs/cas/evo/proof.f.mjs +6 -3
  39. package/fjs/cas/module.f.mjs +96 -109
  40. package/fjs/ci/common/module.f.d.mts +1 -1
  41. package/fjs/ci/common/module.f.mjs +1 -0
  42. package/fjs/ci/config/module.f.d.mts +2 -2
  43. package/fjs/ci/config/module.f.mjs +2 -2
  44. package/fjs/ci/nix/proof.f.d.mts +2 -0
  45. package/fjs/ci/nix/proof.f.mjs +2 -2
  46. package/fjs/ci/proof.f.d.mts +4 -2
  47. package/fjs/ci/proof.f.mjs +4 -3
  48. package/fjs/cli/proof.f.d.mts +4 -2
  49. package/fjs/cli/proof.f.mjs +4 -2
  50. package/fjs/common/monoid/module.f.d.mts +70 -12
  51. package/fjs/common/monoid/module.f.mjs +177 -14
  52. package/fjs/common/monoid/proof.f.d.mts +12 -1
  53. package/fjs/common/monoid/proof.f.mjs +88 -4
  54. package/fjs/common/monoid/types.d.ts +23 -0
  55. package/fjs/crypto/secp/proof.f.d.mts +3 -1
  56. package/fjs/crypto/secp/proof.f.mjs +3 -1
  57. package/fjs/crypto/sha2/proof.f.d.mts +3 -1
  58. package/fjs/crypto/sha2/proof.f.mjs +3 -1
  59. package/fjs/crypto/vdf/module.f.d.mts +23 -4
  60. package/fjs/crypto/vdf/module.f.mjs +6 -4
  61. package/fjs/dev/module.f.d.mts +5 -2
  62. package/fjs/dev/module.f.mjs +5 -4
  63. package/fjs/dev/package_json/module.f.d.mts +7 -0
  64. package/fjs/dev/package_json/module.f.mjs +10 -7
  65. package/fjs/dev/update/module.f.d.mts +3 -0
  66. package/fjs/dev/update/module.f.mjs +3 -2
  67. package/fjs/dev/update/proof.f.d.mts +3 -0
  68. package/fjs/dev/update/proof.f.mjs +1 -2
  69. package/fjs/djs/parser/module.f.d.mts +3 -0
  70. package/fjs/djs/parser/module.f.mjs +18 -0
  71. package/fjs/djs/parser/proof.f.d.mts +3 -0
  72. package/fjs/djs/parser/proof.f.mjs +13 -1
  73. package/fjs/djs/proof.f.d.mts +3 -0
  74. package/fjs/djs/proof.f.mjs +4 -1
  75. package/fjs/djs/serializer/module.f.mjs +5 -4
  76. package/fjs/djs/tokenizer/module.f.mjs +21 -13
  77. package/fjs/djs/tokenizer/proof.f.d.mts +3 -0
  78. package/fjs/djs/tokenizer/proof.f.mjs +14 -2
  79. package/fjs/djs/transpiler/module.f.d.mts +1 -12
  80. package/fjs/djs/transpiler/module.f.mjs +1 -20
  81. package/fjs/djs/transpiler/types.d.ts +25 -0
  82. package/fjs/effects/eff/module.f.d.mts +10 -0
  83. package/fjs/effects/eff/module.f.mjs +4 -2
  84. package/fjs/effects/eff/proof.f.d.mts +3 -0
  85. package/fjs/effects/eff/proof.f.mjs +4 -1
  86. package/fjs/effects/list/module.f.d.mts +10 -2
  87. package/fjs/effects/list/module.f.mjs +4 -2
  88. package/fjs/effects/memory/module.f.d.mts +4 -2
  89. package/fjs/effects/memory/module.f.mjs +4 -3
  90. package/fjs/effects/memory/proof.f.d.mts +4 -0
  91. package/fjs/effects/memory/proof.f.mjs +5 -2
  92. package/fjs/effects/mock/module.f.d.mts +10 -2
  93. package/fjs/effects/mock/module.f.mjs +4 -2
  94. package/fjs/effects/module.d.mts +8 -0
  95. package/fjs/effects/module.f.d.mts +6 -4
  96. package/fjs/effects/module.f.mjs +6 -5
  97. package/fjs/effects/module.mjs +9 -1
  98. package/fjs/effects/node/memory/module.d.mts +3 -0
  99. package/fjs/effects/node/memory/module.mjs +3 -2
  100. package/fjs/effects/node/memory/proof.d.mts +2 -0
  101. package/fjs/effects/node/memory/proof.mjs +2 -1
  102. package/fjs/effects/node/module.d.mts +5 -0
  103. package/fjs/effects/node/module.f.d.mts +17 -12
  104. package/fjs/effects/node/module.f.mjs +6 -12
  105. package/fjs/effects/node/module.mjs +5 -17
  106. package/fjs/effects/node/virtual/module.f.d.mts +6 -3
  107. package/fjs/effects/node/virtual/module.f.mjs +6 -5
  108. package/fjs/effects/node/virtual/proof.f.d.mts +4 -1
  109. package/fjs/effects/node/virtual/proof.f.mjs +13 -1
  110. package/fjs/effects/proof.f.d.mts +3 -0
  111. package/fjs/effects/proof.f.mjs +4 -1
  112. package/fjs/emergent_testing/all.test.d.mts +8 -0
  113. package/fjs/emergent_testing/all.test.mjs +14 -0
  114. package/fjs/emergent_testing/module.f.d.mts +6 -1
  115. package/fjs/emergent_testing/module.f.mjs +40 -66
  116. package/fjs/emergent_testing/proof.f.mjs +5 -5
  117. package/fjs/fsc/bnf.f.d.mts +3 -0
  118. package/fjs/fsc/bnf.f.mjs +4 -1
  119. package/fjs/fsc/json.f.d.mts +3 -0
  120. package/fjs/fsc/json.f.mjs +4 -1
  121. package/fjs/fsc/module.f.d.mts +9 -0
  122. package/fjs/fsc/module.f.mjs +5 -3
  123. package/fjs/fsm/proof.f.d.mts +3 -0
  124. package/fjs/fsm/proof.f.mjs +4 -1
  125. package/fjs/js/tokenizer/module.f.d.mts +7 -0
  126. package/fjs/js/tokenizer/module.f.mjs +19 -55
  127. package/fjs/mcp/module.f.d.mts +36 -1
  128. package/fjs/mcp/module.f.mjs +9 -7
  129. package/fjs/mcp/proof.f.d.mts +11 -1
  130. package/fjs/mcp/proof.f.mjs +11 -18
  131. package/fjs/media/html/module.f.d.mts +12 -0
  132. package/fjs/media/html/module.f.mjs +6 -4
  133. package/fjs/media/html/proof.f.d.mts +3 -0
  134. package/fjs/media/html/proof.f.mjs +4 -1
  135. package/fjs/media/json/parser/module.f.d.mts +1 -1
  136. package/fjs/media/json/parser/module.f.mjs +25 -8
  137. package/fjs/media/json/parser/types.d.ts +5 -0
  138. package/fjs/media/json/rtti/proof.f.d.mts +3 -0
  139. package/fjs/media/json/rtti/proof.f.mjs +3 -3
  140. package/fjs/media/json/schema/module.f.d.mts +61 -27
  141. package/fjs/media/json/schema/module.f.mjs +228 -63
  142. package/fjs/media/json/schema/proof.f.d.mts +41 -0
  143. package/fjs/media/json/schema/proof.f.mjs +219 -7
  144. package/fjs/media/json/serializer/module.f.d.mts +13 -0
  145. package/fjs/media/json/serializer/module.f.mjs +7 -7
  146. package/fjs/media/json/tokenizer/module.f.d.mts +8 -0
  147. package/fjs/media/json/tokenizer/module.f.mjs +24 -5
  148. package/fjs/media/nix/module.f.d.mts +13 -0
  149. package/fjs/media/nix/module.f.mjs +4 -2
  150. package/fjs/media/nix/proof.f.d.mts +3 -0
  151. package/fjs/media/nix/proof.f.mjs +4 -1
  152. package/fjs/media/revision/module.f.d.mts +5 -0
  153. package/fjs/media/revision/module.f.mjs +8 -11
  154. package/fjs/media/revision/proof.f.d.mts +4 -0
  155. package/fjs/media/revision/proof.f.mjs +5 -2
  156. package/fjs/media/type/module.f.d.mts +28 -11
  157. package/fjs/media/type/module.f.mjs +69 -85
  158. package/fjs/media/type/proof.f.d.mts +16 -0
  159. package/fjs/media/type/proof.f.mjs +44 -4
  160. package/fjs/module.d.mts +5 -0
  161. package/fjs/module.f.d.mts +8 -0
  162. package/fjs/module.f.mjs +4 -2
  163. package/fjs/module.mjs +6 -0
  164. package/fjs/path/module.f.d.mts +8 -0
  165. package/fjs/path/module.f.mjs +4 -2
  166. package/fjs/proof.f.d.mts +4 -0
  167. package/fjs/proof.f.mjs +5 -2
  168. package/fjs/protocol/json_rpc/module.f.d.mts +1 -1
  169. package/fjs/protocol/json_rpc/module.f.mjs +7 -4
  170. package/fjs/protocol/json_rpc/proof.f.d.mts +6 -0
  171. package/fjs/protocol/json_rpc/proof.f.mjs +22 -1
  172. package/fjs/protocol/mcp/proof.f.d.mts +4 -0
  173. package/fjs/protocol/mcp/proof.f.mjs +47 -24
  174. package/fjs/protocol/mcp/stdio/module.f.d.mts +2 -4
  175. package/fjs/protocol/mcp/stdio/module.f.mjs +1 -8
  176. package/fjs/protocol/mcp/stdio/proof.f.d.mts +1 -1
  177. package/fjs/protocol/mcp/stdio/proof.f.mjs +1 -1
  178. package/fjs/protocol/mcp/stdio/types.d.ts +14 -0
  179. package/fjs/sul/id/module.f.d.mts +5 -0
  180. package/fjs/sul/id/module.f.mjs +5 -4
  181. package/fjs/sul/level/hash/module.f.d.mts +4 -1
  182. package/fjs/sul/level/hash/module.f.mjs +4 -3
  183. package/fjs/sul/level/hash/proof.f.d.mts +4 -0
  184. package/fjs/sul/level/hash/proof.f.mjs +5 -2
  185. package/fjs/sul/level/literal/module.f.d.mts +4 -1
  186. package/fjs/sul/level/literal/module.f.mjs +4 -3
  187. package/fjs/sul/level/literal/proof.f.d.mts +3 -0
  188. package/fjs/sul/level/literal/proof.f.mjs +4 -1
  189. package/fjs/sul/module.f.d.mts +5 -3
  190. package/fjs/sul/module.f.mjs +5 -4
  191. package/fjs/sul/proof.f.d.mts +4 -0
  192. package/fjs/sul/proof.f.mjs +5 -2
  193. package/fjs/text/ascii/module.f.d.mts +26 -0
  194. package/fjs/text/ascii/module.f.mjs +49 -1
  195. package/fjs/text/ascii/proof.f.d.mts +10 -0
  196. package/fjs/text/ascii/proof.f.mjs +33 -1
  197. package/fjs/text/code_point/module.f.d.mts +21 -3
  198. package/fjs/text/code_point/module.f.mjs +24 -8
  199. package/fjs/text/code_point/proof.f.d.mts +1 -0
  200. package/fjs/text/code_point/proof.f.mjs +28 -0
  201. package/fjs/text/module.f.d.mts +4 -2
  202. package/fjs/text/module.f.mjs +4 -3
  203. package/fjs/text/proof.f.d.mts +3 -0
  204. package/fjs/text/proof.f.mjs +4 -1
  205. package/fjs/text/sgr/module.f.d.mts +4 -1
  206. package/fjs/text/sgr/module.f.mjs +4 -3
  207. package/fjs/text/sgr/proof.f.d.mts +3 -0
  208. package/fjs/text/sgr/proof.f.mjs +4 -1
  209. package/fjs/text/utf16/module.f.d.mts +5 -1
  210. package/fjs/text/utf16/module.f.mjs +31 -33
  211. package/fjs/text/utf16/proof.f.d.mts +3 -1
  212. package/fjs/text/utf16/proof.f.mjs +18 -1
  213. package/fjs/text/utf8/module.f.d.mts +9 -5
  214. package/fjs/text/utf8/module.f.mjs +16 -18
  215. package/fjs/types/array/module.f.d.mts +2 -1
  216. package/fjs/types/array/module.f.mjs +2 -2
  217. package/fjs/types/bigfloat/module.f.d.mts +21 -1
  218. package/fjs/types/bigfloat/module.f.mjs +33 -7
  219. package/fjs/types/bigfloat/proof.f.d.mts +1 -0
  220. package/fjs/types/bigfloat/proof.f.mjs +46 -0
  221. package/fjs/types/bigint/module.f.d.mts +4 -0
  222. package/fjs/types/bigint/module.f.mjs +4 -3
  223. package/fjs/types/bit_vec/module.f.d.mts +10 -14
  224. package/fjs/types/bit_vec/module.f.mjs +61 -71
  225. package/fjs/types/bit_vec/proof.f.d.mts +6 -0
  226. package/fjs/types/bit_vec/proof.f.mjs +29 -3
  227. package/fjs/types/btree/find/module.f.d.mts +5 -1
  228. package/fjs/types/btree/find/module.f.mjs +5 -5
  229. package/fjs/types/btree/find/proof.f.d.mts +5 -1
  230. package/fjs/types/btree/find/proof.f.mjs +5 -3
  231. package/fjs/types/btree/module.f.d.mts +3 -0
  232. package/fjs/types/btree/module.f.mjs +3 -2
  233. package/fjs/types/btree/proof.f.d.mts +5 -1
  234. package/fjs/types/btree/proof.f.mjs +5 -3
  235. package/fjs/types/btree/remove/module.f.d.mts +11 -0
  236. package/fjs/types/btree/remove/module.f.mjs +9 -9
  237. package/fjs/types/btree/remove/proof.f.d.mts +3 -0
  238. package/fjs/types/btree/remove/proof.f.mjs +4 -1
  239. package/fjs/types/btree/set/module.f.d.mts +9 -0
  240. package/fjs/types/btree/set/module.f.mjs +5 -6
  241. package/fjs/types/btree/set/proof.f.d.mts +3 -0
  242. package/fjs/types/btree/set/proof.f.mjs +4 -1
  243. package/fjs/types/btree/types/module.f.d.mts +2 -1
  244. package/fjs/types/btree/types/module.f.mjs +2 -1
  245. package/fjs/types/byte_set/module.f.d.mts +10 -1
  246. package/fjs/types/byte_set/module.f.mjs +5 -3
  247. package/fjs/types/byte_set/proof.f.d.mts +3 -1
  248. package/fjs/types/byte_set/proof.f.mjs +3 -1
  249. package/fjs/types/function/compare/module.f.d.mts +3 -2
  250. package/fjs/types/function/compare/module.f.mjs +3 -2
  251. package/fjs/types/function/module.f.d.mts +8 -1
  252. package/fjs/types/function/module.f.mjs +8 -1
  253. package/fjs/types/function/operator/module.f.d.mts +2 -1
  254. package/fjs/types/function/operator/module.f.mjs +2 -2
  255. package/fjs/types/list/module.f.d.mts +9 -2
  256. package/fjs/types/list/module.f.mjs +5 -3
  257. package/fjs/types/list/proof.f.d.mts +4 -1
  258. package/fjs/types/list/proof.f.mjs +4 -2
  259. package/fjs/types/nibble_set/module.f.d.mts +2 -1
  260. package/fjs/types/nibble_set/module.f.mjs +2 -2
  261. package/fjs/types/nominal/module.f.d.mts +2 -1
  262. package/fjs/types/nominal/module.f.mjs +2 -1
  263. package/fjs/types/nullable/module.f.d.mts +8 -2
  264. package/fjs/types/nullable/module.f.mjs +4 -2
  265. package/fjs/types/number/module.f.d.mts +4 -0
  266. package/fjs/types/number/module.f.mjs +4 -3
  267. package/fjs/types/object/module.f.d.mts +14 -2
  268. package/fjs/types/object/module.f.mjs +15 -6
  269. package/fjs/types/object/proof.f.d.mts +5 -2
  270. package/fjs/types/object/proof.f.mjs +6 -3
  271. package/fjs/types/object/structurally_same/module.f.d.mts +39 -0
  272. package/fjs/types/object/structurally_same/module.f.mjs +59 -0
  273. package/fjs/types/object/structurally_same/proof.f.d.mts +6 -0
  274. package/fjs/types/object/structurally_same/proof.f.mjs +73 -0
  275. package/fjs/types/ordered_map/module.f.d.mts +5 -0
  276. package/fjs/types/ordered_map/module.f.mjs +5 -4
  277. package/fjs/types/ordered_map/proof.f.d.mts +3 -0
  278. package/fjs/types/ordered_map/proof.f.mjs +4 -1
  279. package/fjs/types/patricia_trie/module.f.d.mts +2 -1
  280. package/fjs/types/patricia_trie/module.f.mjs +2 -2
  281. package/fjs/types/patricia_trie/proof.f.d.mts +3 -0
  282. package/fjs/types/patricia_trie/proof.f.mjs +4 -1
  283. package/fjs/types/prime_field/module.f.d.mts +3 -1
  284. package/fjs/types/prime_field/module.f.mjs +3 -2
  285. package/fjs/types/range/module.f.d.mts +2 -1
  286. package/fjs/types/range/module.f.mjs +2 -2
  287. package/fjs/types/range_map/module.f.d.mts +6 -0
  288. package/fjs/types/range_map/module.f.mjs +6 -9
  289. package/fjs/types/range_map/proof.f.d.mts +5 -1
  290. package/fjs/types/range_map/proof.f.mjs +5 -3
  291. package/fjs/types/range_set/module.f.d.mts +5 -0
  292. package/fjs/types/range_set/module.f.mjs +1 -0
  293. package/fjs/types/range_set/proof.f.d.mts +3 -0
  294. package/fjs/types/range_set/proof.f.mjs +4 -1
  295. package/fjs/types/result/module.d.mts +8 -0
  296. package/fjs/types/result/module.f.d.mts +37 -7
  297. package/fjs/types/result/module.f.mjs +38 -8
  298. package/fjs/types/result/module.mjs +9 -1
  299. package/fjs/types/result/proof.f.d.mts +5 -0
  300. package/fjs/types/result/proof.f.mjs +22 -2
  301. package/fjs/types/rtti/common/module.f.d.mts +35 -2
  302. package/fjs/types/rtti/common/module.f.mjs +9 -7
  303. package/fjs/types/rtti/common/proof.f.d.mts +4 -0
  304. package/fjs/types/rtti/common/proof.f.mjs +5 -2
  305. package/fjs/types/rtti/data/module.f.d.mts +120 -0
  306. package/fjs/types/rtti/data/module.f.mjs +1030 -0
  307. package/fjs/types/rtti/data/proof.f.d.mts +75 -0
  308. package/fjs/types/rtti/data/proof.f.mjs +566 -0
  309. package/fjs/types/rtti/data/types.d.ts +83 -0
  310. package/fjs/types/rtti/module.f.d.mts +12 -5
  311. package/fjs/types/rtti/module.f.mjs +7 -5
  312. package/fjs/types/rtti/parse/module.f.d.mts +38 -0
  313. package/fjs/types/rtti/parse/module.f.mjs +9 -7
  314. package/fjs/types/rtti/parse/proof.f.mjs +18 -38
  315. package/fjs/types/rtti/proof.f.d.mts +3 -1
  316. package/fjs/types/rtti/proof.f.mjs +3 -1
  317. package/fjs/types/rtti/ts/module.f.d.mts +68 -9
  318. package/fjs/types/rtti/ts/module.f.mjs +262 -30
  319. package/fjs/types/rtti/ts/proof.f.d.mts +44 -0
  320. package/fjs/types/rtti/ts/proof.f.mjs +152 -4
  321. package/fjs/types/rtti/ts/types.d.ts +11 -0
  322. package/fjs/types/rtti/types.d.ts +40 -0
  323. package/fjs/types/rtti/validate/module.f.d.mts +36 -1
  324. package/fjs/types/rtti/validate/module.f.mjs +6 -4
  325. package/fjs/types/sorted_list/module.f.d.mts +4 -1
  326. package/fjs/types/sorted_list/module.f.mjs +21 -12
  327. package/fjs/types/sorted_list/proof.f.d.mts +3 -1
  328. package/fjs/types/sorted_list/proof.f.mjs +3 -1
  329. package/fjs/types/sorted_set/module.f.d.mts +31 -1
  330. package/fjs/types/sorted_set/module.f.mjs +4 -2
  331. package/fjs/types/sorted_set/proof.f.d.mts +3 -1
  332. package/fjs/types/sorted_set/proof.f.mjs +3 -1
  333. package/fjs/types/string/module.f.d.mts +4 -0
  334. package/fjs/types/string/module.f.mjs +4 -3
  335. package/fjs/types/string_set/module.f.d.mts +3 -1
  336. package/fjs/types/string_set/module.f.mjs +3 -2
  337. package/fjs/types/ts/module.f.d.mts +2 -0
  338. package/fjs/types/ts/module.f.mjs +3 -3
  339. package/fjs/types/ts/proof.f.d.mts +1 -0
  340. package/fjs/types/ts/proof.f.mjs +5 -0
  341. package/fjs/types/ts/types.d.ts +6 -1
  342. package/fjs/types/uint8array/module.f.d.mts +13 -2
  343. package/fjs/types/uint8array/module.f.mjs +20 -15
  344. package/fjs/website/module.f.d.mts +3 -0
  345. package/fjs/website/module.f.mjs +3 -2
  346. package/package.json +3 -3
  347. package/fjs/asn.1/types.js +0 -6
  348. package/fjs/asserts/types.js +0 -6
  349. package/fjs/basen/types.js +0 -6
  350. package/fjs/bnf/data/types.js +0 -6
  351. package/fjs/bnf/descent/types.js +0 -6
  352. package/fjs/bnf/ll1/types.js +0 -6
  353. package/fjs/bnf/token_symbol/types.js +0 -6
  354. package/fjs/bnf/types.js +0 -6
  355. package/fjs/cas/evo/types.js +0 -7
  356. package/fjs/cas/types.js +0 -6
  357. package/fjs/ci/common/types.js +0 -1
  358. package/fjs/ci/nix/types.js +0 -6
  359. package/fjs/ci/types.js +0 -6
  360. package/fjs/cli/types.js +0 -6
  361. package/fjs/common/monoid/types.js +0 -6
  362. package/fjs/crypto/pow/types.js +0 -6
  363. package/fjs/crypto/secp/types.js +0 -6
  364. package/fjs/crypto/sha2/types.js +0 -6
  365. package/fjs/crypto/sign/types.js +0 -6
  366. package/fjs/crypto/vdf/types.js +0 -6
  367. package/fjs/dev/types.js +0 -6
  368. package/fjs/djs/ast/types.js +0 -8
  369. package/fjs/djs/parser/types.js +0 -7
  370. package/fjs/djs/tokenizer/types.js +0 -7
  371. package/fjs/djs/types.js +0 -7
  372. package/fjs/effects/eff/types.js +0 -6
  373. package/fjs/effects/list/types.js +0 -6
  374. package/fjs/effects/memory/types.js +0 -6
  375. package/fjs/effects/mock/types.js +0 -6
  376. package/fjs/effects/node/types.js +0 -6
  377. package/fjs/effects/node/virtual/types.js +0 -7
  378. package/fjs/effects/types.js +0 -6
  379. package/fjs/emergent_testing/all.test.d.ts +0 -1
  380. package/fjs/emergent_testing/all.test.js +0 -5
  381. package/fjs/emergent_testing/scenarios/all.d.ts +0 -1
  382. package/fjs/emergent_testing/scenarios/all.js +0 -1
  383. package/fjs/emergent_testing/scenarios/async-subtests.fail.d.ts +0 -6
  384. package/fjs/emergent_testing/scenarios/async-subtests.fail.js +0 -9
  385. package/fjs/emergent_testing/scenarios/async-subtests.pass.d.ts +0 -6
  386. package/fjs/emergent_testing/scenarios/async-subtests.pass.js +0 -9
  387. package/fjs/emergent_testing/scenarios/async.fail.d.ts +0 -3
  388. package/fjs/emergent_testing/scenarios/async.fail.js +0 -6
  389. package/fjs/emergent_testing/scenarios/async.pass.d.ts +0 -3
  390. package/fjs/emergent_testing/scenarios/async.pass.js +0 -5
  391. package/fjs/emergent_testing/scenarios/fail.fail.d.ts +0 -3
  392. package/fjs/emergent_testing/scenarios/fail.fail.js +0 -3
  393. package/fjs/emergent_testing/scenarios/return-value.pass.d.ts +0 -3
  394. package/fjs/emergent_testing/scenarios/return-value.pass.js +0 -4
  395. package/fjs/emergent_testing/scenarios/thenable.pass.d.ts +0 -5
  396. package/fjs/emergent_testing/scenarios/thenable.pass.js +0 -11
  397. package/fjs/emergent_testing/scenarios/thenable2.pass.d.ts +0 -5
  398. package/fjs/emergent_testing/scenarios/thenable2.pass.js +0 -3
  399. package/fjs/emergent_testing/scenarios/throw.pass.d.ts +0 -5
  400. package/fjs/emergent_testing/scenarios/throw.pass.js +0 -3
  401. package/fjs/emergent_testing/types.js +0 -6
  402. package/fjs/js/tokenizer/types.js +0 -6
  403. package/fjs/media/html/types.js +0 -6
  404. package/fjs/media/json/parser/types.js +0 -6
  405. package/fjs/media/json/tokenizer/types.js +0 -6
  406. package/fjs/media/json/types.js +0 -13
  407. package/fjs/media/nix/types.js +0 -6
  408. package/fjs/media/revision/types.js +0 -8
  409. package/fjs/media/type/types.js +0 -6
  410. package/fjs/media/types.js +0 -7
  411. package/fjs/nanvm/types.js +0 -11
  412. package/fjs/protocol/json_rpc/types.js +0 -8
  413. package/fjs/protocol/mcp/types.js +0 -8
  414. package/fjs/sul/id/types.js +0 -6
  415. package/fjs/sul/level/hash/types.js +0 -6
  416. package/fjs/sul/level/literal/types.js +0 -6
  417. package/fjs/sul/types.js +0 -6
  418. package/fjs/text/sgr/types.js +0 -6
  419. package/fjs/text/types.js +0 -6
  420. package/fjs/text/utf16/types.js +0 -6
  421. package/fjs/text/utf8/types.js +0 -6
  422. package/fjs/types/array/types.js +0 -6
  423. package/fjs/types/bigfloat/types.js +0 -6
  424. package/fjs/types/bigint/types.js +0 -6
  425. package/fjs/types/bit_vec/types.js +0 -6
  426. package/fjs/types/btree/find/types.js +0 -6
  427. package/fjs/types/btree/types/types.js +0 -6
  428. package/fjs/types/byte_set/types.js +0 -6
  429. package/fjs/types/function/compare/types.js +0 -6
  430. package/fjs/types/function/operator/types.js +0 -6
  431. package/fjs/types/function/types.js +0 -6
  432. package/fjs/types/list/types.js +0 -6
  433. package/fjs/types/nibble_set/types.js +0 -6
  434. package/fjs/types/nominal/types.js +0 -6
  435. package/fjs/types/nullable/types.js +0 -6
  436. package/fjs/types/object/types.js +0 -8
  437. package/fjs/types/option/types.js +0 -6
  438. package/fjs/types/ordered_map/types.js +0 -6
  439. package/fjs/types/patricia_trie/types.js +0 -6
  440. package/fjs/types/phantom/types.js +0 -11
  441. package/fjs/types/prime_field/types.js +0 -6
  442. package/fjs/types/range/types.js +0 -6
  443. package/fjs/types/range_map/types.js +0 -6
  444. package/fjs/types/result/types.js +0 -6
  445. package/fjs/types/rtti/common/types.js +0 -1
  446. package/fjs/types/rtti/parse/types.js +0 -1
  447. package/fjs/types/rtti/ts/types.js +0 -1
  448. package/fjs/types/rtti/types.js +0 -1
  449. package/fjs/types/rtti/validate/types.js +0 -1
  450. package/fjs/types/sorted_list/types.js +0 -6
  451. package/fjs/types/sorted_set/types.js +0 -6
  452. package/fjs/types/string_set/types.js +0 -6
  453. package/fjs/types/ts/types.js +0 -8
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
9
9
  import { map, toArray } from '../../types/list/module.f.mjs'
10
- import { commaJoin0Plus, option, range, repeat0Plus, set } from '../module.f.mjs'
10
+ import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
11
11
  import { emptyTagMap, toData } from '../data/module.f.mjs'
12
12
  import { descentParser } from './module.f.mjs'
13
13
  import { assertEq, assertNotNullish } from '../../asserts/module.f.mjs'
@@ -323,6 +323,82 @@ export const proof = {
323
323
  if (result !== `{"ast":{"sequence":[{"tag":"minus","sequence":[[${cp1('-')},"minus"]]},{"sequence":[[${cp1('2')},"two"]]}]},"success":true,"idx":2}`) { throw result }
324
324
  },
325
325
  ],
326
+ logicalEof: [
327
+ () => {
328
+ // The matcher synthesizes one EOF after the physical input, so the
329
+ // `eof` terminal matches empty input. It contributes no AST leaf,
330
+ // and the public index stays physical.
331
+ const m = descentParser(eof)
332
+ const mr = m('', [])
333
+ assertEq(JSON.stringify(mr), '{"ast":{"sequence":[]},"success":true,"idx":0}')
334
+ },
335
+ () => {
336
+ // Callers pass physical symbols only, so EOF is not available
337
+ // before the end of the input.
338
+ const m = descentParser(eof)
339
+ const mr = descentParserCpOnly(m, '', toArray(stringToCodePointList('A')))
340
+ assertEq(mr.success, false)
341
+ const f = assertNotNullish(mr.failure)
342
+ assertEq(f.idx, 0)
343
+ assertEq(f.expected.length, 1)
344
+ assertEq(f.expected[0], eof)
345
+ },
346
+ () => {
347
+ // Non-empty input: the terminal consumes the synthesized EOF after
348
+ // the last code point, and `idx` still reports `input.length`.
349
+ const m = descentParser([range('AA'), eof])
350
+ const cp = toArray(stringToCodePointList('A'))
351
+ const mr = descentParserCpOnly(m, '', cp)
352
+ assertEq(mr.success, true)
353
+ assertEq(mr.idx, cp.length)
354
+ assertEq(JSON.stringify(mr.ast), `{"sequence":[{"sequence":[[${cp1('A')},null]]},{"sequence":[]}]}`)
355
+ },
356
+ () => {
357
+ // Exactly one EOF is synthesized: a second `eof` terminal has
358
+ // nothing left to consume, and its failure points at `input.length`.
359
+ const m = descentParser([eof, eof])
360
+ const mr = m('', [])
361
+ assertEq(mr.success, false)
362
+ const f = assertNotNullish(mr.failure)
363
+ assertEq(f.idx, 0)
364
+ assertEq(f.expected.length, 1)
365
+ assertEq(f.expected[0], eof)
366
+ },
367
+ () => {
368
+ // EOF as one alternative among ordinary terminals.
369
+ const m = descentParser({ a: range('AA'), e: eof })
370
+ assertEq(JSON.stringify(m('', [])), '{"ast":{"tag":"e","sequence":[]},"success":true,"idx":0}')
371
+ const mr = descentParserCpOnly(m, '', toArray(stringToCodePointList('A')))
372
+ assertEq(mr.success, true)
373
+ assertEq(mr.idx, 1)
374
+ },
375
+ () => {
376
+ // Repetition terminates on EOF: consuming it moves the complete
377
+ // cursor, so the repeat makes exactly one round and then takes its
378
+ // empty branch — with `idx` alone this would never stop.
379
+ const m = descentParser(repeat0Plus(eof))
380
+ const mr = m('', [])
381
+ assertEq(JSON.stringify(mr), '{"ast":{"sequence":[{"sequence":[]},{"tag":"none","sequence":[]}]},"success":true,"idx":0}')
382
+ },
383
+ () => {
384
+ // Backtracking restores the complete cursor: `x` consumes EOF and
385
+ // then fails, so `y` must still find EOF available.
386
+ const m = descentParser({ x: [eof, range('AA')], y: eof })
387
+ assertEq(JSON.stringify(m('', [])), '{"ast":{"tag":"y","sequence":[]},"success":true,"idx":0}')
388
+ },
389
+ () => {
390
+ // Diagnostic ordering by the complete cursor: `y` got further than
391
+ // `x` — the same physical index, but past the EOF it consumed — so
392
+ // only its expectation is reported, and at the physical end.
393
+ const m = descentParser({ x: range('AA'), y: [eof, range('BB')] })
394
+ const mr = m('', [])
395
+ assertEq(mr.success, false)
396
+ const f = assertNotNullish(mr.failure)
397
+ assertEq(f.idx, 0)
398
+ assertEq(f.expected.length, 1)
399
+ assertEq(f.expected[0], range('BB'))
400
+ },
401
+ ],
326
402
  furthestFailure: [
327
403
  () => {
328
404
  // A branch rejected *before* the high-water mark must not pull it back:
@@ -7,9 +7,11 @@ import type { CodePoint } from '../../text/utf16/types.ts';
7
7
  import type { TerminalRange } from '../types.ts';
8
8
  export type AstTag = string | true | undefined;
9
9
  /**
10
- * Recursive descent matcher for a single named rule.
10
+ * Recursive descent matcher for a single named rule, starting from `startPos` —
11
+ * a position that counts the synthesized end-of-input symbol, unlike the public
12
+ * `idx` of the result.
11
13
  */
12
- export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePointMeta<T>[], idx: number) => DescentMatchResult<T>;
14
+ export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePointMeta<T>[], startPos: number) => DescentMatchResult<T>;
13
15
  /**
14
16
  * Where a match ran out of road, for diagnostics.
15
17
  *
@@ -24,6 +26,11 @@ export type DescentMatchRule<T> = (name: string, tag: AstTag, s: readonly CodePo
24
26
  *
25
27
  * `idx` is `0` with an empty `expected` when the match failed without ever
26
28
  * rejecting a terminal, as an empty variant does.
29
+ *
30
+ * `idx` is physical, so a terminal rejected at — or past — the synthesized
31
+ * end-of-input symbol reports `input.length`. The high-water mark itself is
32
+ * kept on the complete cursor, so those two are still ordered against each
33
+ * other and their expected terminals do not merge.
27
34
  */
28
35
  export type DescentFailure = {
29
36
  readonly idx: number;
@@ -41,8 +48,9 @@ export type DescentFailure = {
41
48
  * On failure `idx` has rewound to the start of the enclosing sequence and
42
49
  * locates nothing; read `failure.idx` instead.
43
50
  *
44
- * The same type describes a match in progress, where `failure` is likewise
45
- * absent until the match ends.
51
+ * `idx` is physical `0 <= idx <= input.length` so a match that consumed the
52
+ * synthesized end-of-input symbol reports `input.length`, the same as one that
53
+ * stopped just before it.
46
54
  */
47
55
  export type DescentMatchResult<T> = {
48
56
  readonly ast: AstRuleMeta<T>;
@@ -8,19 +8,24 @@
8
8
  * grammar is not LL(1) — a first/first conflict. Nullability is looked up from
9
9
  * {@link emptyTagMap} in `fjs/bnf/data` rather than re-derived here.
10
10
  *
11
+ * The caller passes physical symbols only; the matcher synthesizes the one
12
+ * logical EOF ({@link eofSymbol}) after them, so a grammar can dispatch on the
13
+ * end of input with the `eof` terminal.
14
+ *
11
15
  * See `./types.ts` for the type-level API.
12
16
  *
13
17
  * @module
14
18
  *
19
+ * @import { CodePoint } from '../../text/utf16/types.ts'
15
20
  * @import { Properties } from '../../types/range_map/types.ts'
16
21
  * @import { StringSet } from '../../types/string_set/types.ts'
17
22
  * @import { EmptyTag, RuleSet } from '../data/types.ts'
18
23
  * @import { Rule as FRule } from '../types.ts'
19
- * @import { AstSequence, AstTag, Match, MatchResult, MatchRule, Remainder, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
24
+ * @import { AstSequence, AstTag, Match, MatchResult, Remainder, _AstRule, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
20
25
  */
21
26
  import type { RuleSet } from '../data/types.ts';
22
27
  import type { Rule as FRule } from '../types.ts';
23
- import type { Match, _DispatchMap } from './types.ts';
28
+ import type { AstSequence, AstTag, Match, _AstRule, _DispatchMap, _DispatchRule } from './types.ts';
24
29
  /**
25
30
  * Builds a dispatch map for a {@link RuleSet} to enable predictive parsing.
26
31
  *
@@ -33,6 +38,27 @@ export declare const dispatchMap: (ruleSet: RuleSet) => _DispatchMap;
33
38
  * @type {(fr: FRule) => Match}
34
39
  */
35
40
  export declare const parser: (fr: FRule) => Match;
41
+ export type _Cursor = number;
42
+ export type _Position = _Cursor | null;
43
+ export type _Result = {
44
+ readonly ast: _AstRule;
45
+ readonly success: boolean;
46
+ readonly pos: _Position;
47
+ };
48
+ export type _Frame = {
49
+ readonly tag: AstTag;
50
+ readonly rules: readonly string[];
51
+ readonly ruleIndex: number;
52
+ readonly seq: AstSequence;
53
+ };
54
+ export type _Stack = null | {
55
+ readonly top: _Frame;
56
+ readonly rest: _Stack;
57
+ };
58
+ export type _Task = {
59
+ readonly rule: _DispatchRule;
60
+ readonly pos: _Cursor;
61
+ };
36
62
  /**
37
63
  * Creates an LL(1) parser from an already materialized {@link RuleSet}.
38
64
  *
@@ -8,22 +8,27 @@
8
8
  * grammar is not LL(1) — a first/first conflict. Nullability is looked up from
9
9
  * {@link emptyTagMap} in `fjs/bnf/data` rather than re-derived here.
10
10
  *
11
+ * The caller passes physical symbols only; the matcher synthesizes the one
12
+ * logical EOF ({@link eofSymbol}) after them, so a grammar can dispatch on the
13
+ * end of input with the `eof` terminal.
14
+ *
11
15
  * See `./types.ts` for the type-level API.
12
16
  *
13
17
  * @module
14
18
  *
19
+ * @import { CodePoint } from '../../text/utf16/types.ts'
15
20
  * @import { Properties } from '../../types/range_map/types.ts'
16
21
  * @import { StringSet } from '../../types/string_set/types.ts'
17
22
  * @import { EmptyTag, RuleSet } from '../data/types.ts'
18
23
  * @import { Rule as FRule } from '../types.ts'
19
- * @import { AstSequence, AstTag, Match, MatchResult, MatchRule, Remainder, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
24
+ * @import { AstSequence, AstTag, Match, MatchResult, Remainder, _AstRule, _Dispatch, _DispatchMap, _DispatchResult, _DispatchRule } from './types.ts'
20
25
  */
21
26
 
22
27
  import { strictEqual } from '../../types/function/operator/module.f.mjs'
23
28
  import { toArray } from '../../types/list/module.f.mjs'
24
29
  import { rangeMap } from '../../types/range_map/module.f.mjs'
25
30
  import { contains, set } from '../../types/string_set/module.f.mjs'
26
- import { rangeDecode } from '../module.f.mjs'
31
+ import { eofSymbol, rangeDecode } from '../module.f.mjs'
27
32
  import { definedEntries } from '../../types/object/module.f.mjs'
28
33
  import { emptyTagMap, toData } from '../data/module.f.mjs'
29
34
 
@@ -145,13 +150,101 @@ export const parser = fr => {
145
150
  return parserRuleSet(data[0])
146
151
  }
147
152
 
148
- /** @type {(tag: AstTag, sequence: AstSequence, r: Remainder) => MatchResult} */
149
- const mrSuccess = (tag, sequence, r) =>
150
- [{tag, sequence}, true, r]
153
+ /**
154
+ * A match position over the physical input: `0 .. cp.length` are the physical
155
+ * positions, and `cp.length + 1` is where the one synthesized EOF has been
156
+ * consumed.
157
+ *
158
+ * This is the `(idx, eofConsumed)` cursor written as one number: `eofConsumed`
159
+ * can only be true at the physical end, so the pair and the extended position
160
+ * hold the same information.
161
+ *
162
+ * @typedef {number} _Cursor
163
+ */
164
+
165
+ /**
166
+ * Where a match stopped: a {@link _Cursor}, or `null` when it ran out of input
167
+ * — the `null` {@link Remainder} this backend reports for that.
168
+ *
169
+ * @typedef {_Cursor|null} _Position
170
+ */
171
+
172
+ /**
173
+ * The machine's own result: a {@link MatchResult} positioned by a cursor
174
+ * instead of by a materialized remainder.
175
+ *
176
+ * @typedef {{
177
+ * readonly ast: _AstRule
178
+ * readonly success: boolean
179
+ * readonly pos: _Position
180
+ * }} _Result
181
+ */
182
+
183
+ /**
184
+ * A suspended rules-chain match: `rules[ruleIndex]` is being matched by the
185
+ * current task, and `seq` holds the ASTs matched so far — starting with the
186
+ * dispatched symbol's leaf, empty when that symbol was the synthesized EOF.
187
+ *
188
+ * @typedef {{
189
+ * readonly tag: AstTag
190
+ * readonly rules: readonly string[]
191
+ * readonly ruleIndex: number
192
+ * readonly seq: AstSequence
193
+ * }} _Frame
194
+ */
195
+
196
+ /**
197
+ * Immutable cons-cell stack: O(1) push/pop, no array copying per step.
198
+ *
199
+ * @typedef {null | {
200
+ * readonly top: _Frame
201
+ * readonly rest: _Stack
202
+ * }} _Stack
203
+ */
204
+
205
+ /**
206
+ * The rule invocation about to be evaluated, or `null` when a result is ready
207
+ * to resume the innermost frame instead.
208
+ *
209
+ * @typedef {{
210
+ * readonly rule: _DispatchRule
211
+ * readonly pos: _Cursor
212
+ * }} _Task
213
+ */
214
+
215
+ /** @type {(tag: AstTag, sequence: AstSequence, pos: _Position) => _Result} */
216
+ const mrSuccess = (tag, sequence, pos) =>
217
+ ({ast: {tag, sequence}, success: true, pos})
151
218
 
152
- /** @type {(tag: AstTag, sequence: AstSequence, r: Remainder) => MatchResult} */
153
- const mrFail = (tag, sequence, r) =>
154
- [{tag, sequence}, false, r]
219
+ /** @type {(tag: AstTag, sequence: AstSequence, pos: _Position) => _Result} */
220
+ const mrFail = (tag, sequence, pos) =>
221
+ ({ast: {tag, sequence}, success: false, pos})
222
+
223
+ /**
224
+ * The semantic symbol a cursor points at: a code point inside the physical
225
+ * input, and the synthesized {@link eofSymbol} at its end. Only meaningful
226
+ * where the cursor still has a symbol, `pos <= cp.length`.
227
+ *
228
+ * @type {(cp: readonly CodePoint[], pos: _Cursor) => number}
229
+ */
230
+ const symbolAt = (cp, pos) => pos < cp.length ? cp[pos] : eofSymbol
231
+
232
+ /**
233
+ * What consuming the symbol at a cursor contributes to the AST: the code point
234
+ * itself, and nothing for the synthesized EOF — it has no physical source
235
+ * element.
236
+ *
237
+ * @type {(cp: readonly CodePoint[], pos: _Cursor) => AstSequence}
238
+ */
239
+ const leafAt = (cp, pos) => pos < cp.length ? [cp[pos]] : []
240
+
241
+ /**
242
+ * The public remainder of a position. It stays physical, so consuming EOF
243
+ * leaves it empty; the slice is materialized once, at the end of a match.
244
+ *
245
+ * @type {(cp: readonly CodePoint[], pos: _Position) => Remainder}
246
+ */
247
+ const remainderAt = (cp, pos) => pos === null ? null : cp.slice(Math.min(pos, cp.length))
155
248
 
156
249
  /**
157
250
  * Creates an LL(1) parser from an already materialized {@link RuleSet}.
@@ -161,39 +254,88 @@ const mrFail = (tag, sequence, r) =>
161
254
  export const parserRuleSet = ruleSet => {
162
255
  const map = dispatchMap(ruleSet)
163
256
 
164
- /** @type {MatchRule} */
165
- const f = ({emptyTag, rangeMap}, cp) => {
166
- if (cp.length === 0) {
167
- return mrSuccess(emptyTag, [], emptyTag === undefined ? null : cp)
168
- }
169
- const [cp0] = cp
170
- const dr = dispatchOp.get(rangeMap)(cp0)
171
- if (dr === null) {
172
- return emptyTag === undefined
173
- ? mrFail(emptyTag, [], cp)
174
- : mrSuccess(emptyTag, [], cp)
175
- }
176
- /** @type {AstSequence} */
177
- let seq = [cp0]
178
- const [, ...restCp] = cp
179
- /** @type {readonly number[]} */
180
- let r = restCp
181
- const {tag, rules} = dr
182
- for (const i of rules) {
183
- const rule = typeof i === 'string' ? /** @type {_DispatchRule} */ (map[i]) : i
184
- const res = f(rule, r)
185
- const [astRule, success, newR] = res
186
- if (success === false) {
187
- return res
257
+ /** @type {(name: string) => _DispatchRule} */
258
+ const dispatched = name => /** @type {_DispatchRule} */ (map[name])
259
+
260
+ // The matcher as an explicit-stack machine: each iteration either starts the
261
+ // current task (dispatching one rule and pushing a frame for the rules chain
262
+ // that symbol selected) or feeds the pending result into the innermost frame.
263
+ // Semantics are identical to the former recursive matcher, but the JS call
264
+ // stack stays O(1) however deep the grammar recurses: a right-recursive rule
265
+ // (e.g. a `repeat0Plus` chain) descends once per consumed code point, so the
266
+ // depth used to grow with input length and overflow (see the longInput proof
267
+ // group). Positions are cursors into the shared input array for the same
268
+ // reason: re-slicing the remainder per step made a match quadratic.
269
+ /** @type {(dr0: _DispatchRule, cp: readonly CodePoint[]) => MatchResult} */
270
+ const f = (dr0, cp) => {
271
+ /** @type {_Stack} */
272
+ let stack = null
273
+ /** @type {_Task|null} */
274
+ let task = {rule: dr0, pos: 0}
275
+ /** @type {_Result} */
276
+ let result = mrFail(undefined, [], 0)
277
+
278
+ while (true) {
279
+ if (task !== null) {
280
+ // The explicit annotation cuts a control-flow inference cycle
281
+ // (TS7022): `task`'s narrowed type feeds `pos`, which feeds the
282
+ // `task` assignment below that the narrowing depends on.
283
+ /** @type {_Task} */
284
+ const current = task
285
+ const {rule: {emptyTag, rangeMap}, pos} = current
286
+ task = null
287
+ // The one logical EOF is available at the physical end, and only
288
+ // there: a rule that dispatches on it consumes it, once. Past it
289
+ // no symbol is left to dispatch on.
290
+ const dr = pos > cp.length ? null : dispatchOp.get(rangeMap)(symbolAt(cp, pos))
291
+ if (dr === null) {
292
+ if (emptyTag !== undefined) {
293
+ result = mrSuccess(emptyTag, [], pos)
294
+ } else if (pos >= cp.length) {
295
+ // Nothing left to reject: the match ran out of input.
296
+ result = mrSuccess(emptyTag, [], null)
297
+ } else {
298
+ result = mrFail(emptyTag, [], pos)
299
+ }
300
+ continue
301
+ }
302
+ const {tag, rules} = dr
303
+ const seq = leafAt(cp, pos)
304
+ const next = pos + 1
305
+ if (rules.length === 0) {
306
+ result = mrSuccess(tag, seq, next)
307
+ } else {
308
+ stack = {top: {tag, rules, ruleIndex: 0, seq}, rest: stack}
309
+ task = {rule: dispatched(rules[0]), pos: next}
310
+ }
311
+ continue
312
+ }
313
+
314
+ if (stack === null) {
315
+ const {ast, success, pos} = result
316
+ return [ast, success, remainderAt(cp, pos)]
317
+ }
318
+ const frame = stack.top
319
+ stack = stack.rest
320
+
321
+ const {ast, success, pos} = result
322
+ // A failing item's own result propagates unchanged, exactly as the
323
+ // recursive version returned it through the chain.
324
+ if (success === false) { continue }
325
+ const seq = [...frame.seq, ast]
326
+ if (pos === null) {
327
+ result = mrSuccess(frame.tag, seq, null)
328
+ continue
188
329
  }
189
- seq = [...seq, astRule]
190
- if (newR === null) {
191
- return mrSuccess(tag, seq, null)
330
+ const ruleIndex = frame.ruleIndex + 1
331
+ if (ruleIndex < frame.rules.length) {
332
+ stack = {top: {...frame, ruleIndex, seq}, rest: stack}
333
+ task = {rule: dispatched(frame.rules[ruleIndex]), pos}
334
+ } else {
335
+ result = mrSuccess(frame.tag, seq, pos)
192
336
  }
193
- r = newR
194
337
  }
195
- return mrSuccess(tag, seq, r)
196
338
  }
197
339
 
198
- return (name, cp) => f(/** @type {_DispatchRule} */ (map[name]), cp)
340
+ return (name, cp) => f(dispatched(name), cp)
199
341
  }
@@ -7,6 +7,8 @@
7
7
  export declare const proof: {
8
8
  dispatch: (() => void)[];
9
9
  parser: (() => void)[];
10
+ longInput: (() => void)[];
11
+ logicalEof: (() => void)[];
10
12
  repeat: (() => void)[];
11
13
  repeatParser: (() => void)[];
12
14
  throw: {
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { stringToCodePointList } from '../../text/utf16/module.f.mjs'
9
9
  import { toArray } from '../../types/list/module.f.mjs'
10
- import { commaJoin0Plus, option, range, repeat0Plus, set } from '../module.f.mjs'
10
+ import { commaJoin0Plus, eof, option, range, repeat0Plus, set } from '../module.f.mjs'
11
11
  import { toData } from '../data/module.f.mjs'
12
12
  import { dispatchMap, parser, parserRuleSet } from './module.f.mjs'
13
13
  import { assertEq } from '../../asserts/module.f.mjs'
@@ -274,6 +274,67 @@ export const proof = {
274
274
  expect(' [{ "q": [ 12, false, [}], "a"] }] ', false)
275
275
  }
276
276
  ],
277
+ longInput: [
278
+ () => {
279
+ // Long right-recursive repetition: one `repeat0Plus` chain across the
280
+ // whole input. This is the shape that overflowed the JS call stack
281
+ // when the matcher recursed once per consumed code point.
282
+ const m = parser(repeat0Plus(set(' \n\r\t')))
283
+ const [, success, remainder] = m('', toArray(stringToCodePointList(' '.repeat(10000))))
284
+ assertEq(success, true)
285
+ assertEq(remainder?.length, 0)
286
+ },
287
+ () => {
288
+ // Deep non-repetition nesting: 5000 bracket levels in the JSON-like
289
+ // test grammar — a shape a repetition-specific fix would not cover.
290
+ const m = parser(deterministic())
291
+ const n = 5000
292
+ const cp = toArray(stringToCodePointList('['.repeat(n) + ']'.repeat(n)))
293
+ const [, success, remainder] = m('', cp)
294
+ assertEq(success, true)
295
+ assertEq(remainder?.length, 0)
296
+ },
297
+ ],
298
+ logicalEof: [
299
+ () => {
300
+ // EOF dispatches below every ordinary symbol, so its cut point is
301
+ // `-2` — the stored endpoint codes never reach the dispatch map.
302
+ const dm = dispatchMap(toData(eof)[0])
303
+ assertEq(JSON.stringify(dm), '{"":{"rangeMap":[[null,-2],[{"rules":[]},-1]]}}')
304
+ },
305
+ () => {
306
+ // The matcher synthesizes one EOF after the physical input, so an
307
+ // `eof` terminal matches empty input. It adds no AST leaf, and the
308
+ // remainder stays physical: empty, not `null`.
309
+ const m = parser(eof)
310
+ assertEq(JSON.stringify(m('', [])), '[{"sequence":[]},true,[]]')
311
+ },
312
+ () => {
313
+ // Callers pass physical symbols only, so EOF is not available
314
+ // before the end of the input.
315
+ const m = parser(eof)
316
+ assertEq(JSON.stringify(m('', [65])), '[{"sequence":[]},false,[65]]')
317
+ },
318
+ () => {
319
+ // Non-empty input: the terminal consumes the synthesized EOF after
320
+ // the last code point.
321
+ const m = parser([range('AA'), eof])
322
+ assertEq(JSON.stringify(m('', [65])), '[{"sequence":[65,{"sequence":[]}]},true,[]]')
323
+ },
324
+ () => {
325
+ // Exactly one EOF is synthesized: the second `eof` terminal has
326
+ // nothing to consume, so the match runs out of input — the `null`
327
+ // remainder this backend reports for that.
328
+ const m = parser([eof, eof])
329
+ assertEq(JSON.stringify(m('', [])), '[{"sequence":[{"sequence":[]}]},true,null]')
330
+ },
331
+ () => {
332
+ // EOF as one alternative among ordinary terminals.
333
+ const m = parser({ a: range('AA'), e: eof })
334
+ assertEq(JSON.stringify(m('', [])), '[{"tag":"e","sequence":[]},true,[]]')
335
+ assertEq(JSON.stringify(m('', [65])), '[{"tag":"a","sequence":[65]},true,[]]')
336
+ },
337
+ ],
277
338
  repeat: [
278
339
  () => {
279
340
  /** @type {readonly [RuleSet, string]} */
@@ -16,12 +16,16 @@ export type _DispatchRule = {
16
16
  export type _Dispatch = RangeMapArray<_DispatchResult>;
17
17
  /** @internal */
18
18
  export type _DispatchResult = _DispatchRuleCollection | null;
19
- /** @internal */
20
- export type _DispatchRuleOrName = _DispatchRule | string;
21
- /** @internal */
19
+ /**
20
+ * The rules a dispatched symbol selects, to be matched one after another. They
21
+ * are names into the {@link _DispatchMap}: the builder only ever appends rule
22
+ * names, so the matcher resolves each one there.
23
+ *
24
+ * @internal
25
+ */
22
26
  export type _DispatchRuleCollection = {
23
27
  readonly tag: string | undefined;
24
- readonly rules: _DispatchRuleOrName[];
28
+ readonly rules: readonly string[];
25
29
  };
26
30
  /** @internal */
27
31
  export type _DispatchMap = StringMap<_DispatchRule>;
@@ -41,6 +45,9 @@ export type AstSequence = readonly (_AstRule | CodePoint)[];
41
45
  export type AstTag = string | true | undefined;
42
46
  /**
43
47
  * Represents the remaining input after a match attempt, or `null` if no match is possible.
48
+ *
49
+ * The remainder is physical: consuming the synthesized end-of-input symbol
50
+ * leaves it empty rather than making it `null`.
44
51
  */
45
52
  export type Remainder = readonly CodePoint[] | null;
46
53
  /**
@@ -51,9 +58,8 @@ export type Remainder = readonly CodePoint[] | null;
51
58
  export type MatchResult = readonly [_AstRule, boolean, Remainder];
52
59
  /**
53
60
  * LL(1) parser function for matching by rule name.
61
+ *
62
+ * `s` holds physical symbols only; the matcher synthesizes the one logical
63
+ * end-of-input symbol after them.
54
64
  */
55
65
  export type Match = (name: string, s: readonly CodePoint[]) => MatchResult;
56
- /**
57
- * Internal match function signature used by compiled dispatch rules.
58
- */
59
- export type MatchRule = (dr: _DispatchRule, s: readonly CodePoint[]) => MatchResult;
@@ -12,6 +12,14 @@
12
12
  */
13
13
  import type { Tuple } from '../types/array/types.ts';
14
14
  import type { TerminalRange, Sequence, Rule, RangeVariant, None, Option, Repeat0Plus, Repeat1Plus, Join1Plus, Repeat } from './types.ts';
15
+ /**
16
+ * The logical end-of-input symbol.
17
+ *
18
+ * `-1` is outside the non-negative physical-symbol domain, so no alphabet
19
+ * adapter can produce it and no ordinary symbol has to be reserved for it.
20
+ * Parser backends synthesize it exactly once, after the physical input.
21
+ */
22
+ export declare const eofSymbol = -1;
15
23
  /** @type {(a: number, b: number) => TerminalRange} */
16
24
  export declare const rangeEncode: (a: number, b: number) => TerminalRange;
17
25
  /**
@@ -21,16 +29,17 @@ export declare const rangeEncode: (a: number, b: number) => TerminalRange;
21
29
  */
22
30
  export declare const oneEncode: (a: number) => TerminalRange;
23
31
  /**
24
- * End-of-file marker: `mask`, the single largest value the 24-bit symbol
25
- * space can hold (the top of `fullRange`). Deliberately outside Unicode
26
- * (`unicodeRange` tops out at `0x10FFFF`) so it can never collide with a
27
- * real code point.
32
+ * End-of-file marker: the singleton range of {@link eofSymbol}. Deliberately
33
+ * outside the ordinary symbol domain and so outside Unicode — so it can
34
+ * never collide with a real code point.
28
35
  *
29
36
  * @type {TerminalRange}
30
37
  */
31
38
  export declare const eof: TerminalRange;
32
39
  /**
33
- * Full 24-bit symbol range packed into a single {@link TerminalRange}.
40
+ * Every ordinary symbol packed into a single {@link TerminalRange}. EOF is not
41
+ * one of them, so complements over this range never include it.
42
+ *
34
43
  * @type {TerminalRange}
35
44
  */
36
45
  export declare const fullRange: TerminalRange;
@@ -44,7 +53,7 @@ export declare const unicodeRange: TerminalRange;
44
53
  */
45
54
  export declare const unicodeMax: string;
46
55
  /**
47
- * Decodes a packed range into `[start, end]` symbols.
56
+ * Decodes a packed range into `[start, end]` semantic symbols.
48
57
  *
49
58
  * @type {(r: number) => Tuple<2, number>}
50
59
  */