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,163 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Dev
5
+ module Printer
6
+ class IRV2Formatter
7
+ def initialize(irv2_data)
8
+ @irv2 = irv2_data
9
+ end
10
+
11
+ def format
12
+ output = []
13
+
14
+ output += format_header
15
+ output << ""
16
+ output += format_declarations
17
+ output += format_analysis_details
18
+
19
+ output.join("\n")
20
+ end
21
+
22
+ private
23
+
24
+ def format_header
25
+ output = []
26
+ output << "Schema: #{@irv2['$schema']}" if @irv2["$schema"]
27
+ output << "Version: #{@irv2['version']}" if @irv2["version"]
28
+ output << "Module: #{@irv2['module']}"
29
+ output << "Declarations: #{@irv2['declarations'].keys.join(', ')}"
30
+ output << "Inputs: #{@irv2['analysis']['inputs'].size}"
31
+ output
32
+ end
33
+
34
+ def format_declarations
35
+ output = []
36
+ @irv2["declarations"].each do |name, decl|
37
+ output += format_declaration(name, decl)
38
+ output << ""
39
+ end
40
+ output
41
+ end
42
+
43
+ def format_declaration(name, decl)
44
+ output = []
45
+ output << "## #{name}"
46
+
47
+ # Format parameters
48
+ params = decl["parameters"].map do |param|
49
+ case param["type"]
50
+ when "input"
51
+ "#{param['name']}: #{param['path'].join('.')} (#{param['dtype']})"
52
+ else
53
+ "#{param['name']}: #{param['type']}"
54
+ end
55
+ end
56
+ output << " Parameters: #{params.join(', ')}"
57
+
58
+ # Format operations
59
+ output << " Operations:"
60
+ decl["operations"].each_with_index do |op, idx|
61
+ output << " #{format_operation(idx, op)}"
62
+ end
63
+
64
+ output << " Result: %#{decl['result']}"
65
+ output
66
+ end
67
+
68
+ def format_operation(idx, op)
69
+ base_op = case op["op"]
70
+ when "LoadInput"
71
+ "LoadInput(#{op['args'].first.join('.')})"
72
+ when "Const"
73
+ "Const(#{op['args'].first})"
74
+ when "Map"
75
+ op_name = op.dig("attrs", "op") || "unknown"
76
+ args_str = format_operation_args(op["args"])
77
+ "Map(#{op_name}) <- #{args_str}"
78
+ when "ConstructTuple"
79
+ args_str = format_operation_args(op["args"])
80
+ "ConstructTuple(#{args_str})"
81
+ else
82
+ args_str = format_operation_args(op["args"])
83
+ "#{op['op']}(#{args_str})"
84
+ end
85
+
86
+ # Add attributes if present and not just 'op'
87
+ attrs = op["attrs"] || {}
88
+ extra_attrs = attrs.reject { |k, _| ["op", :op].include?(k) }
89
+ attr_str = extra_attrs.empty? ? "" : " [#{extra_attrs.map { |k, v| "#{k}: #{v}" }.join(', ')}]"
90
+
91
+ "%#{idx} = #{base_op}#{attr_str}"
92
+ end
93
+
94
+ def format_operation_args(args)
95
+ return "" unless args
96
+
97
+ args.map do |arg|
98
+ if arg.respond_to?(:id) && arg.respond_to?(:op)
99
+ "%#{arg.id}"
100
+ elsif arg.is_a?(Array)
101
+ arg.join(".")
102
+ else
103
+ arg.to_s
104
+ end
105
+ end.join(", ")
106
+ end
107
+
108
+ def format_analysis_details
109
+ output = []
110
+ output << ""
111
+ output << "## Analysis"
112
+
113
+ defaults = @irv2["analysis"]["defaults"]
114
+ if defaults
115
+ output << " Defaults:"
116
+ defaults.each { |k, v| output << " #{k}: #{v}" }
117
+ end
118
+
119
+ # Add input plans within analysis section
120
+ output << ""
121
+ output << " Input Plans:"
122
+ @irv2["analysis"]["inputs"].each do |input|
123
+ path_str = input["path"].join(".")
124
+ axes_info = input["axes"].empty? ? "(scalar)" : "(axes: #{input['axes'].join(', ')})"
125
+
126
+ output << " #{path_str}: #{input['dtype']} #{axes_info}"
127
+
128
+ # Add policy information if different from defaults
129
+ output << " key_policy: #{input['key_policy']}" if input["key_policy"] != defaults["key_policy"]
130
+ output << " on_missing: #{input['on_missing']}" if input["on_missing"] != defaults["on_missing"]
131
+
132
+ # Add access chain details
133
+ if input["chain"] && !input["chain"].empty?
134
+ chain_str = input["chain"].map { |link| format_chain_link(link) }.join(" -> ")
135
+ output << " chain: #{chain_str}"
136
+ end
137
+ end
138
+
139
+ output
140
+ end
141
+
142
+ def format_chain_link(link)
143
+ case link["kind"]
144
+ when "scalar_leaf"
145
+ "scalar(#{link['key']})"
146
+ when "array_element"
147
+ alias_info = link["alias"] ? ":#{link['alias']}" : ""
148
+ axis_info = link["axis"] ? "@#{link['axis']}" : ""
149
+ "element(#{link['key'] || 'item'}#{alias_info}#{axis_info})"
150
+ when "array_field"
151
+ axis_info = link["axis"] ? "@#{link['axis']}" : ""
152
+ "array_field(#{link['key']}#{axis_info})"
153
+ when "hash_value"
154
+ "hash[#{link['key']}]"
155
+ else
156
+ key_info = link["key"] ? "(#{link['key']})" : ""
157
+ "#{link['kind']}#{key_info}"
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,44 @@
1
+ require "json"
2
+
3
+ module Kumi
4
+ module Dev
5
+ module Printer
6
+ module WidthAwareJson
7
+ module_function
8
+
9
+ def dump(obj, max: 120, indent: 0)
10
+ # First try a compact one-liner
11
+ one = JSON.generate(obj)
12
+ return one if one.size <= max
13
+
14
+ case obj
15
+ when Array
16
+ items = obj.map { |v| dump(v, max: max, indent: indent + 2) }
17
+ join_multiline("[", items, "]", indent)
18
+ when Hash
19
+ items = obj.map do |k, v|
20
+ key = JSON.generate(k)
21
+ val = dump(v, max: max, indent: indent + 2)
22
+ "#{key}: #{val}"
23
+ end
24
+ join_multiline("{", items, "}", indent)
25
+ else
26
+ one # scalars just return compact
27
+ end
28
+ end
29
+
30
+ def join_multiline(open, items, close, indent)
31
+ pad = " " * (indent + 2)
32
+ [
33
+ open,
34
+ pad + items.join(",\n" + pad),
35
+ (" " * indent) + close
36
+ ].join("\n")
37
+ end
38
+ end
39
+
40
+ # Usage:
41
+ # puts WidthAwareJSON.dump(ir_hash, max: 140)
42
+ end
43
+ end
44
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
3
+ require "json"
4
4
 
5
5
  module Kumi
6
6
  module Dev
@@ -167,18 +167,18 @@ module Kumi
167
167
  puts "Total events: #{events.length}"
168
168
  puts "VM operations: #{total_ops}"
169
169
  puts "VM executions: #{vm_execution_count}"
170
-
170
+
171
171
  # Schema differentiation
172
172
  schema_stats = schema_breakdown
173
173
  if schema_stats.any? && schema_stats.keys.first != "Unknown"
174
- puts "Schemas analyzed: #{schema_stats.keys.join(", ")}"
174
+ puts "Schemas analyzed: #{schema_stats.keys.join(', ')}"
175
175
  schema_stats.each do |schema, stats|
176
176
  puts " #{schema}: #{stats[:operations]} operations, #{stats[:time]}ms"
177
177
  end
178
178
  else
179
179
  puts "Schema runs: #{runs_analyzed.length} (runs: #{runs_analyzed.join(', ')})"
180
180
  end
181
-
181
+
182
182
  puts "Total VM time: #{total_vm_time.round(4)}ms"
183
183
  puts "Average per VM execution: #{vm_execution_count > 0 ? (total_vm_time / vm_execution_count).round(4) : 0}ms"
184
184
  puts
@@ -191,13 +191,13 @@ module Kumi
191
191
  end
192
192
 
193
193
  mem = memory_analysis
194
- if mem
195
- puts
196
- puts "Memory Growth:"
197
- puts " Heap: +#{mem[:growth][:heap_objects]} objects (#{mem[:growth][:heap_growth_pct]}%)"
198
- puts " RSS: +#{mem[:growth][:rss_mb]}MB (#{mem[:growth][:rss_growth_pct]}%)"
199
- puts " GC: #{mem[:growth][:minor_gcs]} minor, #{mem[:growth][:major_gcs]} major"
200
- end
194
+ return unless mem
195
+
196
+ puts
197
+ puts "Memory Growth:"
198
+ puts " Heap: +#{mem[:growth][:heap_objects]} objects (#{mem[:growth][:heap_growth_pct]}%)"
199
+ puts " RSS: +#{mem[:growth][:rss_mb]}MB (#{mem[:growth][:rss_growth_pct]}%)"
200
+ puts " GC: #{mem[:growth][:minor_gcs]} minor, #{mem[:growth][:major_gcs]} major"
201
201
  end
202
202
 
203
203
  def detailed_report(limit: 15)
@@ -206,7 +206,7 @@ module Kumi
206
206
  puts "=== TOP #{limit} HOTSPOTS ==="
207
207
  hotspots = hotspot_analysis(limit: limit)
208
208
  hotspots.each_with_index do |(key, stats), i|
209
- puts "#{(i+1).to_s.rjust(2)}. #{key.ljust(40)} #{stats[:total_ms].to_s.rjust(10)}ms (#{stats[:count]} calls, #{stats[:avg_ms]}ms avg)"
209
+ puts "#{(i + 1).to_s.rjust(2)}. #{key.ljust(40)} #{stats[:total_ms].to_s.rjust(10)}ms (#{stats[:count]} calls, #{stats[:avg_ms]}ms avg)"
210
210
  end
211
211
 
212
212
  # Schema breakdown if available
@@ -218,7 +218,7 @@ module Kumi
218
218
  puts "#{schema}:"
219
219
  puts " Operations: #{stats[:operations]}"
220
220
  puts " Total time: #{stats[:time]}ms"
221
- puts " Declarations: #{stats[:declarations].join(", ")}"
221
+ puts " Declarations: #{stats[:declarations].join(', ')}"
222
222
  puts
223
223
  end
224
224
  end
@@ -268,34 +268,32 @@ module Kumi
268
268
  return unless File.exist?(@jsonl_file)
269
269
 
270
270
  File.readlines(@jsonl_file).each do |line|
271
- begin
272
- event = JSON.parse(line.strip)
273
- next unless event && event.is_a?(Hash)
274
-
275
- @events << event
276
-
277
- case event["kind"]
278
- when "phase"
279
- @phases << event
280
- when "mem"
281
- @memory_snapshots << event
282
- when "final_summary"
283
- @final_summary = event
284
- else
285
- # VM operations don't have a "kind" field - they have ts, run, decl, i, tag, wall_ms, cpu_ms, etc.
286
- # According to profiler.rb line 118-130, VM operations are identified by having decl + tag but no kind
287
- if event["decl"] && event["tag"] && !event["kind"]
288
- @operations << event
289
- elsif event["kind"] && !["summary", "cache_analysis"].include?(event["kind"])
290
- # Handle any future event types that have a kind but aren't known
291
- @operations << event
292
- end
271
+ event = JSON.parse(line.strip)
272
+ next unless event && event.is_a?(Hash)
273
+
274
+ @events << event
275
+
276
+ case event["kind"]
277
+ when "phase"
278
+ @phases << event
279
+ when "mem"
280
+ @memory_snapshots << event
281
+ when "final_summary"
282
+ @final_summary = event
283
+ else
284
+ # VM operations don't have a "kind" field - they have ts, run, decl, i, tag, wall_ms, cpu_ms, etc.
285
+ # According to profiler.rb line 118-130, VM operations are identified by having decl + tag but no kind
286
+ if event["decl"] && event["tag"] && !event["kind"]
287
+ @operations << event
288
+ elsif event["kind"] && !%w[summary cache_analysis].include?(event["kind"])
289
+ # Handle any future event types that have a kind but aren't known
290
+ @operations << event
293
291
  end
294
- rescue JSON::ParserError
295
- # Skip malformed JSON lines
296
292
  end
293
+ rescue JSON::ParserError
294
+ # Skip malformed JSON lines
297
295
  end
298
296
  end
299
297
  end
300
298
  end
301
- end
299
+ end
@@ -21,7 +21,7 @@ module Kumi
21
21
 
22
22
  puts "Profiling: #{script_path}"
23
23
  puts "Configuration:"
24
- puts " Output: #{ENV['KUMI_PROFILE_FILE']}"
24
+ puts " Output: #{ENV.fetch('KUMI_PROFILE_FILE', nil)}"
25
25
  puts " Phases: enabled"
26
26
  puts " Operations: #{ENV['KUMI_PROFILE_OPS'] == '1' ? 'enabled' : 'disabled'}"
27
27
  puts " Sampling: #{ENV['KUMI_PROFILE_SAMPLE'] || '1'}"
@@ -38,7 +38,7 @@ module Kumi
38
38
  # Execute the script
39
39
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
40
40
  begin
41
- result = Dev::Profiler.phase("script_execution", script: File.basename(script_path)) do
41
+ Dev::Profiler.phase("script_execution", script: File.basename(script_path)) do
42
42
  # Execute in a clean environment to avoid polluting the current process
43
43
  load(File.expand_path(script_path))
44
44
  end
@@ -67,8 +67,6 @@ module Kumi
67
67
  false
68
68
  end
69
69
 
70
- private
71
-
72
70
  def self.setup_profiler_env(opts)
73
71
  # Always enable profiling
74
72
  ENV["KUMI_PROFILE"] = "1"
@@ -84,14 +82,14 @@ module Kumi
84
82
  ENV["KUMI_PROFILE_STREAM"] = opts[:stream] ? "1" : "0"
85
83
 
86
84
  # Operations profiling
87
- if opts[:phases_only]
88
- ENV["KUMI_PROFILE_OPS"] = "0"
89
- elsif opts[:ops]
90
- ENV["KUMI_PROFILE_OPS"] = "1"
91
- else
92
- # Default: phases only
93
- ENV["KUMI_PROFILE_OPS"] = "0"
94
- end
85
+ ENV["KUMI_PROFILE_OPS"] = if opts[:phases_only]
86
+ "0"
87
+ elsif opts[:ops]
88
+ "1"
89
+ else
90
+ # Default: phases only
91
+ "0"
92
+ end
95
93
 
96
94
  # Sampling
97
95
  ENV["KUMI_PROFILE_SAMPLE"] = opts[:sample].to_s if opts[:sample]
@@ -104,7 +102,7 @@ module Kumi
104
102
  end
105
103
 
106
104
  def self.show_analysis(opts)
107
- output_file = ENV["KUMI_PROFILE_FILE"]
105
+ output_file = ENV.fetch("KUMI_PROFILE_FILE", nil)
108
106
 
109
107
  unless File.exist?(output_file)
110
108
  puts "No profile data generated"
@@ -131,31 +129,29 @@ module Kumi
131
129
  else
132
130
  # Show summary + key insights
133
131
  aggregator.summary_report
134
-
132
+
135
133
  # Add some key insights for CLI users
136
134
  puts
137
135
  puts "=== KEY INSIGHTS ==="
138
-
136
+
139
137
  # Show top hotspots
140
138
  hotspots = aggregator.hotspot_analysis(limit: 3)
141
139
  if hotspots.any?
142
140
  puts "Top Performance Bottlenecks:"
143
- hotspots.each_with_index do |(key, stats), i|
144
- puts " #{i+1}. #{stats[:decl]} (#{stats[:tag]}): #{stats[:total_ms]}ms"
141
+ hotspots.each_with_index do |(_key, stats), i|
142
+ puts " #{i + 1}. #{stats[:decl]} (#{stats[:tag]}): #{stats[:total_ms]}ms"
145
143
  end
146
144
  end
147
-
145
+
148
146
  # Reference analysis summary
149
147
  ref_analysis = aggregator.reference_operation_analysis
150
148
  if ref_analysis[:operations] > 0
151
149
  puts "Reference Operation Impact: #{(ref_analysis[:total_time] / aggregator.vm_execution_time * 100).round(1)}% of VM time"
152
150
  end
153
-
151
+
154
152
  # Memory impact
155
153
  mem = aggregator.memory_analysis
156
- if mem
157
- puts "Memory Impact: #{mem[:growth][:heap_growth_pct]}% heap growth, #{mem[:growth][:rss_growth_pct]}% RSS growth"
158
- end
154
+ puts "Memory Impact: #{mem[:growth][:heap_growth_pct]}% heap growth, #{mem[:growth][:rss_growth_pct]}% RSS growth" if mem
159
155
  end
160
156
 
161
157
  puts
@@ -196,4 +192,4 @@ module Kumi
196
192
  end
197
193
  end
198
194
  end
199
- end
195
+ end
@@ -23,19 +23,19 @@ module Kumi
23
23
  Kumi::Analyzer.run_analysis_passes(schema, Kumi::Analyzer::DEFAULT_PASSES, state, errors)
24
24
  end
25
25
  ir = final_state[:ir_module]
26
-
26
+
27
27
  result = Result.new(
28
28
  state: final_state,
29
29
  ir: ir,
30
30
  errors: errors
31
31
  )
32
-
32
+
33
33
  # Report trace file if enabled
34
34
  if opts[:trace] && defined?(@trace_file) && @trace_file
35
35
  trace_file_path = @trace_file
36
36
  result.define_singleton_method(:trace_file) { trace_file_path }
37
37
  end
38
-
38
+
39
39
  result
40
40
  rescue StandardError => e
41
41
  # Convert exception to error if not already captured
@@ -48,38 +48,28 @@ module Kumi
48
48
  end
49
49
  end
50
50
 
51
- private
52
-
53
51
  def self.setup_env_vars(opts)
54
52
  if opts[:trace]
55
53
  ENV["KUMI_DEBUG_STATE"] = "1"
56
54
  trace_file = ENV["KUMI_DEBUG_FILE"] || "tmp/state_trace.jsonl"
57
55
  ENV["KUMI_DEBUG_FILE"] = trace_file
58
-
56
+
59
57
  # Store for later reporting
60
58
  @trace_file = trace_file
61
59
  end
62
60
 
63
- if opts[:snap]
64
- ENV["KUMI_CHECKPOINT_PHASES"] = opts[:snap]
65
- end
61
+ ENV["KUMI_CHECKPOINT_PHASES"] = opts[:snap] if opts[:snap]
66
62
 
67
- if opts[:snap_dir]
68
- ENV["KUMI_CHECKPOINT_DIR"] = opts[:snap_dir]
69
- end
63
+ ENV["KUMI_CHECKPOINT_DIR"] = opts[:snap_dir] if opts[:snap_dir]
70
64
 
71
- if opts[:resume_from]
72
- ENV["KUMI_CHECKPOINT_RESUME_FROM"] = opts[:resume_from]
73
- end
65
+ ENV["KUMI_CHECKPOINT_RESUME_FROM"] = opts[:resume_from] if opts[:resume_from]
74
66
 
75
- if opts[:resume_at]
76
- ENV["KUMI_CHECKPOINT_RESUME_AT"] = opts[:resume_at]
77
- end
67
+ ENV["KUMI_CHECKPOINT_RESUME_AT"] = opts[:resume_at] if opts[:resume_at]
78
68
 
79
- if opts[:stop_after]
80
- ENV["KUMI_CHECKPOINT_STOP_AFTER"] = opts[:stop_after]
81
- end
69
+ return unless opts[:stop_after]
70
+
71
+ ENV["KUMI_CHECKPOINT_STOP_AFTER"] = opts[:stop_after]
82
72
  end
83
73
  end
84
74
  end
85
- end
75
+ end
@@ -0,0 +1,39 @@
1
+ // run_kumi_direct.mjs
2
+ import fs from "fs";
3
+ import path from "path";
4
+
5
+ async function main() {
6
+ try {
7
+ const modulePath = path.resolve(process.argv[2]);
8
+ const inputPath = path.resolve(process.argv[3]);
9
+ const declsToRun = (process.argv[4] || "")
10
+ .split(",")
11
+ .map(s => s.trim())
12
+ .filter(Boolean);
13
+
14
+ if (!modulePath || !inputPath || declsToRun.length === 0) {
15
+ console.error("Usage: node run_kumi_direct.mjs <module.mjs> <input.json> <decl1,decl2,...>");
16
+ process.exit(2);
17
+ }
18
+
19
+ const mod = await import(modulePath);
20
+ const input = JSON.parse(fs.readFileSync(inputPath, "utf-8"));
21
+
22
+ const results = {};
23
+ for (const decl of declsToRun) {
24
+ const fnName = `_${decl}`;
25
+ const fn = mod[fnName];
26
+ if (typeof fn !== "function") {
27
+ throw new Error(`Missing export ${fnName}`);
28
+ }
29
+ results[decl] = fn(input);
30
+ }
31
+
32
+ console.log(JSON.stringify(results));
33
+ } catch (err) {
34
+ console.error(`JS Runner Error: ${err?.message}\n${err?.stack}`);
35
+ process.exit(1);
36
+ }
37
+ }
38
+
39
+ main();
data/lib/kumi/dev.rb CHANGED
@@ -4,11 +4,11 @@ module Kumi
4
4
  module Dev
5
5
  # Alias to the execution engine profiler for cross-layer access
6
6
  Profiler = Kumi::Core::IR::ExecutionEngine::Profiler
7
-
7
+
8
8
  # Load profile runner for CLI
9
9
  autoload :ProfileRunner, "kumi/dev/profile_runner"
10
-
10
+
11
11
  # Load profile aggregator for data analysis
12
12
  autoload :ProfileAggregator, "kumi/dev/profile_aggregator"
13
13
  end
14
- end
14
+ end
@@ -4,25 +4,25 @@ module Kumi
4
4
  module Frontends
5
5
  module Ruby
6
6
  module_function
7
-
7
+
8
8
  def load(path:, inputs: {})
9
9
  mod = Module.new
10
10
  mod.extend(Kumi::Schema)
11
11
  mod.module_eval(File.read(path), path)
12
-
12
+
13
13
  # Extract just the syntax tree AST (same as Text frontend)
14
14
  schema_ast = if mod.const_defined?(:GoldenSchema)
15
- golden = mod.const_get(:GoldenSchema)
16
- golden.build if golden.respond_to?(:build)
17
- golden.__syntax_tree__
18
- elsif mod.__syntax_tree__
19
- mod.__syntax_tree__
20
- else
21
- raise "No schema AST found. Make sure the .rb file calls 'schema do...end'"
22
- end
23
-
15
+ golden = mod.const_get(:GoldenSchema)
16
+ golden.build if golden.respond_to?(:build)
17
+ golden.__syntax_tree__
18
+ elsif mod.__syntax_tree__
19
+ mod.__syntax_tree__
20
+ else
21
+ raise "No schema AST found. Make sure the .rb file calls 'schema do...end'"
22
+ end
23
+
24
24
  [schema_ast, inputs]
25
25
  end
26
26
  end
27
27
  end
28
- end
28
+ end
@@ -4,43 +4,48 @@ module Kumi
4
4
  module Frontends
5
5
  module Text
6
6
  module_function
7
-
8
- def load(path:, inputs: {})
9
- src = File.read(path)
10
-
7
+
8
+ # Load from a file path or a raw string.
9
+ # Usage:
10
+ # Text.load(path: "schema.kumi", inputs: {...})
11
+ # Text.load(src: "...raw text...", inputs: {...})
12
+ def load(path: nil, src: nil, inputs: {})
13
+ raise ArgumentError, "provide either :path or :src" if (path.nil? && src.nil?) || (path && src)
14
+
15
+ src ||= File.read(path)
16
+ file_label = path || "(string)"
17
+
11
18
  begin
12
19
  require "kumi-parser"
13
20
  ast = Kumi::Parser::TextParser.parse(src)
14
- Core::Analyzer::Debug.info(:parse, kind: :text, file: path, ok: true) if Core::Analyzer::Debug.enabled?
21
+ Core::Analyzer::Debug.info(:parse, kind: :text, file: file_label, ok: true) if Core::Analyzer::Debug.enabled?
15
22
  [ast, inputs]
16
23
  rescue LoadError
17
24
  raise "kumi-parser gem not available. Install: gem install kumi-parser"
18
25
  rescue StandardError => e
19
26
  loc = (e.respond_to?(:location) && e.location) || {}
20
27
  line, col = loc.values_at(:line, :column)
21
- snippet = self.code_frame(src, line, col)
22
- raise StandardError, "#{path}:#{line || '?'}:#{col || '?'}: #{e.message}\n#{snippet}"
28
+ snippet = code_frame(src, line, col)
29
+ raise StandardError, "#{file_label}:#{line || '?'}:#{col || '?'}: #{e.message}\n#{snippet}"
23
30
  end
24
31
  end
25
-
26
- private
27
-
32
+
28
33
  def self.code_frame(src, line, col, context: 2)
29
34
  return "" unless line
30
-
31
- lines = src.lines
32
- from = [line - 1 - context, 0].max
33
- to = [line - 1 + context, lines.length - 1].min
34
- out = []
35
-
35
+
36
+ lines = src.lines
37
+ from = [line - 1 - context, 0].max
38
+ to = [line - 1 + context, lines.length - 1].min
39
+ out = []
40
+
36
41
  (from..to).each do |i|
37
- prefix = (i + 1 == line) ? "➤" : " "
38
- out << "#{prefix} %4d | %s" % [i + 1, lines[i].rstrip]
39
- out << " | %s^" % (" " * (col - 1)) if i + 1 == line && col
42
+ prefix = i + 1 == line ? "➤" : " "
43
+ out << format("#{prefix} %4d | %s", i + 1, lines[i].rstrip)
44
+ out << format(" | %s^", " " * (col - 1)) if i + 1 == line && col
40
45
  end
41
-
46
+
42
47
  out.join("\n")
43
48
  end
44
49
  end
45
50
  end
46
- end
51
+ end