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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/README.md +31 -99
- data/data/kernels/ruby/core/arithmetic.yaml +2 -2
- data/docs/COMPOSED_SCHEMAS.md +137 -0
- data/docs/SCHEMA_IMPORTS.md +275 -0
- data/docs/SYNTAX.md +48 -0
- data/golden/array_element/expected/schema_ruby.rb +2 -27
- data/golden/array_index/expected/nast.txt +6 -6
- data/golden/array_index/expected/schema_ruby.rb +4 -31
- data/golden/array_operations/expected/lir_06_const_prop.txt +4 -8
- data/golden/array_operations/expected/schema_javascript.mjs +4 -8
- data/golden/array_operations/expected/schema_ruby.rb +10 -43
- data/golden/cascade_logic/expected/lir_06_const_prop.txt +7 -14
- data/golden/cascade_logic/expected/schema_javascript.mjs +7 -14
- data/golden/cascade_logic/expected/schema_ruby.rb +11 -45
- data/golden/chained_fusion/expected/lir_06_const_prop.txt +8 -18
- data/golden/chained_fusion/expected/schema_javascript.mjs +8 -18
- data/golden/chained_fusion/expected/schema_ruby.rb +14 -53
- data/golden/decimal_explicit/expected/schema_ruby.rb +4 -31
- data/golden/element_arrays/expected/lir_06_const_prop.txt +5 -11
- data/golden/element_arrays/expected/schema_javascript.mjs +5 -11
- data/golden/element_arrays/expected/schema_ruby.rb +13 -50
- data/golden/empty_and_null_inputs/expected/schema_ruby.rb +4 -31
- data/golden/example_xpto/expected/ast.txt +23 -0
- data/golden/example_xpto/expected/input_plan.txt +1 -0
- data/golden/example_xpto/expected/lir_00_unoptimized.txt +16 -0
- data/golden/example_xpto/expected/lir_01_hoist_scalar_references.txt +16 -0
- data/golden/example_xpto/expected/lir_02_inlined.txt +16 -0
- data/golden/example_xpto/expected/lir_03_cse.txt +16 -0
- data/golden/example_xpto/expected/lir_04_1_loop_fusion.txt +16 -0
- data/golden/example_xpto/expected/lir_04_loop_invcm.txt +16 -0
- data/golden/example_xpto/expected/lir_06_const_prop.txt +13 -0
- data/golden/example_xpto/expected/nast.txt +17 -0
- data/golden/example_xpto/expected/schema_javascript.mjs +13 -0
- data/golden/example_xpto/expected/schema_ruby.rb +13 -0
- data/golden/example_xpto/expected/snast.txt +17 -0
- data/golden/example_xpto/expected.json +4 -0
- data/golden/example_xpto/input.json +3 -0
- data/golden/example_xpto/schema.kumi +8 -0
- data/golden/function_overload/expected/schema_ruby.rb +2 -27
- data/golden/game_of_life/expected/lir_06_const_prop.txt +236 -287
- data/golden/game_of_life/expected/schema_javascript.mjs +32 -39
- data/golden/game_of_life/expected/schema_ruby.rb +34 -66
- data/golden/hash_keys/expected/lir_06_const_prop.txt +4 -10
- data/golden/hash_keys/expected/schema_javascript.mjs +6 -12
- data/golden/hash_keys/expected/schema_ruby.rb +8 -39
- data/golden/hash_value/expected/lir_06_const_prop.txt +3 -6
- data/golden/hash_value/expected/schema_javascript.mjs +3 -6
- data/golden/hash_value/expected/schema_ruby.rb +7 -37
- data/golden/hierarchical_complex/expected/lir_06_const_prop.txt +9 -18
- data/golden/hierarchical_complex/expected/schema_javascript.mjs +9 -18
- data/golden/hierarchical_complex/expected/schema_ruby.rb +14 -51
- data/golden/inline_rename_scope_leak/expected/lir_06_const_prop.txt +2 -6
- data/golden/inline_rename_scope_leak/expected/schema_javascript.mjs +2 -6
- data/golden/inline_rename_scope_leak/expected/schema_ruby.rb +7 -39
- data/golden/input_reference/expected/schema_ruby.rb +6 -35
- data/golden/interleaved_fusion/expected/lir_06_const_prop.txt +6 -14
- data/golden/interleaved_fusion/expected/schema_javascript.mjs +6 -14
- data/golden/interleaved_fusion/expected/schema_ruby.rb +11 -47
- data/golden/let_inline/expected/lir_06_const_prop.txt +1 -2
- data/golden/let_inline/expected/schema_javascript.mjs +1 -2
- data/golden/let_inline/expected/schema_ruby.rb +3 -29
- data/golden/loop_fusion/expected/lir_06_const_prop.txt +4 -10
- data/golden/loop_fusion/expected/schema_javascript.mjs +4 -10
- data/golden/loop_fusion/expected/schema_ruby.rb +8 -41
- data/golden/min_reduce_scope/expected/lir_06_const_prop.txt +3 -6
- data/golden/min_reduce_scope/expected/schema_javascript.mjs +3 -6
- data/golden/min_reduce_scope/expected/schema_ruby.rb +8 -39
- data/golden/mixed_dimensions/expected/lir_06_const_prop.txt +1 -2
- data/golden/mixed_dimensions/expected/schema_javascript.mjs +1 -2
- data/golden/mixed_dimensions/expected/schema_ruby.rb +5 -33
- data/golden/multirank_hoisting/expected/lir_06_const_prop.txt +9 -18
- data/golden/multirank_hoisting/expected/schema_javascript.mjs +9 -18
- data/golden/multirank_hoisting/expected/schema_ruby.rb +16 -55
- data/golden/nested_hash/expected/lir_06_const_prop.txt +1 -2
- data/golden/nested_hash/expected/schema_javascript.mjs +1 -2
- data/golden/nested_hash/expected/schema_ruby.rb +3 -29
- data/golden/reduction_broadcast/expected/schema_ruby.rb +5 -33
- data/golden/roll/expected/lir_06_const_prop.txt +8 -15
- data/golden/roll/expected/schema_javascript.mjs +8 -15
- data/golden/roll/expected/schema_ruby.rb +13 -48
- data/golden/schema_imports_broadcasting_with_imports/expected/ast.txt +26 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/input_plan.txt +5 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_00_unoptimized.txt +20 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_01_hoist_scalar_references.txt +20 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_02_inlined.txt +22 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_03_cse.txt +21 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_04_1_loop_fusion.txt +21 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_04_loop_invcm.txt +21 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/lir_06_const_prop.txt +21 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/nast.txt +12 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/schema_javascript.mjs +22 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/schema_ruby.rb +24 -0
- data/golden/schema_imports_broadcasting_with_imports/expected/snast.txt +12 -0
- data/golden/schema_imports_broadcasting_with_imports/expected.json +4 -0
- data/golden/schema_imports_broadcasting_with_imports/input.json +7 -0
- data/golden/schema_imports_broadcasting_with_imports/schema.kumi +14 -0
- data/golden/schema_imports_complex_order_calc/expected/ast.txt +82 -0
- data/golden/schema_imports_complex_order_calc/expected/input_plan.txt +16 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_00_unoptimized.txt +94 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_01_hoist_scalar_references.txt +94 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_02_inlined.txt +187 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_03_cse.txt +131 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_04_1_loop_fusion.txt +131 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_04_loop_invcm.txt +131 -0
- data/golden/schema_imports_complex_order_calc/expected/lir_06_const_prop.txt +131 -0
- data/golden/schema_imports_complex_order_calc/expected/nast.txt +56 -0
- data/golden/schema_imports_complex_order_calc/expected/schema_javascript.mjs +147 -0
- data/golden/schema_imports_complex_order_calc/expected/schema_ruby.rb +149 -0
- data/golden/schema_imports_complex_order_calc/expected/snast.txt +56 -0
- data/golden/schema_imports_complex_order_calc/expected.json +12 -0
- data/golden/schema_imports_complex_order_calc/input.json +20 -0
- data/golden/schema_imports_complex_order_calc/schema.kumi +33 -0
- data/golden/schema_imports_composed_order/expected/ast.txt +33 -0
- data/golden/schema_imports_composed_order/expected/input_plan.txt +3 -0
- data/golden/schema_imports_composed_order/expected/lir_00_unoptimized.txt +25 -0
- data/golden/schema_imports_composed_order/expected/lir_01_hoist_scalar_references.txt +25 -0
- data/golden/schema_imports_composed_order/expected/lir_02_inlined.txt +33 -0
- data/golden/schema_imports_composed_order/expected/lir_03_cse.txt +33 -0
- data/golden/schema_imports_composed_order/expected/lir_04_1_loop_fusion.txt +33 -0
- data/golden/schema_imports_composed_order/expected/lir_04_loop_invcm.txt +33 -0
- data/golden/schema_imports_composed_order/expected/lir_06_const_prop.txt +33 -0
- data/golden/schema_imports_composed_order/expected/nast.txt +25 -0
- data/golden/schema_imports_composed_order/expected/schema_javascript.mjs +35 -0
- data/golden/schema_imports_composed_order/expected/schema_ruby.rb +33 -0
- data/golden/schema_imports_composed_order/expected/snast.txt +25 -0
- data/golden/schema_imports_composed_order/expected.json +6 -0
- data/golden/schema_imports_composed_order/input.json +5 -0
- data/golden/schema_imports_composed_order/schema.kumi +15 -0
- data/golden/schema_imports_discount_with_tax/expected/ast.txt +37 -0
- data/golden/schema_imports_discount_with_tax/expected/input_plan.txt +2 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_00_unoptimized.txt +30 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_01_hoist_scalar_references.txt +30 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_02_inlined.txt +37 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_03_cse.txt +34 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_04_1_loop_fusion.txt +34 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_04_loop_invcm.txt +34 -0
- data/golden/schema_imports_discount_with_tax/expected/lir_06_const_prop.txt +34 -0
- data/golden/schema_imports_discount_with_tax/expected/nast.txt +30 -0
- data/golden/schema_imports_discount_with_tax/expected/schema_javascript.mjs +37 -0
- data/golden/schema_imports_discount_with_tax/expected/schema_ruby.rb +34 -0
- data/golden/schema_imports_discount_with_tax/expected/snast.txt +30 -0
- data/golden/schema_imports_discount_with_tax/expected.json +7 -0
- data/golden/schema_imports_discount_with_tax/input.json +4 -0
- data/golden/schema_imports_discount_with_tax/schema.kumi +15 -0
- data/golden/schema_imports_line_items/expected/ast.txt +35 -0
- data/golden/schema_imports_line_items/expected/input_plan.txt +8 -0
- data/golden/schema_imports_line_items/expected/lir_00_unoptimized.txt +19 -0
- data/golden/schema_imports_line_items/expected/lir_01_hoist_scalar_references.txt +19 -0
- data/golden/schema_imports_line_items/expected/lir_02_inlined.txt +24 -0
- data/golden/schema_imports_line_items/expected/lir_03_cse.txt +22 -0
- data/golden/schema_imports_line_items/expected/lir_04_1_loop_fusion.txt +22 -0
- data/golden/schema_imports_line_items/expected/lir_04_loop_invcm.txt +22 -0
- data/golden/schema_imports_line_items/expected/lir_06_const_prop.txt +22 -0
- data/golden/schema_imports_line_items/expected/nast.txt +19 -0
- data/golden/schema_imports_line_items/expected/schema_javascript.mjs +23 -0
- data/golden/schema_imports_line_items/expected/schema_ruby.rb +22 -0
- data/golden/schema_imports_line_items/expected/snast.txt +19 -0
- data/golden/schema_imports_line_items/expected.json +5 -0
- data/golden/schema_imports_line_items/input.json +13 -0
- data/golden/schema_imports_line_items/schema.kumi +17 -0
- data/golden/schema_imports_multiple/expected/ast.txt +35 -0
- data/golden/schema_imports_multiple/expected/input_plan.txt +2 -0
- data/golden/schema_imports_multiple/expected/lir_00_unoptimized.txt +29 -0
- data/golden/schema_imports_multiple/expected/lir_01_hoist_scalar_references.txt +29 -0
- data/golden/schema_imports_multiple/expected/lir_02_inlined.txt +41 -0
- data/golden/schema_imports_multiple/expected/lir_03_cse.txt +37 -0
- data/golden/schema_imports_multiple/expected/lir_04_1_loop_fusion.txt +37 -0
- data/golden/schema_imports_multiple/expected/lir_04_loop_invcm.txt +37 -0
- data/golden/schema_imports_multiple/expected/lir_06_const_prop.txt +37 -0
- data/golden/schema_imports_multiple/expected/nast.txt +28 -0
- data/golden/schema_imports_multiple/expected/schema_javascript.mjs +40 -0
- data/golden/schema_imports_multiple/expected/schema_ruby.rb +37 -0
- data/golden/schema_imports_multiple/expected/snast.txt +28 -0
- data/golden/schema_imports_multiple/expected.json +7 -0
- data/golden/schema_imports_multiple/input.json +4 -0
- data/golden/schema_imports_multiple/schema.kumi +15 -0
- data/golden/schema_imports_nested_expressions/expected/ast.txt +31 -0
- data/golden/schema_imports_nested_expressions/expected/input_plan.txt +3 -0
- data/golden/schema_imports_nested_expressions/expected/lir_00_unoptimized.txt +22 -0
- data/golden/schema_imports_nested_expressions/expected/lir_01_hoist_scalar_references.txt +22 -0
- data/golden/schema_imports_nested_expressions/expected/lir_02_inlined.txt +32 -0
- data/golden/schema_imports_nested_expressions/expected/lir_03_cse.txt +32 -0
- data/golden/schema_imports_nested_expressions/expected/lir_04_1_loop_fusion.txt +32 -0
- data/golden/schema_imports_nested_expressions/expected/lir_04_loop_invcm.txt +32 -0
- data/golden/schema_imports_nested_expressions/expected/lir_06_const_prop.txt +28 -0
- data/golden/schema_imports_nested_expressions/expected/nast.txt +23 -0
- data/golden/schema_imports_nested_expressions/expected/schema_javascript.mjs +29 -0
- data/golden/schema_imports_nested_expressions/expected/schema_ruby.rb +28 -0
- data/golden/schema_imports_nested_expressions/expected/snast.txt +23 -0
- data/golden/schema_imports_nested_expressions/expected.json +5 -0
- data/golden/schema_imports_nested_expressions/input.json +5 -0
- data/golden/schema_imports_nested_expressions/schema.kumi +13 -0
- data/golden/schema_imports_nested_with_reductions/expected/ast.txt +47 -0
- data/golden/schema_imports_nested_with_reductions/expected/input_plan.txt +12 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_00_unoptimized.txt +31 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_01_hoist_scalar_references.txt +31 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_02_inlined.txt +58 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_03_cse.txt +49 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_04_1_loop_fusion.txt +51 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_04_loop_invcm.txt +49 -0
- data/golden/schema_imports_nested_with_reductions/expected/lir_06_const_prop.txt +49 -0
- data/golden/schema_imports_nested_with_reductions/expected/nast.txt +23 -0
- data/golden/schema_imports_nested_with_reductions/expected/schema_javascript.mjs +49 -0
- data/golden/schema_imports_nested_with_reductions/expected/schema_ruby.rb +52 -0
- data/golden/schema_imports_nested_with_reductions/expected/snast.txt +23 -0
- data/golden/schema_imports_nested_with_reductions/expected.json +6 -0
- data/golden/schema_imports_nested_with_reductions/input.json +16 -0
- data/golden/schema_imports_nested_with_reductions/schema.kumi +23 -0
- data/golden/schema_imports_with_imports/expected/ast.txt +19 -0
- data/golden/schema_imports_with_imports/expected/input_plan.txt +1 -0
- data/golden/schema_imports_with_imports/expected/lir_00_unoptimized.txt +13 -0
- data/golden/schema_imports_with_imports/expected/lir_01_hoist_scalar_references.txt +13 -0
- data/golden/schema_imports_with_imports/expected/lir_02_inlined.txt +14 -0
- data/golden/schema_imports_with_imports/expected/lir_03_cse.txt +13 -0
- data/golden/schema_imports_with_imports/expected/lir_04_1_loop_fusion.txt +13 -0
- data/golden/schema_imports_with_imports/expected/lir_04_loop_invcm.txt +13 -0
- data/golden/schema_imports_with_imports/expected/lir_06_const_prop.txt +13 -0
- data/golden/schema_imports_with_imports/expected/nast.txt +13 -0
- data/golden/schema_imports_with_imports/expected/schema_javascript.mjs +13 -0
- data/golden/schema_imports_with_imports/expected/schema_ruby.rb +13 -0
- data/golden/schema_imports_with_imports/expected/snast.txt +13 -0
- data/golden/schema_imports_with_imports/expected.json +4 -0
- data/golden/schema_imports_with_imports/input.json +3 -0
- data/golden/schema_imports_with_imports/schema.kumi +10 -0
- data/golden/shift/expected/lir_06_const_prop.txt +18 -30
- data/golden/shift/expected/schema_javascript.mjs +18 -30
- data/golden/shift/expected/schema_ruby.rb +25 -67
- data/golden/shift_2d/expected/lir_06_const_prop.txt +36 -60
- data/golden/shift_2d/expected/schema_javascript.mjs +36 -60
- data/golden/shift_2d/expected/schema_ruby.rb +49 -109
- data/golden/simple_math/expected/lir_06_const_prop.txt +3 -6
- data/golden/simple_math/expected/schema_javascript.mjs +3 -6
- data/golden/simple_math/expected/schema_ruby.rb +8 -39
- data/golden/streaming_basics/expected/lir_06_const_prop.txt +6 -12
- data/golden/streaming_basics/expected/schema_javascript.mjs +6 -12
- data/golden/streaming_basics/expected/schema_ruby.rb +14 -51
- data/golden/tuples/expected/lir_06_const_prop.txt +5 -22
- data/golden/tuples/expected/schema_javascript.mjs +5 -22
- data/golden/tuples/expected/schema_ruby.rb +11 -57
- data/golden/tuples_and_arrays/expected/lir_06_const_prop.txt +4 -8
- data/golden/tuples_and_arrays/expected/schema_javascript.mjs +4 -8
- data/golden/tuples_and_arrays/expected/schema_ruby.rb +9 -41
- data/golden/us_tax_2024/expected/lir_06_const_prop.txt +94 -171
- data/golden/us_tax_2024/expected/schema_javascript.mjs +13 -21
- data/golden/us_tax_2024/expected/schema_ruby.rb +15 -48
- data/golden/with_constants/expected/lir_06_const_prop.txt +3 -8
- data/golden/with_constants/expected/schema_javascript.mjs +3 -8
- data/golden/with_constants/expected/schema_ruby.rb +5 -35
- data/lib/kumi/analyzer.rb +8 -7
- data/lib/kumi/configuration.rb +7 -6
- data/lib/kumi/core/analyzer/passes/attach_anchors_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/attach_terminal_info_pass.rb +1 -1
- data/lib/kumi/core/analyzer/passes/codegen/js/declaration_emitter.rb +20 -0
- data/lib/kumi/core/analyzer/passes/codegen/ruby/declaration_emitter.rb +16 -7
- data/lib/kumi/core/analyzer/passes/codegen/ruby/output_buffer.rb +3 -35
- data/lib/kumi/core/analyzer/passes/dependency_resolver.rb +6 -0
- data/lib/kumi/core/analyzer/passes/import_analysis_pass.rb +90 -0
- data/lib/kumi/core/analyzer/passes/lir/constant_propagation_pass.rb +77 -36
- data/lib/kumi/core/analyzer/passes/lir/lower_pass.rb +26 -11
- data/lib/kumi/core/analyzer/passes/name_indexer.rb +20 -2
- data/lib/kumi/core/analyzer/passes/nast_dimensional_analyzer_pass.rb +44 -0
- data/lib/kumi/core/analyzer/passes/normalize_to_nast_pass.rb +30 -0
- data/lib/kumi/core/analyzer/passes/semantic_constraint_validator.rb +5 -1
- data/lib/kumi/core/analyzer/passes/snast_pass.rb +15 -0
- data/lib/kumi/core/lir/build.rb +27 -0
- data/lib/kumi/core/lir/peephole.rb +164 -0
- data/lib/kumi/core/nast.rb +16 -0
- data/lib/kumi/core/ruby_parser/build_context.rb +3 -1
- data/lib/kumi/core/ruby_parser/parser.rb +1 -1
- data/lib/kumi/core/ruby_parser/schema_builder.rb +33 -3
- data/lib/kumi/dev/golden/result.rb +9 -3
- data/lib/kumi/dev/golden/runtime_test.rb +16 -1
- data/lib/kumi/dev/golden.rb +18 -20
- data/lib/kumi/dev/golden_schema_modules.rb +8 -0
- data/lib/kumi/dev/golden_schema_wrapper.rb +116 -0
- data/lib/kumi/dev/support/kumi_runner.mjs +18 -0
- data/lib/kumi/schema.rb +44 -2
- data/lib/kumi/support/lir_printer.rb +21 -5
- data/lib/kumi/support/nast_printer.rb +11 -0
- data/lib/kumi/support/s_expression_printer.rb +9 -0
- data/lib/kumi/support/snast_printer.rb +6 -0
- data/lib/kumi/syntax/import_call.rb +11 -0
- data/lib/kumi/syntax/import_declaration.rb +11 -0
- data/lib/kumi/syntax/root.rb +2 -2
- data/lib/kumi/test_shared_schemas/compound.rb +21 -0
- data/lib/kumi/test_shared_schemas/discount.rb +19 -0
- data/lib/kumi/test_shared_schemas/price.rb +19 -0
- data/lib/kumi/test_shared_schemas/subtotal.rb +22 -0
- data/lib/kumi/test_shared_schemas/tax.rb +18 -0
- data/lib/kumi/version.rb +1 -1
- data/lib/kumi.rb +19 -4
- 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 =
|
|
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
|
data/lib/kumi/dev/golden.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
63
|
-
results =
|
|
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
|
-
|
|
73
|
-
results =
|
|
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,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
|
-
|
|
69
|
+
CompiledSchemaWrapper.new(__kumi_compiled_module__, {})
|
|
38
70
|
end
|
|
39
71
|
|
|
40
72
|
def from(input_data)
|
|
41
73
|
ensure_compiled!
|
|
42
|
-
|
|
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}(#{
|
|
74
|
+
"#{res}call #{fn}(#{list_with_immediates(ins)})#{stamp(ins)}"
|
|
75
75
|
when :Select
|
|
76
|
-
c, t, f = ins
|
|
77
|
-
"#{res}select #{
|
|
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 =
|
|
84
|
-
"#{res}acc_add #{fn}(#{acc}, #{
|
|
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
|
data/lib/kumi/syntax/root.rb
CHANGED
|
@@ -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
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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"
|