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
@@ -6,10 +6,9 @@
6
6
 
7
7
  import { identity } from '../../types/function/module.f.mjs'
8
8
  import { sort } from '../../types/object/module.f.mjs'
9
- import { oneEncode, option, range, rangeDecode, repeat0Plus, set } from '../module.f.mjs'
10
- import { emptyTagMap, toData } from './module.f.mjs'
9
+ import { none, oneEncode, option, range, rangeDecode, repeat0Plus, set } from '../module.f.mjs'
10
+ import { detectRepeat, emptyTagMap, isRepeat, toData } from './module.f.mjs'
11
11
  import { assertEq } from '../../asserts/module.f.mjs'
12
-
13
12
  import { stringify } from '../../media/json/module.f.mjs'
14
13
  import { classic, deterministic } from '../testlib.f.mjs'
15
14
 
@@ -89,11 +88,82 @@ export const proof = {
89
88
  if (result !== '[{"0":{"some":"1","none":"3"},"1":["2"],"2":1627390049,"3":[],"":["0","r"],"r":{"some":"","none":"3"}},"r"]') { throw result }
90
89
  },
91
90
  () => {
91
+ // The item is not nullable, so this one folds into a `repeat`, and
92
+ // the recursive and empty branches it replaced are pruned.
92
93
  const repeatRule = repeat0Plus(set(' \n\r\t'))
93
94
  const result = stringify(identity)(toData(repeatRule))
94
- if (result !== '[{"0":{" ":"1","\\n":"2","\\r":"3","\\t":"4"},"1":536870944,"2":167772170,"3":218103821,"4":150994953,"5":[],"":["0","r"],"r":{"some":"","none":"5"}},"r"]') { throw result }
95
+ const expected = '[{"0":{" ":"1","\\n":"2","\\r":"3","\\t":"4"},"1":536870944,"2":167772170,"3":218103821,"4":150994953,"r":"0"},"r"]'
96
+ assertEq(result, expected, [result, expected])
95
97
  }
96
98
  ],
99
+ isRepeat: () => {
100
+ assertEq(isRepeat('a'), true)
101
+ // Nothing else in a rule set is a string, so the four rule kinds are
102
+ // told apart by JavaScript type alone — no shape has to be probed.
103
+ assertEq(isRepeat(['a', 'b']), false)
104
+ assertEq(isRepeat({ some: 'a' }), false)
105
+ assertEq(isRepeat(oneEncode(0x41)), false)
106
+ },
107
+ detectRepeat: [
108
+ () => {
109
+ const result = stringify(identity)(toData(repeat0Plus(range('AF'))))
110
+ const expected = '[{"0":1090519110,"r":"0"},"r"]'
111
+ assertEq(result, expected, [result, expected])
112
+ },
113
+ () => {
114
+ // Nothing about the fold depends on `repeat0Plus`: a hand-written
115
+ // 0-or-more list is the same shape and folds the same way. `classic`
116
+ // spells one out as `characters`.
117
+ const [ruleSet] = toData(classic())
118
+ const repeats = Object.entries(ruleSet).filter(([, v]) => isRepeat(v))
119
+ assertEq(JSON.stringify(repeats), '[["characters","character"]]')
120
+ },
121
+ () => {
122
+ // Already folded: a `repeat` is not itself a variant to fold again.
123
+ const [ruleSet, entry] = toData(repeat0Plus(range('AF')))
124
+ assertEq(
125
+ stringify(identity)(detectRepeat(ruleSet, entry)),
126
+ stringify(identity)(ruleSet))
127
+ },
128
+ () => {
129
+ // 1-or-more: the base branch is the item, not the empty rule.
130
+ const digit = range('09')
131
+ const digits = () => ({ digit, digits: [digit, digits] })
132
+ const result = stringify(identity)(toData(digits))
133
+ const expected = '[{"0":["","digits"],"":805306425,"digits":{"digit":"","digits":"0"}},"digits"]'
134
+ assertEq(result, expected, [result, expected])
135
+ },
136
+ () => {
137
+ // A separated list repeats `[item, separator, self]`; which of the
138
+ // three items are the list's elements is not something the shape
139
+ // says, so it stays a variant.
140
+ const sep = () => ({ none, list: [range('09'), ',', sep] })
141
+ const result = stringify(identity)(toData(sep))
142
+ const expected = '[{"0":["1","2","sep"],"1":805306425,"2":["3"],"3":738197548,"":[],"sep":{"none":"","list":"0"}},"sep"]'
143
+ assertEq(result, expected, [result, expected])
144
+ },
145
+ () => {
146
+ // The tail is not the rule's only self-reference: the item leads back
147
+ // into it, so the recursion is a tree rather than a list.
148
+ const nested = () => ({ none, some: [inner, nested] })
149
+ const inner = () => ({ leaf: range('AA'), group: ['(', nested, ')'] })
150
+ const [ruleSet] = toData(nested)
151
+ assertEq(JSON.stringify(ruleSet.nested), '{"none":"","some":"0"}')
152
+ },
153
+ () => {
154
+ // A nullable item gives the same input infinitely many parses, so
155
+ // the repetition is not the unambiguous one this fold is limited to.
156
+ const [ruleSet, entry] = toData(repeat0Plus(option('a')))
157
+ assertEq(JSON.stringify(ruleSet[entry]), '{"some":"","none":"3"}')
158
+ },
159
+ () => {
160
+ // Two branches, an empty one and a terminal: the non-empty branch is
161
+ // not a sequence at all.
162
+ const result = stringify(identity)(toData({ e: '', a: range('AA') }))
163
+ const expected = '[{"0":[],"1":1090519105,"":{"e":"0","a":"1"}},""]'
164
+ assertEq(result, expected, [result, expected])
165
+ },
166
+ ],
97
167
  variantTest: () => {
98
168
  const varintRule = { a: 'a', b: 'b'}
99
169
  const result = stringify(sort)(toData(varintRule))
@@ -16,15 +16,33 @@ export type TerminalRange = number;
16
16
  export type Sequence = readonly string[];
17
17
  /** A variant of rule names. */
18
18
  export type Variant = StringMap<string>;
19
+ /**
20
+ * Zero or more repetitions of the named rule.
21
+ *
22
+ * The functional grammar has no repetition primitive — `repeat0Plus(x)` expands
23
+ * to a right-recursive variant — so this is the one rule kind `toData` derives
24
+ * rather than transcribes: it recognizes the unambiguous 0-or-more shape and
25
+ * emits this instead, which is what lets a parser backend match the body
26
+ * iteratively and produce one flat node for the whole repetition.
27
+ *
28
+ * A bare rule name keeps the four rule kinds disjoint by JavaScript type alone:
29
+ * a number is a {@link TerminalRange}, an array a {@link Sequence}, an object a
30
+ * {@link Variant}, and a string this. Nothing else in a {@link RuleSet} is a
31
+ * string, so no shape has to be probed to tell one kind from another. (The
32
+ * *functional* `DataRule` does have a string case — a Unicode literal — but
33
+ * that one never reaches here: `toData` expands it to terminals.)
34
+ */
35
+ export type Repeat = string;
19
36
  /**
20
37
  * Grammar rule definition.
21
38
  *
22
39
  * It can be one of:
23
40
  * - a tagged variant map,
24
41
  * - a sequence of referenced rule names,
25
- * - an encoded terminal range.
42
+ * - an encoded terminal range,
43
+ * - the name of a rule to repeat zero or more times.
26
44
  */
27
- export type Rule = Variant | Sequence | TerminalRange;
45
+ export type Rule = Variant | Sequence | TerminalRange | Repeat;
28
46
  /** The full grammar */
29
47
  export type RuleSet = Readonly<Record<string, Rule>>;
30
48
  /**
@@ -4,24 +4,53 @@
4
4
  * Built from the serializable IR in `fjs/bnf/data`, this is a sibling of the
5
5
  * LL(1) dispatch builder (`fjs/bnf/ll1`). It walks the grammar by recursive
6
6
  * descent and preserves per-code-point metadata, producing a metadata-aware
7
- * AST ({@link AstRuleMeta}). Nullability (which rule can match empty input) is
8
- * computed once by {@link emptyTagMap} in `fjs/bnf/data`.
7
+ * AST over leaves that carry it `Ast<CodePointMeta<T>>`, built with the
8
+ * shared layer in `fjs/bnf/matcher`. Nullability (which rule can match empty
9
+ * input) is computed once by {@link emptyTagMap} in `fjs/bnf/data`.
10
+ *
11
+ * The caller passes physical symbols only; the matcher synthesizes the one
12
+ * logical EOF after them, so a grammar can require the end of input with the
13
+ * `eof` terminal.
9
14
  *
10
15
  * A failed result also carries a {@link DescentFailure}: the furthest position a
11
16
  * terminal was rejected at, which — unlike the result's own index — never
12
17
  * rewinds and is what diagnostics should be built from.
13
18
  *
19
+ * A `Repeat` rule is matched iteratively rather than by descending into itself
20
+ * once per item, so a repetition produces one AST node holding a flat sequence
21
+ * of the items it matched instead of the right-recursive chain its functional
22
+ * spelling would otherwise build.
23
+ *
14
24
  * See `./types.ts` for the type-level API.
15
25
  *
16
26
  * @module
17
27
  *
18
28
  * @import { TerminalRange } from '../types.ts'
19
- * @import { Rule as DataRule, Sequence } from '../data/types.ts'
29
+ * @import { Rule as DataRule, RuleSet, Sequence } from '../data/types.ts'
20
30
  * @import { Rule as FRule } from '../types.ts'
21
- * @import { AstTag, AstSequenceMeta, DescentFailure, DescentMatch, DescentMatchResult, DescentMatchRule } from './types.ts'
31
+ * @import { List } from '../../types/list/types.ts'
32
+ * @import { Ast, AstResult, AstSequence, AstTag, Cursor } from '../matcher/types.ts'
33
+ * @import { CodePointMeta, DescentFailure, DescentMatch, DescentMatchResult, DescentMatchRule } from './types.ts'
22
34
  */
35
+ import type { TerminalRange } from '../types.ts';
36
+ import type { RuleSet } from '../data/types.ts';
23
37
  import type { Rule as FRule } from '../types.ts';
24
- import type { DescentMatch } from './types.ts';
38
+ import type { AstResult, Cursor } from '../matcher/types.ts';
39
+ import type { CodePointMeta, DescentMatch } from './types.ts';
40
+ export type _Failure = {
41
+ readonly pos: Cursor;
42
+ readonly expected: readonly TerminalRange[];
43
+ };
44
+ export type _Result<T> = AstResult<CodePointMeta<T>, Cursor>;
45
+ /**
46
+ * Creates a recursive descent parser from an already materialized
47
+ * {@link RuleSet}, preserving metadata for each consumed code point.
48
+ *
49
+ * @template T
50
+ * @param {RuleSet} ruleSet
51
+ * @returns {DescentMatch<T>}
52
+ */
53
+ export declare const descentParserRuleSet: <T>(ruleSet: RuleSet) => DescentMatch<T>;
25
54
  /**
26
55
  * Creates a recursive descent parser that preserves metadata for each consumed
27
56
  * code point.
@@ -4,52 +4,97 @@
4
4
  * Built from the serializable IR in `fjs/bnf/data`, this is a sibling of the
5
5
  * LL(1) dispatch builder (`fjs/bnf/ll1`). It walks the grammar by recursive
6
6
  * descent and preserves per-code-point metadata, producing a metadata-aware
7
- * AST ({@link AstRuleMeta}). Nullability (which rule can match empty input) is
8
- * computed once by {@link emptyTagMap} in `fjs/bnf/data`.
7
+ * AST over leaves that carry it `Ast<CodePointMeta<T>>`, built with the
8
+ * shared layer in `fjs/bnf/matcher`. Nullability (which rule can match empty
9
+ * input) is computed once by {@link emptyTagMap} in `fjs/bnf/data`.
10
+ *
11
+ * The caller passes physical symbols only; the matcher synthesizes the one
12
+ * logical EOF after them, so a grammar can require the end of input with the
13
+ * `eof` terminal.
9
14
  *
10
15
  * A failed result also carries a {@link DescentFailure}: the furthest position a
11
16
  * terminal was rejected at, which — unlike the result's own index — never
12
17
  * rewinds and is what diagnostics should be built from.
13
18
  *
19
+ * A `Repeat` rule is matched iteratively rather than by descending into itself
20
+ * once per item, so a repetition produces one AST node holding a flat sequence
21
+ * of the items it matched instead of the right-recursive chain its functional
22
+ * spelling would otherwise build.
23
+ *
14
24
  * See `./types.ts` for the type-level API.
15
25
  *
16
26
  * @module
17
27
  *
18
28
  * @import { TerminalRange } from '../types.ts'
19
- * @import { Rule as DataRule, Sequence } from '../data/types.ts'
29
+ * @import { Rule as DataRule, RuleSet, Sequence } from '../data/types.ts'
20
30
  * @import { Rule as FRule } from '../types.ts'
21
- * @import { AstTag, AstSequenceMeta, DescentFailure, DescentMatch, DescentMatchResult, DescentMatchRule } from './types.ts'
31
+ * @import { List } from '../../types/list/types.ts'
32
+ * @import { Ast, AstResult, AstSequence, AstTag, Cursor } from '../matcher/types.ts'
33
+ * @import { CodePointMeta, DescentFailure, DescentMatch, DescentMatchResult, DescentMatchRule } from './types.ts'
22
34
  */
23
35
 
24
36
  import { rangeDecode } from '../module.f.mjs'
25
37
  import { contains as rangeContains } from '../../types/range/module.f.mjs'
38
+ import { concat, toArray } from '../../types/list/module.f.mjs'
26
39
  import { definedEntries } from '../../types/object/module.f.mjs'
27
- import { emptyTagMap, toData } from '../data/module.f.mjs'
40
+ import { emptyTagMap, isRepeat, toData } from '../data/module.f.mjs'
41
+ import { leafAt, mrFail, mrSuccess, physicalIdx, symbolAt } from '../matcher/module.f.mjs'
42
+
43
+ /**
44
+ * The furthest-failure record while matching, positioned by the complete
45
+ * {@link Cursor}. {@link DescentFailure} is its public, physically-positioned
46
+ * form.
47
+ *
48
+ * @typedef {{
49
+ * readonly pos: Cursor
50
+ * readonly expected: readonly TerminalRange[]
51
+ * }} _Failure
52
+ */
53
+
54
+ /**
55
+ * The machine's own result: a {@link DescentMatchResult} positioned by the
56
+ * complete cursor, and with no failure record — that one is tracked per match
57
+ * rather than per frame. This backend always has a position, so it needs no
58
+ * `null` case.
59
+ *
60
+ * @template T
61
+ * @typedef {AstResult<CodePointMeta<T>, Cursor>} _Result
62
+ */
63
+
64
+ /**
65
+ * A leaf here is a code point with its metadata, so its symbol is the first
66
+ * half. This is the only thing {@link symbolAt} needs to know about a leaf.
67
+ *
68
+ * @type {<T>(leaf: CodePointMeta<T>) => number}
69
+ */
70
+ const symbolOf = ([symbol]) => symbol
71
+
72
+ const symbolAtCp = symbolAt(symbolOf)
28
73
 
29
74
  /**
30
75
  * Folds one rejected terminal into the furthest-failure record: further along
31
- * replaces, the same position accumulates (ignoring repeats), earlier is
32
- * discarded.
76
+ * replaces, the same cursor accumulates (ignoring repeats), earlier is
77
+ * discarded. The comparison is on the complete cursor, so a failure after EOF
78
+ * was consumed is further than one at the same physical index before it.
33
79
  *
34
- * @type {(failure: DescentFailure, idx: number, terminal: TerminalRange) => DescentFailure}
80
+ * @type {(failure: _Failure, pos: Cursor, terminal: TerminalRange) => _Failure}
35
81
  */
36
- const recordFailure = (failure, idx, terminal) => {
37
- if (idx > failure.idx) { return { idx, expected: [terminal] } }
38
- if (idx < failure.idx || failure.expected.includes(terminal)) { return failure }
39
- return { idx, expected: [...failure.expected, terminal] }
82
+ const recordFailure = (failure, pos, terminal) => {
83
+ if (pos > failure.pos) { return { pos, expected: [terminal] } }
84
+ if (pos < failure.pos || failure.expected.includes(terminal)) { return failure }
85
+ return { pos, expected: [...failure.expected, terminal] }
40
86
  }
41
87
 
42
88
  /**
43
- * Creates a recursive descent parser that preserves metadata for each consumed
44
- * code point.
89
+ * Creates a recursive descent parser from an already materialized
90
+ * {@link RuleSet}, preserving metadata for each consumed code point.
45
91
  *
46
92
  * @template T
47
- * @param {FRule} fr
93
+ * @param {RuleSet} ruleSet
48
94
  * @returns {DescentMatch<T>}
49
95
  */
50
- export const descentParser = fr => {
51
- const data = toData(fr)
52
- const emptyTags = emptyTagMap(data[0])
96
+ export const descentParserRuleSet = ruleSet => {
97
+ const emptyTags = emptyTagMap(ruleSet)
53
98
 
54
99
  // A suspended sequence match: items[itemIndex] is being matched by the current
55
100
  // task; `seq` holds the ASTs of the items already matched.
@@ -59,8 +104,8 @@ export const descentParser = fr => {
59
104
  * readonly tag: AstTag
60
105
  * readonly items: Sequence
61
106
  * readonly itemIndex: number
62
- * readonly startIdx: number
63
- * readonly seq: AstSequenceMeta<T>
107
+ * readonly startPos: Cursor
108
+ * readonly seq: AstSequence<CodePointMeta<T>>
64
109
  * }} _SeqFrame
65
110
  */
66
111
 
@@ -72,12 +117,30 @@ export const descentParser = fr => {
72
117
  * readonly kind: 'variant'
73
118
  * readonly entries: readonly (readonly [string, string])[]
74
119
  * readonly entryIndex: number
75
- * readonly idx: number
76
- * readonly emptyResult: DescentMatchResult<T>
120
+ * readonly pos: Cursor
121
+ * readonly emptyResult: _Result<T>
77
122
  * }} _VariantFrame
78
123
  */
79
124
 
80
- /** @typedef {_SeqFrame | _VariantFrame} _Frame */
125
+ // A suspended repetition: `item` is being matched by the current task for the
126
+ // round that began at `roundStart`, and `items` holds the ASTs of the rounds
127
+ // that already completed. They accumulate as a list rather than an array
128
+ // because a repetition is as long as its input: appending to an array per
129
+ // round would copy the whole prefix each time and make one repetition
130
+ // quadratic in the number of items it matched.
131
+ /**
132
+ * @typedef {{
133
+ * readonly kind: 'repeat'
134
+ * readonly tag: AstTag
135
+ * readonly item: string
136
+ * readonly items: _Items
137
+ * readonly roundStart: Cursor
138
+ * }} _RepeatFrame
139
+ */
140
+
141
+ /** @typedef {List<Ast<CodePointMeta<T>>>} _Items */
142
+
143
+ /** @typedef {_SeqFrame | _VariantFrame | _RepeatFrame} _Frame */
81
144
 
82
145
  // Immutable cons-cell stack: O(1) push/pop, no array copying per step.
83
146
  /**
@@ -91,12 +154,28 @@ export const descentParser = fr => {
91
154
  // tuple), or null when a result is ready to resume the innermost frame.
92
155
  /**
93
156
  * @typedef {{
157
+ * readonly kind: 'rule'
94
158
  * readonly name: string
95
159
  * readonly tag: AstTag
96
- * readonly idx: number
97
- * }} _Task
160
+ * readonly pos: Cursor
161
+ * }} _RuleTask
98
162
  */
99
163
 
164
+ // The next round of a repetition, about to be started. Both the rule that
165
+ // introduces a repetition and the frame that finishes one of its rounds go
166
+ // through this, so a round is set up in exactly one place.
167
+ /**
168
+ * @typedef {{
169
+ * readonly kind: 'repeat'
170
+ * readonly tag: AstTag
171
+ * readonly item: string
172
+ * readonly items: _Items
173
+ * readonly pos: Cursor
174
+ * }} _RepeatTask
175
+ */
176
+
177
+ /** @typedef {_RuleTask | _RepeatTask} _Task */
178
+
100
179
  // The recursive-descent matcher as an explicit-stack machine: each iteration either
101
180
  // starts the current task (pushing a frame for a sequence/variant and descending into
102
181
  // its first child) or feeds the pending result into the innermost frame. Semantics are
@@ -104,97 +183,130 @@ export const descentParser = fr => {
104
183
  // grammar recursion depth — right-recursive rules (e.g. repeat0Plus chains) no longer
105
184
  // overflow on long input (see the longInput proof group).
106
185
  /** @type {DescentMatchRule<T>} */
107
- const f = (name, tag, cp, idx) => {
108
- /** @type {(tag: AstTag, sequence: AstSequenceMeta<T>, idx: number) => DescentMatchResult<T>} */
109
- const mrSuccess = (tag, sequence, idx) => ({ ast: {tag, sequence}, success: true, idx })
110
- /** @type {(tag: AstTag, sequence: AstSequenceMeta<T>, idx: number) => DescentMatchResult<T>} */
111
- const mrFail = (tag, sequence, idx) => ({ ast: {tag, sequence}, success: false, idx })
186
+ const f = (name, tag, cp, startPos) => {
187
+ const physical = physicalIdx(cp.length)
112
188
 
113
189
  /** @type {_Stack} */
114
190
  let stack = null
115
191
  /** @type {_Task | null} */
116
- let task = { name, tag, idx }
117
- /** @type {DescentMatchResult<T>} */
118
- let result = mrFail(undefined, [], idx)
192
+ let task = { kind: 'rule', name, tag, pos: startPos }
193
+ /** @type {_Result<T>} */
194
+ let result = mrFail(undefined, [], startPos)
119
195
  // High-water mark across the whole match, so it survives the rewinds a
120
196
  // failing sequence item does to `result`.
121
- /** @type {DescentFailure} */
122
- let furthest = { idx: 0, expected: [] }
197
+ /** @type {_Failure} */
198
+ let furthest = { pos: 0, expected: [] }
123
199
 
124
200
  while (true) {
125
201
  if (task !== null) {
126
202
  // The explicit annotation cuts a control-flow inference cycle (TS7022):
127
203
  // `name`'s narrowed type feeds `rule`, whose type would otherwise feed the
128
204
  // later `task` assignments that `name`'s narrowing depends on.
129
- const { name, tag, idx } = /** @type {_Task} */ (task)
205
+ const current = /** @type {_Task} */ (task)
130
206
  task = null
207
+ if (current.kind === 'repeat') {
208
+ // One round of a repetition is one match of its item, so the
209
+ // frame below carries the rounds already collected and the
210
+ // position this round may have to rewind to.
211
+ stack = { top: { kind: 'repeat', tag: current.tag, item: current.item, items: current.items, roundStart: current.pos }, rest: stack }
212
+ task = { kind: 'rule', name: current.item, tag: undefined, pos: current.pos }
213
+ continue
214
+ }
215
+ const { name, tag, pos } = current
131
216
  /** @type {DataRule} */
132
- const rule = data[0][name]
217
+ const rule = ruleSet[name]
133
218
  if (typeof rule === 'number') {
134
219
  // No nullable case: `emptyTagOf` in `bnf/data` returns `undefined`
135
220
  // for every terminal, so `emptyTags[name]` here is always
136
221
  // `undefined` and a terminal either consumes one symbol or fails.
137
- if (idx < cp.length && rangeContains(...rangeDecode(rule))(cp[idx][0])) {
138
- result = mrSuccess(tag, [cp[idx]], idx + 1)
222
+ // Past the synthesized EOF there is no symbol left to consume.
223
+ if (pos <= cp.length && rangeContains(...rangeDecode(rule))(symbolAtCp(cp, pos))) {
224
+ result = mrSuccess(tag, leafAt(cp, pos), pos + 1)
139
225
  } else {
140
226
  // The only place a terminal is rejected, so the only place
141
227
  // the furthest failure can advance.
142
- furthest = recordFailure(furthest, idx, rule)
143
- result = mrFail(undefined, [], idx)
228
+ furthest = recordFailure(furthest, pos, rule)
229
+ result = mrFail(undefined, [], pos)
144
230
  }
145
231
  } else if (rule instanceof Array) {
146
232
  if (rule.length === 0) {
147
- result = mrSuccess(tag, [], idx)
233
+ result = mrSuccess(tag, [], pos)
148
234
  } else {
149
- stack = { top: { kind: 'seq', tag, items: rule, itemIndex: 0, startIdx: idx, seq: [] }, rest: stack }
150
- task = { name: rule[0], tag: undefined, idx }
235
+ stack = { top: { kind: 'seq', tag, items: rule, itemIndex: 0, startPos: pos, seq: [] }, rest: stack }
236
+ task = { kind: 'rule', name: rule[0], tag: undefined, pos }
151
237
  }
238
+ } else if (isRepeat(rule)) {
239
+ task = { kind: 'repeat', tag, item: rule, items: null, pos }
152
240
  } else {
153
241
  const entries = definedEntries(rule)
154
242
  const emptyTag = emptyTags[name]
155
- const emptyResult = mrFail(emptyTag, [], idx)
243
+ const emptyResult = mrFail(emptyTag, [], pos)
156
244
  if (entries.length === 0) {
157
245
  result = emptyResult
158
246
  } else {
159
- stack = { top: { kind: 'variant', entries, entryIndex: 0, idx, emptyResult }, rest: stack }
247
+ stack = { top: { kind: 'variant', entries, entryIndex: 0, pos, emptyResult }, rest: stack }
160
248
  const [entryTag, entryName] = entries[0]
161
- task = { name: entryName, tag: entryTag, idx }
249
+ task = { kind: 'rule', name: entryName, tag: entryTag, pos }
162
250
  }
163
251
  }
164
252
  continue
165
253
  }
166
254
 
167
255
  if (stack === null) {
256
+ const { ast, success, pos } = result
257
+ /** @type {DescentMatchResult<T>} */
258
+ const mr = { ast, success, idx: physical(pos) }
168
259
  // A success has nothing to diagnose; only a failure carries it.
169
- return result.success ? result : { ...result, failure: furthest }
260
+ return success
261
+ ? mr
262
+ : { ...mr, failure: { idx: physical(furthest.pos), expected: furthest.expected } }
170
263
  }
171
264
  const frame = stack.top
172
265
  stack = stack.rest
173
266
 
174
267
  if (frame.kind === 'seq') {
175
- const { ast: astRule, success, idx: nidx } = result
268
+ const { ast: astRule, success, pos } = result
176
269
  if (success === false) {
177
- result = mrFail(frame.tag, [], frame.startIdx)
270
+ result = mrFail(frame.tag, [], frame.startPos)
178
271
  } else {
179
272
  const seq = [...frame.seq, astRule]
180
273
  const itemIndex = frame.itemIndex + 1
181
274
  if (itemIndex < frame.items.length) {
182
275
  stack = { top: { ...frame, itemIndex, seq }, rest: stack }
183
- task = { name: frame.items[itemIndex], tag: undefined, idx: nidx }
276
+ task = { kind: 'rule', name: frame.items[itemIndex], tag: undefined, pos }
277
+ } else {
278
+ result = mrSuccess(frame.tag, seq, pos)
279
+ }
280
+ }
281
+ } else if (frame.kind === 'repeat') {
282
+ if (result.success === false) {
283
+ // A round that fails ends the repetition instead of failing
284
+ // it: the rounds before it stand, and the whole match rewinds
285
+ // to where the failed round began.
286
+ result = mrSuccess(frame.tag, toArray(frame.items), frame.roundStart)
287
+ } else {
288
+ const items = concat(frame.items)([result.ast])
289
+ if (result.pos === frame.roundStart) {
290
+ // A round that consumed nothing would repeat forever. Only
291
+ // a hand-written `repeat` over a nullable rule reaches
292
+ // this — `toData` never derives one — so keep the one
293
+ // empty round and stop.
294
+ result = mrSuccess(frame.tag, toArray(items), result.pos)
184
295
  } else {
185
- result = mrSuccess(frame.tag, seq, nidx)
296
+ task = { kind: 'repeat', tag: frame.tag, item: frame.item, items, pos: result.pos }
186
297
  }
187
298
  }
188
299
  } else {
189
300
  // success that consumed input wins immediately: the frame stays popped and
190
301
  // `result` propagates to the frame below, matching the recursive `return m`.
191
- if (!(result.success && frame.idx !== result.idx)) {
302
+ // Consuming EOF counts as consumption, because the cursor moved.
303
+ if (!(result.success && frame.pos !== result.pos)) {
192
304
  const emptyResult = result.success ? result : frame.emptyResult
193
305
  const entryIndex = frame.entryIndex + 1
194
306
  if (entryIndex < frame.entries.length) {
195
307
  stack = { top: { ...frame, entryIndex, emptyResult }, rest: stack }
196
308
  const [entryTag, entryName] = frame.entries[entryIndex]
197
- task = { name: entryName, tag: entryTag, idx: frame.idx }
309
+ task = { kind: 'rule', name: entryName, tag: entryTag, pos: frame.pos }
198
310
  } else {
199
311
  result = emptyResult
200
312
  }
@@ -210,3 +322,13 @@ export const descentParser = fr => {
210
322
 
211
323
  return match
212
324
  }
325
+
326
+ /**
327
+ * Creates a recursive descent parser that preserves metadata for each consumed
328
+ * code point.
329
+ *
330
+ * @template T
331
+ * @param {FRule} fr
332
+ * @returns {DescentMatch<T>}
333
+ */
334
+ export const descentParser = fr => descentParserRuleSet(toData(fr)[0])
@@ -2,6 +2,7 @@
2
2
  * @module
3
3
  *
4
4
  * @import { CodePoint } from '../../text/utf16/types.ts'
5
+ * @import { RuleSet } from '../data/types.ts'
5
6
  * @import { DescentMatch, CodePointMeta, DescentMatchResult } from './types.ts'
6
7
  */
7
8
  export declare const proof: {
@@ -9,5 +10,7 @@ export declare const proof: {
9
10
  descentParser: (() => void)[];
10
11
  longInput: (() => void)[];
11
12
  descentParserWithMeta: (() => void)[];
13
+ logicalEof: (() => void)[];
14
+ repeat: (() => void)[];
12
15
  furthestFailure: (() => void)[];
13
16
  };