kumi 0.0.31 → 0.0.33

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 (294) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/README.md +31 -99
  4. data/data/kernels/ruby/core/arithmetic.yaml +2 -2
  5. data/docs/COMPOSED_SCHEMAS.md +137 -0
  6. data/docs/SCHEMA_IMPORTS.md +275 -0
  7. data/docs/SYNTAX.md +48 -0
  8. data/golden/array_element/expected/schema_ruby.rb +2 -27
  9. data/golden/array_index/expected/nast.txt +6 -6
  10. data/golden/array_index/expected/schema_ruby.rb +4 -31
  11. data/golden/array_operations/expected/lir_06_const_prop.txt +4 -8
  12. data/golden/array_operations/expected/schema_javascript.mjs +4 -8
  13. data/golden/array_operations/expected/schema_ruby.rb +10 -43
  14. data/golden/cascade_logic/expected/lir_06_const_prop.txt +7 -14
  15. data/golden/cascade_logic/expected/schema_javascript.mjs +7 -14
  16. data/golden/cascade_logic/expected/schema_ruby.rb +11 -45
  17. data/golden/chained_fusion/expected/lir_06_const_prop.txt +8 -18
  18. data/golden/chained_fusion/expected/schema_javascript.mjs +8 -18
  19. data/golden/chained_fusion/expected/schema_ruby.rb +14 -53
  20. data/golden/decimal_explicit/expected/schema_ruby.rb +4 -31
  21. data/golden/element_arrays/expected/lir_06_const_prop.txt +5 -11
  22. data/golden/element_arrays/expected/schema_javascript.mjs +5 -11
  23. data/golden/element_arrays/expected/schema_ruby.rb +13 -50
  24. data/golden/empty_and_null_inputs/expected/schema_ruby.rb +4 -31
  25. data/golden/example_xpto/expected/ast.txt +23 -0
  26. data/golden/example_xpto/expected/input_plan.txt +1 -0
  27. data/golden/example_xpto/expected/lir_00_unoptimized.txt +16 -0
  28. data/golden/example_xpto/expected/lir_01_hoist_scalar_references.txt +16 -0
  29. data/golden/example_xpto/expected/lir_02_inlined.txt +16 -0
  30. data/golden/example_xpto/expected/lir_03_cse.txt +16 -0
  31. data/golden/example_xpto/expected/lir_04_1_loop_fusion.txt +16 -0
  32. data/golden/example_xpto/expected/lir_04_loop_invcm.txt +16 -0
  33. data/golden/example_xpto/expected/lir_06_const_prop.txt +13 -0
  34. data/golden/example_xpto/expected/nast.txt +17 -0
  35. data/golden/example_xpto/expected/schema_javascript.mjs +13 -0
  36. data/golden/example_xpto/expected/schema_ruby.rb +13 -0
  37. data/golden/example_xpto/expected/snast.txt +17 -0
  38. data/golden/example_xpto/expected.json +4 -0
  39. data/golden/example_xpto/input.json +3 -0
  40. data/golden/example_xpto/schema.kumi +8 -0
  41. data/golden/function_overload/expected/schema_ruby.rb +2 -27
  42. data/golden/game_of_life/expected/lir_06_const_prop.txt +236 -287
  43. data/golden/game_of_life/expected/schema_javascript.mjs +32 -39
  44. data/golden/game_of_life/expected/schema_ruby.rb +34 -66
  45. data/golden/hash_keys/expected/lir_06_const_prop.txt +4 -10
  46. data/golden/hash_keys/expected/schema_javascript.mjs +6 -12
  47. data/golden/hash_keys/expected/schema_ruby.rb +8 -39
  48. data/golden/hash_value/expected/lir_06_const_prop.txt +3 -6
  49. data/golden/hash_value/expected/schema_javascript.mjs +3 -6
  50. data/golden/hash_value/expected/schema_ruby.rb +7 -37
  51. data/golden/hierarchical_complex/expected/lir_06_const_prop.txt +9 -18
  52. data/golden/hierarchical_complex/expected/schema_javascript.mjs +9 -18
  53. data/golden/hierarchical_complex/expected/schema_ruby.rb +14 -51
  54. data/golden/inline_rename_scope_leak/expected/lir_06_const_prop.txt +2 -6
  55. data/golden/inline_rename_scope_leak/expected/schema_javascript.mjs +2 -6
  56. data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +7 -39
  57. data/golden/input_reference/expected/schema_ruby.rb +6 -35
  58. data/golden/interleaved_fusion/expected/lir_06_const_prop.txt +6 -14
  59. data/golden/interleaved_fusion/expected/schema_javascript.mjs +6 -14
  60. data/golden/interleaved_fusion/expected/schema_ruby.rb +11 -47
  61. data/golden/let_inline/expected/lir_06_const_prop.txt +1 -2
  62. data/golden/let_inline/expected/schema_javascript.mjs +1 -2
  63. data/golden/let_inline/expected/schema_ruby.rb +3 -29
  64. data/golden/loop_fusion/expected/lir_06_const_prop.txt +4 -10
  65. data/golden/loop_fusion/expected/schema_javascript.mjs +4 -10
  66. data/golden/loop_fusion/expected/schema_ruby.rb +8 -41
  67. data/golden/min_reduce_scope/expected/lir_06_const_prop.txt +3 -6
  68. data/golden/min_reduce_scope/expected/schema_javascript.mjs +3 -6
  69. data/golden/min_reduce_scope/expected/schema_ruby.rb +8 -39
  70. data/golden/mixed_dimensions/expected/lir_06_const_prop.txt +1 -2
  71. data/golden/mixed_dimensions/expected/schema_javascript.mjs +1 -2
  72. data/golden/mixed_dimensions/expected/schema_ruby.rb +5 -33
  73. data/golden/multirank_hoisting/expected/lir_06_const_prop.txt +9 -18
  74. data/golden/multirank_hoisting/expected/schema_javascript.mjs +9 -18
  75. data/golden/multirank_hoisting/expected/schema_ruby.rb +16 -55
  76. data/golden/nested_hash/expected/lir_06_const_prop.txt +1 -2
  77. data/golden/nested_hash/expected/schema_javascript.mjs +1 -2
  78. data/golden/nested_hash/expected/schema_ruby.rb +3 -29
  79. data/golden/reduction_broadcast/expected/schema_ruby.rb +5 -33
  80. data/golden/roll/expected/lir_06_const_prop.txt +8 -15
  81. data/golden/roll/expected/schema_javascript.mjs +8 -15
  82. data/golden/roll/expected/schema_ruby.rb +13 -48
  83. data/golden/schema_imports_broadcasting_with_imports/expected/ast.txt +26 -0
  84. data/golden/schema_imports_broadcasting_with_imports/expected/input_plan.txt +5 -0
  85. data/golden/schema_imports_broadcasting_with_imports/expected/lir_00_unoptimized.txt +20 -0
  86. data/golden/schema_imports_broadcasting_with_imports/expected/lir_01_hoist_scalar_references.txt +20 -0
  87. data/golden/schema_imports_broadcasting_with_imports/expected/lir_02_inlined.txt +22 -0
  88. data/golden/schema_imports_broadcasting_with_imports/expected/lir_03_cse.txt +21 -0
  89. data/golden/schema_imports_broadcasting_with_imports/expected/lir_04_1_loop_fusion.txt +21 -0
  90. data/golden/schema_imports_broadcasting_with_imports/expected/lir_04_loop_invcm.txt +21 -0
  91. data/golden/schema_imports_broadcasting_with_imports/expected/lir_06_const_prop.txt +21 -0
  92. data/golden/schema_imports_broadcasting_with_imports/expected/nast.txt +12 -0
  93. data/golden/schema_imports_broadcasting_with_imports/expected/schema_javascript.mjs +22 -0
  94. data/golden/schema_imports_broadcasting_with_imports/expected/schema_ruby.rb +24 -0
  95. data/golden/schema_imports_broadcasting_with_imports/expected/snast.txt +12 -0
  96. data/golden/schema_imports_broadcasting_with_imports/expected.json +4 -0
  97. data/golden/schema_imports_broadcasting_with_imports/input.json +7 -0
  98. data/golden/schema_imports_broadcasting_with_imports/schema.kumi +14 -0
  99. data/golden/schema_imports_complex_order_calc/expected/ast.txt +82 -0
  100. data/golden/schema_imports_complex_order_calc/expected/input_plan.txt +16 -0
  101. data/golden/schema_imports_complex_order_calc/expected/lir_00_unoptimized.txt +94 -0
  102. data/golden/schema_imports_complex_order_calc/expected/lir_01_hoist_scalar_references.txt +94 -0
  103. data/golden/schema_imports_complex_order_calc/expected/lir_02_inlined.txt +187 -0
  104. data/golden/schema_imports_complex_order_calc/expected/lir_03_cse.txt +131 -0
  105. data/golden/schema_imports_complex_order_calc/expected/lir_04_1_loop_fusion.txt +131 -0
  106. data/golden/schema_imports_complex_order_calc/expected/lir_04_loop_invcm.txt +131 -0
  107. data/golden/schema_imports_complex_order_calc/expected/lir_06_const_prop.txt +131 -0
  108. data/golden/schema_imports_complex_order_calc/expected/nast.txt +56 -0
  109. data/golden/schema_imports_complex_order_calc/expected/schema_javascript.mjs +147 -0
  110. data/golden/schema_imports_complex_order_calc/expected/schema_ruby.rb +149 -0
  111. data/golden/schema_imports_complex_order_calc/expected/snast.txt +56 -0
  112. data/golden/schema_imports_complex_order_calc/expected.json +12 -0
  113. data/golden/schema_imports_complex_order_calc/input.json +20 -0
  114. data/golden/schema_imports_complex_order_calc/schema.kumi +33 -0
  115. data/golden/schema_imports_composed_order/expected/ast.txt +33 -0
  116. data/golden/schema_imports_composed_order/expected/input_plan.txt +3 -0
  117. data/golden/schema_imports_composed_order/expected/lir_00_unoptimized.txt +25 -0
  118. data/golden/schema_imports_composed_order/expected/lir_01_hoist_scalar_references.txt +25 -0
  119. data/golden/schema_imports_composed_order/expected/lir_02_inlined.txt +33 -0
  120. data/golden/schema_imports_composed_order/expected/lir_03_cse.txt +33 -0
  121. data/golden/schema_imports_composed_order/expected/lir_04_1_loop_fusion.txt +33 -0
  122. data/golden/schema_imports_composed_order/expected/lir_04_loop_invcm.txt +33 -0
  123. data/golden/schema_imports_composed_order/expected/lir_06_const_prop.txt +33 -0
  124. data/golden/schema_imports_composed_order/expected/nast.txt +25 -0
  125. data/golden/schema_imports_composed_order/expected/schema_javascript.mjs +35 -0
  126. data/golden/schema_imports_composed_order/expected/schema_ruby.rb +33 -0
  127. data/golden/schema_imports_composed_order/expected/snast.txt +25 -0
  128. data/golden/schema_imports_composed_order/expected.json +6 -0
  129. data/golden/schema_imports_composed_order/input.json +5 -0
  130. data/golden/schema_imports_composed_order/schema.kumi +15 -0
  131. data/golden/schema_imports_discount_with_tax/expected/ast.txt +37 -0
  132. data/golden/schema_imports_discount_with_tax/expected/input_plan.txt +2 -0
  133. data/golden/schema_imports_discount_with_tax/expected/lir_00_unoptimized.txt +30 -0
  134. data/golden/schema_imports_discount_with_tax/expected/lir_01_hoist_scalar_references.txt +30 -0
  135. data/golden/schema_imports_discount_with_tax/expected/lir_02_inlined.txt +37 -0
  136. data/golden/schema_imports_discount_with_tax/expected/lir_03_cse.txt +34 -0
  137. data/golden/schema_imports_discount_with_tax/expected/lir_04_1_loop_fusion.txt +34 -0
  138. data/golden/schema_imports_discount_with_tax/expected/lir_04_loop_invcm.txt +34 -0
  139. data/golden/schema_imports_discount_with_tax/expected/lir_06_const_prop.txt +34 -0
  140. data/golden/schema_imports_discount_with_tax/expected/nast.txt +30 -0
  141. data/golden/schema_imports_discount_with_tax/expected/schema_javascript.mjs +37 -0
  142. data/golden/schema_imports_discount_with_tax/expected/schema_ruby.rb +34 -0
  143. data/golden/schema_imports_discount_with_tax/expected/snast.txt +30 -0
  144. data/golden/schema_imports_discount_with_tax/expected.json +7 -0
  145. data/golden/schema_imports_discount_with_tax/input.json +4 -0
  146. data/golden/schema_imports_discount_with_tax/schema.kumi +15 -0
  147. data/golden/schema_imports_line_items/expected/ast.txt +35 -0
  148. data/golden/schema_imports_line_items/expected/input_plan.txt +8 -0
  149. data/golden/schema_imports_line_items/expected/lir_00_unoptimized.txt +19 -0
  150. data/golden/schema_imports_line_items/expected/lir_01_hoist_scalar_references.txt +19 -0
  151. data/golden/schema_imports_line_items/expected/lir_02_inlined.txt +24 -0
  152. data/golden/schema_imports_line_items/expected/lir_03_cse.txt +22 -0
  153. data/golden/schema_imports_line_items/expected/lir_04_1_loop_fusion.txt +22 -0
  154. data/golden/schema_imports_line_items/expected/lir_04_loop_invcm.txt +22 -0
  155. data/golden/schema_imports_line_items/expected/lir_06_const_prop.txt +22 -0
  156. data/golden/schema_imports_line_items/expected/nast.txt +19 -0
  157. data/golden/schema_imports_line_items/expected/schema_javascript.mjs +23 -0
  158. data/golden/schema_imports_line_items/expected/schema_ruby.rb +22 -0
  159. data/golden/schema_imports_line_items/expected/snast.txt +19 -0
  160. data/golden/schema_imports_line_items/expected.json +5 -0
  161. data/golden/schema_imports_line_items/input.json +13 -0
  162. data/golden/schema_imports_line_items/schema.kumi +17 -0
  163. data/golden/schema_imports_multiple/expected/ast.txt +35 -0
  164. data/golden/schema_imports_multiple/expected/input_plan.txt +2 -0
  165. data/golden/schema_imports_multiple/expected/lir_00_unoptimized.txt +29 -0
  166. data/golden/schema_imports_multiple/expected/lir_01_hoist_scalar_references.txt +29 -0
  167. data/golden/schema_imports_multiple/expected/lir_02_inlined.txt +41 -0
  168. data/golden/schema_imports_multiple/expected/lir_03_cse.txt +37 -0
  169. data/golden/schema_imports_multiple/expected/lir_04_1_loop_fusion.txt +37 -0
  170. data/golden/schema_imports_multiple/expected/lir_04_loop_invcm.txt +37 -0
  171. data/golden/schema_imports_multiple/expected/lir_06_const_prop.txt +37 -0
  172. data/golden/schema_imports_multiple/expected/nast.txt +28 -0
  173. data/golden/schema_imports_multiple/expected/schema_javascript.mjs +40 -0
  174. data/golden/schema_imports_multiple/expected/schema_ruby.rb +37 -0
  175. data/golden/schema_imports_multiple/expected/snast.txt +28 -0
  176. data/golden/schema_imports_multiple/expected.json +7 -0
  177. data/golden/schema_imports_multiple/input.json +4 -0
  178. data/golden/schema_imports_multiple/schema.kumi +15 -0
  179. data/golden/schema_imports_nested_expressions/expected/ast.txt +31 -0
  180. data/golden/schema_imports_nested_expressions/expected/input_plan.txt +3 -0
  181. data/golden/schema_imports_nested_expressions/expected/lir_00_unoptimized.txt +22 -0
  182. data/golden/schema_imports_nested_expressions/expected/lir_01_hoist_scalar_references.txt +22 -0
  183. data/golden/schema_imports_nested_expressions/expected/lir_02_inlined.txt +32 -0
  184. data/golden/schema_imports_nested_expressions/expected/lir_03_cse.txt +32 -0
  185. data/golden/schema_imports_nested_expressions/expected/lir_04_1_loop_fusion.txt +32 -0
  186. data/golden/schema_imports_nested_expressions/expected/lir_04_loop_invcm.txt +32 -0
  187. data/golden/schema_imports_nested_expressions/expected/lir_06_const_prop.txt +28 -0
  188. data/golden/schema_imports_nested_expressions/expected/nast.txt +23 -0
  189. data/golden/schema_imports_nested_expressions/expected/schema_javascript.mjs +29 -0
  190. data/golden/schema_imports_nested_expressions/expected/schema_ruby.rb +28 -0
  191. data/golden/schema_imports_nested_expressions/expected/snast.txt +23 -0
  192. data/golden/schema_imports_nested_expressions/expected.json +5 -0
  193. data/golden/schema_imports_nested_expressions/input.json +5 -0
  194. data/golden/schema_imports_nested_expressions/schema.kumi +13 -0
  195. data/golden/schema_imports_nested_with_reductions/expected/ast.txt +47 -0
  196. data/golden/schema_imports_nested_with_reductions/expected/input_plan.txt +12 -0
  197. data/golden/schema_imports_nested_with_reductions/expected/lir_00_unoptimized.txt +31 -0
  198. data/golden/schema_imports_nested_with_reductions/expected/lir_01_hoist_scalar_references.txt +31 -0
  199. data/golden/schema_imports_nested_with_reductions/expected/lir_02_inlined.txt +58 -0
  200. data/golden/schema_imports_nested_with_reductions/expected/lir_03_cse.txt +49 -0
  201. data/golden/schema_imports_nested_with_reductions/expected/lir_04_1_loop_fusion.txt +51 -0
  202. data/golden/schema_imports_nested_with_reductions/expected/lir_04_loop_invcm.txt +49 -0
  203. data/golden/schema_imports_nested_with_reductions/expected/lir_06_const_prop.txt +49 -0
  204. data/golden/schema_imports_nested_with_reductions/expected/nast.txt +23 -0
  205. data/golden/schema_imports_nested_with_reductions/expected/schema_javascript.mjs +49 -0
  206. data/golden/schema_imports_nested_with_reductions/expected/schema_ruby.rb +52 -0
  207. data/golden/schema_imports_nested_with_reductions/expected/snast.txt +23 -0
  208. data/golden/schema_imports_nested_with_reductions/expected.json +6 -0
  209. data/golden/schema_imports_nested_with_reductions/input.json +16 -0
  210. data/golden/schema_imports_nested_with_reductions/schema.kumi +23 -0
  211. data/golden/schema_imports_with_imports/expected/ast.txt +19 -0
  212. data/golden/schema_imports_with_imports/expected/input_plan.txt +1 -0
  213. data/golden/schema_imports_with_imports/expected/lir_00_unoptimized.txt +13 -0
  214. data/golden/schema_imports_with_imports/expected/lir_01_hoist_scalar_references.txt +13 -0
  215. data/golden/schema_imports_with_imports/expected/lir_02_inlined.txt +14 -0
  216. data/golden/schema_imports_with_imports/expected/lir_03_cse.txt +13 -0
  217. data/golden/schema_imports_with_imports/expected/lir_04_1_loop_fusion.txt +13 -0
  218. data/golden/schema_imports_with_imports/expected/lir_04_loop_invcm.txt +13 -0
  219. data/golden/schema_imports_with_imports/expected/lir_06_const_prop.txt +13 -0
  220. data/golden/schema_imports_with_imports/expected/nast.txt +13 -0
  221. data/golden/schema_imports_with_imports/expected/schema_javascript.mjs +13 -0
  222. data/golden/schema_imports_with_imports/expected/schema_ruby.rb +13 -0
  223. data/golden/schema_imports_with_imports/expected/snast.txt +13 -0
  224. data/golden/schema_imports_with_imports/expected.json +4 -0
  225. data/golden/schema_imports_with_imports/input.json +3 -0
  226. data/golden/schema_imports_with_imports/schema.kumi +10 -0
  227. data/golden/shift/expected/lir_06_const_prop.txt +18 -30
  228. data/golden/shift/expected/schema_javascript.mjs +18 -30
  229. data/golden/shift/expected/schema_ruby.rb +25 -67
  230. data/golden/shift_2d/expected/lir_06_const_prop.txt +36 -60
  231. data/golden/shift_2d/expected/schema_javascript.mjs +36 -60
  232. data/golden/shift_2d/expected/schema_ruby.rb +49 -109
  233. data/golden/simple_math/expected/lir_06_const_prop.txt +3 -6
  234. data/golden/simple_math/expected/schema_javascript.mjs +3 -6
  235. data/golden/simple_math/expected/schema_ruby.rb +8 -39
  236. data/golden/streaming_basics/expected/lir_06_const_prop.txt +6 -12
  237. data/golden/streaming_basics/expected/schema_javascript.mjs +6 -12
  238. data/golden/streaming_basics/expected/schema_ruby.rb +14 -51
  239. data/golden/tuples/expected/lir_06_const_prop.txt +5 -22
  240. data/golden/tuples/expected/schema_javascript.mjs +5 -22
  241. data/golden/tuples/expected/schema_ruby.rb +11 -57
  242. data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +4 -8
  243. data/golden/tuples_and_arrays/expected/schema_javascript.mjs +4 -8
  244. data/golden/tuples_and_arrays/expected/schema_ruby.rb +9 -41
  245. data/golden/us_tax_2024/expected/lir_06_const_prop.txt +94 -171
  246. data/golden/us_tax_2024/expected/schema_javascript.mjs +13 -21
  247. data/golden/us_tax_2024/expected/schema_ruby.rb +15 -48
  248. data/golden/with_constants/expected/lir_06_const_prop.txt +3 -8
  249. data/golden/with_constants/expected/schema_javascript.mjs +3 -8
  250. data/golden/with_constants/expected/schema_ruby.rb +5 -35
  251. data/lib/kumi/analyzer.rb +8 -7
  252. data/lib/kumi/configuration.rb +7 -6
  253. data/lib/kumi/core/analyzer/passes/attach_anchors_pass.rb +1 -1
  254. data/lib/kumi/core/analyzer/passes/attach_terminal_info_pass.rb +1 -1
  255. data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +20 -0
  256. data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +16 -7
  257. data/lib/kumi/core/analyzer/passes/codegen/ruby/output_buffer.rb +3 -35
  258. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +6 -0
  259. data/lib/kumi/core/analyzer/passes/import_analysis_pass.rb +90 -0
  260. data/lib/kumi/core/analyzer/passes/lir/constant_propagation_pass.rb +77 -36
  261. data/lib/kumi/core/analyzer/passes/lir/lower_pass.rb +26 -11
  262. data/lib/kumi/core/analyzer/passes/name_indexer.rb +20 -2
  263. data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +44 -0
  264. data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +30 -0
  265. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +5 -1
  266. data/lib/kumi/core/analyzer/passes/snast_pass.rb +15 -0
  267. data/lib/kumi/core/lir/build.rb +27 -0
  268. data/lib/kumi/core/lir/peephole.rb +164 -0
  269. data/lib/kumi/core/nast.rb +16 -0
  270. data/lib/kumi/core/ruby_parser/build_context.rb +3 -1
  271. data/lib/kumi/core/ruby_parser/parser.rb +1 -1
  272. data/lib/kumi/core/ruby_parser/schema_builder.rb +33 -3
  273. data/lib/kumi/dev/golden/result.rb +9 -3
  274. data/lib/kumi/dev/golden/runtime_test.rb +16 -1
  275. data/lib/kumi/dev/golden.rb +18 -20
  276. data/lib/kumi/dev/golden_schema_modules.rb +8 -0
  277. data/lib/kumi/dev/golden_schema_wrapper.rb +116 -0
  278. data/lib/kumi/dev/support/kumi_runner.mjs +18 -0
  279. data/lib/kumi/schema.rb +44 -2
  280. data/lib/kumi/support/lir_printer.rb +21 -5
  281. data/lib/kumi/support/nast_printer.rb +11 -0
  282. data/lib/kumi/support/s_expression_printer.rb +9 -0
  283. data/lib/kumi/support/snast_printer.rb +6 -0
  284. data/lib/kumi/syntax/import_call.rb +11 -0
  285. data/lib/kumi/syntax/import_declaration.rb +11 -0
  286. data/lib/kumi/syntax/root.rb +2 -2
  287. data/lib/kumi/test_shared_schemas/compound.rb +21 -0
  288. data/lib/kumi/test_shared_schemas/discount.rb +19 -0
  289. data/lib/kumi/test_shared_schemas/price.rb +19 -0
  290. data/lib/kumi/test_shared_schemas/subtotal.rb +22 -0
  291. data/lib/kumi/test_shared_schemas/tax.rb +18 -0
  292. data/lib/kumi/version.rb +1 -1
  293. data/lib/kumi.rb +19 -4
  294. metadata +176 -3
@@ -71,22 +71,28 @@ module Kumi
71
71
  end
72
72
 
73
73
  class SchemaTestResult
74
- attr_reader :schema_name, :test_results, :error
74
+ attr_reader :schema_name, :test_results, :error, :skipped, :skip_reason
75
75
 
76
- def initialize(schema_name:, test_results: [], error: nil)
76
+ def initialize(schema_name:, test_results: [], error: nil, skipped: false, skip_reason: nil)
77
77
  @schema_name = schema_name
78
78
  @test_results = test_results
79
79
  @error = error
80
+ @skipped = skipped
81
+ @skip_reason = skip_reason
80
82
  end
81
83
 
82
84
  def passed?
83
- error.nil? && test_results.all?(&:passed?)
85
+ skipped? || (error.nil? && test_results.all?(&:passed?))
84
86
  end
85
87
 
86
88
  def failed?
87
89
  !passed?
88
90
  end
89
91
 
92
+ def skipped?
93
+ skipped
94
+ end
95
+
90
96
  def passed_count
91
97
  test_results.count(&:passed?)
92
98
  end
@@ -17,6 +17,15 @@ module Kumi
17
17
  end
18
18
 
19
19
  def run(base_dir)
20
+ # Skip JavaScript runtime tests for schemas with imports (requires generated shared modules)
21
+ if language == :javascript && has_imports?(base_dir)
22
+ return SchemaTestResult.new(
23
+ schema_name: schema_name,
24
+ skipped: true,
25
+ skip_reason: "JavaScript runtime testing for schemas with imports requires generated shared modules"
26
+ )
27
+ end
28
+
20
29
  expected_outputs = load_expected_outputs(base_dir)
21
30
  actual_outputs = execute_schema(base_dir, expected_outputs.keys)
22
31
 
@@ -43,6 +52,12 @@ module Kumi
43
52
 
44
53
  private
45
54
 
55
+ def has_imports?(base_dir)
56
+ schema_file = File.join(base_dir, "schema.kumi")
57
+ return false unless File.exist?(schema_file)
58
+ File.read(schema_file).match?(/\bimport\s+/)
59
+ end
60
+
46
61
  def load_expected_outputs(base_dir)
47
62
  expected_file = File.join(base_dir, "expected.json")
48
63
  JSON.parse(File.read(expected_file))
@@ -72,7 +87,7 @@ module Kumi
72
87
  module_name = code.match(/module (Kumi::Compiled::\S+)/)[1]
73
88
  eval(code)
74
89
  module_const = Object.const_get(module_name)
75
- instance = module_const.from(input_data)
90
+ instance = Kumi::CompiledSchemaWrapper.new(module_const, input_data)
76
91
 
77
92
  decl_names.to_h { |name| [name, instance[name.to_sym]] }
78
93
  end
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "fileutils"
4
- require "json"
5
- require "open3"
3
+ require_relative "../schema"
6
4
 
7
5
  require_relative "golden/representation"
8
6
  require_relative "golden/result"
@@ -15,11 +13,19 @@ require_relative "golden/suite"
15
13
  module Kumi
16
14
  module Dev
17
15
  module Golden
16
+ # Precompile shared schemas so __kumi_syntax_tree__ is available for imports
17
+ def self.precompile_schemas!
18
+ if defined?(Kumi::TestSharedSchemas)
19
+ Kumi::TestSharedSchemas.constants.each do |const|
20
+ mod = Kumi::TestSharedSchemas.const_get(const)
21
+ mod.runner if mod.is_a?(Module) && mod.respond_to?(:runner)
22
+ end
23
+ end
24
+ end
25
+
18
26
  module_function
19
27
 
20
- def list
21
- suite.list
22
- end
28
+ def list = suite.list
23
29
 
24
30
  def update!(*names)
25
31
  names = [names].flatten.compact
@@ -44,14 +50,10 @@ module Kumi
44
50
  names = names_arg.any? ? names_arg : suite.send(:schema_names)
45
51
 
46
52
  ruby_names = suite.send(:filter_testable_schemas, names, :ruby)
47
- ruby_results = ruby_names.map do |schema_name|
48
- RuntimeTest.new(schema_name, :ruby).run(suite.send(:schema_dir, schema_name))
49
- end
53
+ ruby_results = ruby_names.map { |n| RuntimeTest.new(n, :ruby).run(suite.send(:schema_dir, n)) }
50
54
 
51
55
  js_names = suite.send(:filter_testable_schemas, names, :javascript)
52
- js_results = js_names.map do |schema_name|
53
- RuntimeTest.new(schema_name, :javascript).run(suite.send(:schema_dir, schema_name))
54
- end
56
+ js_results = js_names.map { |n| RuntimeTest.new(n, :javascript).run(suite.send(:schema_dir, n)) }
55
57
 
56
58
  Reporter.new.report_runtime_tests(ruby: ruby_results, javascript: js_results)
57
59
  end
@@ -59,20 +61,16 @@ module Kumi
59
61
  def test_codegen!(*names_arg)
60
62
  names_arg = [names_arg].flatten.compact
61
63
  names = names_arg.any? ? names_arg : suite.send(:schema_names)
62
- testable_names = suite.send(:filter_testable_schemas, names, :ruby)
63
- results = testable_names.map do |schema_name|
64
- RuntimeTest.new(schema_name, :ruby).run(suite.send(:schema_dir, schema_name))
65
- end
64
+ testable = suite.send(:filter_testable_schemas, names, :ruby)
65
+ results = testable.map { |n| RuntimeTest.new(n, :ruby).run(suite.send(:schema_dir, n)) }
66
66
  Reporter.new.report_runtime_tests(ruby: results)
67
67
  end
68
68
 
69
69
  def test_js_codegen!(*names_arg)
70
70
  names_arg = [names_arg].flatten.compact
71
71
  names = names_arg.any? ? names_arg : suite.send(:schema_names)
72
- testable_names = suite.send(:filter_testable_schemas, names, :javascript)
73
- results = testable_names.map do |schema_name|
74
- RuntimeTest.new(schema_name, :javascript).run(suite.send(:schema_dir, schema_name))
75
- end
72
+ testable = suite.send(:filter_testable_schemas, names, :javascript)
73
+ results = testable.map { |n| RuntimeTest.new(n, :javascript).run(suite.send(:schema_dir, n)) }
76
74
  Reporter.new.report_runtime_tests(javascript: results)
77
75
  end
78
76
 
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Base module for golden schema imports
4
+ # Shared schemas from golden/_shared/ should be required separately
5
+ # before using any schemas that import from GoldenSchemas
6
+
7
+ module GoldenSchemas
8
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Dev
5
+ # Wraps golden test schemas as importable Ruby modules
6
+ # Allows golden schemas to import from other golden schemas
7
+ #
8
+ # Usage:
9
+ # tax_schema = GoldenSchemaWrapper.load('golden/tax_rate/schema.kumi')
10
+ # Schemas::Tax = GoldenSchemaWrapper.as_module(tax_schema, 'Schemas::Tax')
11
+ #
12
+ # # Now other schemas can: import :calculate_tax, from: Schemas::Tax
13
+ class GoldenSchemaWrapper
14
+ # Load a golden schema from a .kumi file
15
+ def self.load(path)
16
+ full_path = File.expand_path(path)
17
+ raise "Schema file not found: #{full_path}" unless File.exist?(full_path)
18
+
19
+ content = File.read(full_path)
20
+ # Parse using the standard parser
21
+ root = Kumi::Core::RubyParser::Dsl.build_syntax_tree { instance_eval(content) }
22
+ root
23
+ end
24
+
25
+ # Wrap a schema root in a module that can be used for imports
26
+ # Creates: module_const with kumi_schema_instance method
27
+ def self.as_module(schema_root, const_path)
28
+ # Create nested module structure: Schemas::Tax, Schemas::Payment, etc
29
+ parts = const_path.split("::")
30
+ module_name = parts.pop
31
+ parent_path = parts.empty? ? "Object" : parts.join("::")
32
+
33
+ # Get or create parent module
34
+ parent = if parent_path == "Object"
35
+ Object
36
+ else
37
+ parts.inject(Object) do |mod, part|
38
+ if mod.const_defined?(part, false)
39
+ mod.const_get(part)
40
+ else
41
+ new_mod = Module.new
42
+ mod.const_set(part, new_mod)
43
+ new_mod
44
+ end
45
+ end
46
+ end
47
+
48
+ # Analyze the schema to get metadata
49
+ analyzed_state = analyze_schema(schema_root)
50
+ input_metadata = extract_input_metadata(schema_root)
51
+
52
+ # Create the schema module
53
+ schema_module = Module.new do
54
+ define_singleton_method :kumi_schema_instance do
55
+ @instance ||= create_instance(schema_root, analyzed_state, input_metadata)
56
+ end
57
+
58
+ define_singleton_method :create_instance do |root, state, meta|
59
+ schema_obj = Object.new
60
+ def schema_obj.root
61
+ @root_ast
62
+ end
63
+
64
+ def schema_obj.input_metadata
65
+ @input_metadata
66
+ end
67
+
68
+ def schema_obj.analyzed_state
69
+ @analyzed_state
70
+ end
71
+
72
+ schema_obj.instance_variable_set(:@root_ast, root)
73
+ schema_obj.instance_variable_set(:@input_metadata, meta)
74
+ schema_obj.instance_variable_set(:@analyzed_state, state)
75
+ schema_obj
76
+ end
77
+ end
78
+
79
+ parent.const_set(module_name, schema_module)
80
+ schema_module
81
+ end
82
+
83
+ private
84
+
85
+ def self.analyze_schema(schema_root)
86
+ # Run full analysis on the schema
87
+ registry = Kumi::RegistryV2.load
88
+ state = Kumi::Core::Analyzer::AnalysisState.new({})
89
+ state = state.with(:registry, registry)
90
+ errors = []
91
+
92
+ # Run DEFAULT_PASSES
93
+ Kumi::Analyzer::DEFAULT_PASSES.each do |pass_class|
94
+ pass = pass_class.new(schema_root, state)
95
+ state = pass.run(errors)
96
+ raise "Analysis failed: #{errors.map(&:to_s).join(', ')}" unless errors.empty?
97
+ end
98
+
99
+ state
100
+ end
101
+
102
+ def self.extract_input_metadata(schema_root)
103
+ metadata = {}
104
+ return metadata unless schema_root.inputs
105
+
106
+ schema_root.inputs.each do |input_decl|
107
+ metadata[input_decl.name] = {
108
+ type: input_decl.type_spec&.kind || :any
109
+ }
110
+ end
111
+
112
+ metadata
113
+ end
114
+ end
115
+ end
116
+ end
@@ -1,6 +1,7 @@
1
1
  // run_kumi_direct.mjs
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import { fileURLToPath } from 'url';
4
5
 
5
6
  async function main() {
6
7
  try {
@@ -16,6 +17,23 @@ async function main() {
16
17
  process.exit(2);
17
18
  }
18
19
 
20
+ // Setup global namespace for imported schemas
21
+ const sharedDir = path.resolve(path.dirname(modulePath), '../../_shared');
22
+ globalThis.GoldenSchemas = {};
23
+
24
+ // Load all available shared schema modules
25
+ const sharedSchemas = ['tax', 'discount', 'compound'];
26
+ for (const schemaName of sharedSchemas) {
27
+ try {
28
+ const module = await import(path.resolve(sharedDir, `${schemaName}_javascript.mjs`));
29
+ // Convert snake_case to PascalCase for class name
30
+ const className = schemaName.split('_').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join('');
31
+ globalThis.GoldenSchemas[className] = module[className];
32
+ } catch (e) {
33
+ // Shared modules may not exist for all schemas
34
+ }
35
+ }
36
+
19
37
  const mod = await import(modulePath);
20
38
  const input = JSON.parse(fs.readFileSync(inputPath, "utf-8"));
21
39
 
data/lib/kumi/schema.rb CHANGED
@@ -5,6 +5,38 @@ require "digest"
5
5
  require "fileutils"
6
6
 
7
7
  module Kumi
8
+ # Thin wrapper providing backward-compatible interface for pure module functions.
9
+ # The compiled module now contains only module-level functions (def self._name(input)),
10
+ # but users expect an instance-like interface with .from(), .update(), [].
11
+ # This wrapper bridges that gap.
12
+ class CompiledSchemaWrapper
13
+ def initialize(compiled_module, input_data)
14
+ @compiled_module = compiled_module
15
+ @input = input_data
16
+ end
17
+
18
+ def [](declaration_name)
19
+ method_name = "_#{declaration_name}"
20
+ unless @compiled_module.respond_to?(method_name)
21
+ raise KeyError, "Unknown declaration: #{declaration_name}"
22
+ end
23
+ @compiled_module.public_send(method_name, @input)
24
+ end
25
+
26
+ def update(new_input)
27
+ @input = @input.merge(new_input)
28
+ self
29
+ end
30
+
31
+ def from(new_input)
32
+ CompiledSchemaWrapper.new(@compiled_module, new_input)
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :compiled_module, :input
38
+ end
39
+
8
40
  # This module is the main entry point for users of the Kumi DSL.
9
41
  # When a user module `extend`s this, it gains the `schema` block method
10
42
  # and the `from` class method to execute the compiled logic.
@@ -34,12 +66,12 @@ module Kumi
34
66
  def runner
35
67
  ensure_compiled!
36
68
 
37
- __kumi_compiled_module__.from({})
69
+ CompiledSchemaWrapper.new(__kumi_compiled_module__, {})
38
70
  end
39
71
 
40
72
  def from(input_data)
41
73
  ensure_compiled!
42
- __kumi_compiled_module__.from(input_data)
74
+ CompiledSchemaWrapper.new(__kumi_compiled_module__, input_data)
43
75
  end
44
76
 
45
77
  def write_source(file_path, platform: :ruby)
@@ -94,6 +126,16 @@ module Kumi
94
126
  # to mix in the compiled methods (_total_payroll, etc.) and the instance
95
127
  # method `__kumi_compiled_module__`.
96
128
  @__kumi_compiled_module__ = Kumi::Compiled.const_get(schema_digest)
129
+
130
+ # Create a wrapper module with the compiled functions available as instance methods.
131
+ # This allows them to be extended as singleton methods on the schema module.
132
+ # This enables schema imports to work: GoldenSchemas::Tax._tax({amount: 100})
133
+ wrapper = Module.new
134
+ @__kumi_compiled_module__.singleton_methods(false).each do |method_name|
135
+ wrapper.define_method(method_name, @__kumi_compiled_module__.method(method_name).to_proc)
136
+ end
137
+ self.extend(wrapper)
138
+
97
139
  @kumi_compiled = true
98
140
  end
99
141
  end
@@ -71,17 +71,17 @@ module Kumi
71
71
  "#{res}load_field #{only(ins.inputs)}[#{fmt_key(key)}]#{stamp(ins)}"
72
72
  when :KernelCall
73
73
  fn = ins.attributes[:fn]
74
- "#{res}call #{fn}(#{list(ins.inputs)})#{stamp(ins)}"
74
+ "#{res}call #{fn}(#{list_with_immediates(ins)})#{stamp(ins)}"
75
75
  when :Select
76
- c, t, f = ins.inputs
77
- "#{res}select #{fmt_reg(c)}, #{fmt_reg(t)}, #{fmt_reg(f)}#{stamp(ins)}"
76
+ c, t, f = resolved_inputs(ins)
77
+ "#{res}select #{c}, #{t}, #{f}#{stamp(ins)}"
78
78
  when :DeclareAccumulator
79
79
  "#{res}decl_acc#{stamp(ins)}"
80
80
  when :Accumulate
81
81
  acc = fmt_reg(ins.result_register)
82
82
  fn = ins.attributes[:fn]
83
- v = only(ins.inputs)
84
- "#{res}acc_add #{fn}(#{acc}, #{fmt_reg(v)})#{stamp(ins)}"
83
+ v = resolved_inputs(ins).first
84
+ "#{res}acc_add #{fn}(#{acc}, #{v})#{stamp(ins)}"
85
85
  when :LoadAccumulator
86
86
  acc = ins.inputs.first or raise "No accumulator bound"
87
87
  "#{res}acc_load #{fmt_reg(acc)}#{stamp(ins)}"
@@ -141,3 +141,19 @@ module Kumi
141
141
  end
142
142
  end
143
143
  end
144
+ def resolved_inputs(ins)
145
+ inputs = Array(ins.inputs)
146
+ imm_queue = Array(ins.immediates)
147
+
148
+ inputs.map do |input|
149
+ if input == :__immediate_placeholder__
150
+ fmt_lit(imm_queue.shift)
151
+ else
152
+ fmt_reg(input)
153
+ end
154
+ end
155
+ end
156
+
157
+ def list_with_immediates(ins)
158
+ resolved_inputs(ins).join(", ")
159
+ end
@@ -80,6 +80,17 @@ module Kumi
80
80
  lines << indent(print_node(node.value, depth + 1), depth + 1)
81
81
  lines << indent(")", depth)
82
82
  lines.join("\n")
83
+ when Kumi::Core::NAST::ImportCall
84
+ if node.args.empty?
85
+ "(ImportCall :#{node.fn_name})"
86
+ else
87
+ lines = ["(ImportCall :#{node.fn_name}"]
88
+ node.input_mapping_keys.zip(node.args).each do |key, arg|
89
+ lines << indent("(#{key} #{print_node(arg, depth + 1)})", depth + 1)
90
+ end
91
+ lines << indent(")", depth)
92
+ lines.join("\n")
93
+ end
83
94
  else
84
95
  node.inspect
85
96
  end
@@ -26,6 +26,7 @@ module Kumi
26
26
  when Kumi::Syntax::DeclarationReference then visit_declaration_reference(node)
27
27
  when Kumi::Syntax::Literal then visit_literal(node)
28
28
  when Kumi::Syntax::HashExpression then visit_hash_expression(node)
29
+ when Kumi::Syntax::ImportCall then visit_import_call(node)
29
30
  else visit_generic(node)
30
31
  end
31
32
  end
@@ -127,6 +128,14 @@ module Kumi
127
128
  "(HashExpression\n#{indent_str(2)}#{pairs}\n#{indent_str})"
128
129
  end
129
130
 
131
+ def visit_import_call(node)
132
+ pairs = node.input_mapping.map do |key, value|
133
+ "(#{key} #{child_printer.visit(value)})"
134
+ end.join("\n#{indent_str(2)}")
135
+
136
+ "(ImportCall :#{node.fn_name}\n#{indent_str(2)}#{pairs}\n#{indent_str})"
137
+ end
138
+
130
139
  def visit_generic(node)
131
140
  class_name = node.class.name&.split("::")&.last || node.class.to_s
132
141
 
@@ -95,6 +95,12 @@ module Kumi
95
95
  when NAST::Pair
96
96
  value = format_concise(node.value, indent_level + 1)
97
97
  "#{indent}(Pair #{node.key}\n#{value}\n#{indent}) #{stamp_str}"
98
+ when NAST::ImportCall
99
+ header = "(ImportCall :#{node.fn_name}"
100
+ args = node.input_mapping_keys.zip(node.args).map do |key, arg|
101
+ format_concise(arg, indent_level + 1).sub(/^\s+/, "#{indent} (#{key} ").tap { |s| s << ")" }
102
+ end.join("\n")
103
+ "#{indent}#{header}\n#{args}\n#{indent}) #{stamp_str}"
98
104
  else
99
105
  "#{indent}(UnknownNode: #{node.class})"
100
106
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ ImportCall = Struct.new(:fn_name, :input_mapping, :loc) do
6
+ include Node
7
+
8
+ def children = input_mapping.values
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module Syntax
5
+ ImportDeclaration = Struct.new(:names, :module_ref, :loc) do
6
+ include Node
7
+
8
+ def children = []
9
+ end
10
+ end
11
+ end
@@ -4,10 +4,10 @@ module Kumi
4
4
  module Syntax
5
5
  # Represents the root of the Abstract Syntax Tree.
6
6
  # It holds all the top-level declarations parsed from the source.
7
- Root = Struct.new(:inputs, :values, :traits) do
7
+ Root = Struct.new(:inputs, :values, :traits, :imports) do
8
8
  include Node
9
9
 
10
- def children = [inputs, values, traits]
10
+ def children = [inputs, values, traits, imports]
11
11
 
12
12
  def digest
13
13
  # The digest must be stable and depend on anything that could change the
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module TestSharedSchemas
5
+ module Compound
6
+ extend Kumi::Schema
7
+
8
+ schema do
9
+ input do
10
+ decimal :principal
11
+ decimal :rate
12
+ integer :years
13
+ end
14
+
15
+ value :annual_interest, input.principal * input.rate
16
+ value :total_interest, annual_interest * input.years
17
+ value :final_amount, input.principal + total_interest
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module TestSharedSchemas
5
+ module Discount
6
+ extend Kumi::Schema
7
+
8
+ schema do
9
+ input do
10
+ decimal :price
11
+ decimal :rate
12
+ end
13
+
14
+ value :discounted, input.price * (1.0 - input.rate)
15
+ value :savings, input.price * input.rate
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module TestSharedSchemas
5
+ module Price
6
+ extend Kumi::Schema
7
+
8
+ schema do
9
+ input do
10
+ decimal :base_price
11
+ decimal :discount_rate
12
+ end
13
+
14
+ value :discounted, input.base_price * (1.0 - input.discount_rate)
15
+ value :discount_amount, input.base_price * input.discount_rate
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module TestSharedSchemas
5
+ module Subtotal
6
+ extend Kumi::Schema
7
+
8
+ schema do
9
+ input do
10
+ array :items do
11
+ hash :item do
12
+ integer :quantity
13
+ integer :unit_price
14
+ end
15
+ end
16
+ end
17
+
18
+ value :subtotal, fn(:sum, input.items.item.quantity * input.items.item.unit_price)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kumi
4
+ module TestSharedSchemas
5
+ module Tax
6
+ extend Kumi::Schema
7
+
8
+ schema do
9
+ input do
10
+ decimal :amount
11
+ end
12
+
13
+ value :tax, input.amount * 0.15
14
+ value :total, input.amount + tax
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/kumi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kumi
4
- VERSION = "0.0.31"
4
+ VERSION = "0.0.33"
5
5
  end
data/lib/kumi.rb CHANGED
@@ -4,9 +4,9 @@ require "zeitwerk"
4
4
  require "mutex_m"
5
5
  # require "pry" # COMMENT AFTER DEBUGGING
6
6
 
7
- loader = Zeitwerk::Loader.for_gem
8
- loader.ignore("#{__dir__}/kumi-cli")
9
- loader.inflector.inflect(
7
+ AUTOLOADER = Zeitwerk::Loader.for_gem
8
+ AUTOLOADER.ignore("#{__dir__}/kumi-cli")
9
+ AUTOLOADER.inflector.inflect(
10
10
  "assemble_irv2_pass" => "AssembleIRV2Pass",
11
11
  "ast_emitter" => "ASTEmitter",
12
12
  "attach_terminal_info_pass" => "AttachTerminalInfoPass",
@@ -36,7 +36,7 @@ loader.inflector.inflect(
36
36
  "ruby_ast" => "RubyAST",
37
37
  "vm" => "VM"
38
38
  )
39
- loader.setup
39
+ AUTOLOADER.setup
40
40
 
41
41
  module Kumi
42
42
  # Provides access to the singleton configuration object.
@@ -60,4 +60,19 @@ module Kumi
60
60
  # A namespace for dynamically created compiled modules.
61
61
  module Compiled
62
62
  end
63
+
64
+ # Load shared schemas only when explicitly requested (for golden tests)
65
+ def self.load_shared_schemas!
66
+ # Ensure JIT compilation mode for schemas being loaded
67
+ Kumi.configure { |c| c.compilation_mode = :jit }
68
+
69
+ AUTOLOADER.eager_load_dir("#{__dir__}/kumi/test_shared_schemas")
70
+ # Populate GoldenSchemas module (already defined in golden_schema_modules.rb)
71
+ Kumi::TestSharedSchemas.constants.each do |const|
72
+ GoldenSchemas.const_set(const, Kumi::TestSharedSchemas.const_get(const)) unless GoldenSchemas.const_defined?(const)
73
+ end
74
+ end
63
75
  end
76
+
77
+ # Load golden schema module base
78
+ require_relative "kumi/dev/golden_schema_modules"