kumi 0.0.9 → 0.0.11

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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/CLAUDE.md +18 -258
  4. data/README.md +188 -121
  5. data/docs/AST.md +1 -1
  6. data/docs/FUNCTIONS.md +52 -8
  7. data/docs/VECTOR_SEMANTICS.md +286 -0
  8. data/docs/compiler_design_principles.md +86 -0
  9. data/docs/features/README.md +15 -2
  10. data/docs/features/hierarchical-broadcasting.md +349 -0
  11. data/docs/features/javascript-transpiler.md +148 -0
  12. data/docs/features/performance.md +1 -3
  13. data/docs/features/s-expression-printer.md +2 -2
  14. data/docs/schema_metadata.md +7 -7
  15. data/examples/deep_schema_compilation_and_evaluation_benchmark.rb +21 -15
  16. data/examples/game_of_life.rb +2 -4
  17. data/lib/kumi/analyzer.rb +34 -14
  18. data/lib/kumi/compiler.rb +4 -283
  19. data/lib/kumi/core/analyzer/passes/broadcast_detector.rb +717 -66
  20. data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +1 -1
  21. data/lib/kumi/core/analyzer/passes/input_access_planner_pass.rb +47 -0
  22. data/lib/kumi/core/analyzer/passes/input_collector.rb +118 -99
  23. data/lib/kumi/core/analyzer/passes/join_reduce_planning_pass.rb +293 -0
  24. data/lib/kumi/core/analyzer/passes/lower_to_ir_pass.rb +993 -0
  25. data/lib/kumi/core/analyzer/passes/pass_base.rb +2 -2
  26. data/lib/kumi/core/analyzer/passes/scope_resolution_pass.rb +346 -0
  27. data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +28 -0
  28. data/lib/kumi/core/analyzer/passes/toposorter.rb +9 -3
  29. data/lib/kumi/core/analyzer/passes/type_checker.rb +9 -5
  30. data/lib/kumi/core/analyzer/passes/type_consistency_checker.rb +2 -2
  31. data/lib/kumi/core/analyzer/passes/{type_inferencer.rb → type_inferencer_pass.rb} +4 -4
  32. data/lib/kumi/core/analyzer/passes/unsat_detector.rb +92 -48
  33. data/lib/kumi/core/analyzer/plans.rb +52 -0
  34. data/lib/kumi/core/analyzer/structs/access_plan.rb +20 -0
  35. data/lib/kumi/core/analyzer/structs/input_meta.rb +29 -0
  36. data/lib/kumi/core/compiler/access_builder.rb +36 -0
  37. data/lib/kumi/core/compiler/access_planner.rb +219 -0
  38. data/lib/kumi/core/compiler/accessors/base.rb +69 -0
  39. data/lib/kumi/core/compiler/accessors/each_indexed_accessor.rb +84 -0
  40. data/lib/kumi/core/compiler/accessors/materialize_accessor.rb +55 -0
  41. data/lib/kumi/core/compiler/accessors/ravel_accessor.rb +73 -0
  42. data/lib/kumi/core/compiler/accessors/read_accessor.rb +41 -0
  43. data/lib/kumi/core/compiler_base.rb +137 -0
  44. data/lib/kumi/core/error_reporter.rb +6 -5
  45. data/lib/kumi/core/errors.rb +4 -0
  46. data/lib/kumi/core/explain.rb +157 -205
  47. data/lib/kumi/core/export/node_builders.rb +2 -2
  48. data/lib/kumi/core/export/node_serializers.rb +1 -1
  49. data/lib/kumi/core/function_registry/collection_functions.rb +100 -6
  50. data/lib/kumi/core/function_registry/conditional_functions.rb +14 -4
  51. data/lib/kumi/core/function_registry/function_builder.rb +142 -53
  52. data/lib/kumi/core/function_registry/logical_functions.rb +173 -3
  53. data/lib/kumi/core/function_registry/stat_functions.rb +156 -0
  54. data/lib/kumi/core/function_registry.rb +138 -98
  55. data/lib/kumi/core/ir/execution_engine/combinators.rb +117 -0
  56. data/lib/kumi/core/ir/execution_engine/interpreter.rb +336 -0
  57. data/lib/kumi/core/ir/execution_engine/values.rb +46 -0
  58. data/lib/kumi/core/ir/execution_engine.rb +50 -0
  59. data/lib/kumi/core/ir.rb +58 -0
  60. data/lib/kumi/core/ruby_parser/build_context.rb +2 -2
  61. data/lib/kumi/core/ruby_parser/declaration_reference_proxy.rb +0 -12
  62. data/lib/kumi/core/ruby_parser/dsl_cascade_builder.rb +37 -16
  63. data/lib/kumi/core/ruby_parser/input_builder.rb +61 -8
  64. data/lib/kumi/core/ruby_parser/parser.rb +1 -1
  65. data/lib/kumi/core/ruby_parser/schema_builder.rb +2 -2
  66. data/lib/kumi/core/ruby_parser/sugar.rb +7 -0
  67. data/lib/kumi/errors.rb +2 -0
  68. data/lib/kumi/js.rb +23 -0
  69. data/lib/kumi/registry.rb +17 -22
  70. data/lib/kumi/runtime/executable.rb +213 -0
  71. data/lib/kumi/schema.rb +15 -4
  72. data/lib/kumi/schema_metadata.rb +2 -2
  73. data/lib/kumi/support/ir_dump.rb +491 -0
  74. data/lib/kumi/support/s_expression_printer.rb +17 -16
  75. data/lib/kumi/syntax/array_expression.rb +6 -6
  76. data/lib/kumi/syntax/call_expression.rb +4 -4
  77. data/lib/kumi/syntax/cascade_expression.rb +4 -4
  78. data/lib/kumi/syntax/case_expression.rb +4 -4
  79. data/lib/kumi/syntax/declaration_reference.rb +4 -4
  80. data/lib/kumi/syntax/hash_expression.rb +4 -4
  81. data/lib/kumi/syntax/input_declaration.rb +6 -5
  82. data/lib/kumi/syntax/input_element_reference.rb +5 -5
  83. data/lib/kumi/syntax/input_reference.rb +5 -5
  84. data/lib/kumi/syntax/literal.rb +4 -4
  85. data/lib/kumi/syntax/location.rb +5 -0
  86. data/lib/kumi/syntax/node.rb +33 -34
  87. data/lib/kumi/syntax/root.rb +6 -6
  88. data/lib/kumi/syntax/trait_declaration.rb +4 -4
  89. data/lib/kumi/syntax/value_declaration.rb +4 -4
  90. data/lib/kumi/version.rb +1 -1
  91. data/lib/kumi.rb +6 -15
  92. data/scripts/analyze_broadcast_methods.rb +68 -0
  93. data/scripts/analyze_cascade_methods.rb +74 -0
  94. data/scripts/check_broadcasting_coverage.rb +51 -0
  95. data/scripts/find_dead_code.rb +114 -0
  96. metadata +36 -9
  97. data/docs/features/array-broadcasting.md +0 -170
  98. data/lib/kumi/cli.rb +0 -449
  99. data/lib/kumi/core/compiled_schema.rb +0 -43
  100. data/lib/kumi/core/evaluation_wrapper.rb +0 -40
  101. data/lib/kumi/core/schema_instance.rb +0 -111
  102. data/lib/kumi/core/vectorization_metadata.rb +0 -110
  103. data/migrate_to_core_iterative.rb +0 -938
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5f9f087001a482c906f041da8cb229511966a11c56e3ced99930b59d4141543
4
- data.tar.gz: fe5fafe03a5ca1e414b5bc3af9eccd830553aa8f44762e9d9b38e589fa342fd1
3
+ metadata.gz: 3eb46e14716bf14c3d9165ffac957211f41ad5a21a74ad37c47b37c37e01b312
4
+ data.tar.gz: fd0e36d65ac41079c27cf9699a3e092ff762bc76b3af8fc90df2ec763fed3806
5
5
  SHA512:
6
- metadata.gz: b26279c08a9387616104252d24147c920f27b0f66574cde1987024325c5fd1ba87aff876b39fdc3d4f472d9aba2c713b19a5105890b66ac3ef10a3018a0b1bca
7
- data.tar.gz: d4c8db755880cd7088fd4b6087d2f38e86a4fdee11f867d58a480e143494ca2b85440abd9249b8c02a469a9ad21642c287d5ef8f30948bdc6d67695a895c1c13
6
+ metadata.gz: 54ed5e72d6acf863e0f7ed0986c8db83fab22526bcffb97b4c1b96343e724b0ae505804baed5554933c452478ced8c46ec24a6568426813e69c4007994588de6
7
+ data.tar.gz: '09aabb772643aab71d957060c934f05be5838a1056b7c635822b75759106a3119844cc7e20f96b8990ec658d969f2d2e0143ceb43d36f8d48da061c2bb80cb6a'
data/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ ## [0.0.11] – 2025-08-13
2
+ ### Added
3
+ - Intermediate Representation (IR) and slot-based VM interpreter.
4
+ - Scope-aware vector semantics (alignment, lift, hierarchical indices).
5
+ - Debug tooling: IR dump, VM/lowering traces via DEBUG_* flags.
6
+
7
+ ### Changed
8
+ - Analyzer now lowers to IR via `LowerToIRPass`.
9
+ - Access modes: `:read`, `:ravel`, `:each_indexed`, `:materialize`.
10
+
11
+ ### Removed (BREAKING)
12
+ - JavaScript transpiler (legacy compiler).
13
+
14
+ ### Requirements
15
+ - Ruby >= 3.1 (Was >= 3.0)
16
+
17
+ ### Notes
18
+ - No expected DSL changes for typical schemas; report regressions.
data/CLAUDE.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # CLAUDE.md
2
2
 
3
+ !! Important:
3
4
  !! Remember, this gem is not on production yet, so no backward compatilibity is necessary. But do not change the public interfaces (e.g. DSL, Schema) without explicitly requested or demanded.
4
5
  !! We are using zeitwerk, i.e.: no requires
5
- !! Do not care about linter or coverage unless asked to do so.
6
- !! IMPORTANT: Communication style - Write direct, factual statements. Avoid promotional language, unnecessary claims, or marketing speak. State what the system does, not what benefits it provides. Use TODOs for missing information rather than placeholder claims.
6
+ !! Disregard linting or coverage issues unless asked to do so.
7
+ !! Communication style - Write direct, factual statements. Avoid promotional language, unnecessary claims, or marketing speak. State what the system does, not what benefits it provides. Use TODOs for missing information rather than placeholder claims.
8
+ !! See all Available Functions in docs/FUNCTIONS.md
7
9
 
8
10
  ## Project Overview
9
11
 
@@ -16,18 +18,13 @@ Kumi is a Declarative logic and rules engine framework with static analysis for
16
18
  - `bundle exec rspec spec/path/to/specific_spec.rb` - Run specific test file
17
19
  - `bundle exec rspec spec/path/to/specific_spec.rb:123` - Run specific test at line
18
20
 
19
- ### Gem Management
20
- - `bundle install` - Install dependencies
21
- - `gem build kumi.gemspec` - Build the gem
22
- - `gem install ./kumi-*.gem` - Install locally built gem
23
-
24
21
  ## Architecture Overview
25
22
 
26
23
  ### Core Components
27
24
 
28
25
  **Schema System** (`lib/kumi/schema.rb`):
29
26
  - Entry point that ties together parsing, analysis, and compilation
30
- - Provides the `schema(&block)` DSL method that builds the syntax tree, runs analysis, and compiles to executable form
27
+ - DSL method `schema(&block)` builds the syntax tree, runs analysis, and compiles to executable form
31
28
  - Generates a `Runner` instance for executing queries against input data
32
29
 
33
30
  **Parser** (`lib/kumi/ruby_parser{/*,.rb}`):
@@ -60,71 +57,18 @@ Kumi is a Declarative logic and rules engine framework with static analysis for
60
57
  - **Pass 8**: `type_checker.rb` - Validate function types and compatibility using inferred types
61
58
 
62
59
  **Compiler** (`lib/kumi/compiler.rb`):
63
- - Transforms analyzed syntax tree into executable lambda functions
60
+ - Compiles analyzed syntax tree into executable lambda functions
64
61
  - Maps each expression type to a compilation method
65
62
  - Handles function calls via `Kumi::Registry`
66
63
  - Produces `CompiledSchema` with executable bindings
67
64
 
68
65
  **Function Registry** (`lib/kumi/function_registry.rb`):
69
66
  - Registry of available functions (operators, math, string, logical, collection operations)
70
- - Supports custom function registration with comprehensive type metadata
67
+ - Supports custom function registration with type metadata
71
68
  - Each function includes param_types, return_type, arity, and description
72
69
  - Core functions include: `==`, `>`, `<`, `add`, `multiply`, `and`, `or`, `clamp`, etc.
73
- - Maintains backward compatibility with legacy type checking system
74
70
  - Function documents are generated by the script ./scripts/generate_function_docs.rb
75
71
 
76
- **Runner** (`lib/kumi/runner.rb`):
77
- - Executes compiled schemas against input data
78
- - Provides `fetch(key)` for individual value retrieval with caching
79
- - Provides `slice(*keys)` for batch evaluation
80
- - Provides `explain(key)` for detailed execution tracing
81
-
82
- **Input Validation System** (`lib/kumi/input/` and `lib/kumi/domain/`):
83
- - `input/validator.rb` - Main validation coordinator for type and domain checking
84
- - `input/type_matcher.rb` - Type validation logic for primitive and complex types
85
- - `input/violation_creator.rb` - Creates standardized violation objects with detailed messages
86
- - `domain/validator.rb` - Domain constraint validation (ranges, arrays, procs)
87
- - `domain/range_analyzer.rb` - Range domain analysis and validation
88
- - `domain/enum_analyzer.rb` - Enumeration domain analysis and validation
89
- - `domain/violation_formatter.rb` - Formats domain violation error messages
90
-
91
- ## DSL Syntax Requirements
92
-
93
- ### Critical Syntax Rules
94
-
95
- **Module Definition Structure** (REQUIRED for CLI):
96
- ```ruby
97
- # CORRECT - CLI can find and load this
98
- module SchemaName
99
- extend Kumi::Schema
100
-
101
- schema do
102
- # schema definition here
103
- end
104
- end
105
-
106
- # INCORRECT - CLI cannot load standalone schemas
107
- schema do # This won't work with CLI
108
- # schema definition
109
- end
110
- ```
111
-
112
- **Function Call Syntax**:
113
- - **Symbol style**: `fn(:function_name, arg1, arg2, ...)` - The only supported function call syntax
114
-
115
- **Arithmetic Operations**:
116
- - **Sugar Syntax**: `input.field1 + input.field2` - Works for input fields and value references
117
- - **Function Syntax**: `fn(:add, input.field1, input.field2)` - Always works, more explicit
118
- - **Mixed**: Use sugar for simple operations, functions for complex ones
119
-
120
- **Cascade Condition Syntax**:
121
- ```ruby
122
- value :status do
123
- on trait_name, "Result"
124
- base "Default"
125
- end
126
- ```
127
-
128
72
  ### Key Patterns
129
73
  **DSL Structure**:
130
74
  ```ruby
@@ -142,38 +86,22 @@ schema do
142
86
  string :category
143
87
  end
144
88
 
145
-
146
-
147
89
  # Fields with no declared type
148
90
  any :misc_field
149
91
  end
150
92
 
151
- trait :name, (expression) # Boolean conditions with new syntax
93
+ trait :name, (expression) # Boolean conditions
152
94
  value :name, expression # Computed values
153
95
  value :name do # Conditional logic
154
- on condition, result
155
- base default_result
96
+ on condition, result # on <trait> ?,<trait> , <expr>
97
+ base default_result # base <expr>
156
98
  end
157
99
  end
158
100
  ```
159
101
 
160
102
  **IMPORTANT CASCADE CONDITION SYNTAX:**
161
103
  In cascade expressions (`value :name do ... end`), trait references use bare identifiers:
162
- ```ruby
163
- value :status do
164
- on adult, "Adult Status"
165
- on verified, "Verified User"
166
- base "Unverified"
167
- end
168
- ```
169
104
 
170
- **Input Block System**:
171
- - **Required**: All schemas must have an `input` block declaring expected fields
172
- - **Type Declarations**: Preferred via type-specific methods (e.g. `integer :field`, `string :name`, `any :field` for untyped fields)
173
- - **Complex Types**: Use helper functions: `array(:element_type)` and `hash(:key_type, :value_type)`
174
- - **Domain Constraints**: Fields can have domains: `integer :age, domain: 18..65` (validated at runtime)
175
- - **Field Access**: Use `input.field_name` to reference input fields in expressions
176
- - **Separation**: Input metadata (types, domains) is separate from business logic
177
105
 
178
106
  **Expression Types**:
179
107
  - `input.field_name` - Access input data with operator methods (>=, <=, >, <, ==, !=)
@@ -190,86 +118,24 @@ end
190
118
  4. Execute with Runner
191
119
 
192
120
  **Type System** (`lib/kumi/types.rb`):
193
- - Simple symbol-based type system for clean and intuitive declaration
121
+ - Symbol-based type system
194
122
  - **Dual Type System**: Declared types (from input blocks) and inferred types (from expressions)
195
- - Automatic type inference for all declarations based on expression analysis
123
+ - Type inference for all declarations based on expression analysis
196
124
  - Type primitives: `:string`, `:integer`, `:float`, `:boolean`, `:any`, `:symbol`, `:regexp`, `:time`, `:date`, `:datetime`
197
125
  - Collection types: `array(:element_type)` and `hash(:key_type, :value_type)` helper functions
198
- - Type compatibility checking and unification algorithms for numeric types
199
- - Enhanced error messages showing type provenance (declared vs inferred)
200
- - Legacy compatibility constants maintained for backward compatibility
201
-
202
- ### Examples Directory
203
-
204
- The `examples/` directory contains comprehensive examples showing Kumi usage patterns:
205
- - `cascade_demonstration.rb` - Demonstrates cascade logic with UnsatDetector fixes (working)
206
- - `working_comprehensive_schema.rb` - Complete feature showcase (current best practices, working)
207
- - Mathematical predicate examples - Safe mutual recursion patterns using cascade mutual exclusion
208
- - `federal_tax_calculator_2024.rb` - Real-world tax calculation example (working)
209
- - `tax_2024.rb` - Simple tax example with explain functionality (working)
210
- - `wide_schema_compilation_and_evaluation_benchmark.rb` - Performance benchmark for wide schemas (compilation and evaluation scaling)
211
- - `deep_schema_compilation_and_evaluation_benchmark.rb` - Performance benchmark for deep dependency chains (stack-safe evaluation)
212
- - `comprehensive_god_schema.rb` - Complex example (currently has UnsatDetector semantic errors)
213
-
214
- *Note: Some examples may use deprecated syntax and should be updated to use the new input block system.*
215
-
216
- ## Test Structure
217
-
218
- - `spec/kumi/` - Unit tests for core components
219
- - `spec/integration/` - Integration tests for full workflows
220
- - `spec/fixtures/` - Test fixtures and sample schemas
221
- - `spec/support/` - Test helpers (`ast_factory.rb`, `schema_generator.rb`)
222
126
 
223
127
  ## Files for Understanding
224
128
 
225
129
  . `docs/*` - Documents about Kumi, its features, DSL syntax, ...
226
- - `examples/*` Random examples of very diverse contexts.
130
+ - `examples/*` Random examples of diverse contexts.
227
131
 
228
132
  ### Troubleshooting Schema Issues
229
- - **Parse Errors**: Check function syntax (avoid empty `fn()` calls)
230
- - **Module Not Found**: Ensure proper module structure and naming, see examples
231
- - **UnsatDetector Errors**: Review trait logic for contradictions, add debugs!
232
- - **Type Errors**: Check input block type declarations match usage, add debugs!
233
- - **Runtime Errors**: Use explain to trace computation dependencies, add debugs!
133
+ DEBUG, DEBUG. DEBUG LOGS!
234
134
 
235
- ## Input Block System Details
236
-
237
- ### Required Input Blocks
238
- - **All schemas must have an input block** -
239
- - Input blocks declare expected fields with optional type and domain constraints
240
- - **Empty input blocks are allowed** -`input {}` Even if its not very useful.
241
- - Fields are accessed via `input.field_name` or `input.field.nested_field.nested_nested_field` which
242
- works for referencing nested array input declarations.
243
-
244
- ### Type System Integration
245
- - **Declared Types**: Explicit type declarations in input blocks (e.g. `integer :field`, `string :name`, `any :field`)
246
- - **Inferred Types**: Types automatically inferred from expression analysis
247
- - **Type Checking**: Validates compatibility between declared and inferred types
248
- - **Enhanced Errors**: Error messages show type provenance (declared vs inferred)
249
- - **Helper Functions**: Use `array(:type)` and `hash(:key_type, :value_type)` for complex types
250
-
251
- ### Parser Components
252
- See `lib/kumi/ruby_parser/parser.rb`
253
-
254
- ### Domain Constraints
255
- - Can be declared: `integer :age, domain: 18..65`
256
- - Supports Range domains (`18..65`), Array domains (`%w[active inactive]`), and Proc domains for custom validation
257
- - Analyzer do some limited domain UNSAT detection, and its used to validated against input at Runtime
258
- ### Type Examples
259
- ```ruby
260
- input do
261
- string :name
262
- integer :age, domain: 18..65
263
- hash :metadata, key: { type: :string }, val: { type: :any }
264
-
265
- #generic type
266
- any :misc # this will make Kumi lose most of its analyze/inference power
267
- end
268
- ```
269
135
 
270
136
  ### Array Broadcasting System
271
137
 
272
- **Automatic Vectorization**: Field access on array inputs (`input.items.price`) applies operations element-wise with intelligent map/reduce detection.
138
+ **Vectorization**: Field access on array inputs (`input.items.price`) applies operations element-wise with map/reduce detection.
273
139
 
274
140
  **Basic Broadcasting**:
275
141
  ```ruby
@@ -278,6 +144,9 @@ input do
278
144
  float :price
279
145
  integer :quantity
280
146
  string :category
147
+ array :prices do
148
+ element :integer, :val
149
+ end
281
150
  end
282
151
  end
283
152
 
@@ -285,112 +154,3 @@ end
285
154
  value :subtotals, input.line_items.price * input.line_items.quantity
286
155
  trait :is_taxable, (input.line_items.category != "digital")
287
156
  ```
288
-
289
- **Aggregation Operations**: Functions consuming arrays automatically detected:
290
- ```ruby
291
- value :total_subtotal, fn(:sum, subtotals)
292
- value :avg_price, fn(:avg, input.line_items.price)
293
- value :max_quantity, fn(:max, input.line_items.quantity)
294
- ```
295
-
296
- **Implementation Components**:
297
- - **InputElementReference** AST nodes for nested field access paths
298
- - **BroadcastDetector** analyzer pass identifies vectorized vs scalar operations
299
- - **Compiler** generates appropriate map/reduce functions based on usage context
300
- - **Type Inference** automatically infers types for array element operations
301
- - Supports arbitrary depth field access with nested arrays and hashes
302
-
303
- ### Trait Syntax Evolution
304
-
305
- **Current Syntax** (recommended):
306
- ```ruby
307
- trait :adult, (input.age >= 18)
308
- trait :qualified, (input.age >= 21) & (input.score > 80) & (input.verified == true)
309
- ```
310
-
311
- **Composite Trait Syntax** (NEW - bare identifier references):
312
- ```ruby
313
- # Base traits
314
- trait :adult, (input.age >= 18)
315
- trait :verified, (input.verified == true)
316
- trait :high_score, (input.score > 80)
317
-
318
- # Composite traits using bare identifier syntax
319
- trait :eligible, adult & verified & high_score
320
- trait :mixed, adult & (input.income > 50_000) & verified
321
-
322
- # Backward compatibility - both syntaxes work together
323
- trait :legacy_mix, adult & ref(:verified) & (input.score > 90)
324
- ```
325
-
326
- **Deprecated Syntax** (with warnings):
327
- ```ruby
328
- trait :adult, input.age, :>=, 18 # OLD - shows deprecation warning
329
- trait :qualified, input.age, :>=, 21, input.score # OLD - shows deprecation warning
330
- ```
331
-
332
- **Key Changes**:
333
- - **NEW**: Bare identifier syntax allows direct trait reference: `adult` instead of `ref(:adult)`
334
- - New syntax uses parenthesized expressions: `trait :name, (expression)`
335
- - FieldRef nodes have operator methods that create CallExpression nodes
336
- - Logical AND chaining via `&` operator (Ruby limitation prevents `&&`)
337
- - Only AND operations supported to maintain constraint satisfaction system
338
- - **Backward Compatible**: Both `trait_name` and `ref(:trait_name)` work together
339
- - Old syntax maintained with deprecation warnings for backward compatibility
340
-
341
- ## Common Development Tasks
342
-
343
- ### Adding New Analyzer Passes
344
- 1. Create pass class inheriting from `PassBase` in `lib/kumi/analyzer/passes/`
345
- 2. Implement `run(errors)` method that calls `set_state(key, value)` to store results
346
- 3. Add pass to `PASSES` array in `lib/kumi/analyzer.rb` in correct order
347
- 4. Consider dependencies on other passes (e.g., TypeChecker needs TypeInferencer)
348
-
349
- ## Architecture Design Principles
350
-
351
- - **Multi-pass Analysis**: Each analysis pass has a single responsibility and builds on previous passes
352
- - **Immutable Syntax Tree**: AST nodes are immutable; analysis results stored separately in analyzer state
353
- - **Dependency-driven Evaluation**: All computation follows dependency graph to ensure correct order
354
- - **Type Safety**: Optional but comprehensive type checking without breaking existing schemas
355
- - **Ruby Integration**: Leverages Ruby's metaprogramming while providing structured analysis
356
- - **Unified Error Reporting**: Consistent, localized error messages throughout the system with clear interface patterns
357
-
358
- ## Code Organization Patterns
359
-
360
- ### Testing Best Practices
361
- - **Spec Organization**: Tests organized by component with clear separation between unit and integration tests
362
- - **Error Variable Extraction**: RSpec patterns avoid multiline block chains by extracting error variables for assertion
363
-
364
- ## Development Guides and Standards
365
-
366
- ### Error Reporting Standards
367
- **For Parser Classes**:
368
- ```ruby
369
- class MyParser
370
- include ErrorReporting
371
-
372
- def parse_something
373
- # Immediate error raising
374
- raise_syntax_error("Invalid syntax", location: current_location)
375
- end
376
- end
377
- ```
378
-
379
- **For Analyzer Passes**:
380
- ```ruby
381
- class MyAnalyzerPass < PassBase
382
- def run(errors)
383
- # Error accumulation with enhanced location
384
- report_error(errors, "semantic error", location: node.loc, type: :semantic)
385
-
386
- # Backward compatible method
387
- add_error(errors, node.loc, "legacy format error")
388
- end
389
- end
390
- ```
391
- ### Testing Error Scenarios
392
- - Use `spec/integration/dsl_breakage_spec.rb` patterns for comprehensive error testing
393
- - Use `spec/integration/potential_breakage_spec.rb` for edge cases break
394
- - Use `spec/fixtures/location_tracking_test_schema.rb` fixture for testing different syntax error types
395
-
396
- #