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.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +127 -0
  4. data/lib/systemrdl/error.rb +55 -0
  5. data/lib/systemrdl/evaluator/address_allocation.rb +126 -0
  6. data/lib/systemrdl/evaluator/address_operation.rb +103 -0
  7. data/lib/systemrdl/evaluator/addrmap.rb +67 -0
  8. data/lib/systemrdl/evaluator/array_component.rb +42 -0
  9. data/lib/systemrdl/evaluator/builtin_properties.rb +400 -0
  10. data/lib/systemrdl/evaluator/common.rb +22 -0
  11. data/lib/systemrdl/evaluator/component_definition.rb +185 -0
  12. data/lib/systemrdl/evaluator/component_insts.rb +106 -0
  13. data/lib/systemrdl/evaluator/container_component.rb +16 -0
  14. data/lib/systemrdl/evaluator/field.rb +245 -0
  15. data/lib/systemrdl/evaluator/instance.rb +120 -0
  16. data/lib/systemrdl/evaluator/list.rb +26 -0
  17. data/lib/systemrdl/evaluator/literal.rb +173 -0
  18. data/lib/systemrdl/evaluator/operation.rb +241 -0
  19. data/lib/systemrdl/evaluator/processor.rb +166 -0
  20. data/lib/systemrdl/evaluator/property.rb +116 -0
  21. data/lib/systemrdl/evaluator/property_assignment.rb +220 -0
  22. data/lib/systemrdl/evaluator/reference.rb +135 -0
  23. data/lib/systemrdl/evaluator/reg.rb +156 -0
  24. data/lib/systemrdl/evaluator/regfile.rb +33 -0
  25. data/lib/systemrdl/evaluator/root.rb +39 -0
  26. data/lib/systemrdl/evaluator/value.rb +13 -0
  27. data/lib/systemrdl/evaluator.rb +14 -0
  28. data/lib/systemrdl/model/instance.rb +194 -0
  29. data/lib/systemrdl/model/value.rb +54 -0
  30. data/lib/systemrdl/model.rb +11 -0
  31. data/lib/systemrdl/parser/generated_parser.rb +2808 -0
  32. data/lib/systemrdl/parser/node.rb +17 -0
  33. data/lib/systemrdl/parser/parser.rb +86 -0
  34. data/lib/systemrdl/parser/scanner.rb +251 -0
  35. data/lib/systemrdl/parser/systemrdl.y +448 -0
  36. data/lib/systemrdl/parser/token.rb +58 -0
  37. data/lib/systemrdl/parser.rb +11 -0
  38. data/lib/systemrdl/version.rb +5 -0
  39. data/lib/systemrdl.rb +90 -0
  40. metadata +96 -0
@@ -0,0 +1,400 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SystemRDL
4
+ module Evaluator
5
+ module BuiltinProperties
6
+ class << self
7
+ attr_reader :properties
8
+
9
+ def find(name)
10
+ properties.find { |prop| prop.name == name }
11
+ end
12
+
13
+ private
14
+
15
+ def def_property(name, &)
16
+ @properties ||= []
17
+ @properties << PropertyDefinition.new(name, &)
18
+ end
19
+ end
20
+
21
+ #
22
+ # Table G1—Property cross-reference
23
+ #
24
+ def_property :accesswidth do |prop|
25
+ prop.targets = [:reg]
26
+ prop.types = [:longint]
27
+ prop.dynamic_assign = true
28
+ prop.ref_target = false
29
+ prop.per_element_assign = false
30
+ end
31
+
32
+ def_property :addressing do |prop|
33
+ prop.targets = [:addrmap]
34
+ prop.types = [:addressingtype]
35
+ prop.dynamic_assign = false
36
+ prop.ref_target = false
37
+ prop.per_element_assign = false
38
+ prop.default_value = :regalign
39
+ end
40
+
41
+ def_property :alignment do |prop|
42
+ prop.targets = [:addrmap, :regfile]
43
+ prop.types = [:longint]
44
+ prop.dynamic_assign = false
45
+ prop.ref_target = false
46
+ prop.per_element_assign = false
47
+ end
48
+
49
+ def_property :anded do |prop|
50
+ prop.targets = [:field]
51
+ prop.types = [:boolean]
52
+ prop.dynamic_assign = true
53
+ prop.ref_target = true
54
+ prop.per_element_assign = false
55
+ prop.default_value = false
56
+ end
57
+
58
+ def_property :bigendian do |prop|
59
+ prop.targets = [:addrmap]
60
+ prop.types = [:boolean]
61
+ prop.dynamic_assign = true
62
+ prop.ref_target = false
63
+ prop.per_element_assign = false
64
+ prop.default_value = false
65
+ end
66
+
67
+ def_property :desc do |prop|
68
+ prop.types = [:string]
69
+ prop.dynamic_assign = true
70
+ prop.ref_target = false
71
+ prop.per_element_assign = true
72
+ prop.default_value = proc { '' }
73
+ end
74
+
75
+ def_property :errextbus do |prop|
76
+ prop.targets = [:addrmap, :regfile, :reg]
77
+ prop.types = [:boolean]
78
+ prop.dynamic_assign = false
79
+ prop.ref_target = false
80
+ prop.per_element_assign = false
81
+ prop.default_value = false
82
+ end
83
+
84
+ def_property :fieldwidth do |prop|
85
+ prop.targets = [:field]
86
+ prop.types = [:longint]
87
+ prop.dynamic_assign = false
88
+ prop.per_element_assign = false
89
+ prop.ref_target = false
90
+ end
91
+
92
+ def_property :hw do |prop|
93
+ prop.targets = [:field]
94
+ prop.types = [:accesstype]
95
+ prop.dynamic_assign = false
96
+ prop.ref_target = false
97
+ prop.per_element_assign = false
98
+ prop.default_value = :rw
99
+ end
100
+
101
+ def_property :hwclr do |prop|
102
+ prop.targets = [:field]
103
+ prop.types = [:boolean, :field_reference, :property_reference]
104
+ prop.dynamic_assign = true
105
+ prop.ref_target = proc { set? }
106
+ prop.per_element_assign = false
107
+ prop.default_value = false
108
+ end
109
+
110
+ def_property :hwenable do |prop|
111
+ prop.targets = [:field]
112
+ prop.types = [:field_reference, :property_reference]
113
+ prop.dynamic_assign = true
114
+ prop.ref_target = proc { set? }
115
+ prop.per_element_assign = false
116
+ end
117
+
118
+ def_property :hwmask do |prop|
119
+ prop.targets = [:field]
120
+ prop.types = [:field_reference, :property_reference]
121
+ prop.dynamic_assign = true
122
+ prop.ref_target = proc { set? }
123
+ prop.per_element_assign = false
124
+ end
125
+
126
+ def_property :hwset do |prop|
127
+ prop.targets = [:field]
128
+ prop.types = [:boolean, :field_reference, :property_reference]
129
+ prop.dynamic_assign = true
130
+ prop.ref_target = proc { set? }
131
+ prop.per_element_assign = false
132
+ prop.default_value = false
133
+ end
134
+
135
+ def_property :littleendian do |prop|
136
+ prop.targets = [:addrmap]
137
+ prop.types = [:boolean]
138
+ prop.dynamic_assign = true
139
+ prop.ref_target = false
140
+ prop.per_element_assign = false
141
+ prop.default_value = false
142
+ end
143
+
144
+ def_property :lsb0 do |prop|
145
+ prop.targets = [:addrmap]
146
+ prop.types = [:boolean]
147
+ prop.dynamic_assign = false
148
+ prop.ref_target = false
149
+ prop.per_element_assign = false
150
+ prop.default_value = false
151
+ end
152
+
153
+ def_property :msb0 do |prop|
154
+ prop.targets = [:addrmap]
155
+ prop.types = [:boolean]
156
+ prop.dynamic_assign = false
157
+ prop.ref_target = false
158
+ prop.per_element_assign = false
159
+ prop.default_value = false
160
+ end
161
+
162
+ def_property :name do |prop|
163
+ prop.types = [:string]
164
+ prop.dynamic_assign = true
165
+ prop.ref_target = false
166
+ prop.per_element_assign = true
167
+ prop.default_value = proc { |inst| inst.name.to_s }
168
+ end
169
+
170
+ def_property :next do |prop|
171
+ prop.targets = [:field]
172
+ prop.types = [:field_reference, :property_reference]
173
+ prop.dynamic_assign = true
174
+ prop.per_element_assign = false
175
+ prop.ref_target = proc { set? }
176
+ end
177
+
178
+ def_property :onread do |prop|
179
+ prop.targets = [:field]
180
+ prop.types = [:onreadtype]
181
+ prop.dynamic_assign = true
182
+ prop.ref_target = false
183
+ prop.per_element_assign = false
184
+ end
185
+
186
+ def_property :onwrite do |prop|
187
+ prop.targets = [:field]
188
+ prop.types = [:onwritetype]
189
+ prop.dynamic_assign = true
190
+ prop.ref_target = false
191
+ prop.per_element_assign = false
192
+ end
193
+
194
+ def_property :ored do |prop|
195
+ prop.targets = [:field]
196
+ prop.types = [:boolean]
197
+ prop.dynamic_assign = true
198
+ prop.ref_target = true
199
+ prop.per_element_assign = false
200
+ prop.default_value = false
201
+ end
202
+
203
+ def_property :paritycheck do |prop|
204
+ prop.targets = [:field]
205
+ prop.types = [:boolean]
206
+ prop.dynamic_assign = false
207
+ prop.ref_target = false
208
+ prop.per_element_assign = false
209
+ prop.default_value = false
210
+ end
211
+
212
+ def_property :precedence do |prop|
213
+ prop.targets = [:field]
214
+ prop.types = [:precedencetype]
215
+ prop.dynamic_assign = true
216
+ prop.ref_target = false
217
+ prop.per_element_assign = false
218
+ prop.default_value = :sw
219
+ end
220
+
221
+ def_property :rclr do |prop|
222
+ prop.targets = [:field]
223
+ prop.types = [:boolean]
224
+ prop.dynamic_assign = true
225
+ prop.ref_target = false
226
+ prop.per_element_assign = false
227
+ prop.default_value = false
228
+ end
229
+
230
+ def_property :regwidth do |prop|
231
+ prop.targets = [:reg]
232
+ prop.types = [:longint]
233
+ prop.dynamic_assign = false
234
+ prop.ref_target = false
235
+ prop.per_element_assign = false
236
+ prop.default_value = 32
237
+ end
238
+
239
+ def_property :reset do |prop|
240
+ prop.targets = [:field]
241
+ prop.types = [:bit, :field_reference, :property_reference]
242
+ prop.dynamic_assign = true
243
+ prop.ref_target = proc { set? }
244
+ prop.per_element_assign = false
245
+ end
246
+
247
+ def_property :resetsignal do |prop|
248
+ prop.targets = [:field]
249
+ prop.types = [:field_reference, :property_reference]
250
+ prop.dynamic_assign = true
251
+ prop.ref_target = proc { set? }
252
+ prop.per_element_assign = false
253
+ end
254
+
255
+ def_property :rset do |prop|
256
+ prop.targets = [:field]
257
+ prop.types = [:boolean]
258
+ prop.dynamic_assign = true
259
+ prop.ref_target = false
260
+ prop.per_element_assign = false
261
+ prop.default_value = false
262
+ end
263
+
264
+ def_property :rsvdset do |prop|
265
+ prop.targets = [:addrmap]
266
+ prop.types = [:boolean]
267
+ prop.dynamic_assign = false
268
+ prop.ref_target = false
269
+ prop.per_element_assign = false
270
+ prop.default_value = false
271
+ end
272
+
273
+ def_property :rsvdsetX do |prop|
274
+ prop.targets = [:addrmap]
275
+ prop.types = [:boolean]
276
+ prop.dynamic_assign = false
277
+ prop.ref_target = false
278
+ prop.per_element_assign = false
279
+ prop.default_value = false
280
+ end
281
+
282
+ def_property :shared do |prop|
283
+ prop.targets = [:reg]
284
+ prop.types = [:boolean]
285
+ prop.dynamic_assign = false
286
+ prop.ref_target = false
287
+ prop.per_element_assign = false
288
+ prop.default_value = false
289
+ end
290
+
291
+ def_property :sharedextbus do |prop|
292
+ prop.targets = [:addrmap, :regfile]
293
+ prop.types = [:boolean]
294
+ prop.dynamic_assign = false
295
+ prop.ref_target = false
296
+ prop.per_element_assign = false
297
+ prop.default_value = false
298
+ end
299
+
300
+ def_property :singlepulse do |prop|
301
+ prop.targets = [:field]
302
+ prop.types = [:boolean]
303
+ prop.dynamic_assign = true
304
+ prop.ref_target = false
305
+ prop.per_element_assign = false
306
+ prop.default_value = false
307
+ end
308
+
309
+ def_property :sw do |prop|
310
+ prop.targets = [:field]
311
+ prop.types = [:accesstype]
312
+ prop.dynamic_assign = true
313
+ prop.ref_target = false
314
+ prop.per_element_assign = false
315
+ prop.default_value = :rw
316
+ end
317
+
318
+ def_property :swacc do |prop|
319
+ prop.targets = [:field]
320
+ prop.types = [:boolean]
321
+ prop.dynamic_assign = true
322
+ prop.ref_target = true
323
+ prop.per_element_assign = false
324
+ prop.default_value = false
325
+ end
326
+
327
+ def_property :swmod do |prop|
328
+ prop.targets = [:field]
329
+ prop.types = [:boolean]
330
+ prop.dynamic_assign = true
331
+ prop.ref_target = true
332
+ prop.per_element_assign = false
333
+ prop.default_value = false
334
+ end
335
+
336
+ def_property :swwe do |prop|
337
+ prop.targets = [:field]
338
+ prop.types = [:boolean, :field_reference, :property_reference]
339
+ prop.dynamic_assign = true
340
+ prop.ref_target = proc { set? }
341
+ prop.per_element_assign = false
342
+ prop.default_value = false
343
+ end
344
+
345
+ def_property :swwel do |prop|
346
+ prop.targets = [:field]
347
+ prop.types = [:boolean, :field_reference, :property_reference]
348
+ prop.dynamic_assign = true
349
+ prop.ref_target = proc { set? }
350
+ prop.per_element_assign = false
351
+ prop.default_value = false
352
+ end
353
+
354
+ def_property :we do |prop|
355
+ prop.targets = [:field]
356
+ prop.types = [:boolean, :field_reference, :property_reference]
357
+ prop.dynamic_assign = true
358
+ prop.ref_target = proc { set? }
359
+ prop.per_element_assign = false
360
+ prop.default_value = false
361
+ end
362
+
363
+ def_property :wel do |prop|
364
+ prop.targets = [:field]
365
+ prop.types = [:boolean, :field_reference, :property_reference]
366
+ prop.dynamic_assign = true
367
+ prop.ref_target = proc { set? }
368
+ prop.per_element_assign = false
369
+ prop.default_value = false
370
+ end
371
+
372
+ def_property :woclr do |prop|
373
+ prop.targets = [:field]
374
+ prop.types = [:boolean]
375
+ prop.dynamic_assign = true
376
+ prop.ref_target = false
377
+ prop.per_element_assign = false
378
+ prop.default_value = false
379
+ end
380
+
381
+ def_property :woset do |prop|
382
+ prop.targets = [:field]
383
+ prop.types = [:boolean]
384
+ prop.dynamic_assign = true
385
+ prop.ref_target = false
386
+ prop.per_element_assign = false
387
+ prop.default_value = false
388
+ end
389
+
390
+ def_property :xored do |prop|
391
+ prop.targets = [:field]
392
+ prop.types = [:boolean]
393
+ prop.dynamic_assign = true
394
+ prop.ref_target = true
395
+ prop.per_element_assign = false
396
+ prop.default_value = false
397
+ end
398
+ end
399
+ end
400
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SystemRDL
4
+ module Evaluator
5
+ module Common
6
+ include RaiseEvaluationError
7
+
8
+ def initialize(token_range)
9
+ @token_range = token_range
10
+ end
11
+
12
+ attr_reader :token_range
13
+ attr_reader :parent
14
+ attr_reader :component
15
+
16
+ def connect(parent, component)
17
+ @parent = parent
18
+ @component = component
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SystemRDL
4
+ module Evaluator
5
+ class ComponentDefinition
6
+ include Common
7
+
8
+ def initialize(id, elements, insts, token_range)
9
+ super(token_range)
10
+ @id = id || insts.insts[0].inst_id
11
+ @definitions = {}
12
+ @elements = elements
13
+ @insts = insts
14
+ @default_properties = {}
15
+ end
16
+
17
+ attr_reader :id
18
+ attr_reader :definitions
19
+
20
+ def connect(parent, component)
21
+ super
22
+ @component&.add_definition(self)
23
+ @elements.each { |element| element.connect(self, self) }
24
+ @insts&.connect(self, self)
25
+ end
26
+
27
+ def upper_layers(include_self: false)
28
+ return [] if layer == :root
29
+
30
+ layers = [*component.upper_layers, component]
31
+ layers << self if include_self
32
+ layers
33
+ end
34
+
35
+ def evaluate(instance, **optargs)
36
+ check_definable(instance)
37
+ @insts&.evaluate(instance, @parent, @id, **optargs)
38
+ end
39
+
40
+ def create_instances(parent_instance, inst_name, inst_values, token_range, **optargs)
41
+ eval_array(inst_values) do |array_info|
42
+ create_instance(
43
+ parent_instance, inst_name, inst_values,
44
+ array_info, token_range, **optargs
45
+ )
46
+ end
47
+ end
48
+
49
+ def validate(_instance)
50
+ end
51
+
52
+ def revalidate(_instance)
53
+ end
54
+
55
+ def finalize(_instance)
56
+ end
57
+
58
+ def assign_default_property(name, value, token_range)
59
+ if @default_properties.key?(name)
60
+ message = "#{name} already assigned in this scope"
61
+ raise_evaluation_error message, token_range
62
+ end
63
+
64
+ @default_properties[name] = value
65
+ end
66
+
67
+ def find_default_property(name)
68
+ upper_layers.reverse_each do |component|
69
+ if (prop = component.default_properties[name])
70
+ return prop
71
+ end
72
+ end
73
+
74
+ nil
75
+ end
76
+
77
+ private
78
+
79
+ def check_power_of_2(instance, name, min_value)
80
+ value = instance.property_value(name)
81
+ return unless value
82
+
83
+ return if power_of_2?(value.value, min_value)
84
+
85
+ message = "#{name} must be a power of 2: #{value}"
86
+ raise_evaluation_error message, value.token_range
87
+ end
88
+
89
+ def power_of_2?(value, min_value)
90
+ value >= min_value && value.nobits?(value - 1)
91
+ end
92
+
93
+ def check_property_exclusivity(instance, names)
94
+ properties =
95
+ names
96
+ .map { |name| instance.property_value(name) }
97
+ .select { |v| v&.value }
98
+ return if properties.size <= 1
99
+
100
+ labels = [names[..-2].join(', '), names[-1]].join(' and ')
101
+ message = "#{labels} properties are mutually exclusive"
102
+
103
+ raise_evaluation_error message, *properties.map(&:token_range)
104
+ end
105
+
106
+ def check_definable(instance)
107
+ return if instance.definable?(self)
108
+
109
+ message = "#{layer} definition not allowed in #{instance.layer}"
110
+ raise_evaluation_error message, token_range
111
+ end
112
+
113
+ def eval_array(_inst_values)
114
+ yield(nil, nil)
115
+ end
116
+
117
+ def create_instance(parent_instance, inst_name, inst_values, array_info, token_range, **optargs)
118
+ unless unique_instance?(parent_instance, inst_name, array_info)
119
+ message = "duplicated instance: #{inst_name}"
120
+ raise_evaluation_error message, token_range
121
+ end
122
+
123
+ instance = instance_class.new(self, parent_instance, inst_name, array_info, token_range)
124
+
125
+ init_properties(instance)
126
+ eval_body(instance, **optargs)
127
+ apply_inst_values(instance, inst_values)
128
+ post_build(instance)
129
+ instance.validate
130
+
131
+ parent_instance.instances << instance if parent_instance
132
+ instance
133
+ end
134
+
135
+ def unique_instance?(parent_instance, inst_name, array_info)
136
+ return true unless parent_instance
137
+
138
+ parent_instance.instances.none? do |inst|
139
+ if inst.name != inst_name
140
+ false
141
+ elsif inst.array? && array_info
142
+ inst.array_info.id != array_info.id
143
+ else
144
+ true
145
+ end
146
+ end
147
+ end
148
+
149
+ def init_properties(instance)
150
+ prop_defs = BuiltinProperties.properties
151
+ prop_defs.each do |prop_def|
152
+ next unless prop_def.target?(instance)
153
+
154
+ prop = prop_def.create(instance)
155
+ instance.properties << prop
156
+ end
157
+ end
158
+
159
+ def eval_body(instance, **optargs)
160
+ @default_properties.clear
161
+ @elements.each { |element| element.evaluate(instance, **optargs) }
162
+ end
163
+
164
+ def apply_inst_values(_instance, _inst_values)
165
+ end
166
+
167
+ def post_build(_instance)
168
+ end
169
+
170
+ protected
171
+
172
+ def add_definition(definition)
173
+ id = definition.id.value
174
+ if @definitions.key?(id)
175
+ message = "duplicated component: #{id}"
176
+ raise_evaluation_error message, definition.token_range
177
+ end
178
+
179
+ @definitions[id] = definition
180
+ end
181
+
182
+ attr_reader :default_properties
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SystemRDL
4
+ module Evaluator
5
+ class ComponentInsts
6
+ include Common
7
+
8
+ def initialize(insts, token_range)
9
+ super(token_range)
10
+ @insts = insts
11
+ end
12
+
13
+ attr_reader :insts
14
+
15
+ def connect(parent, component)
16
+ super
17
+ @insts.each { |inst| inst.connect(self, component) }
18
+ end
19
+
20
+ def evaluate(instance, base, id, **optargs)
21
+ component_definition = find_component_definition(base, id, **optargs)
22
+ check_recursive_instance(instance, component_definition)
23
+ check_instantiable(instance, component_definition)
24
+
25
+ @insts.each do |inst|
26
+ inst.evaluate(instance, component_definition, **optargs)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def find_component_definition(base, id, **optargs)
33
+ base.upper_layers(include_self: true).reverse_each do |component|
34
+ definition = component.definitions[id.value]
35
+ next unless definition
36
+
37
+ unless optargs[:test] || (definition.layer in :reg | :field)
38
+ message = "#{definition.layer} instance not supported yet"
39
+ raise_evaluation_error message, token_range
40
+ end
41
+
42
+ return definition
43
+ end
44
+
45
+ raise_evaluation_error "undefined component: #{id.value}", token_range
46
+ end
47
+
48
+ def check_recursive_instance(instance, component_definition)
49
+ components = instance.definition.upper_layers(include_self: true)
50
+ return if components.none? { |component| component.equal?(component_definition) }
51
+
52
+ message = 'recursive instance not allowed'
53
+ raise_evaluation_error message, token_range
54
+ end
55
+
56
+ def check_instantiable(instance, component_definition)
57
+ return if instance.instantiable?(component_definition)
58
+
59
+ message = "#{component_definition.layer} instance not allowed in #{instance.layer}"
60
+ raise_evaluation_error message, token_range
61
+ end
62
+ end
63
+
64
+ class ComponentInst
65
+ include Common
66
+
67
+ def initialize(inst_id, inst_values, token_range)
68
+ super(token_range)
69
+ @inst_id = inst_id
70
+ @inst_values = inst_values
71
+ end
72
+
73
+ attr_reader :inst_id
74
+
75
+ def evaluate(instance, component_definition, **optargs)
76
+ inst_values = eval_inst_values(instance, **optargs)
77
+ component_definition.create_instances(instance, @inst_id.value, inst_values, @token_range, **optargs)
78
+ end
79
+
80
+ private
81
+
82
+ def eval_inst_values(instance, **optargs)
83
+ @inst_values&.transform_values { |value| value&.evaluate(instance, **optargs) }
84
+ end
85
+ end
86
+
87
+ class ExplicitComponentInst
88
+ include Common
89
+
90
+ def initialize(id, insts, token_range)
91
+ super(token_range)
92
+ @id = id
93
+ @insts = insts
94
+ end
95
+
96
+ def connect(parent, component)
97
+ super
98
+ @insts.connect(self, component)
99
+ end
100
+
101
+ def evaluate(instance, **optargs)
102
+ @insts.evaluate(instance, @component, @id, **optargs)
103
+ end
104
+ end
105
+ end
106
+ end