kumi 0.0.17 → 0.0.19

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 +28 -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 +47 -5
  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,64 @@
1
+ # lib/kumi/core/lir/analyze.rb
2
+ # Single-pass context builder. Derives loop tables and per-register lineage.
3
+ module Kumi
4
+ module Core
5
+ module LIR
6
+ module Analyze
7
+ module_function
8
+
9
+ # Returns:
10
+ # - loop_table: { loop_id => { id:, axis:, input:, start:, end: } }
11
+ # - active_axes: Array<Array<Symbol>> per instruction index
12
+ # - active_ids: Array<Array<Symbol>> per instruction index
13
+ # - definition_table: { reg => index }
14
+ # - use_table: { reg => [indices...] }
15
+ # - register_axes: { reg => [:axis...] } lineage at def site
16
+ # - register_ids: { reg => [:L1,:L2,...] } loop ids at def site
17
+ def context(instructions, ids: nil)
18
+ frames = []
19
+ loop_table = {}
20
+ active_axes = Array.new(instructions.length) { [] }
21
+ active_ids = Array.new(instructions.length) { [] }
22
+ definition_table = {}
23
+ use_table = Hash.new { |h, k| h[k] = [] }
24
+
25
+ instructions.each_with_index do |instruction, idx|
26
+ definition_table[instruction.result_register] = idx if instruction.result_register
27
+ instruction.inputs&.each { |r| use_table[r] << idx }
28
+
29
+ case instruction.opcode
30
+ when :LoopStart
31
+ id = (instruction.attributes[:id] ||= (ids || Ids.new).generate_loop_id)
32
+ frames << { id:, axis: instruction.attributes[:axis], input: instruction.inputs&.first, start: idx }
33
+ when :LoopEnd
34
+ frame = frames.pop or raise Error, "LoopEnd without frame at #{idx}"
35
+ loop_table[frame[:id]] = frame.merge(end: idx)
36
+ end
37
+
38
+ active_axes[idx] = frames.map { _1[:axis] }
39
+ active_ids[idx] = frames.map { _1[:id] }
40
+ end
41
+
42
+ raise Error, "unclosed loops" unless frames.empty?
43
+
44
+ register_axes = {}
45
+ register_ids = {}
46
+ definition_table.each do |reg, def_idx|
47
+ register_axes[reg] = active_axes[def_idx]
48
+ register_ids[reg] = active_ids[def_idx]
49
+ end
50
+
51
+ {
52
+ loop_table:,
53
+ active_axes:,
54
+ active_ids:,
55
+ definition_table:,
56
+ use_table:,
57
+ register_axes:,
58
+ register_ids:
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,363 @@
1
+ # lib/kumi/core/lir/build.rb
2
+ # Builders for each opcode. Keep params clear. Carry optional location.
3
+ module Kumi
4
+ module Core
5
+ module LIR
6
+ module Build
7
+ module_function
8
+
9
+ # Constant
10
+ # Params:
11
+ # value: literal value
12
+ # dtype: dtype of the literal
13
+ # as: result register symbol/name
14
+ # location: optional Location
15
+ # Result: produces(result_register, stamp(dtype))
16
+ def constant(value:, dtype:, as: nil, ids: nil, location: nil)
17
+ as ||= ids.generate_temp
18
+ Instruction.new(
19
+ opcode: :Constant,
20
+ result_register: as,
21
+ stamp: Stamp.new(dtype: dtype),
22
+ inputs: [],
23
+ immediates: [Literal.new(value: value, dtype: dtype)],
24
+ attributes: {},
25
+ location:
26
+ )
27
+ end
28
+
29
+ # LoadInput
30
+ # Params:
31
+ # key: String|Symbol top-level input key
32
+ # dtype: dtype of the loaded field
33
+ # as: result register
34
+ # location: optional Location
35
+ # Result: produces
36
+ def load_input(key:, dtype:, as: nil, ids: nil, location: nil)
37
+ as ||= ids.generate_temp
38
+ Instruction.new(
39
+ opcode: :LoadInput,
40
+ result_register: as,
41
+ stamp: Stamp.new(dtype: dtype),
42
+ inputs: [],
43
+ immediates: [Literal.new(value: key.to_s, dtype: :string)],
44
+ attributes: {},
45
+ location:
46
+ )
47
+ end
48
+
49
+ # LoadDeclaration
50
+ # Params:
51
+ # name: declaration name
52
+ # dtype: dtype of referenced declaration result
53
+ # axes: axes of referenced declaration
54
+ # as: result register
55
+ # location: optional Location
56
+ # Result: produces
57
+ def load_declaration(name:, dtype:, axes:, as: nil, ids: nil, location: nil)
58
+ as ||= ids.generate_temp
59
+ Instruction.new(
60
+ opcode: :LoadDeclaration,
61
+ result_register: as,
62
+ stamp: Stamp.new(dtype: dtype),
63
+ inputs: [],
64
+ immediates: [Literal.new(value: name.to_s, dtype: :string)],
65
+ attributes: { axes: Array(axes).map!(&:to_sym) },
66
+ location:
67
+ )
68
+ end
69
+
70
+ # LoadField
71
+ # Params:
72
+ # object_register: register holding a Hash-like object
73
+ # key: field key to access
74
+ # dtype: dtype of the field
75
+ # as: result register
76
+ # location: optional Location
77
+ # Result: produces
78
+ def load_field(object_register:, key:, dtype:, as: nil, ids: nil, location: nil)
79
+ as ||= ids.generate_temp
80
+ Instruction.new(
81
+ opcode: :LoadField,
82
+ result_register: as,
83
+ stamp: Stamp.new(dtype: dtype),
84
+ inputs: [object_register],
85
+ immediates: [Literal.new(value: key.to_s, dtype: :string)],
86
+ attributes: {},
87
+ location:
88
+ )
89
+ end
90
+
91
+ # LoopStart
92
+ # Params:
93
+ # collection_register: register holding the array to iterate
94
+ # axis: Symbol axis name
95
+ # as_element: register name for the element within loop body
96
+ # as_index: register name for the numeric index
97
+ # id: optional loop id; generated if nil
98
+ # location: optional Location
99
+ # Result: does not produce
100
+ def loop_start(collection_register:, axis:, as_element:, as_index:, id: nil, ids: nil, location: nil)
101
+ Instruction.new(
102
+ opcode: :LoopStart,
103
+ result_register: nil,
104
+ stamp: nil,
105
+ inputs: [collection_register],
106
+ immediates: [],
107
+ attributes: { axis: axis.to_sym, as_element:, as_index:, id: id || ids.generate_loop_id },
108
+ location:
109
+ )
110
+ end
111
+
112
+ # LoopEnd
113
+ # Params:
114
+ # location: optional Location
115
+ # Result: does not produce
116
+ def loop_end(location: nil)
117
+ Instruction.new(
118
+ opcode: :LoopEnd,
119
+ result_register: nil,
120
+ stamp: nil,
121
+ inputs: [],
122
+ immediates: [],
123
+ attributes: {},
124
+ location:
125
+ )
126
+ end
127
+
128
+ # KernelCall
129
+ # Params:
130
+ # function: String function id (e.g., "core.mul")
131
+ # args: Array of register names
132
+ # out_dtype: dtype of the result
133
+ # as: result register
134
+ # location: optional Location
135
+ # Result: produces
136
+ def kernel_call(function:, args:, out_dtype:, as: nil, ids: nil, location: nil)
137
+ as ||= ids.generate_temp
138
+ Instruction.new(
139
+ opcode: :KernelCall,
140
+ result_register: as,
141
+ stamp: Stamp.new(dtype: out_dtype),
142
+ inputs: args,
143
+ immediates: [],
144
+ attributes: { fn: function.to_s },
145
+ location:
146
+ )
147
+ end
148
+
149
+ # Fold
150
+ # Params:
151
+ # function: String function id (e.g., "core.mul")
152
+ # arg: Collection being folded register
153
+ # out_dtype: dtype of the result
154
+ # as: result register
155
+ # location: optional Location
156
+ # Result: produces
157
+ def fold(function:, arg:, out_dtype:, as: nil, ids: nil, location: nil)
158
+ as ||= ids.generate_temp
159
+ Instruction.new(
160
+ opcode: :Fold,
161
+ result_register: as,
162
+ stamp: Stamp.new(dtype: out_dtype),
163
+ inputs: Array(arg),
164
+ immediates: [],
165
+ attributes: { fn: function.to_s },
166
+ location:
167
+ )
168
+ end
169
+
170
+ # Select
171
+ # Params:
172
+ # cond: register name (boolean)
173
+ # on_true: register name
174
+ # on_false: register name
175
+ # out_dtype: dtype of the result
176
+ # as: result register
177
+ # location: optional Location
178
+ # Result: produces
179
+ def select(cond:, on_true:, on_false:, out_dtype:, as: nil, ids: nil, location: nil)
180
+ as ||= ids.generate_temp
181
+ Instruction.new(
182
+ opcode: :Select,
183
+ result_register: as,
184
+ stamp: Stamp.new(dtype: out_dtype),
185
+ inputs: [cond, on_true, on_false],
186
+ immediates: [],
187
+ attributes: {},
188
+ location:
189
+ )
190
+ end
191
+
192
+ # DeclareAccumulator
193
+ # Params:
194
+ # name: Symbol accumulator name
195
+ # initial: Literal identity value
196
+ # location: optional Location
197
+ # Result: does not produce
198
+ def declare_accumulator(dtype:, location: nil, ids: nil, name: nil)
199
+ name ||= ids.generate_acc
200
+ Instruction.new(
201
+ opcode: :DeclareAccumulator,
202
+ result_register: name.to_sym,
203
+ stamp: Stamp.new(dtype: dtype),
204
+ inputs: [],
205
+ immediates: [],
206
+ attributes: {},
207
+ location:
208
+ )
209
+ end
210
+
211
+ # Accumulate
212
+ # Params:
213
+ # accumulator: Symbol accumulator name
214
+ # function: String function id (e.g., "core.add")
215
+ # value_register: register providing the value to accumulate
216
+ # location: optional Location
217
+ # Result: does not produce
218
+ def accumulate(accumulator:, function:, value_register:, dtype:, location: nil)
219
+ Instruction.new(
220
+ opcode: :Accumulate,
221
+ result_register: accumulator.to_sym,
222
+ stamp: Stamp.new(dtype: dtype),
223
+ inputs: [value_register],
224
+ immediates: [],
225
+ attributes: { fn: function.to_s },
226
+ location:
227
+ )
228
+ end
229
+
230
+ # LoadAccumulator
231
+ # Params:
232
+ # name: Symbol accumulator name
233
+ # dtype: dtype of the accumulator
234
+ # as: result register
235
+ # location: optional Location
236
+ # Result: produces
237
+ def load_accumulator(accumulator:, dtype:, ids:, location: nil)
238
+ as = ids.generate_temp
239
+ Instruction.new(
240
+ opcode: :LoadAccumulator,
241
+ result_register: as,
242
+ stamp: Stamp.new(dtype: dtype),
243
+ inputs: [accumulator.to_sym],
244
+ immediates: [],
245
+ attributes: {},
246
+ location:
247
+ )
248
+ end
249
+
250
+ # MakeTuple
251
+ # Params:
252
+ # elements: Array of registers
253
+ # out_dtype: tuple dtype
254
+ # as: result register
255
+ # Result: produces tuple
256
+ def make_tuple(elements:, out_dtype:, as: nil, ids: nil, location: nil)
257
+ as ||= ids.generate_temp
258
+ Instruction.new(
259
+ opcode: :MakeTuple,
260
+ result_register: as,
261
+ stamp: Stamp.new(dtype: out_dtype),
262
+ inputs: elements,
263
+ immediates: [],
264
+ attributes: {},
265
+ location:
266
+ )
267
+ end
268
+
269
+ # MakeObject
270
+ # Params:
271
+ # keys: Array<String|Symbol> in the same order as values
272
+ # values: Array of registers
273
+ # out_dtype: object dtype (or :object)
274
+ # as: result
275
+ def make_object(keys:, values:, as: nil, ids: nil, location: nil)
276
+ as ||= ids.generate_temp
277
+ Instruction.new(
278
+ opcode: :MakeObject,
279
+ result_register: as,
280
+ stamp: Stamp.new(dtype: :object),
281
+ inputs: values,
282
+ immediates: keys.map { |k| Literal.new(value: k.to_s, dtype: :string) },
283
+ attributes: {},
284
+ location: location
285
+ )
286
+ end
287
+
288
+ # TupleGet (optional)
289
+ # Params:
290
+ # tuple: register
291
+ # index: Integer
292
+ # out_dtype: element dtype
293
+ # as: result
294
+ def tuple_get(tuple:, index:, out_dtype:, as: nil, ids: nil, location: nil)
295
+ as ||= ids.generate_temp
296
+ Instruction.new(
297
+ opcode: :TupleGet,
298
+ result_register: as,
299
+ stamp: Stamp.new(dtype: out_dtype),
300
+ inputs: [tuple],
301
+ immediates: [Literal.new(value: Integer(index), dtype: :integer)],
302
+ attributes: {},
303
+ location:
304
+ )
305
+ end
306
+
307
+ def length(collection_register:, as: nil, ids: nil, location: nil)
308
+ as ||= ids.generate_temp
309
+ Instruction.new(
310
+ opcode: :Length,
311
+ result_register: as,
312
+ stamp: Stamp.new(dtype: :integer),
313
+ inputs: [collection_register],
314
+ immediates: [],
315
+ attributes: {},
316
+ location:
317
+ )
318
+ end
319
+
320
+ def gather(collection_register:, index_register:, dtype:, as: nil, ids: nil, location: nil)
321
+ as ||= ids.generate_temp
322
+ Instruction.new(
323
+ opcode: :Gather,
324
+ result_register: as,
325
+ stamp: Stamp.new(dtype: dtype),
326
+ inputs: [collection_register, index_register],
327
+ immediates: [],
328
+ attributes: {},
329
+ location:
330
+ )
331
+ end
332
+
333
+ # Yield
334
+ # Opcode: Yield
335
+ # Semantics:
336
+ # - Exactly one per declaration.
337
+ # - Must be the last instruction in the declaration.
338
+ # - The declaration's result axes are Γ, the active loop stack at the Yield site
339
+ # (i.e., the sequence of surrounding LoopStart frames).
340
+ # - The yielded register's stamp.dtype is the declaration's result dtype.
341
+ # Codegen rule:
342
+ # - If Γ == [], return the yielded scalar.
343
+ # - If Γ != [], materialize a container shaped by Γ and write the yielded value
344
+ # at each iteration of the surrounding loops.
345
+ # Params:
346
+ # result_register: register that holds the final value
347
+ # location: optional Location
348
+ # Result: does not produce
349
+ def yield(result_register:, location: nil)
350
+ Instruction.new(
351
+ opcode: :Yield,
352
+ result_register: nil,
353
+ stamp: nil,
354
+ inputs: [result_register],
355
+ immediates: [],
356
+ attributes: {},
357
+ location:
358
+ )
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end
@@ -0,0 +1,62 @@
1
+ module Kumi
2
+ module Core
3
+ module LIR
4
+ class Emit
5
+ def initialize(registry:, ids:, ops:)
6
+ (@registry = registry
7
+ @ids = ids
8
+ @ops = ops)
9
+ end
10
+
11
+ def iconst(v) = push(Build.constant(value: Integer(v), dtype: :integer, ids: @ids))
12
+
13
+ # Kernel bridge with explicit function ids
14
+ def k_id(fn_id, args, out:)
15
+ ins = Build.kernel_call(function: @registry.resolve_function(fn_id),
16
+ args:, out_dtype: out, ids: @ids)
17
+ push(ins)
18
+ end
19
+
20
+ # Integer arithmetic via canonical ids
21
+ def add_i(a, b) = k_id("core.add", [a, b], out: :integer)
22
+ def sub_i(a, b) = k_id("core.sub", [a, b], out: :integer)
23
+ def mod_i(a, b) = k_id("core.mod", [a, b], out: :integer)
24
+ def lt(a, b) = k_id("core.lt", [a, b], out: :boolean)
25
+ def gt(a, b) = k_id("core.gt", [a, b], out: :boolean)
26
+ def le(a, b) = k_id("core.lte", [a, b], out: :boolean)
27
+ def ge(a, b) = k_id("core.gte", [a, b], out: :boolean)
28
+ def and_(a, b) = k_id("core.and", [a, b], out: :boolean)
29
+
30
+ # Clamp via canonical id
31
+ def clamp(x, lo, hi, out:) = k_id("core.clamp", [x, lo, hi], out:)
32
+
33
+ def length(coll) = push(Build.length(collection_register: coll, ids: @ids))
34
+ def gather(arr, i, dt) = push(Build.gather(collection_register: arr, index_register: i, dtype: dt, ids: @ids))
35
+ def select(c, t, f, dt) = push(Build.select(cond: c, on_true: t, on_false: f, out_dtype: dt, ids: @ids))
36
+
37
+ def const(value, dtype)
38
+ push(Build.constant(value: value, dtype: dtype, ids: @ids))
39
+ end
40
+
41
+ def wrap_index(i, off, nlen)
42
+ i_plus = add_i(i, iconst(off))
43
+ m1 = mod_i(i_plus, nlen)
44
+ p2 = add_i(m1, nlen)
45
+ mod_i(p2, nlen)
46
+ end
47
+
48
+ def clamp_index(j, nlen)
49
+ hi = add_i(nlen, iconst(-1))
50
+ clamp(j, iconst(0), hi, out: :integer)
51
+ end
52
+
53
+ private
54
+
55
+ def push(ins)
56
+ (@ops << ins
57
+ ins.result_register)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,44 @@
1
+ # lib/kumi/core/lir/structs/instruction.rb
2
+ # Fields:
3
+ # - opcode, result_register, stamp, inputs, immediates, attributes, location
4
+ module Kumi
5
+ module Core
6
+ module LIR
7
+ module Structs
8
+ Instruction = Struct.new(
9
+ :opcode, :result_register, :stamp, :inputs, :immediates, :attributes, :location,
10
+ keyword_init: true
11
+ ) do
12
+ SIDE_EFFECT_OPCODES = Set.new(%i[
13
+ LoopStart
14
+ LoopEnd
15
+ DeclareAccumulator
16
+ Accumulate LoadAccumulator
17
+ Yield
18
+ ]).freeze
19
+
20
+ def produces? = !result_register.nil?
21
+
22
+ def side_effect?
23
+ SIDE_EFFECT_OPCODES.include?(opcode)
24
+ end
25
+
26
+ def pure?
27
+ !side_effect?
28
+ end
29
+
30
+ def to_h
31
+ h = { op: opcode }
32
+ h[:result] = result_register if result_register
33
+ h[:stamp] = stamp.to_h if stamp
34
+ h[:inputs] = inputs unless inputs.nil? || inputs.empty?
35
+ h[:immediates] = immediates&.map { |x| x.respond_to?(:to_h) ? x.to_h : x } unless immediates.nil? || immediates.empty?
36
+ h[:attrs] = attributes unless attributes.nil? || attributes.empty?
37
+ h[:loc] = { file: location.file, line: location.line, column: location.column } if location
38
+ h
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,14 @@
1
+ # lib/kumi/core/lir/structs/literal.rb
2
+ module Kumi
3
+ module Core
4
+ module LIR
5
+ module Structs
6
+ Literal = Struct.new(:value, :dtype, keyword_init: true) do
7
+ # include Typed
8
+ def value? = true
9
+ def to_h = { value: value, dtype: dtype }
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ # lib/kumi/core/lir/structs/stamp.rb
2
+ module Kumi
3
+ module Core
4
+ module LIR
5
+ module Structs
6
+ Stamp = Struct.new(:dtype, keyword_init: true) do
7
+ # include Typed # enable if you add typed.rb
8
+ def to_h = { dtype: dtype }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ module Kumi
2
+ module Core
3
+ module LIR
4
+ module Support
5
+ class Error < StandardError; end
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ # lib/kumi/core/lir/ids.rb
2
+ # Ids generates deterministic temp and loop ids. Each compilation context gets its own instance.
3
+ module Kumi
4
+ module Core
5
+ module LIR
6
+ module Support
7
+ class Ids
8
+ def initialize
9
+ reset!
10
+ end
11
+
12
+ def reset!
13
+ @t = 0
14
+ @l = 0
15
+ end
16
+
17
+ def generate_temp(prefix: :t)
18
+ @t += 1
19
+ :"#{prefix}#{@t}"
20
+ end
21
+
22
+ def generate_acc
23
+ generate_temp(prefix: :acc)
24
+ end
25
+
26
+ def generate_loop_id
27
+ @l += 1
28
+ :"L#{@l}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,74 @@
1
+ # lib/kumi/core/lir/validate.rb
2
+ # Per-declaration and program-level structural checks.
3
+ module Kumi
4
+ module Core
5
+ module LIR
6
+ module Validate
7
+ module_function
8
+
9
+ # Validate one declaration's instruction list
10
+ def declaration!(instructions)
11
+ ensure_opcodes!(instructions)
12
+
13
+ defs = {}
14
+ depth = 0
15
+ yield_seen = false
16
+
17
+ instructions.each_with_index do |ins, i|
18
+ # producer stamps
19
+ if ins.result_register
20
+ raise Error, "missing stamp at #{i}" unless ins.stamp.is_a?(Stamp)
21
+
22
+ r = ins.result_register
23
+ raise Error, "redefinition of #{r} at #{i}" if defs.key?(r)
24
+
25
+ defs[r] = i
26
+ end
27
+
28
+ case ins.opcode
29
+ when :LoopStart
30
+ attrs = ins.attributes || {}
31
+ raise Error, "LoopStart missing :axis at #{i}" unless attrs[:axis]
32
+
33
+ depth += 1
34
+ when :LoopEnd
35
+ raise Error, "LoopEnd without LoopStart at #{i}" if depth.zero?
36
+
37
+ depth -= 1
38
+ when :LoadDeclaration
39
+ raise Error, "LoadDeclaration missing :axes at #{i}" unless Array(ins.attributes[:axes]).is_a?(Array)
40
+ raise Error, "LoadDeclaration missing stamp at #{i}" unless ins.stamp.is_a?(Stamp)
41
+ when :Yield
42
+ raise Error, "multiple Yield (at #{i})" if yield_seen
43
+
44
+ yield_seen = true
45
+ raise Error, "instructions after Yield (at #{i})" unless i == instructions.length - 1
46
+ end
47
+ end
48
+
49
+ raise Error, "unclosed loops" unless depth.zero?
50
+ raise Error, "missing Yield" unless yield_seen
51
+
52
+ true
53
+ end
54
+
55
+ # Validate whole program: { name => { operations: [...] } }
56
+ def program!(ops_by_decl)
57
+ ops_by_decl.each do |_name, h|
58
+ declaration!(Array(h[:operations]))
59
+ end
60
+ true
61
+ end
62
+
63
+ def ensure_opcodes!(instructions)
64
+ instructions.each_with_index do |ins, i|
65
+ next if OPCODES.include?(ins.opcode)
66
+
67
+ raise Error, "unknown opcode #{ins.opcode.inspect} at #{i}"
68
+ end
69
+ end
70
+ private_class_method :ensure_opcodes!
71
+ end
72
+ end
73
+ end
74
+ end