kumi 0.0.7 → 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 (171) hide show
  1. checksums.yaml +4 -4
  2. data/CLAUDE.md +1 -1
  3. data/README.md +8 -5
  4. data/examples/game_of_life.rb +1 -1
  5. data/examples/static_analysis_errors.rb +7 -7
  6. data/lib/kumi/analyzer.rb +15 -15
  7. data/lib/kumi/compiler.rb +6 -6
  8. data/lib/kumi/core/analyzer/analysis_state.rb +39 -0
  9. data/lib/kumi/core/analyzer/constant_evaluator.rb +59 -0
  10. data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +248 -0
  11. data/lib/kumi/core/analyzer/passes/declaration_validator.rb +45 -0
  12. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +153 -0
  13. data/lib/kumi/core/analyzer/passes/input_collector.rb +139 -0
  14. data/lib/kumi/core/analyzer/passes/name_indexer.rb +26 -0
  15. data/lib/kumi/core/analyzer/passes/pass_base.rb +52 -0
  16. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +111 -0
  17. data/lib/kumi/core/analyzer/passes/toposorter.rb +110 -0
  18. data/lib/kumi/core/analyzer/passes/type_checker.rb +162 -0
  19. data/lib/kumi/core/analyzer/passes/type_consistency_checker.rb +48 -0
  20. data/lib/kumi/core/analyzer/passes/type_inferencer.rb +236 -0
  21. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +406 -0
  22. data/lib/kumi/core/analyzer/passes/visitor_pass.rb +44 -0
  23. data/lib/kumi/core/atom_unsat_solver.rb +396 -0
  24. data/lib/kumi/core/compiled_schema.rb +43 -0
  25. data/lib/kumi/core/constraint_relationship_solver.rb +641 -0
  26. data/lib/kumi/core/domain/enum_analyzer.rb +55 -0
  27. data/lib/kumi/core/domain/range_analyzer.rb +85 -0
  28. data/lib/kumi/core/domain/validator.rb +82 -0
  29. data/lib/kumi/core/domain/violation_formatter.rb +42 -0
  30. data/lib/kumi/core/error_reporter.rb +166 -0
  31. data/lib/kumi/core/error_reporting.rb +97 -0
  32. data/lib/kumi/core/errors.rb +120 -0
  33. data/lib/kumi/core/evaluation_wrapper.rb +40 -0
  34. data/lib/kumi/core/explain.rb +295 -0
  35. data/lib/kumi/core/export/deserializer.rb +41 -0
  36. data/lib/kumi/core/export/errors.rb +14 -0
  37. data/lib/kumi/core/export/node_builders.rb +142 -0
  38. data/lib/kumi/core/export/node_registry.rb +54 -0
  39. data/lib/kumi/core/export/node_serializers.rb +158 -0
  40. data/lib/kumi/core/export/serializer.rb +25 -0
  41. data/lib/kumi/core/export.rb +35 -0
  42. data/lib/kumi/core/function_registry/collection_functions.rb +202 -0
  43. data/lib/kumi/core/function_registry/comparison_functions.rb +33 -0
  44. data/lib/kumi/core/function_registry/conditional_functions.rb +38 -0
  45. data/lib/kumi/core/function_registry/function_builder.rb +95 -0
  46. data/lib/kumi/core/function_registry/logical_functions.rb +44 -0
  47. data/lib/kumi/core/function_registry/math_functions.rb +74 -0
  48. data/lib/kumi/core/function_registry/string_functions.rb +57 -0
  49. data/lib/kumi/core/function_registry/type_functions.rb +53 -0
  50. data/lib/kumi/{function_registry.rb → core/function_registry.rb} +28 -36
  51. data/lib/kumi/core/input/type_matcher.rb +97 -0
  52. data/lib/kumi/core/input/validator.rb +51 -0
  53. data/lib/kumi/core/input/violation_creator.rb +52 -0
  54. data/lib/kumi/core/json_schema/generator.rb +65 -0
  55. data/lib/kumi/core/json_schema/validator.rb +27 -0
  56. data/lib/kumi/core/json_schema.rb +16 -0
  57. data/lib/kumi/core/ruby_parser/build_context.rb +27 -0
  58. data/lib/kumi/core/ruby_parser/declaration_reference_proxy.rb +38 -0
  59. data/lib/kumi/core/ruby_parser/dsl.rb +14 -0
  60. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +138 -0
  61. data/lib/kumi/core/ruby_parser/expression_converter.rb +128 -0
  62. data/lib/kumi/core/ruby_parser/guard_rails.rb +45 -0
  63. data/lib/kumi/core/ruby_parser/input_builder.rb +127 -0
  64. data/lib/kumi/core/ruby_parser/input_field_proxy.rb +48 -0
  65. data/lib/kumi/core/ruby_parser/input_proxy.rb +31 -0
  66. data/lib/kumi/core/ruby_parser/nested_input.rb +17 -0
  67. data/lib/kumi/core/ruby_parser/parser.rb +71 -0
  68. data/lib/kumi/core/ruby_parser/schema_builder.rb +175 -0
  69. data/lib/kumi/core/ruby_parser/sugar.rb +263 -0
  70. data/lib/kumi/core/ruby_parser.rb +12 -0
  71. data/lib/kumi/core/schema_instance.rb +111 -0
  72. data/lib/kumi/core/types/builder.rb +23 -0
  73. data/lib/kumi/core/types/compatibility.rb +96 -0
  74. data/lib/kumi/core/types/formatter.rb +26 -0
  75. data/lib/kumi/core/types/inference.rb +42 -0
  76. data/lib/kumi/core/types/normalizer.rb +72 -0
  77. data/lib/kumi/core/types/validator.rb +37 -0
  78. data/lib/kumi/core/types.rb +66 -0
  79. data/lib/kumi/core/vectorization_metadata.rb +110 -0
  80. data/lib/kumi/errors.rb +1 -112
  81. data/lib/kumi/registry.rb +37 -0
  82. data/lib/kumi/schema.rb +5 -5
  83. data/lib/kumi/schema_metadata.rb +3 -3
  84. data/lib/kumi/syntax/array_expression.rb +6 -6
  85. data/lib/kumi/syntax/call_expression.rb +4 -4
  86. data/lib/kumi/syntax/cascade_expression.rb +4 -4
  87. data/lib/kumi/syntax/case_expression.rb +4 -4
  88. data/lib/kumi/syntax/declaration_reference.rb +4 -4
  89. data/lib/kumi/syntax/hash_expression.rb +4 -4
  90. data/lib/kumi/syntax/input_declaration.rb +5 -5
  91. data/lib/kumi/syntax/input_element_reference.rb +5 -5
  92. data/lib/kumi/syntax/input_reference.rb +5 -5
  93. data/lib/kumi/syntax/literal.rb +4 -4
  94. data/lib/kumi/syntax/node.rb +34 -34
  95. data/lib/kumi/syntax/root.rb +6 -6
  96. data/lib/kumi/syntax/trait_declaration.rb +4 -4
  97. data/lib/kumi/syntax/value_declaration.rb +4 -4
  98. data/lib/kumi/version.rb +1 -1
  99. data/migrate_to_core_iterative.rb +938 -0
  100. data/scripts/generate_function_docs.rb +9 -9
  101. metadata +75 -72
  102. data/lib/kumi/analyzer/analysis_state.rb +0 -37
  103. data/lib/kumi/analyzer/constant_evaluator.rb +0 -57
  104. data/lib/kumi/analyzer/passes/broadcast_detector.rb +0 -246
  105. data/lib/kumi/analyzer/passes/declaration_validator.rb +0 -43
  106. data/lib/kumi/analyzer/passes/dependency_resolver.rb +0 -151
  107. data/lib/kumi/analyzer/passes/input_collector.rb +0 -137
  108. data/lib/kumi/analyzer/passes/name_indexer.rb +0 -24
  109. data/lib/kumi/analyzer/passes/pass_base.rb +0 -50
  110. data/lib/kumi/analyzer/passes/semantic_constraint_validator.rb +0 -109
  111. data/lib/kumi/analyzer/passes/toposorter.rb +0 -108
  112. data/lib/kumi/analyzer/passes/type_checker.rb +0 -160
  113. data/lib/kumi/analyzer/passes/type_consistency_checker.rb +0 -46
  114. data/lib/kumi/analyzer/passes/type_inferencer.rb +0 -232
  115. data/lib/kumi/analyzer/passes/unsat_detector.rb +0 -404
  116. data/lib/kumi/analyzer/passes/visitor_pass.rb +0 -42
  117. data/lib/kumi/atom_unsat_solver.rb +0 -394
  118. data/lib/kumi/compiled_schema.rb +0 -41
  119. data/lib/kumi/constraint_relationship_solver.rb +0 -638
  120. data/lib/kumi/domain/enum_analyzer.rb +0 -53
  121. data/lib/kumi/domain/range_analyzer.rb +0 -83
  122. data/lib/kumi/domain/validator.rb +0 -80
  123. data/lib/kumi/domain/violation_formatter.rb +0 -40
  124. data/lib/kumi/error_reporter.rb +0 -164
  125. data/lib/kumi/error_reporting.rb +0 -95
  126. data/lib/kumi/evaluation_wrapper.rb +0 -38
  127. data/lib/kumi/explain.rb +0 -293
  128. data/lib/kumi/export/deserializer.rb +0 -39
  129. data/lib/kumi/export/errors.rb +0 -12
  130. data/lib/kumi/export/node_builders.rb +0 -140
  131. data/lib/kumi/export/node_registry.rb +0 -52
  132. data/lib/kumi/export/node_serializers.rb +0 -156
  133. data/lib/kumi/export/serializer.rb +0 -23
  134. data/lib/kumi/export.rb +0 -33
  135. data/lib/kumi/function_registry/collection_functions.rb +0 -200
  136. data/lib/kumi/function_registry/comparison_functions.rb +0 -31
  137. data/lib/kumi/function_registry/conditional_functions.rb +0 -36
  138. data/lib/kumi/function_registry/function_builder.rb +0 -93
  139. data/lib/kumi/function_registry/logical_functions.rb +0 -42
  140. data/lib/kumi/function_registry/math_functions.rb +0 -72
  141. data/lib/kumi/function_registry/string_functions.rb +0 -54
  142. data/lib/kumi/function_registry/type_functions.rb +0 -51
  143. data/lib/kumi/input/type_matcher.rb +0 -95
  144. data/lib/kumi/input/validator.rb +0 -49
  145. data/lib/kumi/input/violation_creator.rb +0 -50
  146. data/lib/kumi/json_schema/generator.rb +0 -63
  147. data/lib/kumi/json_schema/validator.rb +0 -25
  148. data/lib/kumi/json_schema.rb +0 -14
  149. data/lib/kumi/ruby_parser/build_context.rb +0 -25
  150. data/lib/kumi/ruby_parser/declaration_reference_proxy.rb +0 -36
  151. data/lib/kumi/ruby_parser/dsl.rb +0 -12
  152. data/lib/kumi/ruby_parser/dsl_cascade_builder.rb +0 -136
  153. data/lib/kumi/ruby_parser/expression_converter.rb +0 -126
  154. data/lib/kumi/ruby_parser/guard_rails.rb +0 -43
  155. data/lib/kumi/ruby_parser/input_builder.rb +0 -125
  156. data/lib/kumi/ruby_parser/input_field_proxy.rb +0 -46
  157. data/lib/kumi/ruby_parser/input_proxy.rb +0 -29
  158. data/lib/kumi/ruby_parser/nested_input.rb +0 -15
  159. data/lib/kumi/ruby_parser/parser.rb +0 -69
  160. data/lib/kumi/ruby_parser/schema_builder.rb +0 -173
  161. data/lib/kumi/ruby_parser/sugar.rb +0 -261
  162. data/lib/kumi/ruby_parser.rb +0 -10
  163. data/lib/kumi/schema_instance.rb +0 -109
  164. data/lib/kumi/types/builder.rb +0 -21
  165. data/lib/kumi/types/compatibility.rb +0 -94
  166. data/lib/kumi/types/formatter.rb +0 -24
  167. data/lib/kumi/types/inference.rb +0 -40
  168. data/lib/kumi/types/normalizer.rb +0 -70
  169. data/lib/kumi/types/validator.rb +0 -35
  170. data/lib/kumi/types.rb +0 -64
  171. 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.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Muta
@@ -65,73 +65,83 @@ files:
65
65
  - examples/wide_schema_compilation_and_evaluation_benchmark.rb
66
66
  - lib/kumi.rb
67
67
  - lib/kumi/analyzer.rb
68
- - lib/kumi/analyzer/analysis_state.rb
69
- - lib/kumi/analyzer/constant_evaluator.rb
70
- - lib/kumi/analyzer/passes/broadcast_detector.rb
71
- - lib/kumi/analyzer/passes/declaration_validator.rb
72
- - lib/kumi/analyzer/passes/dependency_resolver.rb
73
- - lib/kumi/analyzer/passes/input_collector.rb
74
- - lib/kumi/analyzer/passes/name_indexer.rb
75
- - lib/kumi/analyzer/passes/pass_base.rb
76
- - lib/kumi/analyzer/passes/semantic_constraint_validator.rb
77
- - lib/kumi/analyzer/passes/toposorter.rb
78
- - lib/kumi/analyzer/passes/type_checker.rb
79
- - lib/kumi/analyzer/passes/type_consistency_checker.rb
80
- - lib/kumi/analyzer/passes/type_inferencer.rb
81
- - lib/kumi/analyzer/passes/unsat_detector.rb
82
- - lib/kumi/analyzer/passes/visitor_pass.rb
83
- - lib/kumi/atom_unsat_solver.rb
84
68
  - lib/kumi/cli.rb
85
- - lib/kumi/compiled_schema.rb
86
69
  - lib/kumi/compiler.rb
87
- - lib/kumi/constraint_relationship_solver.rb
88
- - lib/kumi/domain/enum_analyzer.rb
89
- - lib/kumi/domain/range_analyzer.rb
90
- - lib/kumi/domain/validator.rb
91
- - lib/kumi/domain/violation_formatter.rb
92
- - lib/kumi/error_reporter.rb
93
- - 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
94
142
  - lib/kumi/errors.rb
95
- - lib/kumi/evaluation_wrapper.rb
96
- - lib/kumi/explain.rb
97
- - lib/kumi/export.rb
98
- - lib/kumi/export/deserializer.rb
99
- - lib/kumi/export/errors.rb
100
- - lib/kumi/export/node_builders.rb
101
- - lib/kumi/export/node_registry.rb
102
- - lib/kumi/export/node_serializers.rb
103
- - lib/kumi/export/serializer.rb
104
- - lib/kumi/function_registry.rb
105
- - lib/kumi/function_registry/collection_functions.rb
106
- - lib/kumi/function_registry/comparison_functions.rb
107
- - lib/kumi/function_registry/conditional_functions.rb
108
- - lib/kumi/function_registry/function_builder.rb
109
- - lib/kumi/function_registry/logical_functions.rb
110
- - lib/kumi/function_registry/math_functions.rb
111
- - lib/kumi/function_registry/string_functions.rb
112
- - lib/kumi/function_registry/type_functions.rb
113
- - lib/kumi/input/type_matcher.rb
114
- - lib/kumi/input/validator.rb
115
- - lib/kumi/input/violation_creator.rb
116
- - lib/kumi/json_schema.rb
117
- - lib/kumi/json_schema/generator.rb
118
- - lib/kumi/json_schema/validator.rb
119
- - lib/kumi/ruby_parser.rb
120
- - lib/kumi/ruby_parser/build_context.rb
121
- - lib/kumi/ruby_parser/declaration_reference_proxy.rb
122
- - lib/kumi/ruby_parser/dsl.rb
123
- - lib/kumi/ruby_parser/dsl_cascade_builder.rb
124
- - lib/kumi/ruby_parser/expression_converter.rb
125
- - lib/kumi/ruby_parser/guard_rails.rb
126
- - lib/kumi/ruby_parser/input_builder.rb
127
- - lib/kumi/ruby_parser/input_field_proxy.rb
128
- - lib/kumi/ruby_parser/input_proxy.rb
129
- - lib/kumi/ruby_parser/nested_input.rb
130
- - lib/kumi/ruby_parser/parser.rb
131
- - lib/kumi/ruby_parser/schema_builder.rb
132
- - lib/kumi/ruby_parser/sugar.rb
143
+ - lib/kumi/registry.rb
133
144
  - lib/kumi/schema.rb
134
- - lib/kumi/schema_instance.rb
135
145
  - lib/kumi/schema_metadata.rb
136
146
  - lib/kumi/syntax/array_expression.rb
137
147
  - lib/kumi/syntax/call_expression.rb
@@ -147,15 +157,8 @@ files:
147
157
  - lib/kumi/syntax/root.rb
148
158
  - lib/kumi/syntax/trait_declaration.rb
149
159
  - lib/kumi/syntax/value_declaration.rb
150
- - lib/kumi/types.rb
151
- - lib/kumi/types/builder.rb
152
- - lib/kumi/types/compatibility.rb
153
- - lib/kumi/types/formatter.rb
154
- - lib/kumi/types/inference.rb
155
- - lib/kumi/types/normalizer.rb
156
- - lib/kumi/types/validator.rb
157
- - lib/kumi/vectorization_metadata.rb
158
160
  - lib/kumi/version.rb
161
+ - migrate_to_core_iterative.rb
159
162
  - scripts/generate_function_docs.rb
160
163
  homepage: https://github.com/amuta/kumi
161
164
  licenses:
@@ -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,246 +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: :inputs, :declarations
8
- # PRODUCES: :broadcasts
9
- class BroadcastDetector < PassBase
10
- def run(errors)
11
- input_meta = get_state(:inputs) || {}
12
- definitions = get_state(:declarations) || {}
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
- case result[:type]
35
- when :vectorized
36
- compiler_metadata[:vectorized_operations][name] = result[:info]
37
- # Store array source information for dimension checking
38
- array_source = extract_array_source(result[:info], array_fields)
39
- vectorized_values[name] = { vectorized: true, array_source: array_source }
40
- when :reduction
41
- compiler_metadata[:reduction_operations][name] = result[:info]
42
- # Reduction produces scalar, not vectorized
43
- vectorized_values[name] = { vectorized: false }
44
- end
45
- end
46
-
47
- state.with(:broadcasts, compiler_metadata.freeze)
48
- end
49
-
50
- private
51
-
52
- def find_array_fields(input_meta)
53
- result = {}
54
- input_meta.each do |name, meta|
55
- next unless meta[:type] == :array && meta[:children]
56
-
57
- result[name] = {
58
- element_fields: meta[:children].keys,
59
- element_types: meta[:children].transform_values { |v| v[:type] || :any }
60
- }
61
- end
62
- result
63
- end
64
-
65
- def analyze_value_vectorization(name, expr, array_fields, vectorized_values, errors)
66
- case expr
67
- when Kumi::Syntax::InputElementReference
68
- if array_fields.key?(expr.path.first)
69
- { type: :vectorized, info: { source: :array_field_access, path: expr.path } }
70
- else
71
- { type: :scalar }
72
- end
73
-
74
- when Kumi::Syntax::DeclarationReference
75
- # Check if this references a vectorized value
76
- vector_info = vectorized_values[expr.name]
77
- if vector_info && vector_info[:vectorized]
78
- { type: :vectorized, info: { source: :vectorized_declaration, name: expr.name } }
79
- else
80
- { type: :scalar }
81
- end
82
-
83
- when Kumi::Syntax::CallExpression
84
- analyze_call_vectorization(name, expr, array_fields, vectorized_values, errors)
85
-
86
- when Kumi::Syntax::CascadeExpression
87
- analyze_cascade_vectorization(name, expr, array_fields, vectorized_values, errors)
88
-
89
- else
90
- { type: :scalar }
91
- end
92
- end
93
-
94
- def analyze_call_vectorization(_name, expr, array_fields, vectorized_values, errors)
95
- # Check if this is a reduction function using function registry metadata
96
- if FunctionRegistry.reducer?(expr.fn_name)
97
- # Only treat as reduction if the argument is actually vectorized
98
- arg_info = analyze_argument_vectorization(expr.args.first, array_fields, vectorized_values)
99
- if arg_info[:vectorized]
100
- { type: :reduction, info: { function: expr.fn_name, source: arg_info[:source] } }
101
- else
102
- # Not a vectorized reduction - just a regular function call
103
- { type: :scalar }
104
- end
105
-
106
- else
107
- # Special case: all?, any?, none? functions with vectorized trait arguments should be treated as vectorized
108
- # for cascade condition purposes (they get transformed during compilation)
109
- if %i[all? any? none?].include?(expr.fn_name) && expr.args.length == 1
110
- arg = expr.args.first
111
- if arg.is_a?(Kumi::Syntax::ArrayExpression) && arg.elements.length == 1
112
- trait_ref = arg.elements.first
113
- if trait_ref.is_a?(Kumi::Syntax::DeclarationReference) && vectorized_values[trait_ref.name]&.[](:vectorized)
114
- return { type: :vectorized, info: { source: :cascade_condition_with_vectorized_trait, trait: trait_ref.name } }
115
- end
116
- end
117
- end
118
-
119
- # ANY function with vectorized arguments becomes vectorized (with broadcasting)
120
- arg_infos = expr.args.map { |arg| analyze_argument_vectorization(arg, array_fields, vectorized_values) }
121
-
122
- if arg_infos.any? { |info| info[:vectorized] }
123
- # Check for dimension mismatches when multiple arguments are vectorized
124
- vectorized_sources = arg_infos.select { |info| info[:vectorized] }.filter_map { |info| info[:array_source] }.uniq
125
-
126
- if vectorized_sources.length > 1
127
- # Multiple different array sources - this is a dimension mismatch
128
- # Generate enhanced error message with type information
129
- enhanced_message = build_dimension_mismatch_error(expr, arg_infos, array_fields, vectorized_sources)
130
-
131
- report_error(errors, enhanced_message, location: expr.loc, type: :semantic)
132
- return { type: :scalar } # Treat as scalar to prevent further errors
133
- end
134
-
135
- # This is a vectorized operation - ANY function supports broadcasting
136
- { type: :vectorized, info: {
137
- operation: expr.fn_name,
138
- vectorized_args: arg_infos.map.with_index { |info, i| [i, info[:vectorized]] }.to_h
139
- } }
140
- else
141
- { type: :scalar }
142
- end
143
- end
144
- end
145
-
146
- def analyze_argument_vectorization(arg, array_fields, vectorized_values)
147
- case arg
148
- when Kumi::Syntax::InputElementReference
149
- if array_fields.key?(arg.path.first)
150
- { vectorized: true, source: :array_field, array_source: arg.path.first }
151
- else
152
- { vectorized: false }
153
- end
154
-
155
- when Kumi::Syntax::DeclarationReference
156
- # Check if this references a vectorized value
157
- vector_info = vectorized_values[arg.name]
158
- if vector_info && vector_info[:vectorized]
159
- array_source = vector_info[:array_source]
160
- { vectorized: true, source: :vectorized_value, array_source: array_source }
161
- else
162
- { vectorized: false }
163
- end
164
-
165
- when Kumi::Syntax::CallExpression
166
- # Recursively check
167
- result = analyze_value_vectorization(nil, arg, array_fields, vectorized_values, [])
168
- { vectorized: result[:type] == :vectorized, source: :expression }
169
-
170
- else
171
- { vectorized: false }
172
- end
173
- end
174
-
175
- def extract_array_source(info, _array_fields)
176
- case info[:source]
177
- when :array_field_access
178
- info[:path]&.first
179
- when :cascade_condition_with_vectorized_trait
180
- # For cascades, we'd need to trace back to the original source
181
- nil # TODO: Could be enhanced to trace through trait dependencies
182
- end
183
- end
184
-
185
- def analyze_cascade_vectorization(_name, expr, array_fields, vectorized_values, errors)
186
- # A cascade is vectorized if:
187
- # 1. Any of its result expressions are vectorized, OR
188
- # 2. Any of its conditions reference vectorized values (traits or arrays)
189
- vectorized_results = []
190
- vectorized_conditions = []
191
-
192
- expr.cases.each do |case_expr|
193
- # Check if result is vectorized
194
- result_info = analyze_value_vectorization(nil, case_expr.result, array_fields, vectorized_values, errors)
195
- vectorized_results << (result_info[:type] == :vectorized)
196
-
197
- # Check if condition is vectorized
198
- condition_info = analyze_value_vectorization(nil, case_expr.condition, array_fields, vectorized_values, errors)
199
- vectorized_conditions << (condition_info[:type] == :vectorized)
200
- end
201
-
202
- if vectorized_results.any? || vectorized_conditions.any?
203
- { type: :vectorized, info: { source: :cascade_with_vectorized_conditions_or_results } }
204
- else
205
- { type: :scalar }
206
- end
207
- end
208
-
209
- def build_dimension_mismatch_error(_expr, arg_infos, array_fields, vectorized_sources)
210
- # Build detailed error message with type information
211
- summary = "Cannot broadcast operation across arrays from different sources: #{vectorized_sources.join(', ')}. "
212
-
213
- problem_desc = "Problem: Multiple operands are arrays from different sources:\n"
214
-
215
- vectorized_args = arg_infos.select { |info| info[:vectorized] }
216
- vectorized_args.each_with_index do |arg_info, index|
217
- array_source = arg_info[:array_source]
218
- next unless array_source && array_fields[array_source]
219
-
220
- # Determine the type based on array field metadata
221
- type_desc = determine_array_type(array_source, array_fields)
222
- problem_desc += " - Operand #{index + 1} resolves to #{type_desc} from array '#{array_source}'\n"
223
- end
224
-
225
- explanation = "Direct operations on arrays from different sources is ambiguous and not supported. " \
226
- "Vectorized operations can only work on fields from the same array input."
227
-
228
- "#{summary}#{problem_desc}#{explanation}"
229
- end
230
-
231
- def determine_array_type(array_source, array_fields)
232
- field_info = array_fields[array_source]
233
- return "array(any)" unless field_info[:element_types]
234
-
235
- # For nested arrays (like items.name where items is an array), this represents array(element_type)
236
- element_types = field_info[:element_types].values.uniq
237
- if element_types.length == 1
238
- "array(#{element_types.first})"
239
- else
240
- "array(mixed)"
241
- end
242
- end
243
- end
244
- end
245
- end
246
- 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