morpher 0.2.6

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of morpher might be problematic. Click here for more details.

Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.circle.yml +6 -0
  3. data/.gitignore +5 -0
  4. data/.rspec +4 -0
  5. data/.rubocop.yml +8 -0
  6. data/Changelog.md +60 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +20 -0
  9. data/README.md +56 -0
  10. data/Rakefile +95 -0
  11. data/circle.yml +7 -0
  12. data/config/devtools.yml +2 -0
  13. data/config/flay.yml +3 -0
  14. data/config/flog.yml +2 -0
  15. data/config/heckle.yml +3 -0
  16. data/config/mutant.yml +8 -0
  17. data/config/reek.yml +109 -0
  18. data/config/rubocop.yml +138 -0
  19. data/config/yardstick.yml +2 -0
  20. data/examples/README.md +13 -0
  21. data/examples/a.rb +25 -0
  22. data/examples/b.rb +35 -0
  23. data/lib/morpher.rb +111 -0
  24. data/lib/morpher/compiler.rb +17 -0
  25. data/lib/morpher/compiler/emitter.rb +82 -0
  26. data/lib/morpher/compiler/error.rb +84 -0
  27. data/lib/morpher/compiler/evaluator.rb +63 -0
  28. data/lib/morpher/compiler/evaluator/emitter.rb +224 -0
  29. data/lib/morpher/compiler/preprocessor.rb +29 -0
  30. data/lib/morpher/compiler/preprocessor/emitter.rb +54 -0
  31. data/lib/morpher/compiler/preprocessor/emitter/anima.rb +69 -0
  32. data/lib/morpher/compiler/preprocessor/emitter/boolean.rb +31 -0
  33. data/lib/morpher/compiler/preprocessor/emitter/key.rb +87 -0
  34. data/lib/morpher/compiler/preprocessor/emitter/noop.rb +45 -0
  35. data/lib/morpher/compiler/preprocessor/emitter/param.rb +50 -0
  36. data/lib/morpher/evaluation.rb +118 -0
  37. data/lib/morpher/evaluator.rb +40 -0
  38. data/lib/morpher/evaluator/binary.rb +46 -0
  39. data/lib/morpher/evaluator/nary.rb +97 -0
  40. data/lib/morpher/evaluator/nullary.rb +92 -0
  41. data/lib/morpher/evaluator/nullary/parameterized.rb +48 -0
  42. data/lib/morpher/evaluator/predicate.rb +22 -0
  43. data/lib/morpher/evaluator/predicate/boolean.rb +76 -0
  44. data/lib/morpher/evaluator/predicate/contradiction.rb +36 -0
  45. data/lib/morpher/evaluator/predicate/eql.rb +50 -0
  46. data/lib/morpher/evaluator/predicate/negation.rb +52 -0
  47. data/lib/morpher/evaluator/predicate/primitive.rb +49 -0
  48. data/lib/morpher/evaluator/predicate/tautology.rb +36 -0
  49. data/lib/morpher/evaluator/transformer.rb +75 -0
  50. data/lib/morpher/evaluator/transformer/attribute.rb +25 -0
  51. data/lib/morpher/evaluator/transformer/block.rb +81 -0
  52. data/lib/morpher/evaluator/transformer/coerce.rb +166 -0
  53. data/lib/morpher/evaluator/transformer/custom.rb +34 -0
  54. data/lib/morpher/evaluator/transformer/domain.rb +86 -0
  55. data/lib/morpher/evaluator/transformer/domain/attribute_accessors.rb +60 -0
  56. data/lib/morpher/evaluator/transformer/domain/attribute_hash.rb +52 -0
  57. data/lib/morpher/evaluator/transformer/domain/instance_variables.rb +60 -0
  58. data/lib/morpher/evaluator/transformer/domain/param.rb +54 -0
  59. data/lib/morpher/evaluator/transformer/guard.rb +62 -0
  60. data/lib/morpher/evaluator/transformer/hash_transform.rb +149 -0
  61. data/lib/morpher/evaluator/transformer/input.rb +37 -0
  62. data/lib/morpher/evaluator/transformer/key.rb +86 -0
  63. data/lib/morpher/evaluator/transformer/map.rb +100 -0
  64. data/lib/morpher/evaluator/transformer/merge.rb +25 -0
  65. data/lib/morpher/evaluator/transformer/static.rb +27 -0
  66. data/lib/morpher/evaluator/unary.rb +79 -0
  67. data/lib/morpher/node_helpers.rb +19 -0
  68. data/lib/morpher/printer.rb +233 -0
  69. data/lib/morpher/printer/mixin.rb +58 -0
  70. data/lib/morpher/registry.rb +51 -0
  71. data/lib/morpher/type_lookup.rb +51 -0
  72. data/morpher.gemspec +29 -0
  73. data/spec/integration_spec.rb +184 -0
  74. data/spec/rcov.opts +7 -0
  75. data/spec/shared/evaluator_behavior.rb +155 -0
  76. data/spec/spec_helper.rb +36 -0
  77. data/spec/support/ice_nine_config.rb +8 -0
  78. data/spec/support/let_mock_helper.rb +8 -0
  79. data/spec/support/strip_helper.rb +12 -0
  80. data/spec/unit/morpher/compiler/preprocessor_spec.rb +46 -0
  81. data/spec/unit/morpher/evaluator/nullary/parameterized_spec.rb +25 -0
  82. data/spec/unit/morpher/evaluator/predicate/boolean/and_spec.rb +11 -0
  83. data/spec/unit/morpher/evaluator/predicate/boolean/or_spec.rb +26 -0
  84. data/spec/unit/morpher/evaluator/predicate/boolean/xor_spec.rb +26 -0
  85. data/spec/unit/morpher/evaluator/predicate/contrandiction_spec.rb +7 -0
  86. data/spec/unit/morpher/evaluator/predicate/eql_spec.rb +11 -0
  87. data/spec/unit/morpher/evaluator/predicate/negation_spec.rb +10 -0
  88. data/spec/unit/morpher/evaluator/predicate/primitive_spec.rb +17 -0
  89. data/spec/unit/morpher/evaluator/predicate/tautology_spec.rb +7 -0
  90. data/spec/unit/morpher/evaluator/transformer/attribute_spec.rb +9 -0
  91. data/spec/unit/morpher/evaluator/transformer/block_spec.rb +92 -0
  92. data/spec/unit/morpher/evaluator/transformer/coerce/parse_int_spec.rb +23 -0
  93. data/spec/unit/morpher/evaluator/transformer/custom_spec.rb +13 -0
  94. data/spec/unit/morpher/evaluator/transformer/domain/attribute_accessors_spec.rb +48 -0
  95. data/spec/unit/morpher/evaluator/transformer/domain/attribute_hash_spec.rb +40 -0
  96. data/spec/unit/morpher/evaluator/transformer/domain/instance_variables_spec.rb +47 -0
  97. data/spec/unit/morpher/evaluator/transformer/guard_spec.rb +12 -0
  98. data/spec/unit/morpher/evaluator/transformer/hash_transform_spec.rb +47 -0
  99. data/spec/unit/morpher/evaluator/transformer/input_spec.rb +11 -0
  100. data/spec/unit/morpher/evaluator/transformer/map_spec.rb +25 -0
  101. data/spec/unit/morpher/evaluator/transformer/static_spec.rb +10 -0
  102. data/spec/unit/morpher/evaluator_spec.rb +15 -0
  103. data/spec/unit/morpher/printer_spec.rb +21 -0
  104. data/spec/unit/morpher/registry_spec.rb +11 -0
  105. data/spec/unit/morpher_spec.rb +53 -0
  106. metadata +302 -0
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 100
@@ -0,0 +1,13 @@
1
+ Morpher Examples
2
+ ================
3
+
4
+ These are some random examples I captured on parings.
5
+ At this early stage the examples are very "unimpressive" and only scratch the surface.
6
+
7
+ The examples are used for parings to show API in action under IRB:
8
+
9
+ ```
10
+ cd morpher
11
+ bundle exec irb -I lib -r ./examples/your_example.rb
12
+ # Now access the constants defined in example to play with the evaluators
13
+ ```
data/examples/a.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'morpher'
2
+
3
+ extend Morpher::NodeHelpers
4
+
5
+ class Input
6
+ include Anima.new(:foo)
7
+ end # Input
8
+
9
+ node =
10
+ s(:block,
11
+ s(:guard, s(:primitive, Hash)),
12
+ s(:hash_transform,
13
+ s(:key_symbolize, :foo,
14
+ s(:guard,
15
+ s(:or,
16
+ s(:primitive, String),
17
+ s(:primitive, NilClass)
18
+ )
19
+ )
20
+ )
21
+ ),
22
+ s(:load_attribute_hash, s(:param, Input))
23
+ )
24
+
25
+ EVALUATOR = Morpher.compile(node)
data/examples/b.rb ADDED
@@ -0,0 +1,35 @@
1
+ require 'morpher'
2
+
3
+ extend Morpher::NodeHelpers
4
+
5
+ class Address
6
+ include Anima.new(:street)
7
+ end
8
+
9
+ class Person
10
+ include Anima.new(:address)
11
+ end
12
+
13
+ node = s(:block,
14
+ s(:guard, s(:primitive, Hash)),
15
+ s(:hash_transform,
16
+ s(:key_symbolize, 'street',
17
+ s(:guard, s(:primitive, String))
18
+ )
19
+ ),
20
+ s(:load_attribute_hash, s(:param, Address))
21
+ )
22
+
23
+ ADDRESS_EVALUATOR = Morpher.compile(node)
24
+
25
+ node = s(:block,
26
+ s(:guard, s(:primitive, Hash)),
27
+ s(:hash_transform,
28
+ s(:key_symbolize, 'address',
29
+ ADDRESS_EVALUATOR.node
30
+ )
31
+ ),
32
+ s(:load_attribute_hash, s(:param, Person))
33
+ )
34
+
35
+ PERSON_EVALUATOR = Morpher.compile(node)
data/lib/morpher.rb ADDED
@@ -0,0 +1,111 @@
1
+ require 'abstract_type'
2
+ require 'concord'
3
+ require 'anima'
4
+ require 'ast'
5
+ require 'procto'
6
+
7
+ # Library namespace module
8
+ module Morpher
9
+
10
+ Undefined = Module.new.freeze
11
+
12
+ # Return evaluator from node
13
+ #
14
+ # @param [Node]
15
+ #
16
+ # @return [Evaluator]
17
+ #
18
+ # @api private
19
+ #
20
+ def self.compile(node)
21
+ node = Compiler::Preprocessor::DEFAULT.call(node)
22
+ Compiler::Evaluator::DEFAULT.call(node)
23
+ end
24
+
25
+ # Return evaluate block to produce an AST node
26
+ #
27
+ # @return [AST::Node]
28
+ #
29
+ # @api private
30
+ #
31
+ def self.sexp(&block)
32
+ NodeHelpers.module_eval(&block)
33
+ end
34
+
35
+ # Build morpher from yielding sexp blog
36
+ #
37
+ # @return [Evaluator]
38
+ #
39
+ # @api private
40
+ #
41
+ def self.build(&block)
42
+ compile(sexp(&block))
43
+ end
44
+
45
+ end # Morpher
46
+
47
+ require 'morpher/node_helpers'
48
+ require 'morpher/registry'
49
+ require 'morpher/printer'
50
+ require 'morpher/printer/mixin'
51
+ require 'morpher/evaluator'
52
+ require 'morpher/evaluator/nullary'
53
+ require 'morpher/evaluator/nullary/parameterized'
54
+ require 'morpher/evaluator/unary'
55
+ require 'morpher/evaluator/binary'
56
+ require 'morpher/evaluator/nary'
57
+ require 'morpher/evaluator/transformer'
58
+ require 'morpher/evaluator/transformer/block'
59
+ require 'morpher/evaluator/transformer/key'
60
+ require 'morpher/evaluator/transformer/guard'
61
+ require 'morpher/evaluator/transformer/attribute'
62
+ require 'morpher/evaluator/transformer/hash_transform'
63
+ require 'morpher/evaluator/transformer/map'
64
+ require 'morpher/evaluator/transformer/static'
65
+ require 'morpher/evaluator/transformer/input'
66
+ require 'morpher/evaluator/transformer/merge'
67
+ require 'morpher/evaluator/transformer/coerce'
68
+ require 'morpher/evaluator/transformer/custom'
69
+ require 'morpher/evaluator/transformer/domain'
70
+ require 'morpher/evaluator/transformer/domain/param'
71
+ require 'morpher/evaluator/transformer/domain/attribute_hash'
72
+ require 'morpher/evaluator/transformer/domain/instance_variables'
73
+ require 'morpher/evaluator/transformer/domain/attribute_accessors'
74
+ require 'morpher/evaluator/predicate'
75
+ require 'morpher/evaluator/predicate/eql'
76
+ require 'morpher/evaluator/predicate/primitive'
77
+ require 'morpher/evaluator/predicate/negation'
78
+ require 'morpher/evaluator/predicate/tautology'
79
+ require 'morpher/evaluator/predicate/contradiction'
80
+ require 'morpher/evaluator/predicate/boolean'
81
+ require 'morpher/evaluation'
82
+ require 'morpher/evaluation'
83
+ require 'morpher/type_lookup'
84
+ require 'morpher/compiler'
85
+ require 'morpher/compiler/error'
86
+ require 'morpher/compiler/emitter'
87
+ require 'morpher/compiler/evaluator'
88
+ require 'morpher/compiler/evaluator/emitter'
89
+ require 'morpher/compiler/preprocessor'
90
+ require 'morpher/compiler/preprocessor/emitter'
91
+ require 'morpher/compiler/preprocessor/emitter/noop'
92
+ require 'morpher/compiler/preprocessor/emitter/key'
93
+ require 'morpher/compiler/preprocessor/emitter/param'
94
+ require 'morpher/compiler/preprocessor/emitter/boolean'
95
+ require 'morpher/compiler/preprocessor/emitter/anima'
96
+
97
+ module Morpher
98
+ class Compiler
99
+
100
+ class Preprocessor
101
+ # Default preprocessor compiler
102
+ DEFAULT = new(Emitter::REGISTRY.freeze)
103
+ end # Preprocessor
104
+
105
+ class Evaluator
106
+ # Default evaluator compiler
107
+ DEFAULT = new(Morpher::Evaluator::REGISTRY, Emitter::REGISTRY.freeze)
108
+ end # Evaluator
109
+
110
+ end # Compiler
111
+ end # Morpher
@@ -0,0 +1,17 @@
1
+ module Morpher
2
+ # Abstract compiler base class
3
+ class Compiler
4
+ include AbstractType
5
+
6
+ # Call compiler
7
+ #
8
+ # @param [Node] node
9
+ #
10
+ # @return [Object]
11
+ #
12
+ # @api private
13
+ #
14
+ abstract_method :call
15
+
16
+ end # Compiler
17
+ end # Morpher
@@ -0,0 +1,82 @@
1
+ module Morpher
2
+ class Compiler
3
+ # Abstract target indepentand emitter
4
+ class Emitter
5
+ include AbstractType, Adamantium::Flat, NodeHelpers, Procto.call(:output)
6
+ extend NodeHelpers
7
+
8
+ # Return output of emitter
9
+ #
10
+ # @return [Object]
11
+ #
12
+ # @api private
13
+ #
14
+ abstract_method :output
15
+
16
+ # Return node
17
+ #
18
+ # @return [Node]
19
+ #
20
+ # @api private
21
+ #
22
+ abstract_method :node
23
+ private :node
24
+
25
+ private
26
+
27
+ # Return children
28
+ #
29
+ # @return [Array<AST::Node>]
30
+ #
31
+ # @api private
32
+ #
33
+ def children
34
+ node.children
35
+ end
36
+
37
+ # Assert number of child nodes
38
+ #
39
+ # @return [self]
40
+ # if assertion is fullfilled
41
+ #
42
+ # @raise [NodeError]
43
+ # otherwise
44
+ #
45
+ # @api private
46
+ #
47
+ def assert_children_amount(expected_amount)
48
+ actual_amount = children.length
49
+ fail Error::NodeChildren.new(node, expected_amount) unless actual_amount.equal?(expected_amount)
50
+ end
51
+
52
+ # Name children
53
+ #
54
+ # @return [undefined]
55
+ #
56
+ # @api private
57
+ #
58
+ # rubocop:disable MethodLength
59
+ #
60
+ def self.children(*names)
61
+ names.each_with_index do |name, index|
62
+ define_method(name) do
63
+ children.at(index)
64
+ end
65
+ private name
66
+ end
67
+
68
+ define_method(:named_children) do
69
+ names
70
+ end
71
+ private :named_children
72
+
73
+ define_method(:remaining_children) do
74
+ children.drop(names.length)
75
+ end
76
+ private :remaining_children
77
+ end
78
+ private_class_method :children
79
+
80
+ end # Emitter
81
+ end # Compiler
82
+ end # Morpher
@@ -0,0 +1,84 @@
1
+ module Morpher
2
+ class Compiler
3
+
4
+ # Abstract error class for compiler errors
5
+ class Error < RuntimeError
6
+ include AbstractType
7
+
8
+ # Error raised when node children have incorrect amount
9
+ class NodeChildren < self
10
+ include Concord.new(:node, :expected_amount)
11
+
12
+ # Return exception message
13
+ #
14
+ # @return [String]
15
+ #
16
+ # @api private
17
+ #
18
+ def message
19
+ "Expected #{expected_amount} #{_children} for #{type}, got #{actual_amount}: #{children}"
20
+ end
21
+
22
+ private
23
+
24
+ # Return inspected type
25
+ #
26
+ # @return [String]
27
+ #
28
+ # @api private
29
+ #
30
+ def type
31
+ node.type.inspect
32
+ end
33
+
34
+ # Return actual amount of children
35
+ #
36
+ # @return [String]
37
+ #
38
+ # @api private
39
+ #
40
+ def actual_amount
41
+ children.length
42
+ end
43
+
44
+ # Return children
45
+ #
46
+ # @return [Array]
47
+ #
48
+ # @api private
49
+ #
50
+ def children
51
+ node.children
52
+ end
53
+
54
+ # Return user firendly children message
55
+ #
56
+ # @return [String]
57
+ #
58
+ # @api private
59
+ #
60
+ def _children
61
+ expected_amount.equal?(1) ? 'child' : 'children'
62
+ end
63
+
64
+ end # NodeChildren
65
+
66
+ # Error raised on compiling unknown nodes
67
+ class UnknownNode < self
68
+ include Concord.new(:type)
69
+
70
+ # Return exception error message
71
+ #
72
+ # @return [String]
73
+ #
74
+ # @api private
75
+ #
76
+ def message
77
+ "Node type: #{type.inspect} is unknown"
78
+ end
79
+
80
+ end # UnknownNode
81
+
82
+ end # Error
83
+ end # Compiler
84
+ end # Morpher
@@ -0,0 +1,63 @@
1
+ module Morpher
2
+ class Compiler
3
+ # Compiler with evaluators as output
4
+ class Evaluator < self
5
+ include Concord.new(:evaluators, :emitters)
6
+
7
+ # Return evaluator tree for node
8
+ #
9
+ # @param [Node] node
10
+ #
11
+ # @return [Evalautor]
12
+ # on success
13
+ #
14
+ # @raise [Compiler::Error]
15
+ # on error
16
+ #
17
+ # @api private
18
+ #
19
+ def call(node)
20
+ evaluator = evaluator(node)
21
+ emitter = emitter(evaluator)
22
+ emitter.call(self, evaluator, node)
23
+ end
24
+
25
+ private
26
+
27
+ # Lookup evaluator for node
28
+ #
29
+ # @param [Node]
30
+ #
31
+ # @return [Class:Evaluator]
32
+ # if found
33
+ #
34
+ # @raise [Error::UnknownNode]
35
+ # otherwise
36
+ #
37
+ # @api private
38
+ #
39
+ def evaluator(node)
40
+ type = node.type
41
+ evaluators.fetch(type) do
42
+ fail Error::UnknownNode, type
43
+ end
44
+ end
45
+
46
+ # Return emitter for evaluator
47
+ #
48
+ # @param [Class:Evalautor]
49
+ #
50
+ # @return [#call]
51
+ #
52
+ # @api private
53
+ #
54
+ def emitter(evaluator)
55
+ emitters.each do |arity, emitter|
56
+ return emitter if evaluator.ancestors.include?(arity)
57
+ end
58
+ fail Error::UnknownNode, evaluator
59
+ end
60
+
61
+ end # Evaluator
62
+ end # Compiler
63
+ end # Morpher
@@ -0,0 +1,224 @@
1
+ module Morpher
2
+ class Compiler
3
+ class Evaluator
4
+ # Emitter for evaluators
5
+ class Emitter < Compiler::Emitter
6
+ include Registry, Concord.new(:compiler, :evaluator_klass, :node)
7
+
8
+ # Return output
9
+ #
10
+ # @return [Evaluator]
11
+ #
12
+ # @api private
13
+ #
14
+ def output
15
+ validate_node
16
+ evaluator
17
+ end
18
+ memoize :output
19
+
20
+ # Validate node
21
+ #
22
+ # @return [undefined]
23
+ # if successful
24
+ #
25
+ # @raise [Error]
26
+ # otherwise
27
+ #
28
+ # @api private
29
+ #
30
+ abstract_method :validate_node
31
+ private :validate_node
32
+
33
+ # Return evaluator
34
+ #
35
+ # @return [Evaluator]
36
+ #
37
+ # @api private
38
+ #
39
+ abstract_method :evaluator
40
+ private :evaluator
41
+
42
+ # Emitter for nullary non parameterized evaluators
43
+ class Nullary < self
44
+ register Morpher::Evaluator::Nullary
45
+
46
+ private
47
+
48
+ # Return output
49
+ #
50
+ # @return [Evaluator]
51
+ #
52
+ # @api private
53
+ #
54
+ def evaluator
55
+ evaluator_klass.new
56
+ end
57
+
58
+ # Validate node
59
+ #
60
+ # @return [undefined]
61
+ # if successful
62
+ #
63
+ # @raise [Error]
64
+ # otherwise
65
+ #
66
+ # @api private
67
+ #
68
+ def validate_node
69
+ assert_children_amount(0)
70
+ end
71
+
72
+ # Emitter for nullary parameterized evaluators
73
+ class Parameterized < self
74
+ register Morpher::Evaluator::Nullary::Parameterized
75
+
76
+ children :param
77
+
78
+ private
79
+
80
+ # Return output
81
+ #
82
+ # @return [Evaluator]
83
+ #
84
+ # @api private
85
+ #
86
+ def evaluator
87
+ evaluator_klass.new(effective_param)
88
+ end
89
+
90
+ # Return effective param
91
+ #
92
+ # @return [Object]
93
+ #
94
+ # @api private
95
+ #
96
+ def effective_param
97
+ if param.kind_of?(AST::Node) && param.type.equal?(:raw) && param.children.length.equal?(1)
98
+ param.children.first
99
+ else
100
+ param
101
+ end
102
+ end
103
+
104
+ # Validate node
105
+ #
106
+ # @return [undefined]
107
+ # if successful
108
+ #
109
+ # @raise [Error]
110
+ # otherwise
111
+ #
112
+ # @api private
113
+ #
114
+ def validate_node
115
+ assert_children_amount(1)
116
+ end
117
+
118
+ end # Paramterized
119
+ end # Nullary
120
+
121
+ # Emitter for unary evaluators
122
+ class Unary < self
123
+ register Morpher::Evaluator::Unary
124
+ children :operand
125
+
126
+ private
127
+
128
+ # Return evaluator
129
+ #
130
+ # @return [Evaluator]
131
+ #
132
+ # @api private
133
+ #
134
+ def evaluator
135
+ evaluator_klass.new(compiler.call(operand))
136
+ end
137
+
138
+ # Validate node
139
+ #
140
+ # @return [undefined]
141
+ # if successful
142
+ #
143
+ # @raise [Error]
144
+ # otherwise
145
+ #
146
+ # @api private
147
+ #
148
+ def validate_node
149
+ assert_children_amount(1)
150
+ end
151
+
152
+ end # Unary
153
+
154
+ # Emitter for unary evaluators
155
+ class Binary < self
156
+ register Morpher::Evaluator::Binary
157
+ children :left, :right
158
+
159
+ private
160
+
161
+ # Return evaluator
162
+ #
163
+ # @return [Evaluator]
164
+ #
165
+ # @api private
166
+ #
167
+ def evaluator
168
+ evaluator_klass.new(
169
+ compiler.call(left),
170
+ compiler.call(right)
171
+ )
172
+ end
173
+
174
+ # Validate node
175
+ #
176
+ # @return [undefined]
177
+ # if successful
178
+ #
179
+ # @raise [Error]
180
+ # otherwise
181
+ #
182
+ # @api private
183
+ #
184
+ def validate_node
185
+ assert_children_amount(2)
186
+ end
187
+
188
+ end # Unary
189
+
190
+ # Emitter for nary evaluators
191
+ class Nary < self
192
+ register Morpher::Evaluator::Nary
193
+
194
+ private
195
+
196
+ # Return evaluator
197
+ #
198
+ # @return [Evaluator]
199
+ #
200
+ # @api private
201
+ #
202
+ def evaluator
203
+ evaluator_klass.new(children.map(&compiler.method(:call)))
204
+ end
205
+
206
+ # Validate node
207
+ #
208
+ # @return [undefined]
209
+ # if successful
210
+ #
211
+ # @raise [Error]
212
+ # otherwise
213
+ #
214
+ # @api private
215
+ #
216
+ def validate_node
217
+ end
218
+
219
+ end # Nary
220
+
221
+ end # Emitter
222
+ end # Evaluator
223
+ end # Compiler
224
+ end # Morpher