systemrdl 0.1.0
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +127 -0
- data/lib/systemrdl/error.rb +55 -0
- data/lib/systemrdl/evaluator/address_allocation.rb +126 -0
- data/lib/systemrdl/evaluator/address_operation.rb +103 -0
- data/lib/systemrdl/evaluator/addrmap.rb +67 -0
- data/lib/systemrdl/evaluator/array_component.rb +42 -0
- data/lib/systemrdl/evaluator/builtin_properties.rb +400 -0
- data/lib/systemrdl/evaluator/common.rb +22 -0
- data/lib/systemrdl/evaluator/component_definition.rb +185 -0
- data/lib/systemrdl/evaluator/component_insts.rb +106 -0
- data/lib/systemrdl/evaluator/container_component.rb +16 -0
- data/lib/systemrdl/evaluator/field.rb +245 -0
- data/lib/systemrdl/evaluator/instance.rb +120 -0
- data/lib/systemrdl/evaluator/list.rb +26 -0
- data/lib/systemrdl/evaluator/literal.rb +173 -0
- data/lib/systemrdl/evaluator/operation.rb +241 -0
- data/lib/systemrdl/evaluator/processor.rb +166 -0
- data/lib/systemrdl/evaluator/property.rb +116 -0
- data/lib/systemrdl/evaluator/property_assignment.rb +220 -0
- data/lib/systemrdl/evaluator/reference.rb +135 -0
- data/lib/systemrdl/evaluator/reg.rb +156 -0
- data/lib/systemrdl/evaluator/regfile.rb +33 -0
- data/lib/systemrdl/evaluator/root.rb +39 -0
- data/lib/systemrdl/evaluator/value.rb +13 -0
- data/lib/systemrdl/evaluator.rb +14 -0
- data/lib/systemrdl/model/instance.rb +194 -0
- data/lib/systemrdl/model/value.rb +54 -0
- data/lib/systemrdl/model.rb +11 -0
- data/lib/systemrdl/parser/generated_parser.rb +2808 -0
- data/lib/systemrdl/parser/node.rb +17 -0
- data/lib/systemrdl/parser/parser.rb +86 -0
- data/lib/systemrdl/parser/scanner.rb +251 -0
- data/lib/systemrdl/parser/systemrdl.y +448 -0
- data/lib/systemrdl/parser/token.rb +58 -0
- data/lib/systemrdl/parser.rb +11 -0
- data/lib/systemrdl/version.rb +5 -0
- data/lib/systemrdl.rb +90 -0
- metadata +96 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class Operation
|
|
6
|
+
include Common
|
|
7
|
+
|
|
8
|
+
attr_reader :token_range
|
|
9
|
+
|
|
10
|
+
def evaluate(instance, width: nil, **_optargs)
|
|
11
|
+
value, type, width = eval_operation(instance, width)
|
|
12
|
+
Value.new(value, type, width, token_range)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def integral_operand?(operand)
|
|
18
|
+
[:bit, :boolean].include?(operand.type)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def check_integral_operand(operand)
|
|
22
|
+
return if integral_operand?(operand)
|
|
23
|
+
|
|
24
|
+
message = "non integral operand is given: #{operand.type}"
|
|
25
|
+
raise_evaluation_error message, token_range
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_boolean(instance, operand)
|
|
29
|
+
operand = eval_operand(instance, operand, nil, check: true)
|
|
30
|
+
|
|
31
|
+
if operand.type == :boolean
|
|
32
|
+
operand.value
|
|
33
|
+
else
|
|
34
|
+
operand.value != 0
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def to_int(instance, operand, width = nil, evaluation: true)
|
|
39
|
+
operand = eval_operand(instance, operand, width, check: true) if evaluation
|
|
40
|
+
|
|
41
|
+
if operand.type == :boolean
|
|
42
|
+
[(operand.value && 1) || 0, 1]
|
|
43
|
+
else
|
|
44
|
+
[operand.value, width || operand.width]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def eval_operand(instance, operand, width, check:)
|
|
49
|
+
result = operand.evaluate(instance, width:)
|
|
50
|
+
check_integral_operand(result) if check
|
|
51
|
+
result
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def mask(value, width)
|
|
55
|
+
value & ((1 << width) - 1)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class UnaryOperation < Operation
|
|
60
|
+
def initialize(operator, operand, token_range)
|
|
61
|
+
@operator = operator
|
|
62
|
+
@operand = operand
|
|
63
|
+
super(token_range)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def connect(parent, component)
|
|
67
|
+
super
|
|
68
|
+
@operand.connect(self, component)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def expression_width
|
|
72
|
+
if [:~, :+, :-].include?(@operator)
|
|
73
|
+
@operand.expression_width
|
|
74
|
+
else
|
|
75
|
+
1
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def eval_operation(instance, width)
|
|
82
|
+
case @operator
|
|
83
|
+
when :! then logical_negation(instance)
|
|
84
|
+
when :+, :-, :~ then general_op(instance, width)
|
|
85
|
+
when :&, :|, :^ then reduction(instance, @operator, false)
|
|
86
|
+
when :'~&' then reduction(instance, :&, true)
|
|
87
|
+
when :'~|' then reduction(instance, :|, true)
|
|
88
|
+
when :'~^', :'^~' then reduction(instance, :^, true)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def logical_negation(instance)
|
|
93
|
+
value = to_boolean(instance, @operand)
|
|
94
|
+
[!value, :boolean]
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def reduction(instance, operator, negate)
|
|
98
|
+
value, width = to_int(instance, @operand)
|
|
99
|
+
|
|
100
|
+
init_value = { '&': 1, '|': 0, '^': 0 }[operator]
|
|
101
|
+
result = width.times.inject(init_value) do |r, i|
|
|
102
|
+
r.__send__(operator, value[i])
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if negate
|
|
106
|
+
[mask(~result, 1), :bit, 1]
|
|
107
|
+
else
|
|
108
|
+
[result, :bit, 1]
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def general_op(instance, width)
|
|
113
|
+
width ||= @operand.expression_width
|
|
114
|
+
value, _ = to_int(instance, @operand, width)
|
|
115
|
+
|
|
116
|
+
op = { '+': :+@, '-': :-@, '~': :~ }[@operator]
|
|
117
|
+
result = value.__send__(op)
|
|
118
|
+
[mask(result, width), :bit, width]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
class BinaryOperation < Operation
|
|
123
|
+
def initialize(operator, l_operand, r_operand, token_range)
|
|
124
|
+
@operator = operator
|
|
125
|
+
@l_operand = l_operand
|
|
126
|
+
@r_operand = r_operand
|
|
127
|
+
super(token_range)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def connect(parent, component)
|
|
131
|
+
super
|
|
132
|
+
@l_operand.connect(self, component)
|
|
133
|
+
@r_operand.connect(self, component)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def expression_width
|
|
137
|
+
if [:'&&', :'||', :==, :!=, :<, :>, :<=, :>=].include?(@operator)
|
|
138
|
+
1
|
|
139
|
+
else
|
|
140
|
+
eval_expression_width
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def eval_expression_width
|
|
147
|
+
lhs_width = @l_operand.expression_width
|
|
148
|
+
return lhs_width if [:<<, :>>, :**].include?(@operator)
|
|
149
|
+
|
|
150
|
+
rhs_width = @r_operand.expression_width
|
|
151
|
+
|
|
152
|
+
if lhs_width && rhs_width
|
|
153
|
+
[lhs_width, rhs_width].max
|
|
154
|
+
else
|
|
155
|
+
lhs_width || rhs_width
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def eval_operation(instance, width)
|
|
160
|
+
case @operator
|
|
161
|
+
when :'&&', :'||' then logical_op(instance)
|
|
162
|
+
when :==, :!= then equality_op(instance)
|
|
163
|
+
when :<, :>, :<=, :>= then relational_op(instance)
|
|
164
|
+
when :<<, :>>, :** then shift_power_op(instance, width)
|
|
165
|
+
when :'~^', :'^~' then general_op(instance, :^, width, true)
|
|
166
|
+
else general_op(instance, @operator, width, false)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def logical_op(instance)
|
|
171
|
+
lhs = to_boolean(instance, @l_operand)
|
|
172
|
+
rhs = to_boolean(instance, @r_operand)
|
|
173
|
+
if @operator == :'&&'
|
|
174
|
+
[lhs && rhs, :boolean]
|
|
175
|
+
else
|
|
176
|
+
[lhs || rhs, :boolean]
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def equality_op(instance)
|
|
181
|
+
lhs, rhs = eval_eq_operands(instance)
|
|
182
|
+
[lhs.__send__(@operator, rhs), :boolean]
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def eval_eq_operands(instance)
|
|
186
|
+
width = eval_expression_width
|
|
187
|
+
l_operand = eval_operand(instance, @l_operand, width, check: false)
|
|
188
|
+
r_operand = eval_operand(instance, @r_operand, width, check: false)
|
|
189
|
+
|
|
190
|
+
if [l_operand, r_operand].all? { integral_operand?(_1) }
|
|
191
|
+
lhs, _ = to_int(instance, l_operand, evaluation: false)
|
|
192
|
+
rhs, _ = to_int(instance, r_operand, evaluation: false)
|
|
193
|
+
[lhs, rhs]
|
|
194
|
+
elsif l_operand.type == r_operand.type
|
|
195
|
+
[l_operand.value, r_operand.value]
|
|
196
|
+
else
|
|
197
|
+
message = "#{r_operand.type} type is not compatible with #{l_operand.type} type"
|
|
198
|
+
raise_evaluation_error message, @r_operand.token_range
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def relational_op(instance)
|
|
203
|
+
lhs, rhs, _ = integral_operands(instance, nil)
|
|
204
|
+
[lhs.__send__(@operator, rhs), :boolean]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def shift_power_op(instance, width)
|
|
208
|
+
width ||= eval_expression_width
|
|
209
|
+
lhs, _ = to_int(instance, @l_operand, width)
|
|
210
|
+
rhs, _ = to_int(instance, @r_operand)
|
|
211
|
+
|
|
212
|
+
result = lhs.__send__(@operator, rhs)
|
|
213
|
+
[mask(result, width), :bit, width]
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def general_op(instance, operator, width, negate)
|
|
217
|
+
lhs, rhs, width = integral_operands(instance, width)
|
|
218
|
+
|
|
219
|
+
if div_by_0?(rhs)
|
|
220
|
+
message = 'divisor should be non zero value'
|
|
221
|
+
raise_evaluation_error message, @r_operand.token_range
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
result = lhs.__send__(operator, rhs)
|
|
225
|
+
result = ~result if negate
|
|
226
|
+
[mask(result, width), :bit, width]
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def div_by_0?(rhs)
|
|
230
|
+
[:/, :%].include?(@operator) && rhs == 0
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def integral_operands(instance, width)
|
|
234
|
+
width ||= eval_expression_width
|
|
235
|
+
lhs, _ = to_int(instance, @l_operand, width)
|
|
236
|
+
rhs, _ = to_int(instance, @r_operand, width)
|
|
237
|
+
[lhs, rhs, width]
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class Processor < AST::Processor
|
|
6
|
+
def on_id(node)
|
|
7
|
+
id = node.children[0].to_sym
|
|
8
|
+
Value.new(id, nil, nil, node.token_range)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def on_boolean(node)
|
|
12
|
+
Boolean.new(node)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def on_number(node)
|
|
16
|
+
Number.new(node)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def on_verilog_number(node)
|
|
20
|
+
VerilogNumber.new(node)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def on_string(node)
|
|
24
|
+
String.new(node)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def on_accesstype(node)
|
|
28
|
+
AccessType.new(node)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def on_onreadtype(node)
|
|
32
|
+
OnReadType.new(node)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def on_onwritetype(node)
|
|
36
|
+
OnWriteType.new(node)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def on_addressingtype(node)
|
|
40
|
+
AddressingType.new(node)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def on_precedencetype(node)
|
|
44
|
+
PrecedenceType.new(node)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def on_unary_operation(node)
|
|
48
|
+
operator = node.children[0].to_sym
|
|
49
|
+
operand = process(node.children[1])
|
|
50
|
+
UnaryOperation.new(operator, operand, node.token_range)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def on_binary_operation(node)
|
|
54
|
+
operator = node.children[0].to_sym
|
|
55
|
+
l_operand = process(node.children[1])
|
|
56
|
+
r_operand = process(node.children[2])
|
|
57
|
+
BinaryOperation.new(operator, l_operand, r_operand, node.token_range)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def on_array(node)
|
|
61
|
+
elements = process_all(node.children)
|
|
62
|
+
List.new(elements, node.token_range)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def on_range(node)
|
|
66
|
+
elements = process_all(node.children)
|
|
67
|
+
List.new(elements, node.token_range)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def on_instance_ref_element(node)
|
|
71
|
+
id = process(node.children[0])
|
|
72
|
+
array = process(node.children[1])
|
|
73
|
+
InstanceRefElement.new(id, array, node.token_range)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def on_instance_ref(node)
|
|
77
|
+
elements = process_all(node.children)
|
|
78
|
+
InstanceRef.new(elements, node.token_range)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def on_prop_ref(node)
|
|
82
|
+
instance_ref = process(node.children[0])
|
|
83
|
+
prop = process(node.children[1])
|
|
84
|
+
PropRef.new(instance_ref, prop, node.token_range)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def on_default_prop_assignment(node)
|
|
88
|
+
prop_name, value = process_all(node.children)
|
|
89
|
+
DefaultPropertyAssignment.new(prop_name, value, node.token_range)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def on_prop_assignment(node)
|
|
93
|
+
id, value = process_all(node.children)
|
|
94
|
+
prop_ref = PropRef.new(nil, id, node.children[0].token_range)
|
|
95
|
+
PropertyAssignment.new(prop_ref, value, node.token_range)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def on_post_prop_assignment(node)
|
|
99
|
+
prop_ref, value = process_all(node.children)
|
|
100
|
+
PostPropertyAssignment.new(prop_ref, value, node.token_range)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def on_reset_value(node)
|
|
104
|
+
process(node.children[0])
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def on_address_assignment(node)
|
|
108
|
+
process(node.children[0])
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def on_address_stride(node)
|
|
112
|
+
process(node.children[0])
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def on_address_alignment(node)
|
|
116
|
+
process(node.children[0])
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def on_component_inst(node)
|
|
120
|
+
inst_id = process(node.children[0])
|
|
121
|
+
inst_values =
|
|
122
|
+
[
|
|
123
|
+
:array, :range, :reset_value, :address_assignment, :address_stride, :address_alignment
|
|
124
|
+
].zip(node.children[1..]).to_h { |k, n| [k, process(n)] }
|
|
125
|
+
ComponentInst.new(inst_id, inst_values, node.token_range)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def on_component_insts(node)
|
|
129
|
+
insts = process_all(node.children)
|
|
130
|
+
ComponentInsts.new(insts, node.token_range)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def on_explicit_component_inst(node)
|
|
134
|
+
id = process(node.children[0])
|
|
135
|
+
insts = process(node.children[1])
|
|
136
|
+
ExplicitComponentInst.new(id, insts, node.token_range)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def on_component_named_def(node)
|
|
140
|
+
id, *elements = process_all(node.children[1..])
|
|
141
|
+
component_definition(node).new(id, elements, nil, node.token_range)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def on_component_anon_def(node)
|
|
145
|
+
*elements, insts = process_all(node.children[1..])
|
|
146
|
+
component_definition(node).new(nil, elements, insts, node.token_range)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def on_root(node)
|
|
150
|
+
elements = process_all(node.children)
|
|
151
|
+
Root.new(elements, node.token_range)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
private
|
|
155
|
+
|
|
156
|
+
def component_definition(node)
|
|
157
|
+
case node.children[0].to_sym
|
|
158
|
+
when :addrmap then AddrMapDefinition
|
|
159
|
+
when :regfile then RegFileDefinition
|
|
160
|
+
when :reg then RegDefinition
|
|
161
|
+
when :field then FieldDefinition
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SystemRDL
|
|
4
|
+
module Evaluator
|
|
5
|
+
class Property
|
|
6
|
+
def initialize(instance, definition, value)
|
|
7
|
+
@instance = instance
|
|
8
|
+
@definition = definition
|
|
9
|
+
@value = value
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :value
|
|
13
|
+
|
|
14
|
+
def name
|
|
15
|
+
@definition.name
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def types
|
|
19
|
+
@definition.types
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_value(token_range)
|
|
23
|
+
Value.new(self, :property_reference, nil, token_range)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def full_name
|
|
27
|
+
[@instance.full_name, name].join('.')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def ref_target?
|
|
31
|
+
if @definition.ref_target.is_a?(Proc)
|
|
32
|
+
instance_exec(&@definition.ref_target)
|
|
33
|
+
else
|
|
34
|
+
@definition.ref_target
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def dynamic_assign?
|
|
39
|
+
@definition.dynamic_assign
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def per_element_assign?
|
|
43
|
+
@definition.per_element_assign
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def assign(value)
|
|
47
|
+
@value = value
|
|
48
|
+
@assigned = true
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def assigned?
|
|
52
|
+
@assigned || false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def set?
|
|
58
|
+
return false if value.nil?
|
|
59
|
+
|
|
60
|
+
value.value != false
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class PropertyDefinition
|
|
65
|
+
def initialize(name)
|
|
66
|
+
@name = name
|
|
67
|
+
yield(self)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
attr_reader :name
|
|
71
|
+
attr_accessor :targets
|
|
72
|
+
attr_accessor :types
|
|
73
|
+
attr_accessor :ref_target
|
|
74
|
+
attr_accessor :dynamic_assign
|
|
75
|
+
attr_accessor :per_element_assign
|
|
76
|
+
attr_accessor :default_value
|
|
77
|
+
|
|
78
|
+
def target?(instance)
|
|
79
|
+
return false if instance.root?
|
|
80
|
+
|
|
81
|
+
targets.nil? || targets.include?(instance.layer)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def create(instance)
|
|
85
|
+
value = eval_value(instance)
|
|
86
|
+
Property.new(instance, self, value)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def eval_value(instance)
|
|
92
|
+
value = instance.definition.find_default_property(name)
|
|
93
|
+
return value if value
|
|
94
|
+
|
|
95
|
+
value =
|
|
96
|
+
if default_value.is_a?(Proc)
|
|
97
|
+
default_value.call(instance)
|
|
98
|
+
else
|
|
99
|
+
default_value
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
return if value.nil?
|
|
103
|
+
|
|
104
|
+
create_value(value)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def create_value(value)
|
|
108
|
+
case types[0]
|
|
109
|
+
when :longint then Value.new(value, :bit, 64, nil)
|
|
110
|
+
when :boolean then Value.new(value, :boolean, 1, nil)
|
|
111
|
+
else Value.new(value, types[0], nil, nil)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|