kumi 0.0.18 → 0.0.20

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 (676) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +27 -0
  5. data/CLAUDE.md +26 -139
  6. data/README.md +143 -372
  7. data/data/functions/agg/boolean.yaml +14 -0
  8. data/data/functions/agg/numeric.yaml +80 -0
  9. data/data/functions/agg/string.yaml +8 -0
  10. data/data/functions/core/arithmetic.yaml +50 -0
  11. data/data/functions/core/boolean.yaml +18 -0
  12. data/data/functions/core/comparison.yaml +42 -0
  13. data/data/functions/core/constructor.yaml +32 -0
  14. data/data/functions/core/select.yaml +7 -0
  15. data/data/functions/core/stencil.yaml +21 -0
  16. data/data/functions/core/string.yaml +19 -0
  17. data/data/kernels/javascript/agg/boolean.yaml +12 -0
  18. data/data/kernels/javascript/agg/numeric.yaml +27 -0
  19. data/data/kernels/javascript/agg/string.yaml +5 -0
  20. data/data/kernels/javascript/core/arithmetic.yaml +32 -0
  21. data/data/kernels/javascript/core/boolean.yaml +12 -0
  22. data/data/kernels/javascript/core/comparison.yaml +24 -0
  23. data/data/kernels/javascript/core/constructor.yaml +15 -0
  24. data/data/kernels/javascript/core/select.yaml +7 -0
  25. data/data/kernels/javascript/core/string.yaml +12 -0
  26. data/data/kernels/ruby/agg/boolean.yaml +18 -0
  27. data/data/kernels/ruby/agg/numeric.yaml +29 -0
  28. data/data/kernels/ruby/agg/string.yaml +5 -0
  29. data/data/kernels/ruby/core/arithmetic.yaml +38 -0
  30. data/data/kernels/ruby/core/boolean.yaml +15 -0
  31. data/data/kernels/ruby/core/comparison.yaml +30 -0
  32. data/data/kernels/ruby/core/constructor.yaml +17 -0
  33. data/data/kernels/ruby/core/select.yaml +4 -0
  34. data/data/kernels/ruby/core/string.yaml +15 -0
  35. data/debug_ordering.rb +52 -0
  36. data/docs/FORM_SCHEMA.md +85 -0
  37. data/docs/OUTPUT_SCHEMA.md +69 -0
  38. data/docs/SYNTAX.md +626 -373
  39. data/golden/array_element/expected/ast.txt +21 -0
  40. data/golden/array_element/expected/input_plan.txt +5 -0
  41. data/golden/array_element/expected/lir_00_unoptimized.txt +13 -0
  42. data/golden/array_element/expected/lir_01_hoist_scalar_references.txt +13 -0
  43. data/golden/array_element/expected/lir_02_inlined.txt +13 -0
  44. data/golden/array_element/expected/lir_03_cse.txt +13 -0
  45. data/golden/array_element/expected/lir_04_1_loop_fusion.txt +13 -0
  46. data/golden/array_element/expected/lir_04_loop_invcm.txt +13 -0
  47. data/golden/array_element/expected/lir_06_const_prop.txt +13 -0
  48. data/golden/array_element/expected/nast.txt +7 -0
  49. data/golden/array_element/expected/schema_javascript.mjs +13 -0
  50. data/golden/array_element/expected/schema_ruby.rb +41 -0
  51. data/golden/array_element/expected/snast.txt +7 -0
  52. data/golden/array_element/expected.json +5 -0
  53. data/golden/array_element/input.json +9 -0
  54. data/golden/array_element/schema.kumi +11 -0
  55. data/golden/array_index/expected/ast.txt +59 -0
  56. data/golden/array_index/expected/input_plan.txt +5 -0
  57. data/golden/array_index/expected/lir_00_unoptimized.txt +41 -0
  58. data/golden/array_index/expected/lir_01_hoist_scalar_references.txt +41 -0
  59. data/golden/array_index/expected/lir_02_inlined.txt +42 -0
  60. data/golden/array_index/expected/lir_03_cse.txt +40 -0
  61. data/golden/array_index/expected/lir_04_1_loop_fusion.txt +40 -0
  62. data/golden/array_index/expected/lir_04_loop_invcm.txt +40 -0
  63. data/golden/array_index/expected/lir_06_const_prop.txt +40 -0
  64. data/golden/array_index/expected/nast.txt +33 -0
  65. data/golden/array_index/expected/schema_javascript.mjs +46 -0
  66. data/golden/array_index/expected/schema_ruby.rb +75 -0
  67. data/golden/array_index/expected/snast.txt +33 -0
  68. data/golden/array_index/expected.json +5 -0
  69. data/golden/array_index/input.json +1 -0
  70. data/golden/array_index/schema.kumi +19 -0
  71. data/golden/array_operations/expected/ast.txt +50 -0
  72. data/golden/array_operations/expected/input_plan.txt +10 -0
  73. data/golden/array_operations/expected/lir_00_unoptimized.txt +47 -0
  74. data/golden/array_operations/expected/lir_01_hoist_scalar_references.txt +47 -0
  75. data/golden/array_operations/expected/lir_02_inlined.txt +47 -0
  76. data/golden/array_operations/expected/lir_03_cse.txt +47 -0
  77. data/golden/array_operations/expected/lir_04_1_loop_fusion.txt +47 -0
  78. data/golden/array_operations/expected/lir_04_loop_invcm.txt +47 -0
  79. data/golden/array_operations/expected/lir_06_const_prop.txt +47 -0
  80. data/golden/array_operations/expected/nast.txt +32 -0
  81. data/golden/array_operations/expected/schema_javascript.mjs +60 -0
  82. data/golden/array_operations/expected/schema_ruby.rb +91 -0
  83. data/golden/array_operations/expected/snast.txt +32 -0
  84. data/golden/array_operations/expected.json +27 -0
  85. data/golden/array_operations/input.json +8 -0
  86. data/golden/array_operations/schema.kumi +12 -10
  87. data/golden/cascade_logic/expected/ast.txt +37 -0
  88. data/golden/cascade_logic/expected/input_plan.txt +2 -0
  89. data/golden/cascade_logic/expected/lir_00_unoptimized.txt +29 -0
  90. data/golden/cascade_logic/expected/lir_01_hoist_scalar_references.txt +29 -0
  91. data/golden/cascade_logic/expected/lir_02_inlined.txt +37 -0
  92. data/golden/cascade_logic/expected/lir_03_cse.txt +30 -0
  93. data/golden/cascade_logic/expected/lir_04_1_loop_fusion.txt +30 -0
  94. data/golden/cascade_logic/expected/lir_04_loop_invcm.txt +30 -0
  95. data/golden/cascade_logic/expected/lir_06_const_prop.txt +30 -0
  96. data/golden/cascade_logic/expected/nast.txt +32 -0
  97. data/golden/cascade_logic/expected/schema_javascript.mjs +31 -0
  98. data/golden/cascade_logic/expected/schema_ruby.rb +57 -0
  99. data/golden/cascade_logic/expected/snast.txt +32 -0
  100. data/golden/cascade_logic/expected.json +5 -0
  101. data/golden/cascade_logic/input.json +4 -0
  102. data/golden/cascade_logic/schema.kumi +1 -3
  103. data/golden/chained_fusion/expected/ast.txt +57 -0
  104. data/golden/chained_fusion/expected/input_plan.txt +13 -0
  105. data/golden/chained_fusion/expected/lir_00_unoptimized.txt +76 -0
  106. data/golden/chained_fusion/expected/lir_01_hoist_scalar_references.txt +76 -0
  107. data/golden/chained_fusion/expected/lir_02_inlined.txt +114 -0
  108. data/golden/chained_fusion/expected/lir_03_cse.txt +97 -0
  109. data/golden/chained_fusion/expected/lir_04_1_loop_fusion.txt +99 -0
  110. data/golden/chained_fusion/expected/lir_04_loop_invcm.txt +97 -0
  111. data/golden/chained_fusion/expected/lir_06_const_prop.txt +97 -0
  112. data/golden/chained_fusion/expected/nast.txt +55 -0
  113. data/golden/chained_fusion/expected/schema_javascript.mjs +116 -0
  114. data/golden/chained_fusion/expected/schema_ruby.rb +149 -0
  115. data/golden/chained_fusion/expected/snast.txt +55 -0
  116. data/golden/chained_fusion/expected.json +45 -0
  117. data/golden/chained_fusion/input.json +51 -0
  118. data/golden/chained_fusion/schema.kumi +52 -0
  119. data/golden/element_arrays/expected/ast.txt +55 -0
  120. data/golden/element_arrays/expected/input_plan.txt +7 -0
  121. data/golden/element_arrays/expected/lir_00_unoptimized.txt +81 -0
  122. data/golden/element_arrays/expected/lir_01_hoist_scalar_references.txt +81 -0
  123. data/golden/element_arrays/expected/lir_02_inlined.txt +85 -0
  124. data/golden/element_arrays/expected/lir_03_cse.txt +83 -0
  125. data/golden/element_arrays/expected/lir_04_1_loop_fusion.txt +83 -0
  126. data/golden/element_arrays/expected/lir_04_loop_invcm.txt +83 -0
  127. data/golden/element_arrays/expected/lir_06_const_prop.txt +83 -0
  128. data/golden/element_arrays/expected/nast.txt +42 -0
  129. data/golden/element_arrays/expected/schema_javascript.mjs +106 -0
  130. data/golden/element_arrays/expected/schema_ruby.rb +141 -0
  131. data/golden/element_arrays/expected/snast.txt +42 -0
  132. data/golden/element_arrays/expected.json +55 -0
  133. data/golden/element_arrays/input.json +12 -0
  134. data/golden/element_arrays/schema.kumi +21 -0
  135. data/golden/empty_and_null_inputs/expected/ast.txt +42 -0
  136. data/golden/empty_and_null_inputs/expected/input_plan.txt +12 -0
  137. data/golden/empty_and_null_inputs/expected/lir_00_unoptimized.txt +31 -0
  138. data/golden/empty_and_null_inputs/expected/lir_01_hoist_scalar_references.txt +31 -0
  139. data/golden/empty_and_null_inputs/expected/lir_02_inlined.txt +51 -0
  140. data/golden/empty_and_null_inputs/expected/lir_03_cse.txt +49 -0
  141. data/golden/empty_and_null_inputs/expected/lir_04_1_loop_fusion.txt +49 -0
  142. data/golden/empty_and_null_inputs/expected/lir_04_loop_invcm.txt +49 -0
  143. data/golden/empty_and_null_inputs/expected/lir_06_const_prop.txt +49 -0
  144. data/golden/empty_and_null_inputs/expected/nast.txt +18 -0
  145. data/golden/empty_and_null_inputs/expected/schema_javascript.mjs +47 -0
  146. data/golden/empty_and_null_inputs/expected/schema_ruby.rb +79 -0
  147. data/golden/empty_and_null_inputs/expected/snast.txt +18 -0
  148. data/golden/empty_and_null_inputs/expected.json +8 -0
  149. data/golden/empty_and_null_inputs/input.json +16 -0
  150. data/golden/empty_and_null_inputs/schema.kumi +30 -0
  151. data/golden/game_of_life/expected/ast.txt +118 -0
  152. data/golden/game_of_life/expected/input_plan.txt +5 -0
  153. data/golden/game_of_life/expected/lir_00_unoptimized.txt +343 -0
  154. data/golden/game_of_life/expected/lir_01_hoist_scalar_references.txt +343 -0
  155. data/golden/game_of_life/expected/lir_02_inlined.txt +1918 -0
  156. data/golden/game_of_life/expected/lir_03_cse.txt +766 -0
  157. data/golden/game_of_life/expected/lir_04_1_loop_fusion.txt +766 -0
  158. data/golden/game_of_life/expected/lir_04_loop_invcm.txt +766 -0
  159. data/golden/game_of_life/expected/lir_06_const_prop.txt +766 -0
  160. data/golden/game_of_life/expected/nast.txt +104 -0
  161. data/golden/game_of_life/expected/schema_javascript.mjs +98 -0
  162. data/golden/game_of_life/expected/schema_ruby.rb +125 -0
  163. data/golden/game_of_life/expected/snast.txt +104 -0
  164. data/golden/game_of_life/expected.json +3 -0
  165. data/golden/game_of_life/input.json +8 -0
  166. data/golden/game_of_life/schema.kumi +33 -0
  167. data/golden/hash_keys/expected/ast.txt +29 -0
  168. data/golden/hash_keys/expected/input_plan.txt +2 -0
  169. data/golden/hash_keys/expected/lir_00_unoptimized.txt +18 -0
  170. data/golden/hash_keys/expected/lir_01_hoist_scalar_references.txt +18 -0
  171. data/golden/hash_keys/expected/lir_02_inlined.txt +18 -0
  172. data/golden/hash_keys/expected/lir_03_cse.txt +18 -0
  173. data/golden/hash_keys/expected/lir_04_1_loop_fusion.txt +18 -0
  174. data/golden/hash_keys/expected/lir_04_loop_invcm.txt +18 -0
  175. data/golden/hash_keys/expected/lir_06_const_prop.txt +18 -0
  176. data/golden/hash_keys/expected/nast.txt +46 -0
  177. data/golden/hash_keys/expected/schema_javascript.mjs +34 -0
  178. data/golden/hash_keys/expected/schema_ruby.rb +61 -0
  179. data/golden/hash_keys/expected/snast.txt +46 -0
  180. data/golden/hash_keys/expected.json +20 -0
  181. data/golden/hash_keys/input.json +4 -0
  182. data/golden/hash_keys/schema.kumi +14 -0
  183. data/golden/hash_value/expected/ast.txt +37 -0
  184. data/golden/hash_value/expected/input_plan.txt +7 -0
  185. data/golden/hash_value/expected/lir_00_unoptimized.txt +30 -0
  186. data/golden/hash_value/expected/lir_01_hoist_scalar_references.txt +30 -0
  187. data/golden/hash_value/expected/lir_02_inlined.txt +36 -0
  188. data/golden/hash_value/expected/lir_03_cse.txt +33 -0
  189. data/golden/hash_value/expected/lir_04_1_loop_fusion.txt +33 -0
  190. data/golden/hash_value/expected/lir_04_loop_invcm.txt +33 -0
  191. data/golden/hash_value/expected/lir_06_const_prop.txt +33 -0
  192. data/golden/hash_value/expected/nast.txt +25 -0
  193. data/golden/hash_value/expected/schema_javascript.mjs +46 -0
  194. data/golden/hash_value/expected/schema_ruby.rb +75 -0
  195. data/golden/hash_value/expected/snast.txt +25 -0
  196. data/golden/hash_value/expected.json +19 -0
  197. data/golden/hash_value/input.json +12 -0
  198. data/golden/hash_value/schema.kumi +19 -0
  199. data/golden/hierarchical_complex/expected/ast.txt +85 -0
  200. data/golden/hierarchical_complex/expected/input_plan.txt +23 -0
  201. data/golden/hierarchical_complex/expected/lir_00_unoptimized.txt +87 -0
  202. data/golden/hierarchical_complex/expected/lir_01_hoist_scalar_references.txt +87 -0
  203. data/golden/hierarchical_complex/expected/lir_02_inlined.txt +115 -0
  204. data/golden/hierarchical_complex/expected/lir_03_cse.txt +89 -0
  205. data/golden/hierarchical_complex/expected/lir_04_1_loop_fusion.txt +89 -0
  206. data/golden/hierarchical_complex/expected/lir_04_loop_invcm.txt +89 -0
  207. data/golden/hierarchical_complex/expected/lir_06_const_prop.txt +89 -0
  208. data/golden/hierarchical_complex/expected/nast.txt +49 -0
  209. data/golden/hierarchical_complex/expected/schema_javascript.mjs +121 -0
  210. data/golden/hierarchical_complex/expected/schema_ruby.rb +151 -0
  211. data/golden/hierarchical_complex/expected/snast.txt +49 -0
  212. data/golden/hierarchical_complex/expected.json +34 -0
  213. data/golden/hierarchical_complex/input.json +26 -0
  214. data/golden/hierarchical_complex/schema.kumi +38 -0
  215. data/golden/input_reference/expected/ast.txt +46 -0
  216. data/golden/input_reference/expected/input_plan.txt +15 -0
  217. data/golden/input_reference/expected/lir_00_unoptimized.txt +39 -0
  218. data/golden/input_reference/expected/lir_01_hoist_scalar_references.txt +39 -0
  219. data/golden/input_reference/expected/lir_02_inlined.txt +39 -0
  220. data/golden/input_reference/expected/lir_03_cse.txt +39 -0
  221. data/golden/input_reference/expected/lir_04_1_loop_fusion.txt +39 -0
  222. data/golden/input_reference/expected/lir_04_loop_invcm.txt +39 -0
  223. data/golden/input_reference/expected/lir_06_const_prop.txt +39 -0
  224. data/golden/input_reference/expected/nast.txt +21 -0
  225. data/golden/input_reference/expected/schema_javascript.mjs +45 -0
  226. data/golden/input_reference/expected/schema_ruby.rb +74 -0
  227. data/golden/input_reference/expected/snast.txt +21 -0
  228. data/golden/input_reference/expected.json +7 -0
  229. data/golden/input_reference/input.json +11 -0
  230. data/golden/input_reference/schema.kumi +22 -0
  231. data/golden/interleaved_fusion/expected/ast.txt +51 -0
  232. data/golden/interleaved_fusion/expected/input_plan.txt +13 -0
  233. data/golden/interleaved_fusion/expected/lir_00_unoptimized.txt +53 -0
  234. data/golden/interleaved_fusion/expected/lir_01_hoist_scalar_references.txt +53 -0
  235. data/golden/interleaved_fusion/expected/lir_02_inlined.txt +89 -0
  236. data/golden/interleaved_fusion/expected/lir_03_cse.txt +77 -0
  237. data/golden/interleaved_fusion/expected/lir_04_1_loop_fusion.txt +77 -0
  238. data/golden/interleaved_fusion/expected/lir_04_loop_invcm.txt +77 -0
  239. data/golden/interleaved_fusion/expected/lir_06_const_prop.txt +77 -0
  240. data/golden/interleaved_fusion/expected/nast.txt +41 -0
  241. data/golden/interleaved_fusion/expected/schema_javascript.mjs +86 -0
  242. data/golden/interleaved_fusion/expected/schema_ruby.rb +122 -0
  243. data/golden/interleaved_fusion/expected/snast.txt +41 -0
  244. data/golden/interleaved_fusion/expected.json +37 -0
  245. data/golden/interleaved_fusion/input.json +26 -0
  246. data/golden/interleaved_fusion/schema.kumi +57 -0
  247. data/golden/let_inline/expected/ast.txt +33 -0
  248. data/golden/let_inline/expected/input_plan.txt +2 -0
  249. data/golden/let_inline/expected/lir_00_unoptimized.txt +26 -0
  250. data/golden/let_inline/expected/lir_01_hoist_scalar_references.txt +26 -0
  251. data/golden/let_inline/expected/lir_02_inlined.txt +36 -0
  252. data/golden/let_inline/expected/lir_03_cse.txt +30 -0
  253. data/golden/let_inline/expected/lir_04_1_loop_fusion.txt +30 -0
  254. data/golden/let_inline/expected/lir_04_loop_invcm.txt +30 -0
  255. data/golden/let_inline/expected/lir_06_const_prop.txt +30 -0
  256. data/golden/let_inline/expected/nast.txt +26 -0
  257. data/golden/let_inline/expected/schema_javascript.mjs +11 -0
  258. data/golden/let_inline/expected/schema_ruby.rb +37 -0
  259. data/golden/let_inline/expected/snast.txt +26 -0
  260. data/golden/let_inline/expected.json +1 -0
  261. data/golden/let_inline/input.json +1 -0
  262. data/golden/let_inline/schema.kumi +11 -0
  263. data/golden/loop_fusion/expected/ast.txt +44 -0
  264. data/golden/loop_fusion/expected/input_plan.txt +13 -0
  265. data/golden/loop_fusion/expected/lir_00_unoptimized.txt +43 -0
  266. data/golden/loop_fusion/expected/lir_01_hoist_scalar_references.txt +43 -0
  267. data/golden/loop_fusion/expected/lir_02_inlined.txt +62 -0
  268. data/golden/loop_fusion/expected/lir_03_cse.txt +57 -0
  269. data/golden/loop_fusion/expected/lir_04_1_loop_fusion.txt +57 -0
  270. data/golden/loop_fusion/expected/lir_04_loop_invcm.txt +57 -0
  271. data/golden/loop_fusion/expected/lir_06_const_prop.txt +57 -0
  272. data/golden/loop_fusion/expected/nast.txt +32 -0
  273. data/golden/loop_fusion/expected/schema_javascript.mjs +64 -0
  274. data/golden/loop_fusion/expected/schema_ruby.rb +97 -0
  275. data/golden/loop_fusion/expected/snast.txt +32 -0
  276. data/golden/loop_fusion/expected.json +30 -0
  277. data/golden/loop_fusion/input.json +28 -0
  278. data/golden/loop_fusion/schema.kumi +32 -0
  279. data/golden/min_reduce_scope/expected/ast.txt +49 -0
  280. data/golden/min_reduce_scope/expected/input_plan.txt +9 -0
  281. data/golden/min_reduce_scope/expected/lir_00_unoptimized.txt +59 -0
  282. data/golden/min_reduce_scope/expected/lir_01_hoist_scalar_references.txt +59 -0
  283. data/golden/min_reduce_scope/expected/lir_02_inlined.txt +63 -0
  284. data/golden/min_reduce_scope/expected/lir_03_cse.txt +60 -0
  285. data/golden/min_reduce_scope/expected/lir_04_1_loop_fusion.txt +60 -0
  286. data/golden/min_reduce_scope/expected/lir_04_loop_invcm.txt +60 -0
  287. data/golden/min_reduce_scope/expected/lir_06_const_prop.txt +60 -0
  288. data/golden/min_reduce_scope/expected/nast.txt +29 -0
  289. data/golden/min_reduce_scope/expected/schema_javascript.mjs +66 -0
  290. data/golden/min_reduce_scope/expected/schema_ruby.rb +99 -0
  291. data/golden/min_reduce_scope/expected/snast.txt +29 -0
  292. data/golden/min_reduce_scope/expected.json +9 -0
  293. data/golden/min_reduce_scope/input.json +18 -0
  294. data/golden/min_reduce_scope/schema.kumi +25 -0
  295. data/golden/mixed_dimensions/expected/ast.txt +54 -0
  296. data/golden/mixed_dimensions/expected/input_plan.txt +15 -0
  297. data/golden/mixed_dimensions/expected/lir_00_unoptimized.txt +42 -0
  298. data/golden/mixed_dimensions/expected/lir_01_hoist_scalar_references.txt +42 -0
  299. data/golden/mixed_dimensions/expected/lir_02_inlined.txt +48 -0
  300. data/golden/mixed_dimensions/expected/lir_03_cse.txt +48 -0
  301. data/golden/mixed_dimensions/expected/lir_04_1_loop_fusion.txt +48 -0
  302. data/golden/mixed_dimensions/expected/lir_04_loop_invcm.txt +48 -0
  303. data/golden/mixed_dimensions/expected/lir_06_const_prop.txt +48 -0
  304. data/golden/mixed_dimensions/expected/nast.txt +22 -0
  305. data/golden/mixed_dimensions/expected/schema_javascript.mjs +53 -0
  306. data/golden/mixed_dimensions/expected/schema_ruby.rb +84 -0
  307. data/golden/mixed_dimensions/expected/snast.txt +22 -0
  308. data/golden/mixed_dimensions/expected.json +6 -0
  309. data/golden/mixed_dimensions/input.json +22 -0
  310. data/golden/mixed_dimensions/schema.kumi +35 -0
  311. data/golden/multirank_hoisting/expected/ast.txt +72 -0
  312. data/golden/multirank_hoisting/expected/input_plan.txt +18 -0
  313. data/golden/multirank_hoisting/expected/lir_00_unoptimized.txt +75 -0
  314. data/golden/multirank_hoisting/expected/lir_01_hoist_scalar_references.txt +75 -0
  315. data/golden/multirank_hoisting/expected/lir_02_inlined.txt +126 -0
  316. data/golden/multirank_hoisting/expected/lir_03_cse.txt +109 -0
  317. data/golden/multirank_hoisting/expected/lir_04_1_loop_fusion.txt +109 -0
  318. data/golden/multirank_hoisting/expected/lir_04_loop_invcm.txt +109 -0
  319. data/golden/multirank_hoisting/expected/lir_06_const_prop.txt +109 -0
  320. data/golden/multirank_hoisting/expected/nast.txt +39 -0
  321. data/golden/multirank_hoisting/expected/schema_javascript.mjs +128 -0
  322. data/golden/multirank_hoisting/expected/schema_ruby.rb +162 -0
  323. data/golden/multirank_hoisting/expected/snast.txt +39 -0
  324. data/golden/multirank_hoisting/expected.json +15 -0
  325. data/golden/multirank_hoisting/input.json +19 -0
  326. data/golden/multirank_hoisting/schema.kumi +38 -0
  327. data/golden/nested_hash/expected/ast.txt +22 -0
  328. data/golden/nested_hash/expected/input_plan.txt +5 -0
  329. data/golden/nested_hash/expected/lir_00_unoptimized.txt +10 -0
  330. data/golden/nested_hash/expected/lir_01_hoist_scalar_references.txt +10 -0
  331. data/golden/nested_hash/expected/lir_02_inlined.txt +10 -0
  332. data/golden/nested_hash/expected/lir_03_cse.txt +10 -0
  333. data/golden/nested_hash/expected/lir_04_1_loop_fusion.txt +10 -0
  334. data/golden/nested_hash/expected/lir_04_loop_invcm.txt +10 -0
  335. data/golden/nested_hash/expected/lir_06_const_prop.txt +10 -0
  336. data/golden/nested_hash/expected/nast.txt +8 -0
  337. data/golden/nested_hash/expected/schema_javascript.mjs +9 -0
  338. data/golden/nested_hash/expected/schema_ruby.rb +35 -0
  339. data/golden/nested_hash/expected/snast.txt +8 -0
  340. data/golden/nested_hash/expected.json +3 -0
  341. data/golden/nested_hash/input.json +7 -0
  342. data/golden/nested_hash/schema.kumi +11 -0
  343. data/golden/reduction_broadcast/expected/ast.txt +49 -0
  344. data/golden/reduction_broadcast/expected/input_plan.txt +13 -0
  345. data/golden/reduction_broadcast/expected/lir_00_unoptimized.txt +49 -0
  346. data/golden/reduction_broadcast/expected/lir_01_hoist_scalar_references.txt +49 -0
  347. data/golden/reduction_broadcast/expected/lir_02_inlined.txt +80 -0
  348. data/golden/reduction_broadcast/expected/lir_03_cse.txt +68 -0
  349. data/golden/reduction_broadcast/expected/lir_04_1_loop_fusion.txt +68 -0
  350. data/golden/reduction_broadcast/expected/lir_04_loop_invcm.txt +68 -0
  351. data/golden/reduction_broadcast/expected/lir_06_const_prop.txt +68 -0
  352. data/golden/reduction_broadcast/expected/nast.txt +24 -0
  353. data/golden/reduction_broadcast/expected/schema_javascript.mjs +74 -0
  354. data/golden/reduction_broadcast/expected/schema_ruby.rb +110 -0
  355. data/golden/reduction_broadcast/expected/snast.txt +24 -0
  356. data/golden/reduction_broadcast/expected.json +25 -0
  357. data/golden/reduction_broadcast/input.json +19 -0
  358. data/golden/reduction_broadcast/schema.kumi +34 -0
  359. data/golden/roll/expected/ast.txt +36 -0
  360. data/golden/roll/expected/input_plan.txt +3 -0
  361. data/golden/roll/expected/lir_00_unoptimized.txt +56 -0
  362. data/golden/roll/expected/lir_01_hoist_scalar_references.txt +56 -0
  363. data/golden/roll/expected/lir_02_inlined.txt +56 -0
  364. data/golden/roll/expected/lir_03_cse.txt +55 -0
  365. data/golden/roll/expected/lir_04_1_loop_fusion.txt +55 -0
  366. data/golden/roll/expected/lir_04_loop_invcm.txt +55 -0
  367. data/golden/roll/expected/lir_06_const_prop.txt +55 -0
  368. data/golden/roll/expected/nast.txt +26 -0
  369. data/golden/roll/expected/schema_javascript.mjs +65 -0
  370. data/golden/roll/expected/schema_ruby.rb +95 -0
  371. data/golden/roll/expected/snast.txt +26 -0
  372. data/golden/roll/expected.json +6 -0
  373. data/golden/roll/input.json +1 -0
  374. data/golden/roll/schema.kumi +13 -0
  375. data/golden/shift/expected/ast.txt +48 -0
  376. data/golden/shift/expected/input_plan.txt +3 -0
  377. data/golden/shift/expected/lir_00_unoptimized.txt +96 -0
  378. data/golden/shift/expected/lir_01_hoist_scalar_references.txt +96 -0
  379. data/golden/shift/expected/lir_02_inlined.txt +96 -0
  380. data/golden/shift/expected/lir_03_cse.txt +90 -0
  381. data/golden/shift/expected/lir_04_1_loop_fusion.txt +90 -0
  382. data/golden/shift/expected/lir_04_loop_invcm.txt +90 -0
  383. data/golden/shift/expected/lir_06_const_prop.txt +90 -0
  384. data/golden/shift/expected/nast.txt +38 -0
  385. data/golden/shift/expected/schema_javascript.mjs +106 -0
  386. data/golden/shift/expected/schema_ruby.rb +138 -0
  387. data/golden/shift/expected/snast.txt +38 -0
  388. data/golden/shift/expected.json +8 -0
  389. data/golden/shift/input.json +1 -0
  390. data/golden/shift/schema.kumi +15 -0
  391. data/golden/shift_2d/expected/ast.txt +88 -0
  392. data/golden/shift_2d/expected/input_plan.txt +5 -0
  393. data/golden/shift_2d/expected/lir_00_unoptimized.txt +274 -0
  394. data/golden/shift_2d/expected/lir_01_hoist_scalar_references.txt +274 -0
  395. data/golden/shift_2d/expected/lir_02_inlined.txt +274 -0
  396. data/golden/shift_2d/expected/lir_03_cse.txt +262 -0
  397. data/golden/shift_2d/expected/lir_04_1_loop_fusion.txt +262 -0
  398. data/golden/shift_2d/expected/lir_04_loop_invcm.txt +262 -0
  399. data/golden/shift_2d/expected/lir_06_const_prop.txt +262 -0
  400. data/golden/shift_2d/expected/nast.txt +74 -0
  401. data/golden/shift_2d/expected/schema_javascript.mjs +320 -0
  402. data/golden/shift_2d/expected/schema_ruby.rb +358 -0
  403. data/golden/shift_2d/expected/snast.txt +74 -0
  404. data/golden/shift_2d/expected.json +15 -0
  405. data/golden/shift_2d/input.json +14 -0
  406. data/golden/shift_2d/schema.kumi +25 -0
  407. data/golden/simple_math/expected/ast.txt +40 -0
  408. data/golden/simple_math/expected/input_plan.txt +2 -0
  409. data/golden/simple_math/expected/lir_00_unoptimized.txt +31 -0
  410. data/golden/simple_math/expected/lir_01_hoist_scalar_references.txt +31 -0
  411. data/golden/simple_math/expected/lir_02_inlined.txt +31 -0
  412. data/golden/simple_math/expected/lir_03_cse.txt +31 -0
  413. data/golden/simple_math/expected/lir_04_1_loop_fusion.txt +31 -0
  414. data/golden/simple_math/expected/lir_04_loop_invcm.txt +31 -0
  415. data/golden/simple_math/expected/lir_06_const_prop.txt +31 -0
  416. data/golden/simple_math/expected/nast.txt +33 -0
  417. data/golden/simple_math/expected/schema_javascript.mjs +33 -0
  418. data/golden/simple_math/expected/schema_ruby.rb +59 -0
  419. data/golden/simple_math/expected/snast.txt +33 -0
  420. data/golden/simple_math/expected.json +1 -0
  421. data/golden/simple_math/input.json +4 -0
  422. data/golden/simple_math/schema.kumi +2 -1
  423. data/golden/streaming_basics/expected/ast.txt +64 -0
  424. data/golden/streaming_basics/expected/input_plan.txt +8 -0
  425. data/golden/streaming_basics/expected/lir_00_unoptimized.txt +73 -0
  426. data/golden/streaming_basics/expected/lir_01_hoist_scalar_references.txt +73 -0
  427. data/golden/streaming_basics/expected/lir_02_inlined.txt +100 -0
  428. data/golden/streaming_basics/expected/lir_03_cse.txt +84 -0
  429. data/golden/streaming_basics/expected/lir_04_1_loop_fusion.txt +84 -0
  430. data/golden/streaming_basics/expected/lir_04_loop_invcm.txt +84 -0
  431. data/golden/streaming_basics/expected/lir_06_const_prop.txt +84 -0
  432. data/golden/streaming_basics/expected/nast.txt +48 -0
  433. data/golden/streaming_basics/expected/schema_javascript.mjs +94 -0
  434. data/golden/streaming_basics/expected/schema_ruby.rb +127 -0
  435. data/golden/streaming_basics/expected/snast.txt +48 -0
  436. data/golden/streaming_basics/expected.json +10 -0
  437. data/golden/streaming_basics/input.json +8 -0
  438. data/golden/streaming_basics/schema.kumi +24 -0
  439. data/golden/tuples/expected/ast.txt +48 -0
  440. data/golden/tuples/expected/input_plan.txt +1 -0
  441. data/golden/tuples/expected/lir_00_unoptimized.txt +40 -0
  442. data/golden/tuples/expected/lir_01_hoist_scalar_references.txt +40 -0
  443. data/golden/tuples/expected/lir_02_inlined.txt +48 -0
  444. data/golden/tuples/expected/lir_03_cse.txt +48 -0
  445. data/golden/tuples/expected/lir_04_1_loop_fusion.txt +48 -0
  446. data/golden/tuples/expected/lir_04_loop_invcm.txt +48 -0
  447. data/golden/tuples/expected/lir_06_const_prop.txt +48 -0
  448. data/golden/tuples/expected/nast.txt +42 -0
  449. data/golden/tuples/expected/schema_javascript.mjs +51 -0
  450. data/golden/tuples/expected/schema_ruby.rb +77 -0
  451. data/golden/tuples/expected/snast.txt +42 -0
  452. data/golden/tuples/expected.json +7 -0
  453. data/golden/tuples/input.json +3 -0
  454. data/golden/tuples/schema.kumi +11 -0
  455. data/golden/tuples_and_arrays/expected/ast.txt +44 -0
  456. data/golden/tuples_and_arrays/expected/input_plan.txt +7 -0
  457. data/golden/tuples_and_arrays/expected/lir_00_unoptimized.txt +41 -0
  458. data/golden/tuples_and_arrays/expected/lir_01_hoist_scalar_references.txt +41 -0
  459. data/golden/tuples_and_arrays/expected/lir_02_inlined.txt +62 -0
  460. data/golden/tuples_and_arrays/expected/lir_03_cse.txt +51 -0
  461. data/golden/tuples_and_arrays/expected/lir_04_1_loop_fusion.txt +51 -0
  462. data/golden/tuples_and_arrays/expected/lir_04_loop_invcm.txt +51 -0
  463. data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +51 -0
  464. data/golden/tuples_and_arrays/expected/nast.txt +28 -0
  465. data/golden/tuples_and_arrays/expected/schema_javascript.mjs +58 -0
  466. data/golden/tuples_and_arrays/expected/schema_ruby.rb +88 -0
  467. data/golden/tuples_and_arrays/expected/snast.txt +28 -0
  468. data/golden/tuples_and_arrays/expected.json +18 -0
  469. data/golden/tuples_and_arrays/input.json +7 -0
  470. data/golden/tuples_and_arrays/schema.kumi +38 -0
  471. data/golden/with_constants/expected/ast.txt +28 -0
  472. data/golden/with_constants/expected/input_plan.txt +2 -0
  473. data/golden/with_constants/expected/lir_00_unoptimized.txt +17 -0
  474. data/golden/with_constants/expected/lir_01_hoist_scalar_references.txt +17 -0
  475. data/golden/with_constants/expected/lir_02_inlined.txt +17 -0
  476. data/golden/with_constants/expected/lir_03_cse.txt +17 -0
  477. data/golden/with_constants/expected/lir_04_1_loop_fusion.txt +17 -0
  478. data/golden/with_constants/expected/lir_04_loop_invcm.txt +17 -0
  479. data/golden/with_constants/expected/lir_06_const_prop.txt +17 -0
  480. data/golden/with_constants/expected/nast.txt +21 -0
  481. data/golden/with_constants/expected/schema_javascript.mjs +18 -0
  482. data/golden/with_constants/expected/schema_ruby.rb +44 -0
  483. data/golden/with_constants/expected/snast.txt +15 -0
  484. data/golden/with_constants/schema.kumi +10 -0
  485. data/lib/kumi/analyzer.rb +76 -24
  486. data/lib/kumi/configuration.rb +60 -0
  487. data/lib/kumi/core/analyzer/binder.rb +121 -0
  488. data/lib/kumi/core/analyzer/checkpoint.rb +15 -9
  489. data/lib/kumi/core/analyzer/constant_evaluator.rb +32 -37
  490. data/lib/kumi/core/analyzer/constant_folding_helpers.rb +55 -0
  491. data/lib/kumi/core/analyzer/debug.rb +14 -16
  492. data/lib/kumi/core/analyzer/fn_aliases.rb +46 -0
  493. data/lib/kumi/core/analyzer/folder.rb +94 -0
  494. data/lib/kumi/core/analyzer/macro_expander.rb +69 -0
  495. data/lib/kumi/core/analyzer/passes/assemble_irv2_pass.rb +130 -0
  496. data/lib/kumi/core/analyzer/passes/attach_anchors_pass.rb +71 -0
  497. data/lib/kumi/core/analyzer/passes/attach_terminal_info_pass.rb +181 -0
  498. data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +317 -0
  499. data/lib/kumi/core/analyzer/passes/codegen/js/emitter.rb +75 -0
  500. data/lib/kumi/core/analyzer/passes/codegen/js/output_buffer.rb +103 -0
  501. data/lib/kumi/core/analyzer/passes/codegen/js_pass.rb +27 -0
  502. data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +321 -0
  503. data/lib/kumi/core/analyzer/passes/codegen/ruby/emitter.rb +85 -0
  504. data/lib/kumi/core/analyzer/passes/codegen/ruby/output_buffer.rb +111 -0
  505. data/lib/kumi/core/analyzer/passes/codegen/ruby_pass.rb +32 -0
  506. data/lib/kumi/core/analyzer/passes/constant_folding_pass.rb +33 -0
  507. data/lib/kumi/core/analyzer/passes/contract_checker_pass.rb +220 -0
  508. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +5 -6
  509. data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +7 -3
  510. data/lib/kumi/core/analyzer/passes/input_collector.rb +74 -122
  511. data/lib/kumi/core/analyzer/passes/input_form_schema_pass.rb +43 -0
  512. data/lib/kumi/core/analyzer/passes/ir_dependency_pass.rb +1 -1
  513. data/lib/kumi/core/analyzer/passes/ir_execution_schedule_pass.rb +1 -1
  514. data/lib/kumi/core/analyzer/passes/join_reduce_planning_pass.rb +21 -23
  515. data/lib/kumi/core/analyzer/passes/lir/constant_propagation_pass.rb +84 -0
  516. data/lib/kumi/core/analyzer/passes/lir/dead_code_elimination_pass.rb +93 -0
  517. data/lib/kumi/core/analyzer/passes/lir/hoist_scalar_references_pass.rb +115 -0
  518. data/lib/kumi/core/analyzer/passes/lir/inline_declarations_pass.rb +274 -0
  519. data/lib/kumi/core/analyzer/passes/lir/instruction_scheduling_pass.rb +198 -0
  520. data/lib/kumi/core/analyzer/passes/lir/kernel_binding_pass.rb +30 -0
  521. data/lib/kumi/core/analyzer/passes/lir/local_cse_pass.rb +121 -0
  522. data/lib/kumi/core/analyzer/passes/lir/loop_fusion_pass.rb +156 -0
  523. data/lib/kumi/core/analyzer/passes/lir/loop_invariant_code_motion_pass.rb +148 -0
  524. data/lib/kumi/core/analyzer/passes/lir/lower_pass.rb +407 -0
  525. data/lib/kumi/core/analyzer/passes/lir/stencil_emitter.rb +243 -0
  526. data/lib/kumi/core/analyzer/passes/lir/validation_pass.rb +83 -0
  527. data/lib/kumi/core/analyzer/passes/load_input_cse.rb +17 -16
  528. data/lib/kumi/core/analyzer/passes/lower_to_ir_pass.rb +4 -2
  529. data/lib/kumi/core/analyzer/passes/lower_to_irv2_pass.rb +197 -0
  530. data/lib/kumi/core/analyzer/passes/name_indexer.rb +4 -1
  531. data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +237 -0
  532. data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +156 -0
  533. data/lib/kumi/core/analyzer/passes/output_schema_pass.rb +38 -0
  534. data/lib/kumi/core/analyzer/passes/pass_base.rb +30 -4
  535. data/lib/kumi/core/analyzer/passes/precompute_access_paths_pass.rb +93 -0
  536. data/lib/kumi/core/analyzer/passes/scope_resolution_pass.rb +33 -30
  537. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +5 -26
  538. data/lib/kumi/core/analyzer/passes/snast_pass.rb +229 -0
  539. data/lib/kumi/core/analyzer/passes/toposorter.rb +1 -0
  540. data/lib/kumi/core/analyzer/passes/type_checker.rb +13 -0
  541. data/lib/kumi/core/analyzer/passes/type_inferencer_pass.rb +14 -16
  542. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +2 -1
  543. data/lib/kumi/core/analyzer/plans.rb +12 -0
  544. data/lib/kumi/core/analyzer/state_serde.rb +4 -4
  545. data/lib/kumi/core/analyzer/structs/access_plan.rb +2 -2
  546. data/lib/kumi/core/analyzer/unsat_constant_evaluator.rb +59 -0
  547. data/lib/kumi/core/compiler/access_codegen.rb +1 -1
  548. data/lib/kumi/core/compiler/access_emit/base.rb +9 -5
  549. data/lib/kumi/core/compiler/access_emit/each_indexed.rb +10 -3
  550. data/lib/kumi/core/compiler/access_emit/materialize.rb +12 -5
  551. data/lib/kumi/core/compiler/access_emit/ravel.rb +10 -3
  552. data/lib/kumi/core/compiler/access_emit/read.rb +4 -1
  553. data/lib/kumi/core/compiler/access_planner.rb +42 -4
  554. data/lib/kumi/core/compiler/access_planner_v2.rb +164 -0
  555. data/lib/kumi/core/explain.rb +18 -11
  556. data/lib/kumi/core/functions/loader.rb +47 -0
  557. data/lib/kumi/core/functions/model.rb +10 -0
  558. data/lib/kumi/core/functions/type_rules.rb +108 -0
  559. data/lib/kumi/core/ir/execution_engine/interpreter.rb +1 -1
  560. data/lib/kumi/core/ir/execution_engine/profiler.rb +107 -97
  561. data/lib/kumi/core/ir.rb +6 -2
  562. data/lib/kumi/core/irv2/builder.rb +48 -0
  563. data/lib/kumi/core/irv2/declaration.rb +28 -0
  564. data/lib/kumi/core/irv2/module.rb +108 -0
  565. data/lib/kumi/core/irv2/value.rb +28 -0
  566. data/lib/kumi/core/lir/analyze.rb +64 -0
  567. data/lib/kumi/core/lir/build.rb +363 -0
  568. data/lib/kumi/core/lir/emit.rb +62 -0
  569. data/lib/kumi/core/lir/structs/instruction.rb +44 -0
  570. data/lib/kumi/core/lir/structs/literal.rb +14 -0
  571. data/lib/kumi/core/lir/structs/stamp.rb +13 -0
  572. data/lib/kumi/core/lir/support/error.rb +9 -0
  573. data/lib/kumi/core/lir/support/ids.rb +34 -0
  574. data/lib/kumi/core/lir/validate.rb +74 -0
  575. data/lib/kumi/core/lir.rb +34 -0
  576. data/lib/kumi/core/nast.rb +216 -0
  577. data/lib/kumi/core/ruby_parser/dsl.rb +2 -2
  578. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +1 -1
  579. data/lib/kumi/core/ruby_parser/expression_converter.rb +10 -0
  580. data/lib/kumi/core/ruby_parser/input_builder.rb +16 -17
  581. data/lib/kumi/core/ruby_parser/schema_builder.rb +36 -10
  582. data/lib/kumi/core/ruby_parser/sugar.rb +64 -0
  583. data/lib/kumi/core/types/builder.rb +2 -2
  584. data/lib/kumi/core/types/normalizer.rb +2 -0
  585. data/lib/kumi/core/types/validator.rb +10 -3
  586. data/lib/kumi/core/types.rb +7 -0
  587. data/lib/kumi/dev/codegen.rb +194 -0
  588. data/lib/kumi/dev/golden/generator.rb +105 -0
  589. data/lib/kumi/dev/golden/reporter.rb +160 -0
  590. data/lib/kumi/dev/golden/representation.rb +45 -0
  591. data/lib/kumi/dev/golden/result.rb +98 -0
  592. data/lib/kumi/dev/golden/runtime_test.rb +93 -0
  593. data/lib/kumi/dev/golden/suite.rb +131 -0
  594. data/lib/kumi/dev/golden/verifier.rb +76 -0
  595. data/lib/kumi/dev/golden.rb +75 -0
  596. data/lib/kumi/dev/ir.rb +4 -4
  597. data/lib/kumi/dev/parse.rb +1 -1
  598. data/lib/kumi/dev/pretty_printer.rb +229 -0
  599. data/lib/kumi/dev/printer/irv2_formatter.rb +163 -0
  600. data/lib/kumi/dev/printer/width_aware_json.rb +44 -0
  601. data/lib/kumi/dev/profile_aggregator.rb +36 -38
  602. data/lib/kumi/dev/profile_runner.rb +19 -23
  603. data/lib/kumi/dev/runner.rb +12 -22
  604. data/lib/kumi/dev/support/kumi_runner.mjs +39 -0
  605. data/lib/kumi/dev.rb +3 -3
  606. data/lib/kumi/frontends/ruby.rb +12 -12
  607. data/lib/kumi/frontends/text.rb +26 -21
  608. data/lib/kumi/frontends.rb +6 -8
  609. data/lib/kumi/kernel_registry.rb +59 -0
  610. data/lib/kumi/pack/builder.rb +229 -0
  611. data/lib/kumi/pack.rb +15 -0
  612. data/lib/kumi/registry_v2/loader.rb +81 -0
  613. data/lib/kumi/registry_v2.rb +118 -0
  614. data/lib/kumi/schema.rb +83 -43
  615. data/lib/kumi/support/diff.rb +3 -2
  616. data/lib/kumi/support/ir_render.rb +1 -1
  617. data/lib/kumi/support/lir_printer.rb +143 -0
  618. data/lib/kumi/support/nast_printer.rb +93 -0
  619. data/lib/kumi/support/s_expression_printer.rb +5 -4
  620. data/lib/kumi/support/snast_printer.rb +111 -0
  621. data/lib/kumi/syntax/call_expression.rb +1 -1
  622. data/lib/kumi/syntax/input_declaration.rb +2 -2
  623. data/lib/kumi/syntax/node.rb +4 -12
  624. data/lib/kumi/syntax/root.rb +10 -0
  625. data/lib/kumi/syntax/trait_declaration.rb +1 -0
  626. data/lib/kumi/syntax/value_declaration.rb +1 -0
  627. data/lib/kumi/version.rb +1 -1
  628. data/lib/kumi.rb +46 -4
  629. metadata +571 -54
  630. data/docs/AST.md +0 -133
  631. data/docs/DSL.md +0 -154
  632. data/docs/FUNCTIONS.md +0 -176
  633. data/docs/VECTOR_SEMANTICS.md +0 -286
  634. data/docs/compiler_design_principles.md +0 -86
  635. data/docs/dev/analyzer-debug.md +0 -52
  636. data/docs/dev/parse-command.md +0 -64
  637. data/docs/dev/vm-profiling.md +0 -95
  638. data/docs/development/README.md +0 -120
  639. data/docs/development/error-reporting.md +0 -361
  640. data/docs/features/README.md +0 -58
  641. data/docs/features/analysis-type-inference.md +0 -42
  642. data/docs/features/analysis-unsat-detection.md +0 -71
  643. data/docs/features/hierarchical-broadcasting.md +0 -415
  644. data/docs/features/input-declaration-system.md +0 -58
  645. data/docs/features/performance.md +0 -14
  646. data/docs/features/s-expression-printer.md +0 -77
  647. data/docs/schema_metadata/broadcasts.md +0 -53
  648. data/docs/schema_metadata/cascades.md +0 -45
  649. data/docs/schema_metadata/declarations.md +0 -54
  650. data/docs/schema_metadata/dependencies.md +0 -57
  651. data/docs/schema_metadata/evaluation_order.md +0 -29
  652. data/docs/schema_metadata/examples.md +0 -95
  653. data/docs/schema_metadata/inferred_types.md +0 -46
  654. data/docs/schema_metadata/inputs.md +0 -86
  655. data/docs/schema_metadata.md +0 -108
  656. data/golden/mixed_nesting/schema.kumi +0 -42
  657. data/lib/kumi/core/function_registry/collection_functions.rb +0 -298
  658. data/lib/kumi/core/function_registry/comparison_functions.rb +0 -33
  659. data/lib/kumi/core/function_registry/conditional_functions.rb +0 -48
  660. data/lib/kumi/core/function_registry/function_builder.rb +0 -184
  661. data/lib/kumi/core/function_registry/logical_functions.rb +0 -214
  662. data/lib/kumi/core/function_registry/math_functions.rb +0 -74
  663. data/lib/kumi/core/function_registry/stat_functions.rb +0 -156
  664. data/lib/kumi/core/function_registry/string_functions.rb +0 -57
  665. data/lib/kumi/core/function_registry/type_functions.rb +0 -53
  666. data/lib/kumi/core/function_registry.rb +0 -176
  667. data/lib/kumi/registry.rb +0 -32
  668. data/lib/kumi/runtime/executable.rb +0 -135
  669. data/lib/kumi/runtime/run.rb +0 -105
  670. data/performance_results.txt +0 -63
  671. data/scripts/analyze_broadcast_methods.rb +0 -68
  672. data/scripts/analyze_cascade_methods.rb +0 -74
  673. data/scripts/check_broadcasting_coverage.rb +0 -51
  674. data/scripts/find_dead_code.rb +0 -114
  675. data/scripts/generate_function_docs.rb +0 -71
  676. data/scripts/test_mixed_nesting_performance.rb +0 -206
@@ -0,0 +1,34 @@
1
+ # lib/kumi/core/lir.rb
2
+ module Kumi
3
+ module Core
4
+ module LIR
5
+ OPCODES = %i[
6
+ Constant
7
+ LoadInput
8
+ LoadDeclaration
9
+ LoadField
10
+ LoopStart
11
+ LoopEnd
12
+ KernelCall
13
+ Select
14
+ FoldCall
15
+ DeclareAccumulator
16
+ Accumulate
17
+ LoadAccumulator
18
+ MakeTuple
19
+ MakeObject
20
+ TupleGet
21
+ Yield
22
+ ].freeze
23
+
24
+ # Re-exports for stable API
25
+ Stamp = Structs::Stamp
26
+ Literal = Structs::Literal
27
+ Instruction = Structs::Instruction
28
+
29
+ # Re-export support classes
30
+ Ids = Support::Ids
31
+ Error = Support::Error
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,216 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Core
5
+ module NAST
6
+ @next_id_mutex = Mutex.new
7
+ @next_id = 1
8
+
9
+ def self.next_id
10
+ @next_id_mutex.synchronize { @next_id += 1 }
11
+ end
12
+
13
+ def self.reset_id_counter!
14
+ @next_id_mutex.synchronize { @next_id = 1 }
15
+ end
16
+
17
+ Node = Struct.new(:id, :loc, :meta, keyword_init: true) do
18
+ def initialize(**args)
19
+ super
20
+ self.id ||= NAST.next_id
21
+ self.meta ||= {}
22
+ end
23
+
24
+ def accept(visitor)
25
+ visitor.visit_node(self)
26
+ end
27
+ end
28
+
29
+ class Const < Node
30
+ attr_reader :value
31
+
32
+ def initialize(value:, **k)
33
+ super(**k)
34
+ @value = value
35
+ end
36
+
37
+ def accept(visitor)
38
+ visitor.visit_const(self)
39
+ end
40
+ end
41
+
42
+ class InputRef < Node
43
+ attr_reader :path, :fqn, :key_chain, :element_terminal
44
+
45
+ def initialize(path:, fqn: nil, key_chain: [], element_terminal: false, **k)
46
+ super(**k)
47
+ @path = Array(path).map!(&:to_sym)
48
+ @fqn = fqn || @path.join(".")
49
+ @key_chain = Array(key_chain).map!(&:to_sym)
50
+ @element_terminal = !!element_terminal
51
+ end
52
+
53
+ def path_fqn = @fqn
54
+
55
+ def accept(visitor)
56
+ visitor.visit_input_ref(self)
57
+ end
58
+ end
59
+
60
+ class Ref < Node
61
+ attr_reader :name
62
+
63
+ def initialize(name:, **k)
64
+ super(**k)
65
+ @name = name.to_sym
66
+ end
67
+
68
+ def accept(visitor)
69
+ visitor.visit_ref(self)
70
+ end
71
+ end
72
+
73
+ class IndexRef < Node
74
+ attr_reader :name, :input_fqn, :axes
75
+
76
+ def initialize(name:, input_fqn:, **k)
77
+ super(**k)
78
+ @name = name.to_sym
79
+ @input_fqn = input_fqn
80
+ end
81
+
82
+ def axes
83
+ meta[:stamp][:axes]
84
+ end
85
+
86
+ def accept(visitor) = visitor.respond_to?(:visit_index_ref) ? visitor.visit_index_ref(self) : super
87
+ end
88
+
89
+ class Call < Node
90
+ attr_reader :fn, :args, :opts
91
+
92
+ def initialize(fn:, args:, opts: {}, **k)
93
+ super(**k)
94
+ @fn = fn.to_sym
95
+ @args = args
96
+ @opts = opts
97
+ end
98
+
99
+ def accept(visitor)
100
+ visitor.visit_call(self)
101
+ end
102
+ end
103
+
104
+ class Tuple < Node
105
+ attr_reader :args
106
+
107
+ def initialize(args:, **k)
108
+ super(**k)
109
+ @args = args
110
+ end
111
+
112
+ def accept(visitor)
113
+ visitor.visit_tuple(self)
114
+ end
115
+ end
116
+
117
+ class Pair < Node
118
+ attr_reader :key, :value
119
+
120
+ def initialize(key:, value:, **k)
121
+ super(**k)
122
+ @key = key
123
+ @value = value
124
+ end
125
+
126
+ def accept(visitor)
127
+ visitor.visit_pair(self)
128
+ end
129
+ end
130
+
131
+ class Hash < Node
132
+ attr_reader :pairs
133
+
134
+ def initialize(pairs:, **k)
135
+ super(**k)
136
+ @pairs = pairs
137
+ end
138
+
139
+ def accept(visitor)
140
+ visitor.visit_hash(self)
141
+ end
142
+ end
143
+
144
+ # Control: ternary select (pure, eager)
145
+ class Select < Node
146
+ attr_reader :cond, :on_true, :on_false
147
+
148
+ def initialize(cond:, on_true:, on_false:, **k)
149
+ super(**k)
150
+ @cond = cond
151
+ @on_true = on_true
152
+ @on_false = on_false
153
+ end
154
+
155
+ def accept(visitor)
156
+ visitor.respond_to?(:visit_select) ? visitor.visit_select(self) : super
157
+ end
158
+ end
159
+
160
+ # Semantic reduction over explicit axes, with kernel id (e.g., :"agg.sum")
161
+ class Fold < Node
162
+ attr_reader :fn, :arg
163
+
164
+ def initialize(fn:, arg:, **k)
165
+ super(**k)
166
+ @fn = fn.to_sym
167
+ @arg = arg
168
+ end
169
+
170
+ def accept(visitor)
171
+ visitor.respond_to?(:visit_fold) ? visitor.visit_fold(self) : super
172
+ end
173
+ end
174
+
175
+ # Semantic reduction over explicit axes, with kernel id (e.g., :"agg.sum")
176
+ class Reduce < Node
177
+ attr_reader :fn, :over, :arg
178
+
179
+ def initialize(fn:, over:, arg:, **k)
180
+ super(**k)
181
+ @fn = fn.to_sym
182
+ @over = Array(over).map!(&:to_sym)
183
+ @arg = arg
184
+ end
185
+
186
+ def accept(visitor)
187
+ visitor.respond_to?(:visit_reduce) ? visitor.visit_reduce(self) : super
188
+ end
189
+ end
190
+
191
+ class Declaration < Node
192
+ attr_reader :name, :body
193
+
194
+ def initialize(name:, body:, **k)
195
+ super(**k)
196
+ @name = name.to_sym
197
+ @body = body
198
+ end
199
+
200
+ def accept(visitor)
201
+ visitor.visit_declaration(self)
202
+ end
203
+
204
+ def kind
205
+ meta[:kind]
206
+ end
207
+ end
208
+
209
+ Module = Struct.new(:decls, keyword_init: true) do
210
+ def accept(visitor)
211
+ visitor.visit_module(self)
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
@@ -4,9 +4,9 @@ module Kumi
4
4
  module Core
5
5
  module RubyParser
6
6
  module Dsl
7
- def self.build_syntax_tree(&rule_block)
7
+ def self.build_syntax_tree(&)
8
8
  parser = Parser.new
9
- parser.parse(&rule_block)
9
+ parser.parse(&)
10
10
  end
11
11
  end
12
12
  end
@@ -55,7 +55,7 @@ module Kumi
55
55
  add_case(create_literal(true), result)
56
56
  end
57
57
 
58
- def method_missing(method_name, *args, &block)
58
+ def method_missing(method_name, *args, &)
59
59
  return super if !args.empty? || block_given?
60
60
 
61
61
  # Allow direct trait references in cascade conditions
@@ -25,6 +25,8 @@ module Kumi
25
25
  create_literal(obj)
26
26
  when Array
27
27
  create_list(obj)
28
+ when Hash
29
+ create_hash(obj)
28
30
  when Syntax::Node
29
31
  obj
30
32
  else
@@ -81,6 +83,14 @@ module Kumi
81
83
  Kumi::Syntax::ArrayExpression.new(elements, loc: current_location)
82
84
  end
83
85
 
86
+ def create_hash(vhash)
87
+ pairs = vhash.map do |key, val|
88
+ [ensure_syntax(key), ensure_syntax(val)]
89
+ end
90
+
91
+ Kumi::Syntax::HashExpression.new(pairs, loc: current_location)
92
+ end
93
+
84
94
  def handle_custom_object(obj)
85
95
  if obj.respond_to?(:to_ast_node)
86
96
  obj.to_ast_node
@@ -23,9 +23,9 @@ module Kumi
23
23
  end
24
24
  end
25
25
 
26
- def array(name_or_elem_type, **kwargs, &block)
26
+ def array(name_or_elem_type, **kwargs, &)
27
27
  if block_given?
28
- create_array_field_with_block(name_or_elem_type, kwargs, &block)
28
+ create_array_field_with_block(name_or_elem_type, kwargs, &)
29
29
  elsif kwargs.any?
30
30
  create_array_field(name_or_elem_type, kwargs)
31
31
  else
@@ -33,9 +33,9 @@ module Kumi
33
33
  end
34
34
  end
35
35
 
36
- def hash(name_or_key_type, val_type = nil, **kwargs, &block)
36
+ def hash(name_or_key_type, val_type = nil, **kwargs, &)
37
37
  if block_given?
38
- create_hash_field_with_block(name_or_key_type, kwargs, &block)
38
+ create_hash_field_with_block(name_or_key_type, kwargs, &)
39
39
  elsif val_type.nil?
40
40
  create_hash_field(name_or_key_type, kwargs)
41
41
  else
@@ -98,32 +98,31 @@ module Kumi
98
98
  raise_syntax_error("Invalid types for hash `#{field_name}`: #{e.message}", location: @context.current_location)
99
99
  end
100
100
 
101
- def create_array_field_with_block(field_name, options, &block)
101
+ def create_array_field_with_block(field_name, options, &)
102
102
  domain = options[:domain]
103
103
 
104
104
  # Collect children by creating a nested context
105
- children, _, using_elements = collect_array_children(&block)
105
+ children, = collect_array_children(&)
106
106
 
107
107
  # Create the InputDeclaration with children and access_mode
108
- access_mode = using_elements ? :element : :field
108
+ # access_mode = using_elements ? :element : :field
109
109
  @context.inputs << Kumi::Syntax::InputDeclaration.new(
110
110
  field_name,
111
111
  domain,
112
112
  :array,
113
113
  children,
114
- access_mode,
115
114
  loc: @context.current_location
116
115
  )
117
116
  end
118
117
 
119
- def collect_array_children(&block)
118
+ def collect_array_children(&)
120
119
  # Create a temporary nested context to collect children
121
120
  nested_inputs = []
122
121
  nested_context = NestedInput.new(nested_inputs, @context.current_location)
123
122
  nested_builder = InputBuilder.new(nested_context)
124
123
 
125
124
  # Execute the block in the nested context
126
- nested_builder.instance_eval(&block)
125
+ nested_builder.instance_eval(&)
127
126
 
128
127
  # Determine element type based on what was declared
129
128
  elem_type = determine_element_type(nested_builder, nested_inputs)
@@ -151,17 +150,17 @@ module Kumi
151
150
  end
152
151
 
153
152
  # New method: element() declaration - always requires a name
154
- def element(type_spec, name, &block)
153
+ def element(type_spec, name, &)
155
154
  @using_elements = true
156
155
  if block_given?
157
156
  # Named element with nested structure: element(:array, :rows) do ... end
158
157
  # These DO set @using_elements to enable element access mode for multi-dimensional arrays
159
158
  case type_spec
160
159
  when :array
161
- create_array_field_with_block(name, {}, &block)
160
+ create_array_field_with_block(name, {}, &)
162
161
  when :field
163
162
  # Create nested object structure
164
- create_object_element(name, &block)
163
+ create_object_element(name, &)
165
164
  else
166
165
  raise_syntax_error("element(#{type_spec.inspect}, #{name.inspect}) with block only supports :array or :field types",
167
166
  location: @context.current_location)
@@ -173,17 +172,17 @@ module Kumi
173
172
  end
174
173
  end
175
174
 
176
- def create_object_element(name, &block)
175
+ def create_object_element(name, &)
177
176
  # Similar to create_array_field_with_block but for objects
178
- children, = collect_array_children(&block)
177
+ children, = collect_array_children(&)
179
178
  @context.inputs << Kumi::Syntax::InputDeclaration.new(name, nil, :field, children, nil, loc: @context.current_location)
180
179
  end
181
180
 
182
- def create_hash_field_with_block(field_name, options, &block)
181
+ def create_hash_field_with_block(field_name, options, &)
183
182
  domain = options[:domain]
184
183
 
185
184
  # Collect children by creating a nested context (reuse array logic)
186
- children, = collect_array_children(&block)
185
+ children, = collect_array_children(&)
187
186
 
188
187
  # Create the InputDeclaration with children and :field access_mode for hash objects
189
188
  @context.inputs << Kumi::Syntax::InputDeclaration.new(
@@ -8,12 +8,20 @@ module Kumi
8
8
  include Syntax
9
9
  include ErrorReporting
10
10
 
11
- DSL_METHODS = %i[value trait input ref literal fn].freeze
11
+ DSL_METHODS = %i[value trait input ref literal fn select shift roll].freeze
12
12
 
13
13
  def initialize(context)
14
14
  @context = context
15
15
  end
16
16
 
17
+ def let(name = nil, expr = nil, &blk)
18
+ update_location
19
+ validate_value_args(name, expr, blk)
20
+
21
+ expression = blk ? build_cascade(&blk) : ensure_syntax(expr)
22
+ @context.values << Kumi::Syntax::ValueDeclaration.new(name, expression, inline: true, loc: @context.current_location)
23
+ end
24
+
17
25
  def value(name = nil, expr = nil, &blk)
18
26
  update_location
19
27
  validate_value_args(name, expr, blk)
@@ -28,7 +36,7 @@ module Kumi
28
36
  build_positional_trait(args)
29
37
  end
30
38
 
31
- def input(&blk)
39
+ def input(&)
32
40
  return InputProxy.new(@context) unless block_given?
33
41
 
34
42
  raise_syntax_error("input block already defined", location: @context.current_location) if @context.input_block_defined?
@@ -36,7 +44,7 @@ module Kumi
36
44
 
37
45
  update_location
38
46
  input_builder = InputBuilder.new(@context)
39
- input_builder.instance_eval(&blk)
47
+ input_builder.instance_eval(&)
40
48
  end
41
49
 
42
50
  def ref(name)
@@ -49,13 +57,31 @@ module Kumi
49
57
  Kumi::Syntax::Literal.new(value, loc: @context.current_location)
50
58
  end
51
59
 
52
- def fn(fn_name, *args)
60
+ def fn(fn_name, *args, **kwargs)
53
61
  update_location
54
- expr_args = args.map { |a| ensure_syntax(a) }
55
- Kumi::Syntax::CallExpression.new(fn_name, expr_args, loc: @context.current_location)
62
+ expr_args = args.map { ensure_syntax(_1) }
63
+ Kumi::Syntax::CallExpression.new(fn_name, expr_args, kwargs, loc: @context.current_location)
64
+ end
65
+
66
+ def select(condition, value_when_true, value_when_false)
67
+ update_location
68
+ condition_expr = ensure_syntax(condition)
69
+ true_expr = ensure_syntax(value_when_true)
70
+ false_expr = ensure_syntax(value_when_false)
71
+ Kumi::Syntax::CallExpression.new(:__select__, [condition_expr, true_expr, false_expr], loc: @context.current_location)
72
+ end
73
+
74
+ def roll(*args, **kwargs)
75
+ args_expr = args.map { ensure_syntax(_1) }
76
+ Kumi::Syntax::CallExpression.new(:roll, args_expr, kwargs, loc: @context.current_location)
77
+ end
78
+
79
+ def shift(*args, **kwargs)
80
+ args_expr = args.map { ensure_syntax(_1) }
81
+ Kumi::Syntax::CallExpression.new(:roll, args_expr, kwargs, loc: @context.current_location)
56
82
  end
57
83
 
58
- def method_missing(method_name, *args, &block)
84
+ def method_missing(method_name, *args, &)
59
85
  if args.empty? && !block_given?
60
86
  update_location
61
87
  # Create proxy for declaration references (traits/values)
@@ -154,15 +180,15 @@ module Kumi
154
180
  raise_syntax_error("expects a symbol for an operator, got #{operator.class}", location: @context.current_location)
155
181
  end
156
182
 
157
- return if Kumi::Registry.operator?(operator)
183
+ return if Sugar::COMPARISON_OPS.include?(operator)
158
184
 
159
185
  raise_syntax_error("unsupported operator `#{operator}`", location: @context.current_location)
160
186
  end
161
187
 
162
- def build_cascade(&blk)
188
+ def build_cascade(&)
163
189
  expression_converter = ExpressionConverter.new(@context)
164
190
  cascade_builder = DslCascadeBuilder.new(expression_converter, @context.current_location)
165
- cascade_builder.instance_eval(&blk)
191
+ cascade_builder.instance_eval(&)
166
192
  Kumi::Syntax::CascadeExpression.new(cascade_builder.cases, loc: @context.current_location)
167
193
  end
168
194
 
@@ -147,6 +147,70 @@ module Kumi
147
147
  end
148
148
  end
149
149
 
150
+ module HashRefinement
151
+ refine Hash do
152
+ # --- helpers ------------------------------------------------------
153
+ def any_syntax_expressions_in_hash?
154
+ any? { |k, v| Sugar.syntax_expression?(k) || Sugar.syntax_expression?(v) }
155
+ end
156
+
157
+ def to_syntax_hash
158
+ pairs = map { |k, v| Kumi::Syntax::Pair.new(Sugar.ensure_literal(k), Sugar.ensure_literal(v)) }
159
+ Kumi::Syntax::HashExpression.new(pairs)
160
+ end
161
+
162
+ # --- readers: no-arg methods -------------------------------------
163
+ %i[keys values size length empty?].each do |method_name|
164
+ define_method(method_name) do
165
+ if any_syntax_expressions_in_hash?
166
+ Sugar.create_call_expression(method_name, [to_syntax_hash])
167
+ else
168
+ super()
169
+ end
170
+ end
171
+ end
172
+
173
+ # --- membership ---------------------------------------------------
174
+ def include?(key)
175
+ if any_syntax_expressions_in_hash? || Sugar.syntax_expression?(key)
176
+ Sugar.create_call_expression(:has_key?, [to_syntax_hash, Sugar.ensure_literal(key)])
177
+ else
178
+ super
179
+ end
180
+ end
181
+ alias_method :key?, :include?
182
+ alias_method :has_key?, :include?
183
+
184
+ # --- element access -----------------------------------------------
185
+ def [](key)
186
+ if any_syntax_expressions_in_hash? || Sugar.syntax_expression?(key)
187
+ Sugar.create_call_expression(:get, [to_syntax_hash, Sugar.ensure_literal(key)])
188
+ else
189
+ super
190
+ end
191
+ end
192
+
193
+ def fetch(key, default = (missing = true
194
+ nil))
195
+ if any_syntax_expressions_in_hash? || Sugar.syntax_expression?(key) || (!missing && Sugar.syntax_expression?(default))
196
+ args = [to_syntax_hash, Sugar.ensure_literal(key)]
197
+ args << Sugar.ensure_literal(default) unless missing
198
+ Sugar.create_call_expression(:fetch, args)
199
+ else
200
+ missing ? super(key) : super
201
+ end
202
+ end
203
+
204
+ def dig(*path)
205
+ if any_syntax_expressions_in_hash? || path.any? { |k| Sugar.syntax_expression?(k) }
206
+ Sugar.create_call_expression(:dig, [to_syntax_hash, *path.map { |k| Sugar.ensure_literal(k) }])
207
+ else
208
+ super
209
+ end
210
+ end
211
+ end
212
+ end
213
+
150
214
  module ArrayRefinement
151
215
  refine Array do
152
216
  # Helper method to check if array contains any syntax expressions
@@ -8,14 +8,14 @@ module Kumi
8
8
  def self.array(elem_type)
9
9
  raise ArgumentError, "Invalid array element type: #{elem_type}" unless Validator.valid_type?(elem_type)
10
10
 
11
- { array: elem_type }
11
+ "array<#{elem_type}>"
12
12
  end
13
13
 
14
14
  def self.hash(key_type, val_type)
15
15
  raise ArgumentError, "Invalid hash key type: #{key_type}" unless Validator.valid_type?(key_type)
16
16
  raise ArgumentError, "Invalid hash value type: #{val_type}" unless Validator.valid_type?(val_type)
17
17
 
18
- { hash: [key_type, val_type] }
18
+ :hash
19
19
  end
20
20
  end
21
21
  end
@@ -26,9 +26,11 @@ module Kumi
26
26
  when Class
27
27
  # Handle Ruby class inputs
28
28
  case type_input.name
29
+ when "NilClass" then :null
29
30
  when "Integer" then :integer
30
31
  when "String" then :string
31
32
  when "Float" then :float
33
+ when "Symbol" then :symbol
32
34
  when "TrueClass", "FalseClass" then :boolean
33
35
  when "Array" then raise ArgumentError, "Use array(:type) helper for array types"
34
36
  when "Hash" then raise ArgumentError, "Use hash(:key_type, :value_type) helper for hash types"
@@ -5,10 +5,11 @@ module Kumi
5
5
  module Types
6
6
  # Validates type definitions and structures
7
7
  class Validator
8
- VALID_TYPES = %i[string integer float boolean any symbol regexp time date datetime array hash].freeze
8
+ VALID_TYPES = %i[string integer float boolean any symbol regexp time date datetime array hash null].freeze
9
9
 
10
10
  def self.valid_type?(type)
11
- return true if VALID_TYPES.include?(type)
11
+ return true if !type.is_a?(Hash) && VALID_TYPES.include?(type.to_s.to_sym)
12
+
12
13
  return true if array_type?(type)
13
14
  return true if hash_type?(type)
14
15
 
@@ -16,7 +17,13 @@ module Kumi
16
17
  end
17
18
 
18
19
  def self.array_type?(type)
19
- type.is_a?(Hash) && type.keys == [:array] && valid_type?(type[:array])
20
+ return true if type.is_a?(Hash) && type.keys == [:array] && valid_type?(type[:array])
21
+
22
+ type = type.to_s
23
+ type.is_a?(String) && type.match?(/^array<(.+)>$/) && type.scan(/(\w+)/)[1..-1].flatten.all? { |t| valid_type?(t) }
24
+ end
25
+
26
+ def item_types(type)
20
27
  end
21
28
 
22
29
  def self.hash_type?(type)
@@ -6,6 +6,13 @@ module Kumi
6
6
  # Re-export constants for compatibility
7
7
  VALID_TYPES = Validator::VALID_TYPES
8
8
 
9
+ def self.collection?(dtype)
10
+ tuple?(dtype) || array?(dtype)
11
+ end
12
+
13
+ def self.tuple?(dtype) = dtype == :tuple || dtype.match?(/^tuple</)
14
+ def self.array?(dtype) = dtype == :array || dtype.match?(/^array</)
15
+
9
16
  # Validation methods
10
17
  def self.valid_type?(type)
11
18
  Validator.valid_type?(type)