kumi 0.0.6 → 0.0.8

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 (180) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +34 -177
  3. data/README.md +41 -7
  4. data/docs/SYNTAX.md +2 -7
  5. data/docs/features/array-broadcasting.md +1 -1
  6. data/docs/schema_metadata/broadcasts.md +53 -0
  7. data/docs/schema_metadata/cascades.md +45 -0
  8. data/docs/schema_metadata/declarations.md +54 -0
  9. data/docs/schema_metadata/dependencies.md +57 -0
  10. data/docs/schema_metadata/evaluation_order.md +29 -0
  11. data/docs/schema_metadata/examples.md +95 -0
  12. data/docs/schema_metadata/inferred_types.md +46 -0
  13. data/docs/schema_metadata/inputs.md +86 -0
  14. data/docs/schema_metadata.md +108 -0
  15. data/examples/game_of_life.rb +1 -1
  16. data/examples/static_analysis_errors.rb +7 -7
  17. data/lib/kumi/analyzer.rb +20 -20
  18. data/lib/kumi/compiler.rb +44 -50
  19. data/lib/kumi/core/analyzer/analysis_state.rb +39 -0
  20. data/lib/kumi/core/analyzer/constant_evaluator.rb +59 -0
  21. data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +248 -0
  22. data/lib/kumi/core/analyzer/passes/declaration_validator.rb +45 -0
  23. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +153 -0
  24. data/lib/kumi/core/analyzer/passes/input_collector.rb +139 -0
  25. data/lib/kumi/core/analyzer/passes/name_indexer.rb +26 -0
  26. data/lib/kumi/core/analyzer/passes/pass_base.rb +52 -0
  27. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +111 -0
  28. data/lib/kumi/core/analyzer/passes/toposorter.rb +110 -0
  29. data/lib/kumi/core/analyzer/passes/type_checker.rb +162 -0
  30. data/lib/kumi/core/analyzer/passes/type_consistency_checker.rb +48 -0
  31. data/lib/kumi/core/analyzer/passes/type_inferencer.rb +236 -0
  32. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +406 -0
  33. data/lib/kumi/core/analyzer/passes/visitor_pass.rb +44 -0
  34. data/lib/kumi/core/atom_unsat_solver.rb +396 -0
  35. data/lib/kumi/core/compiled_schema.rb +43 -0
  36. data/lib/kumi/core/constraint_relationship_solver.rb +641 -0
  37. data/lib/kumi/core/domain/enum_analyzer.rb +55 -0
  38. data/lib/kumi/core/domain/range_analyzer.rb +85 -0
  39. data/lib/kumi/core/domain/validator.rb +82 -0
  40. data/lib/kumi/core/domain/violation_formatter.rb +42 -0
  41. data/lib/kumi/core/error_reporter.rb +166 -0
  42. data/lib/kumi/core/error_reporting.rb +97 -0
  43. data/lib/kumi/core/errors.rb +120 -0
  44. data/lib/kumi/core/evaluation_wrapper.rb +40 -0
  45. data/lib/kumi/core/explain.rb +295 -0
  46. data/lib/kumi/core/export/deserializer.rb +41 -0
  47. data/lib/kumi/core/export/errors.rb +14 -0
  48. data/lib/kumi/core/export/node_builders.rb +142 -0
  49. data/lib/kumi/core/export/node_registry.rb +54 -0
  50. data/lib/kumi/core/export/node_serializers.rb +158 -0
  51. data/lib/kumi/core/export/serializer.rb +25 -0
  52. data/lib/kumi/core/export.rb +35 -0
  53. data/lib/kumi/core/function_registry/collection_functions.rb +202 -0
  54. data/lib/kumi/core/function_registry/comparison_functions.rb +33 -0
  55. data/lib/kumi/core/function_registry/conditional_functions.rb +38 -0
  56. data/lib/kumi/core/function_registry/function_builder.rb +95 -0
  57. data/lib/kumi/core/function_registry/logical_functions.rb +44 -0
  58. data/lib/kumi/core/function_registry/math_functions.rb +74 -0
  59. data/lib/kumi/core/function_registry/string_functions.rb +57 -0
  60. data/lib/kumi/core/function_registry/type_functions.rb +53 -0
  61. data/lib/kumi/{function_registry.rb → core/function_registry.rb} +28 -36
  62. data/lib/kumi/core/input/type_matcher.rb +97 -0
  63. data/lib/kumi/core/input/validator.rb +51 -0
  64. data/lib/kumi/core/input/violation_creator.rb +52 -0
  65. data/lib/kumi/core/json_schema/generator.rb +65 -0
  66. data/lib/kumi/core/json_schema/validator.rb +27 -0
  67. data/lib/kumi/core/json_schema.rb +16 -0
  68. data/lib/kumi/core/ruby_parser/build_context.rb +27 -0
  69. data/lib/kumi/core/ruby_parser/declaration_reference_proxy.rb +38 -0
  70. data/lib/kumi/core/ruby_parser/dsl.rb +14 -0
  71. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +138 -0
  72. data/lib/kumi/core/ruby_parser/expression_converter.rb +128 -0
  73. data/lib/kumi/core/ruby_parser/guard_rails.rb +45 -0
  74. data/lib/kumi/core/ruby_parser/input_builder.rb +127 -0
  75. data/lib/kumi/core/ruby_parser/input_field_proxy.rb +48 -0
  76. data/lib/kumi/core/ruby_parser/input_proxy.rb +31 -0
  77. data/lib/kumi/core/ruby_parser/nested_input.rb +17 -0
  78. data/lib/kumi/core/ruby_parser/parser.rb +71 -0
  79. data/lib/kumi/core/ruby_parser/schema_builder.rb +175 -0
  80. data/lib/kumi/core/ruby_parser/sugar.rb +263 -0
  81. data/lib/kumi/core/ruby_parser.rb +12 -0
  82. data/lib/kumi/core/schema_instance.rb +111 -0
  83. data/lib/kumi/core/types/builder.rb +23 -0
  84. data/lib/kumi/core/types/compatibility.rb +96 -0
  85. data/lib/kumi/core/types/formatter.rb +26 -0
  86. data/lib/kumi/core/types/inference.rb +42 -0
  87. data/lib/kumi/core/types/normalizer.rb +72 -0
  88. data/lib/kumi/core/types/validator.rb +37 -0
  89. data/lib/kumi/core/types.rb +66 -0
  90. data/lib/kumi/core/vectorization_metadata.rb +110 -0
  91. data/lib/kumi/errors.rb +1 -112
  92. data/lib/kumi/registry.rb +37 -0
  93. data/lib/kumi/schema.rb +13 -7
  94. data/lib/kumi/schema_metadata.rb +524 -0
  95. data/lib/kumi/syntax/array_expression.rb +6 -6
  96. data/lib/kumi/syntax/call_expression.rb +4 -4
  97. data/lib/kumi/syntax/cascade_expression.rb +4 -4
  98. data/lib/kumi/syntax/case_expression.rb +4 -4
  99. data/lib/kumi/syntax/declaration_reference.rb +4 -4
  100. data/lib/kumi/syntax/hash_expression.rb +4 -4
  101. data/lib/kumi/syntax/input_declaration.rb +5 -5
  102. data/lib/kumi/syntax/input_element_reference.rb +5 -5
  103. data/lib/kumi/syntax/input_reference.rb +5 -5
  104. data/lib/kumi/syntax/literal.rb +4 -4
  105. data/lib/kumi/syntax/node.rb +34 -34
  106. data/lib/kumi/syntax/root.rb +6 -6
  107. data/lib/kumi/syntax/trait_declaration.rb +4 -4
  108. data/lib/kumi/syntax/value_declaration.rb +4 -4
  109. data/lib/kumi/version.rb +1 -1
  110. data/lib/kumi.rb +14 -0
  111. data/migrate_to_core_iterative.rb +938 -0
  112. data/scripts/generate_function_docs.rb +9 -9
  113. metadata +85 -69
  114. data/lib/generators/trait_engine/templates/schema_spec.rb.erb +0 -27
  115. data/lib/kumi/analyzer/analysis_state.rb +0 -37
  116. data/lib/kumi/analyzer/constant_evaluator.rb +0 -57
  117. data/lib/kumi/analyzer/passes/broadcast_detector.rb +0 -251
  118. data/lib/kumi/analyzer/passes/declaration_validator.rb +0 -43
  119. data/lib/kumi/analyzer/passes/dependency_resolver.rb +0 -151
  120. data/lib/kumi/analyzer/passes/input_collector.rb +0 -137
  121. data/lib/kumi/analyzer/passes/name_indexer.rb +0 -24
  122. data/lib/kumi/analyzer/passes/pass_base.rb +0 -50
  123. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +0 -110
  124. data/lib/kumi/analyzer/passes/toposorter.rb +0 -108
  125. data/lib/kumi/analyzer/passes/type_checker.rb +0 -162
  126. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +0 -46
  127. data/lib/kumi/analyzer/passes/type_inferencer.rb +0 -232
  128. data/lib/kumi/analyzer/passes/unsat_detector.rb +0 -406
  129. data/lib/kumi/analyzer/passes/visitor_pass.rb +0 -42
  130. data/lib/kumi/atom_unsat_solver.rb +0 -394
  131. data/lib/kumi/compiled_schema.rb +0 -41
  132. data/lib/kumi/constraint_relationship_solver.rb +0 -638
  133. data/lib/kumi/domain/enum_analyzer.rb +0 -53
  134. data/lib/kumi/domain/range_analyzer.rb +0 -83
  135. data/lib/kumi/domain/validator.rb +0 -80
  136. data/lib/kumi/domain/violation_formatter.rb +0 -40
  137. data/lib/kumi/error_reporter.rb +0 -164
  138. data/lib/kumi/error_reporting.rb +0 -95
  139. data/lib/kumi/evaluation_wrapper.rb +0 -38
  140. data/lib/kumi/explain.rb +0 -281
  141. data/lib/kumi/export/deserializer.rb +0 -39
  142. data/lib/kumi/export/errors.rb +0 -12
  143. data/lib/kumi/export/node_builders.rb +0 -140
  144. data/lib/kumi/export/node_registry.rb +0 -52
  145. data/lib/kumi/export/node_serializers.rb +0 -156
  146. data/lib/kumi/export/serializer.rb +0 -23
  147. data/lib/kumi/export.rb +0 -33
  148. data/lib/kumi/function_registry/collection_functions.rb +0 -200
  149. data/lib/kumi/function_registry/comparison_functions.rb +0 -31
  150. data/lib/kumi/function_registry/conditional_functions.rb +0 -36
  151. data/lib/kumi/function_registry/function_builder.rb +0 -93
  152. data/lib/kumi/function_registry/logical_functions.rb +0 -42
  153. data/lib/kumi/function_registry/math_functions.rb +0 -72
  154. data/lib/kumi/function_registry/string_functions.rb +0 -54
  155. data/lib/kumi/function_registry/type_functions.rb +0 -51
  156. data/lib/kumi/input/type_matcher.rb +0 -95
  157. data/lib/kumi/input/validator.rb +0 -49
  158. data/lib/kumi/input/violation_creator.rb +0 -50
  159. data/lib/kumi/parser/build_context.rb +0 -25
  160. data/lib/kumi/parser/declaration_reference_proxy.rb +0 -36
  161. data/lib/kumi/parser/dsl.rb +0 -12
  162. data/lib/kumi/parser/dsl_cascade_builder.rb +0 -136
  163. data/lib/kumi/parser/expression_converter.rb +0 -126
  164. data/lib/kumi/parser/guard_rails.rb +0 -43
  165. data/lib/kumi/parser/input_builder.rb +0 -125
  166. data/lib/kumi/parser/input_field_proxy.rb +0 -46
  167. data/lib/kumi/parser/input_proxy.rb +0 -29
  168. data/lib/kumi/parser/nested_input.rb +0 -15
  169. data/lib/kumi/parser/parser.rb +0 -68
  170. data/lib/kumi/parser/schema_builder.rb +0 -173
  171. data/lib/kumi/parser/sugar.rb +0 -261
  172. data/lib/kumi/schema_instance.rb +0 -109
  173. data/lib/kumi/types/builder.rb +0 -21
  174. data/lib/kumi/types/compatibility.rb +0 -94
  175. data/lib/kumi/types/formatter.rb +0 -24
  176. data/lib/kumi/types/inference.rb +0 -40
  177. data/lib/kumi/types/normalizer.rb +0 -70
  178. data/lib/kumi/types/validator.rb +0 -35
  179. data/lib/kumi/types.rb +0 -64
  180. data/lib/kumi/vectorization_metadata.rb +0 -108
@@ -9,7 +9,7 @@ require "kumi"
9
9
 
10
10
  # Helper to format the type information for display.
11
11
  def format_type(type)
12
- Kumi::Types.type_to_s(type)
12
+ Kumi::Core::Types.type_to_s(type)
13
13
  end
14
14
 
15
15
  # Helper to generate a signature string for a function.
@@ -49,19 +49,19 @@ end
49
49
 
50
50
  def function_categories
51
51
  {
52
- "Logical Functions" => Kumi::FunctionRegistry.logical_operations,
53
- "Comparison Functions" => Kumi::FunctionRegistry.comparison_operators,
54
- "Math Functions" => Kumi::FunctionRegistry.math_operations,
55
- "String Functions" => Kumi::FunctionRegistry.string_operations,
56
- "Collection Functions" => Kumi::FunctionRegistry.collection_operations,
57
- "Conditional Functions" => Kumi::FunctionRegistry.conditional_operations,
58
- "Type & Hash Functions" => Kumi::FunctionRegistry.type_operations
52
+ "Logical Functions" => Kumi::Registry.logical_operations,
53
+ "Comparison Functions" => Kumi::Registry.comparison_operators,
54
+ "Math Functions" => Kumi::Registry.math_operations,
55
+ "String Functions" => Kumi::Registry.string_operations,
56
+ "Collection Functions" => Kumi::Registry.collection_operations,
57
+ "Conditional Functions" => Kumi::Registry.conditional_operations,
58
+ "Type & Hash Functions" => Kumi::Registry.type_operations
59
59
  }
60
60
  end
61
61
 
62
62
  def add_functions_for_category(output, functions)
63
63
  functions.sort.each do |name|
64
- signature = Kumi::FunctionRegistry.signature(name)
64
+ signature = Kumi::Registry.signature(name)
65
65
  output << "* **`#{name}`**: #{signature[:description]}"
66
66
  output << " * **Usage**: #{generate_signature(name, signature)}"
67
67
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Muta
@@ -48,78 +48,101 @@ files:
48
48
  - docs/features/array-broadcasting.md
49
49
  - docs/features/input-declaration-system.md
50
50
  - docs/features/performance.md
51
+ - docs/schema_metadata.md
52
+ - docs/schema_metadata/broadcasts.md
53
+ - docs/schema_metadata/cascades.md
54
+ - docs/schema_metadata/declarations.md
55
+ - docs/schema_metadata/dependencies.md
56
+ - docs/schema_metadata/evaluation_order.md
57
+ - docs/schema_metadata/examples.md
58
+ - docs/schema_metadata/inferred_types.md
59
+ - docs/schema_metadata/inputs.md
51
60
  - examples/deep_schema_compilation_and_evaluation_benchmark.rb
52
61
  - examples/federal_tax_calculator_2024.rb
53
62
  - examples/game_of_life.rb
54
63
  - examples/simple_rpg_game.rb
55
64
  - examples/static_analysis_errors.rb
56
65
  - examples/wide_schema_compilation_and_evaluation_benchmark.rb
57
- - lib/generators/trait_engine/templates/schema_spec.rb.erb
58
66
  - lib/kumi.rb
59
67
  - lib/kumi/analyzer.rb
60
- - lib/kumi/analyzer/analysis_state.rb
61
- - lib/kumi/analyzer/constant_evaluator.rb
62
- - lib/kumi/analyzer/passes/broadcast_detector.rb
63
- - lib/kumi/analyzer/passes/declaration_validator.rb
64
- - lib/kumi/analyzer/passes/dependency_resolver.rb
65
- - lib/kumi/analyzer/passes/input_collector.rb
66
- - lib/kumi/analyzer/passes/name_indexer.rb
67
- - lib/kumi/analyzer/passes/pass_base.rb
68
- - lib/kumi/analyzer/passes/semantic_constraint_validator.rb
69
- - lib/kumi/analyzer/passes/toposorter.rb
70
- - lib/kumi/analyzer/passes/type_checker.rb
71
- - lib/kumi/analyzer/passes/type_consistency_checker.rb
72
- - lib/kumi/analyzer/passes/type_inferencer.rb
73
- - lib/kumi/analyzer/passes/unsat_detector.rb
74
- - lib/kumi/analyzer/passes/visitor_pass.rb
75
- - lib/kumi/atom_unsat_solver.rb
76
68
  - lib/kumi/cli.rb
77
- - lib/kumi/compiled_schema.rb
78
69
  - lib/kumi/compiler.rb
79
- - lib/kumi/constraint_relationship_solver.rb
80
- - lib/kumi/domain/enum_analyzer.rb
81
- - lib/kumi/domain/range_analyzer.rb
82
- - lib/kumi/domain/validator.rb
83
- - lib/kumi/domain/violation_formatter.rb
84
- - lib/kumi/error_reporter.rb
85
- - lib/kumi/error_reporting.rb
70
+ - lib/kumi/core/analyzer/analysis_state.rb
71
+ - lib/kumi/core/analyzer/constant_evaluator.rb
72
+ - lib/kumi/core/analyzer/passes/broadcast_detector.rb
73
+ - lib/kumi/core/analyzer/passes/declaration_validator.rb
74
+ - lib/kumi/core/analyzer/passes/dependency_resolver.rb
75
+ - lib/kumi/core/analyzer/passes/input_collector.rb
76
+ - lib/kumi/core/analyzer/passes/name_indexer.rb
77
+ - lib/kumi/core/analyzer/passes/pass_base.rb
78
+ - lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb
79
+ - lib/kumi/core/analyzer/passes/toposorter.rb
80
+ - lib/kumi/core/analyzer/passes/type_checker.rb
81
+ - lib/kumi/core/analyzer/passes/type_consistency_checker.rb
82
+ - lib/kumi/core/analyzer/passes/type_inferencer.rb
83
+ - lib/kumi/core/analyzer/passes/unsat_detector.rb
84
+ - lib/kumi/core/analyzer/passes/visitor_pass.rb
85
+ - lib/kumi/core/atom_unsat_solver.rb
86
+ - lib/kumi/core/compiled_schema.rb
87
+ - lib/kumi/core/constraint_relationship_solver.rb
88
+ - lib/kumi/core/domain/enum_analyzer.rb
89
+ - lib/kumi/core/domain/range_analyzer.rb
90
+ - lib/kumi/core/domain/validator.rb
91
+ - lib/kumi/core/domain/violation_formatter.rb
92
+ - lib/kumi/core/error_reporter.rb
93
+ - lib/kumi/core/error_reporting.rb
94
+ - lib/kumi/core/errors.rb
95
+ - lib/kumi/core/evaluation_wrapper.rb
96
+ - lib/kumi/core/explain.rb
97
+ - lib/kumi/core/export.rb
98
+ - lib/kumi/core/export/deserializer.rb
99
+ - lib/kumi/core/export/errors.rb
100
+ - lib/kumi/core/export/node_builders.rb
101
+ - lib/kumi/core/export/node_registry.rb
102
+ - lib/kumi/core/export/node_serializers.rb
103
+ - lib/kumi/core/export/serializer.rb
104
+ - lib/kumi/core/function_registry.rb
105
+ - lib/kumi/core/function_registry/collection_functions.rb
106
+ - lib/kumi/core/function_registry/comparison_functions.rb
107
+ - lib/kumi/core/function_registry/conditional_functions.rb
108
+ - lib/kumi/core/function_registry/function_builder.rb
109
+ - lib/kumi/core/function_registry/logical_functions.rb
110
+ - lib/kumi/core/function_registry/math_functions.rb
111
+ - lib/kumi/core/function_registry/string_functions.rb
112
+ - lib/kumi/core/function_registry/type_functions.rb
113
+ - lib/kumi/core/input/type_matcher.rb
114
+ - lib/kumi/core/input/validator.rb
115
+ - lib/kumi/core/input/violation_creator.rb
116
+ - lib/kumi/core/json_schema.rb
117
+ - lib/kumi/core/json_schema/generator.rb
118
+ - lib/kumi/core/json_schema/validator.rb
119
+ - lib/kumi/core/ruby_parser.rb
120
+ - lib/kumi/core/ruby_parser/build_context.rb
121
+ - lib/kumi/core/ruby_parser/declaration_reference_proxy.rb
122
+ - lib/kumi/core/ruby_parser/dsl.rb
123
+ - lib/kumi/core/ruby_parser/dsl_cascade_builder.rb
124
+ - lib/kumi/core/ruby_parser/expression_converter.rb
125
+ - lib/kumi/core/ruby_parser/guard_rails.rb
126
+ - lib/kumi/core/ruby_parser/input_builder.rb
127
+ - lib/kumi/core/ruby_parser/input_field_proxy.rb
128
+ - lib/kumi/core/ruby_parser/input_proxy.rb
129
+ - lib/kumi/core/ruby_parser/nested_input.rb
130
+ - lib/kumi/core/ruby_parser/parser.rb
131
+ - lib/kumi/core/ruby_parser/schema_builder.rb
132
+ - lib/kumi/core/ruby_parser/sugar.rb
133
+ - lib/kumi/core/schema_instance.rb
134
+ - lib/kumi/core/types.rb
135
+ - lib/kumi/core/types/builder.rb
136
+ - lib/kumi/core/types/compatibility.rb
137
+ - lib/kumi/core/types/formatter.rb
138
+ - lib/kumi/core/types/inference.rb
139
+ - lib/kumi/core/types/normalizer.rb
140
+ - lib/kumi/core/types/validator.rb
141
+ - lib/kumi/core/vectorization_metadata.rb
86
142
  - lib/kumi/errors.rb
87
- - lib/kumi/evaluation_wrapper.rb
88
- - lib/kumi/explain.rb
89
- - lib/kumi/export.rb
90
- - lib/kumi/export/deserializer.rb
91
- - lib/kumi/export/errors.rb
92
- - lib/kumi/export/node_builders.rb
93
- - lib/kumi/export/node_registry.rb
94
- - lib/kumi/export/node_serializers.rb
95
- - lib/kumi/export/serializer.rb
96
- - lib/kumi/function_registry.rb
97
- - lib/kumi/function_registry/collection_functions.rb
98
- - lib/kumi/function_registry/comparison_functions.rb
99
- - lib/kumi/function_registry/conditional_functions.rb
100
- - lib/kumi/function_registry/function_builder.rb
101
- - lib/kumi/function_registry/logical_functions.rb
102
- - lib/kumi/function_registry/math_functions.rb
103
- - lib/kumi/function_registry/string_functions.rb
104
- - lib/kumi/function_registry/type_functions.rb
105
- - lib/kumi/input/type_matcher.rb
106
- - lib/kumi/input/validator.rb
107
- - lib/kumi/input/violation_creator.rb
108
- - lib/kumi/parser/build_context.rb
109
- - lib/kumi/parser/declaration_reference_proxy.rb
110
- - lib/kumi/parser/dsl.rb
111
- - lib/kumi/parser/dsl_cascade_builder.rb
112
- - lib/kumi/parser/expression_converter.rb
113
- - lib/kumi/parser/guard_rails.rb
114
- - lib/kumi/parser/input_builder.rb
115
- - lib/kumi/parser/input_field_proxy.rb
116
- - lib/kumi/parser/input_proxy.rb
117
- - lib/kumi/parser/nested_input.rb
118
- - lib/kumi/parser/parser.rb
119
- - lib/kumi/parser/schema_builder.rb
120
- - lib/kumi/parser/sugar.rb
143
+ - lib/kumi/registry.rb
121
144
  - lib/kumi/schema.rb
122
- - lib/kumi/schema_instance.rb
145
+ - lib/kumi/schema_metadata.rb
123
146
  - lib/kumi/syntax/array_expression.rb
124
147
  - lib/kumi/syntax/call_expression.rb
125
148
  - lib/kumi/syntax/cascade_expression.rb
@@ -134,15 +157,8 @@ files:
134
157
  - lib/kumi/syntax/root.rb
135
158
  - lib/kumi/syntax/trait_declaration.rb
136
159
  - lib/kumi/syntax/value_declaration.rb
137
- - lib/kumi/types.rb
138
- - lib/kumi/types/builder.rb
139
- - lib/kumi/types/compatibility.rb
140
- - lib/kumi/types/formatter.rb
141
- - lib/kumi/types/inference.rb
142
- - lib/kumi/types/normalizer.rb
143
- - lib/kumi/types/validator.rb
144
- - lib/kumi/vectorization_metadata.rb
145
160
  - lib/kumi/version.rb
161
+ - migrate_to_core_iterative.rb
146
162
  - scripts/generate_function_docs.rb
147
163
  homepage: https://github.com/amuta/kumi
148
164
  licenses:
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
- require "rails_helper"
3
-
4
- RSpec.describe <%= schema_constant %> do
5
- # Single shared instance for every example
6
- let(:schema) { described_class }
7
-
8
- # Minimal dummy context so every binding can run
9
- let(:ctx) do
10
- {
11
- <% leaf_keys.each do |k| -%>
12
- <%= "#{k}:" %> nil,
13
- <% end -%>
14
- }
15
- end
16
-
17
- <% expose_names.each do |name| -%>
18
- describe "<%= name %>" do
19
- it "evaluates without raising" do
20
- expect {
21
- schema.evaluate_binding(:<%= name %>, ctx)
22
- }.not_to raise_error
23
- end
24
- end
25
-
26
- <% end -%>
27
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Analyzer
5
- # Simple immutable state wrapper to prevent accidental mutations between passes
6
- class AnalysisState
7
- def initialize(data = {})
8
- @data = data.dup.freeze
9
- end
10
-
11
- # Get a value (same as hash access)
12
- def [](key)
13
- @data[key]
14
- end
15
-
16
- # Check if key exists (same as hash)
17
- def key?(key)
18
- @data.key?(key)
19
- end
20
-
21
- # Get all keys (same as hash)
22
- def keys
23
- @data.keys
24
- end
25
-
26
- # Create new state with additional data (simple and clean)
27
- def with(key, value)
28
- AnalysisState.new(@data.merge(key => value))
29
- end
30
-
31
- # Convert back to hash for final result
32
- def to_h
33
- @data.dup
34
- end
35
- end
36
- end
37
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Analyzer
5
- class ConstantEvaluator
6
- include Syntax
7
-
8
- def initialize(definitions)
9
- @definitions = definitions
10
- @memo = {}
11
- end
12
-
13
- OPERATORS = {
14
- add: :+,
15
- subtract: :-,
16
- multiply: :*,
17
- divide: :/
18
- }.freeze
19
-
20
- def evaluate(node, visited = Set.new)
21
- return :unknown unless node
22
- return @memo[node] if @memo.key?(node)
23
- return node.value if node.is_a?(Literal)
24
-
25
- result = case node
26
- when DeclarationReference then evaluate_binding(node, visited)
27
- when CallExpression then evaluate_call_expression(node, visited)
28
- else :unknown
29
- end
30
-
31
- @memo[node] = result unless result == :unknown
32
- result
33
- end
34
-
35
- private
36
-
37
- def evaluate_binding(node, visited)
38
- return :unknown if visited.include?(node.name)
39
-
40
- visited << node.name
41
- definition = @definitions[node.name]
42
- return :unknown unless definition
43
-
44
- evaluate(definition.expression, visited)
45
- end
46
-
47
- def evaluate_call_expression(node, visited)
48
- return :unknown unless OPERATORS.key?(node.fn_name)
49
-
50
- args = node.args.map { |arg| evaluate(arg, visited) }
51
- return :unknown if args.any?(:unknown)
52
-
53
- args.reduce(OPERATORS[node.fn_name])
54
- end
55
- end
56
- end
57
- end
@@ -1,251 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Analyzer
5
- module Passes
6
- # Detects which operations should be broadcast over arrays
7
- # DEPENDENCIES: :input_meta, :definitions
8
- # PRODUCES: :broadcast_metadata
9
- class BroadcastDetector < PassBase
10
- def run(errors)
11
- input_meta = get_state(:input_meta) || {}
12
- definitions = get_state(:definitions) || {}
13
-
14
- # Find array fields with their element types
15
- array_fields = find_array_fields(input_meta)
16
-
17
- # Build compiler metadata
18
- compiler_metadata = {
19
- array_fields: array_fields,
20
- vectorized_operations: {},
21
- reduction_operations: {}
22
- }
23
-
24
- # Track which values are vectorized for type inference
25
- vectorized_values = {}
26
-
27
- # Analyze traits first, then values (to handle dependencies)
28
- traits = definitions.select { |name, decl| decl.is_a?(Kumi::Syntax::TraitDeclaration) }
29
- values = definitions.select { |name, decl| decl.is_a?(Kumi::Syntax::ValueDeclaration) }
30
-
31
- (traits.to_a + values.to_a).each do |name, decl|
32
- result = analyze_value_vectorization(name, decl.expression, array_fields, vectorized_values, errors)
33
-
34
-
35
- case result[:type]
36
- when :vectorized
37
- compiler_metadata[:vectorized_operations][name] = result[:info]
38
- # Store array source information for dimension checking
39
- array_source = extract_array_source(result[:info], array_fields)
40
- vectorized_values[name] = { vectorized: true, array_source: array_source }
41
- when :reduction
42
- compiler_metadata[:reduction_operations][name] = result[:info]
43
- # Reduction produces scalar, not vectorized
44
- vectorized_values[name] = { vectorized: false }
45
- end
46
- end
47
-
48
- state.with(:broadcast_metadata, compiler_metadata.freeze)
49
- end
50
-
51
- private
52
-
53
- def find_array_fields(input_meta)
54
- result = {}
55
- input_meta.each do |name, meta|
56
- if meta[:type] == :array && meta[:children]
57
- result[name] = {
58
- element_fields: meta[:children].keys,
59
- element_types: meta[:children].transform_values { |v| v[:type] || :any }
60
- }
61
- end
62
- end
63
- result
64
- end
65
-
66
- def analyze_value_vectorization(name, expr, array_fields, vectorized_values, errors)
67
- case expr
68
- when Kumi::Syntax::InputElementReference
69
- if array_fields.key?(expr.path.first)
70
- { type: :vectorized, info: { source: :array_field_access, path: expr.path } }
71
- else
72
- { type: :scalar }
73
- end
74
-
75
- when Kumi::Syntax::DeclarationReference
76
- # Check if this references a vectorized value
77
- vector_info = vectorized_values[expr.name]
78
- if vector_info && vector_info[:vectorized]
79
- { type: :vectorized, info: { source: :vectorized_declaration, name: expr.name } }
80
- else
81
- { type: :scalar }
82
- end
83
-
84
- when Kumi::Syntax::CallExpression
85
- analyze_call_vectorization(name, expr, array_fields, vectorized_values, errors)
86
-
87
- when Kumi::Syntax::CascadeExpression
88
- analyze_cascade_vectorization(name, expr, array_fields, vectorized_values, errors)
89
-
90
- else
91
- { type: :scalar }
92
- end
93
- end
94
-
95
- def analyze_call_vectorization(name, expr, array_fields, vectorized_values, errors)
96
- # Check if this is a reduction function using function registry metadata
97
- if FunctionRegistry.reducer?(expr.fn_name)
98
- # Only treat as reduction if the argument is actually vectorized
99
- arg_info = analyze_argument_vectorization(expr.args.first, array_fields, vectorized_values)
100
- if arg_info[:vectorized]
101
- { type: :reduction, info: { function: expr.fn_name, source: arg_info[:source] } }
102
- else
103
- # Not a vectorized reduction - just a regular function call
104
- { type: :scalar }
105
- end
106
-
107
- else
108
- # Special case: all?, any?, none? functions with vectorized trait arguments should be treated as vectorized
109
- # for cascade condition purposes (they get transformed during compilation)
110
- if [:all?, :any?, :none?].include?(expr.fn_name) && expr.args.length == 1
111
- arg = expr.args.first
112
- if arg.is_a?(Kumi::Syntax::ArrayExpression) && arg.elements.length == 1
113
- trait_ref = arg.elements.first
114
- if trait_ref.is_a?(Kumi::Syntax::DeclarationReference) && vectorized_values[trait_ref.name]&.[](:vectorized)
115
- return { type: :vectorized, info: { source: :cascade_condition_with_vectorized_trait, trait: trait_ref.name } }
116
- end
117
- end
118
- end
119
-
120
- # ANY function with vectorized arguments becomes vectorized (with broadcasting)
121
- arg_infos = expr.args.map { |arg| analyze_argument_vectorization(arg, array_fields, vectorized_values) }
122
-
123
- if arg_infos.any? { |info| info[:vectorized] }
124
- # Check for dimension mismatches when multiple arguments are vectorized
125
- vectorized_sources = arg_infos.select { |info| info[:vectorized] }.map { |info| info[:array_source] }.compact.uniq
126
-
127
- if vectorized_sources.length > 1
128
- # Multiple different array sources - this is a dimension mismatch
129
- # Generate enhanced error message with type information
130
- enhanced_message = build_dimension_mismatch_error(expr, arg_infos, array_fields, vectorized_sources)
131
-
132
- report_error(errors, enhanced_message, location: expr.loc, type: :semantic)
133
- return { type: :scalar } # Treat as scalar to prevent further errors
134
- end
135
-
136
- # This is a vectorized operation - ANY function supports broadcasting
137
- { type: :vectorized, info: {
138
- operation: expr.fn_name,
139
- vectorized_args: arg_infos.map.with_index { |info, i| [i, info[:vectorized]] }.to_h
140
- }}
141
- else
142
- { type: :scalar }
143
- end
144
- end
145
- end
146
-
147
- def analyze_argument_vectorization(arg, array_fields, vectorized_values)
148
- case arg
149
- when Kumi::Syntax::InputElementReference
150
- if array_fields.key?(arg.path.first)
151
- { vectorized: true, source: :array_field, array_source: arg.path.first }
152
- else
153
- { vectorized: false }
154
- end
155
-
156
- when Kumi::Syntax::DeclarationReference
157
- # Check if this references a vectorized value
158
- vector_info = vectorized_values[arg.name]
159
- if vector_info && vector_info[:vectorized]
160
- array_source = vector_info[:array_source]
161
- { vectorized: true, source: :vectorized_value, array_source: array_source }
162
- else
163
- { vectorized: false }
164
- end
165
-
166
- when Kumi::Syntax::CallExpression
167
- # Recursively check
168
- result = analyze_value_vectorization(nil, arg, array_fields, vectorized_values, [])
169
- { vectorized: result[:type] == :vectorized, source: :expression }
170
-
171
- else
172
- { vectorized: false }
173
- end
174
- end
175
-
176
- def extract_array_source(info, array_fields)
177
- case info[:source]
178
- when :array_field_access
179
- info[:path]&.first
180
- when :cascade_condition_with_vectorized_trait
181
- # For cascades, we'd need to trace back to the original source
182
- nil # TODO: Could be enhanced to trace through trait dependencies
183
- else
184
- nil
185
- end
186
- end
187
-
188
- def analyze_cascade_vectorization(name, expr, array_fields, vectorized_values, errors)
189
- # A cascade is vectorized if:
190
- # 1. Any of its result expressions are vectorized, OR
191
- # 2. Any of its conditions reference vectorized values (traits or arrays)
192
- vectorized_results = []
193
- vectorized_conditions = []
194
-
195
- expr.cases.each do |case_expr|
196
- # Check if result is vectorized
197
- result_info = analyze_value_vectorization(nil, case_expr.result, array_fields, vectorized_values, errors)
198
- vectorized_results << (result_info[:type] == :vectorized)
199
-
200
- # Check if condition is vectorized
201
- condition_info = analyze_value_vectorization(nil, case_expr.condition, array_fields, vectorized_values, errors)
202
- vectorized_conditions << (condition_info[:type] == :vectorized)
203
-
204
- end
205
-
206
- if vectorized_results.any? || vectorized_conditions.any?
207
- { type: :vectorized, info: { source: :cascade_with_vectorized_conditions_or_results } }
208
- else
209
- { type: :scalar }
210
- end
211
- end
212
-
213
- def build_dimension_mismatch_error(_expr, arg_infos, array_fields, vectorized_sources)
214
- # Build detailed error message with type information
215
- summary = "Cannot broadcast operation across arrays from different sources: #{vectorized_sources.join(', ')}. "
216
-
217
- problem_desc = "Problem: Multiple operands are arrays from different sources:\n"
218
-
219
- vectorized_args = arg_infos.select { |info| info[:vectorized] }
220
- vectorized_args.each_with_index do |arg_info, index|
221
- array_source = arg_info[:array_source]
222
- next unless array_source && array_fields[array_source]
223
-
224
- # Determine the type based on array field metadata
225
- type_desc = determine_array_type(array_source, array_fields)
226
- problem_desc += " - Operand #{index + 1} resolves to #{type_desc} from array '#{array_source}'\n"
227
- end
228
-
229
- explanation = "Direct operations on arrays from different sources is ambiguous and not supported. " \
230
- "Vectorized operations can only work on fields from the same array input."
231
-
232
- "#{summary}#{problem_desc}#{explanation}"
233
- end
234
-
235
- def determine_array_type(array_source, array_fields)
236
- field_info = array_fields[array_source]
237
- return "array(any)" unless field_info[:element_types]
238
-
239
- # For nested arrays (like items.name where items is an array), this represents array(element_type)
240
- element_types = field_info[:element_types].values.uniq
241
- if element_types.length == 1
242
- "array(#{element_types.first})"
243
- else
244
- "array(mixed)"
245
- end
246
- end
247
-
248
- end
249
- end
250
- end
251
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Kumi
4
- module Analyzer
5
- module Passes
6
- # RESPONSIBILITY: Perform local structural validation on each declaration
7
- # DEPENDENCIES: :definitions
8
- # PRODUCES: None (validation only)
9
- # INTERFACE: new(schema, state).run(errors)
10
- class DeclarationValidator < VisitorPass
11
- def run(errors)
12
- each_decl do |decl|
13
- visit(decl) { |node| validate_node(node, errors) }
14
- end
15
- state
16
- end
17
-
18
- private
19
-
20
- def validate_node(node, errors)
21
- case node
22
- when Kumi::Syntax::ValueDeclaration
23
- validate_attribute(node, errors)
24
- when Kumi::Syntax::TraitDeclaration
25
- validate_trait(node, errors)
26
- end
27
- end
28
-
29
- def validate_attribute(node, errors)
30
- return unless node.expression.nil?
31
-
32
- report_error(errors, "attribute `#{node.name}` requires an expression", location: node.loc)
33
- end
34
-
35
- def validate_trait(node, errors)
36
- return if node.expression.is_a?(Kumi::Syntax::CallExpression)
37
-
38
- report_error(errors, "trait `#{node.name}` must wrap a CallExpression", location: node.loc)
39
- end
40
- end
41
- end
42
- end
43
- end