HDLRuby 2.0.8

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 (224) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/HDLRuby.gemspec +36 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +2774 -0
  9. data/README.pdf +0 -0
  10. data/Rakefile +10 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/hdrcc +3 -0
  14. data/lib/HDLRuby/alcc.rb +137 -0
  15. data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
  16. data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
  17. data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
  18. data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
  19. data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
  20. data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
  21. data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
  22. data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
  23. data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
  24. data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
  25. data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
  26. data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
  27. data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
  28. data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
  29. data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
  30. data/lib/HDLRuby/hdr_samples/include.rb +14 -0
  31. data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
  32. data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
  33. data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
  34. data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
  35. data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
  36. data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
  37. data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
  38. data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
  39. data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
  40. data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
  41. data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
  42. data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
  43. data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
  44. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
  45. data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
  46. data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
  47. data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
  48. data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
  49. data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
  50. data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
  51. data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
  52. data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
  53. data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
  54. data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
  55. data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
  56. data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
  57. data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
  58. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
  59. data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
  60. data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
  61. data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
  62. data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
  63. data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
  64. data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
  65. data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
  66. data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
  67. data/lib/HDLRuby/hdrcc.rb +623 -0
  68. data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
  69. data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
  70. data/lib/HDLRuby/high_samples/adder.rb +21 -0
  71. data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
  72. data/lib/HDLRuby/high_samples/addsub.rb +33 -0
  73. data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
  74. data/lib/HDLRuby/high_samples/after.rb +28 -0
  75. data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
  76. data/lib/HDLRuby/high_samples/alu.rb +61 -0
  77. data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
  78. data/lib/HDLRuby/high_samples/before.rb +28 -0
  79. data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
  80. data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
  81. data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
  82. data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
  83. data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
  84. data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
  85. data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
  86. data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
  87. data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
  88. data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
  89. data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
  90. data/lib/HDLRuby/high_samples/case.rb +32 -0
  91. data/lib/HDLRuby/high_samples/case2.rb +30 -0
  92. data/lib/HDLRuby/high_samples/change.rb +23 -0
  93. data/lib/HDLRuby/high_samples/clocks.rb +35 -0
  94. data/lib/HDLRuby/high_samples/comparer.rb +21 -0
  95. data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
  96. data/lib/HDLRuby/high_samples/dff.rb +23 -0
  97. data/lib/HDLRuby/high_samples/each.rb +28 -0
  98. data/lib/HDLRuby/high_samples/exporter.rb +42 -0
  99. data/lib/HDLRuby/high_samples/functions.rb +60 -0
  100. data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
  101. data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
  102. data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
  103. data/lib/HDLRuby/high_samples/instance.rb +37 -0
  104. data/lib/HDLRuby/high_samples/memory.rb +64 -0
  105. data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
  106. data/lib/HDLRuby/high_samples/overload.rb +32 -0
  107. data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
  108. data/lib/HDLRuby/high_samples/ram.rb +27 -0
  109. data/lib/HDLRuby/high_samples/registers.rb +139 -0
  110. data/lib/HDLRuby/high_samples/rom.rb +23 -0
  111. data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
  112. data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
  113. data/lib/HDLRuby/high_samples/shift.rb +31 -0
  114. data/lib/HDLRuby/high_samples/shift2.rb +40 -0
  115. data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
  116. data/lib/HDLRuby/high_samples/test_all.sh +10 -0
  117. data/lib/HDLRuby/high_samples/typedef.rb +24 -0
  118. data/lib/HDLRuby/high_samples/values.rb +70 -0
  119. data/lib/HDLRuby/high_samples/vector.rb +22 -0
  120. data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
  121. data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
  122. data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
  123. data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
  124. data/lib/HDLRuby/hruby_bstr.rb +1085 -0
  125. data/lib/HDLRuby/hruby_check.rb +317 -0
  126. data/lib/HDLRuby/hruby_db.rb +432 -0
  127. data/lib/HDLRuby/hruby_error.rb +44 -0
  128. data/lib/HDLRuby/hruby_high.rb +4103 -0
  129. data/lib/HDLRuby/hruby_low.rb +4735 -0
  130. data/lib/HDLRuby/hruby_low2c.rb +1986 -0
  131. data/lib/HDLRuby/hruby_low2high.rb +738 -0
  132. data/lib/HDLRuby/hruby_low2seq.rb +248 -0
  133. data/lib/HDLRuby/hruby_low2sym.rb +126 -0
  134. data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
  135. data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
  136. data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
  137. data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
  138. data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
  139. data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
  140. data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
  141. data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
  142. data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
  143. data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
  144. data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
  145. data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
  146. data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
  147. data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
  148. data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
  149. data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
  150. data/lib/HDLRuby/hruby_serializer.rb +398 -0
  151. data/lib/HDLRuby/hruby_tools.rb +37 -0
  152. data/lib/HDLRuby/hruby_types.rb +239 -0
  153. data/lib/HDLRuby/hruby_values.rb +64 -0
  154. data/lib/HDLRuby/hruby_verilog.rb +1888 -0
  155. data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
  156. data/lib/HDLRuby/low_samples/adder.yaml +97 -0
  157. data/lib/HDLRuby/low_samples/after.yaml +228 -0
  158. data/lib/HDLRuby/low_samples/before.yaml +223 -0
  159. data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
  160. data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
  161. data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
  162. data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
  163. data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
  164. data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
  165. data/lib/HDLRuby/low_samples/case.yaml +327 -0
  166. data/lib/HDLRuby/low_samples/change.yaml +135 -0
  167. data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
  168. data/lib/HDLRuby/low_samples/cloner.rb +22 -0
  169. data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
  170. data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
  171. data/lib/HDLRuby/low_samples/dff.yaml +107 -0
  172. data/lib/HDLRuby/low_samples/each.yaml +1328 -0
  173. data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
  174. data/lib/HDLRuby/low_samples/functions.yaml +298 -0
  175. data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
  176. data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
  177. data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
  178. data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
  179. data/lib/HDLRuby/low_samples/memory.yaml +678 -0
  180. data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
  181. data/lib/HDLRuby/low_samples/overload.yaml +226 -0
  182. data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
  183. data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
  184. data/lib/HDLRuby/low_samples/ram.yaml +207 -0
  185. data/lib/HDLRuby/low_samples/registers.yaml +228 -0
  186. data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
  187. data/lib/HDLRuby/low_samples/shift.yaml +230 -0
  188. data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
  189. data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
  190. data/lib/HDLRuby/low_samples/test_all.sh +43 -0
  191. data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
  192. data/lib/HDLRuby/low_samples/values.yaml +577 -0
  193. data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
  194. data/lib/HDLRuby/low_samples/vector.yaml +56 -0
  195. data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
  196. data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
  197. data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
  198. data/lib/HDLRuby/sim/Makefile +19 -0
  199. data/lib/HDLRuby/sim/hruby_sim.h +590 -0
  200. data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
  201. data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
  202. data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
  203. data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
  204. data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
  205. data/lib/HDLRuby/std/channel.rb +354 -0
  206. data/lib/HDLRuby/std/clocks.rb +165 -0
  207. data/lib/HDLRuby/std/counters.rb +82 -0
  208. data/lib/HDLRuby/std/decoder.rb +214 -0
  209. data/lib/HDLRuby/std/fsm.rb +516 -0
  210. data/lib/HDLRuby/std/pipeline.rb +220 -0
  211. data/lib/HDLRuby/std/reconf.rb +309 -0
  212. data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
  213. data/lib/HDLRuby/test_hruby_high.rb +594 -0
  214. data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
  215. data/lib/HDLRuby/test_hruby_low.rb +934 -0
  216. data/lib/HDLRuby/v_samples/adder.v +10 -0
  217. data/lib/HDLRuby/v_samples/dff.v +12 -0
  218. data/lib/HDLRuby/v_samples/ram.v +20 -0
  219. data/lib/HDLRuby/v_samples/rom.v +270 -0
  220. data/lib/HDLRuby/version.rb +3 -0
  221. data/lib/HDLRuby.rb +11 -0
  222. data/makedoc +1 -0
  223. data/metadata.yaml +4 -0
  224. metadata +299 -0
@@ -0,0 +1,4735 @@
1
+ require "HDLRuby/hruby_bstr"
2
+ require "HDLRuby/hruby_error"
3
+ require 'forwardable'
4
+
5
+
6
+
7
+ module HDLRuby
8
+ # Some useful constants
9
+ Infinity = +1.0/0.0
10
+ end
11
+
12
+
13
+
14
+ ##
15
+ # Library for describing the basic structures of the hardware component.
16
+ #
17
+ ########################################################################
18
+ module HDLRuby::Low
19
+
20
+ ##
21
+ # Describes a hash for named HDLRuby objects
22
+ class HashName < Hash
23
+ # Adds a named +object+.
24
+ def add(object)
25
+ self[object.name] = object
26
+ end
27
+
28
+ # Tells if +object+ is included in the hash.
29
+ def include?(object)
30
+ return self.has_key?(object.name)
31
+ end
32
+
33
+ # Iterate over the objects included in the hash.
34
+ alias_method :each, :each_value
35
+ end
36
+
37
+ ##
38
+ # Gives parent definition and access properties to an hardware object.
39
+ module Hparent
40
+ # The parent.
41
+ attr_reader :parent
42
+
43
+ # Set the +parent+.
44
+ #
45
+ # Note: if +parent+ is nil, the current parent is removed.
46
+ def parent=(parent)
47
+ if @parent and parent and !@parent.equal?(parent) then
48
+ # The parent is already defined,it is not to be removed,
49
+ # and the new parent is different, error.
50
+ raise AnyError, "Parent already defined."
51
+ else
52
+ @parent = parent
53
+ end
54
+ end
55
+ end
56
+
57
+
58
+ ##
59
+ # Describes a system type.
60
+ #
61
+ # NOTE: delegates its content-related methods to its Scope object.
62
+ class SystemT
63
+
64
+ include Hparent
65
+
66
+ # The name of the system.
67
+ attr_reader :name
68
+
69
+ # The scope of the system type.
70
+ attr_reader :scope
71
+
72
+ # Creates a new system type named +name+ with +scope+.
73
+ def initialize(name,scope)
74
+ # Set the name as a symbol.
75
+ @name = name.to_sym
76
+
77
+ # Initialize the interface (signal instance lists).
78
+ @inputs = HashName.new # The input signals by name
79
+ @outputs = HashName.new # The output signals by name
80
+ @inouts = HashName.new # The inout signals by name
81
+ @interface = [] # The interface signals in order of
82
+ # declaration
83
+
84
+ # Check the scope
85
+ unless scope.is_a?(Scope)
86
+ raise AnyError,
87
+ "Invalid class for a system instance: #{scope.class}"
88
+ end
89
+ # Set the parent of the scope
90
+ scope.parent = self
91
+ # Set the scope
92
+ @scope = scope
93
+
94
+
95
+ # The methods delegated to the scope.
96
+ # Do not use Delegator to keep hand on the attributes of the class.
97
+
98
+ [:add_scope, :each_scope, # :delete_scope,
99
+ :add_systemI, :each_systemI, :get_systemI, # :delete_systemI,
100
+ :add_inner, :each_inner, :get_inner, # :delete_inner,
101
+ :add_behavior, :each_behavior, :each_behavior_deep, # :delete_behavior,
102
+ :add_connection,:each_connection, # :delete_connection
103
+ ].each do |meth_sym|
104
+ define_singleton_method(meth_sym,
105
+ &(@scope.method(meth_sym).to_proc))
106
+ end
107
+ end
108
+
109
+ # Comparison for hash: structural comparison.
110
+ def eql?(obj)
111
+ return false unless obj.is_a?(SystemT)
112
+ return false unless @name.eql?(obj.name)
113
+ return false unless @scope.eql?(obj.scope)
114
+ idx = 0
115
+ obj.each_input do |input|
116
+ return false unless @inputs[input.name].eql?(input)
117
+ idx += 1
118
+ end
119
+ return false unless idx == @inputs.size
120
+ idx = 0
121
+ obj.each_output do |output|
122
+ return false unless @outputs[output.name].eql?(output)
123
+ idx += 1
124
+ end
125
+ return false unless idx == @outputs.size
126
+ idx = 0
127
+ obj.each_inout do |inout|
128
+ return false unless @inouts[inout.name].eql?(inout)
129
+ idx += 1
130
+ end
131
+ return false unless idx == @inouts.size
132
+ return true
133
+ end
134
+
135
+ # Hash function.
136
+ def hash
137
+ return [@name,@scope,@inputs,@outputs,@inouts].hash
138
+ end
139
+
140
+
141
+
142
+ # Handling the signals.
143
+
144
+ # Adds input +signal+.
145
+ def add_input(signal)
146
+ # print "add_input with signal: #{signal.name}\n"
147
+ # Check and add the signal.
148
+ unless signal.is_a?(SignalI)
149
+ raise AnyError,
150
+ "Invalid class for a signal instance: #{signal.class}"
151
+ end
152
+ if @inputs.include?(signal) then
153
+ raise AnyError, "SignalI #{signal.name} already present."
154
+ end
155
+ # Set the parent of the signal.
156
+ signal.parent = self
157
+ # And add the signal.
158
+ @inputs.add(signal)
159
+ @interface << signal
160
+ return signal
161
+ end
162
+
163
+ # Adds output +signal+.
164
+ def add_output(signal)
165
+ # Check and add the signal.
166
+ unless signal.is_a?(SignalI)
167
+ raise AnyError,
168
+ "Invalid class for a signal instance: #{signal.class}"
169
+ end
170
+ if @outputs.include?(signal) then
171
+ raise AnyError, "SignalI #{signal.name} already present."
172
+ end
173
+ # Set the parent of the signal.
174
+ signal.parent = self
175
+ # And add the signal.
176
+ @outputs.add(signal)
177
+ @interface << signal
178
+ return signal
179
+ end
180
+
181
+ # Adds inout +signal+.
182
+ def add_inout(signal)
183
+ # Check and add the signal.
184
+ unless signal.is_a?(SignalI)
185
+ raise AnyError,
186
+ "Invalid class for a signal instance: #{signal.class}"
187
+ end
188
+ if @inouts.include?(signal) then
189
+ raise AnyError, "SignalI #{signal.name} already present."
190
+ end
191
+ # Set the parent of the signal.
192
+ signal.parent = self
193
+ # And add the signal.
194
+ @inouts.add(signal)
195
+ @interface << signal
196
+ return signal
197
+ end
198
+
199
+ # Iterates over the input signals.
200
+ #
201
+ # Returns an enumerator if no ruby block is given.
202
+ def each_input(&ruby_block)
203
+ # No ruby block? Return an enumerator.
204
+ return to_enum(:each_input) unless ruby_block
205
+ # A ruby block? Apply it on each input signal instance.
206
+ @inputs.each(&ruby_block)
207
+ end
208
+
209
+ # Iterates over the output signals.
210
+ #
211
+ # Returns an enumerator if no ruby block is given.
212
+ def each_output(&ruby_block)
213
+ # No ruby block? Return an enumerator.
214
+ return to_enum(:each_output) unless ruby_block
215
+ # A ruby block? Apply it on each output signal instance.
216
+ @outputs.each(&ruby_block)
217
+ end
218
+
219
+ # Iterates over the inout signals.
220
+ #
221
+ # Returns an enumerator if no ruby block is given.
222
+ def each_inout(&ruby_block)
223
+ # No ruby block? Return an enumerator.
224
+ return to_enum(:each_inout) unless ruby_block
225
+ # A ruby block? Apply it on each inout signal instance.
226
+ @inouts.each(&ruby_block)
227
+ end
228
+
229
+ # Iterates over all the signals of the interface of the
230
+ # system.
231
+ #
232
+ # Returns an enumerator if no ruby block is given.
233
+ def each_signal(&ruby_block)
234
+ # No ruby block? Return an enumerator.
235
+ return to_enum(:each_signal) unless ruby_block
236
+ # A ruby block? Apply it on each signal instance.
237
+ @interface.each(&ruby_block)
238
+ end
239
+
240
+ # Iterates over all the signals of the system including its
241
+ # scope (input, output, inout, inner).
242
+ #
243
+ # Returns an enumerator if no ruby block is given.
244
+ def each_signal_all(&ruby_block)
245
+ # No ruby block? Return an enumerator.
246
+ return to_enum(:each_signal) unless ruby_block
247
+ # A ruby block? Apply it on each signal instance.
248
+ @inputs.each(&ruby_block)
249
+ @outputs.each(&ruby_block)
250
+ @inouts.each(&ruby_block)
251
+ end
252
+
253
+ # Iterates over all the signals of the system type and its scope.
254
+ def each_signal_deep(&ruby_block)
255
+ # No ruby block? Return an enumerator.
256
+ return to_enum(:each_signal_deep) unless ruby_block
257
+ # A ruby block?
258
+ # First iterate over the current system type's signals.
259
+ self.each_signal_all(&ruby_block)
260
+ # Then apply on the behaviors (since in HDLRuby:High, blocks can
261
+ # include signals).
262
+ @scope.each_signal_deep(&ruby_block)
263
+ end
264
+
265
+ # Tells if there is any input signal.
266
+ def has_input?
267
+ return !@inputs.empty?
268
+ end
269
+
270
+ # Tells if there is any output signal.
271
+ def has_output?
272
+ return !@outputs.empty?
273
+ end
274
+
275
+ # Tells if there is any output signal.
276
+ def has_inout?
277
+ return !@inouts.empty?
278
+ end
279
+
280
+ # Tells if there is any signal (including in the scope of the system).
281
+ def has_signal?
282
+ return ( self.has_input? or self.has_output? or self.has_inout? or
283
+ self.has_inner? )
284
+ end
285
+
286
+ # Gets an array containing all the input signals.
287
+ def get_all_inputs
288
+ return each_input.to_a
289
+ end
290
+
291
+ # Gets an array containing all the output signals.
292
+ def get_all_outputs
293
+ return each_output.to_a
294
+ end
295
+
296
+ # Gets an array containing all the inout signals.
297
+ def get_all_inouts
298
+ return each_inout.to_a
299
+ end
300
+
301
+ # Gets an array containing all the signals.
302
+ def get_all_signals
303
+ return each_signal.to_a
304
+ end
305
+
306
+ # Gets an input signal by +name+.
307
+ def get_input(name)
308
+ return @inputs[name.to_sym]
309
+ end
310
+
311
+ # Gets an output signal by +name+.
312
+ def get_output(name)
313
+ return @outputs[name.to_sym]
314
+ end
315
+
316
+ # Gets an inout signal by +name+.
317
+ def get_inout(name)
318
+ return @inouts[name.to_sym]
319
+ end
320
+
321
+ # # Gets an inner signal by +name+.
322
+ # def get_inner(name)
323
+ # return @inners[name.to_sym]
324
+ # end
325
+
326
+ # Gets a signal by +name+.
327
+ def get_signal(name)
328
+ return get_input(name) || get_output(name) || get_inout(name) # ||
329
+ # get_inner(name)
330
+ end
331
+
332
+ # Gets an interface signal by order of declaration +i+.
333
+ def get_interface(i)
334
+ return @interface[i]
335
+ end
336
+
337
+ # # Deletes input +signal+.
338
+ # def delete_input(signal)
339
+ # if @inputs.key?(signal) then
340
+ # # The signal is present, delete it.
341
+ # @inputs.delete(signal.name)
342
+ # @interface.delete(signal)
343
+ # # And remove its parent.
344
+ # signal.parent = nil
345
+ # end
346
+ # signal
347
+ # end
348
+
349
+ # # Deletes output +signal+.
350
+ # def delete_output(signal)
351
+ # if @outputs.key?(signal) then
352
+ # # The signal is present, delete it.
353
+ # @outputs.delete(signal.name)
354
+ # @interface.delete(signal)
355
+ # # And remove its parent.
356
+ # signal.parent = nil
357
+ # end
358
+ # signal
359
+ # end
360
+
361
+ # # Deletes inout +signal+.
362
+ # def delete_inout(signal)
363
+ # if @inouts.key?(signal) then
364
+ # # The signal is present, delete it.
365
+ # @inouts.delete(signal.name)
366
+ # @interface.delete(signal)
367
+ # # And remove its parent.
368
+ # signal.parent = nil
369
+ # end
370
+ # signal
371
+ # end
372
+
373
+ # Iterates over the systemT deeply if any.
374
+ def each_systemT_deep(&ruby_block)
375
+ # No ruby block? Return an enumerator.
376
+ return to_enum(:each_systemT_deep) unless ruby_block
377
+ # A ruby block? First apply it to current.
378
+ ruby_block.call(self)
379
+ # And recurse on the systemT accessible through the instances.
380
+ self.scope.each_scope_deep do |scope|
381
+ scope.each_systemI do |systemI|
382
+ # systemI.systemT.each_systemT_deep(&ruby_block)
383
+ systemI.each_systemT do |systemT|
384
+ systemT.each_systemT_deep(&ruby_block)
385
+ end
386
+ end
387
+ end
388
+ end
389
+ end
390
+
391
+
392
+ ##
393
+ # Describes scopes of system types.
394
+ class Scope
395
+
396
+ include Hparent
397
+
398
+ # The name of the scope if any
399
+ attr_reader :name
400
+
401
+ # Creates a new scope with a possible +name+.
402
+ def initialize(name = :"")
403
+ # Check and set the name.
404
+ @name = name.to_sym
405
+ # Initialize the local types.
406
+ @types = HashName.new
407
+ # Initialize the local system types.
408
+ @systemTs = HashName.new
409
+ # Initialize the sub scopes.
410
+ @scopes = []
411
+ # Initialize the inner signal instance lists.
412
+ @inners = HashName.new
413
+ # Initialize the system instances list.
414
+ @systemIs = HashName.new
415
+ # Initialize the non-HDLRuby code chunks list.
416
+ @codes = []
417
+ # Initialize the connections list.
418
+ @connections = []
419
+ # Initialize the behaviors lists.
420
+ @behaviors = []
421
+ end
422
+
423
+ # Comparison for hash: structural comparison.
424
+ def eql?(obj)
425
+ return false unless obj.is_a?(Scope)
426
+ idx = 0
427
+ obj.each_systemT do |systemT|
428
+ return false unless @systemTs[systemT.name].eql?(systemT)
429
+ idx += 1
430
+ end
431
+ return false unless idx == @systemTs.size
432
+ idx = 0
433
+ obj.each_type do |type|
434
+ return false unless @types[type.name].eql?(type)
435
+ idx += 1
436
+ end
437
+ return false unless idx == @types.size
438
+ idx = 0
439
+ obj.each_scope do |scope|
440
+ return false unless @scopes[idx].eql?(scope)
441
+ idx += 1
442
+ end
443
+ return false unless idx == @scopes.size
444
+ idx = 0
445
+ obj.each_inner do |inner|
446
+ return false unless @inners[inner.name].eql?(inner)
447
+ idx += 1
448
+ end
449
+ return false unless idx == @inners.size
450
+ idx = 0
451
+ obj.each_systemI do |systemI|
452
+ return false unless @systemIs[systemI.name].eql?(systemI)
453
+ idx += 1
454
+ end
455
+ return false unless idx == @systemIs.size
456
+ idx = 0
457
+ obj.each_connection do |connection|
458
+ return false unless @connections[idx].eql?(connection)
459
+ idx += 1
460
+ end
461
+ return false unless idx == @connections.size
462
+ idx = 0
463
+ obj.each_behavior do |behavior|
464
+ return false unless @behaviors[idx].eql?(behavior)
465
+ idx += 1
466
+ end
467
+ return false unless idx == @behaviors.size
468
+ return true
469
+ end
470
+
471
+ # Hash function.
472
+ def hash
473
+ return [@systemTs,@types,@scopes,@inners,@systemIs,@connections,@behaviors].hash
474
+ end
475
+
476
+ # Handling the local system types.
477
+
478
+ # Adds system instance +systemT+.
479
+ def add_systemT(systemT)
480
+ # puts "add_systemT with name #{systemT.name}"
481
+ # Check and add the systemT.
482
+ unless systemT.is_a?(SystemT)
483
+ raise AnyError,
484
+ "Invalid class for a system type: #{systemT.class}"
485
+ end
486
+ if @systemTs.include?(systemT) then
487
+ raise AnyError, "SystemT #{systemT.name} already present."
488
+ end
489
+ # Set the parent of the instance
490
+ systemT.parent = self
491
+ # puts "systemT = #{systemT}, parent=#{self}"
492
+ # Add the instance
493
+ @systemTs.add(systemT)
494
+ end
495
+
496
+ # Iterates over the system instances.
497
+ #
498
+ # Returns an enumerator if no ruby block is given.
499
+ def each_systemT(&ruby_block)
500
+ # puts "each_systemT from scope=#{self}"
501
+ # No ruby block? Return an enumerator.
502
+ return to_enum(:each_systemT) unless ruby_block
503
+ # A ruby block? Apply it on each system instance.
504
+ @systemTs.each(&ruby_block)
505
+ end
506
+
507
+ # Tells if there is any system instance.
508
+ def has_systemT?
509
+ return !@systemTs.empty?
510
+ end
511
+
512
+ # Gets a system instance by +name+.
513
+ def get_systemT(name)
514
+ return @systemTs[name]
515
+ end
516
+
517
+ # # Deletes system instance systemT.
518
+ # def delete_systemT(systemT)
519
+ # if @systemTs.key?(systemT.name) then
520
+ # # The instance is present, do remove it.
521
+ # @systemTs.delete(systemT.name)
522
+ # # And remove its parent.
523
+ # systemT.parent = nil
524
+ # end
525
+ # systemT
526
+ # end
527
+
528
+ # Handle the local types.
529
+
530
+ # Adds system instance +type+.
531
+ def add_type(type)
532
+ # puts "add_type with name #{type.name}"
533
+ # Check and add the type.
534
+ unless type.is_a?(Type)
535
+ raise AnyError,
536
+ "Invalid class for a type: #{type.class}"
537
+ end
538
+ if @types.include?(type) then
539
+ raise AnyError, "Type #{type.name} already present."
540
+ end
541
+ # Set the parent of the instance
542
+ type.parent = self
543
+ # puts "type = #{type}, parent=#{self}"
544
+ # Add the instance
545
+ @types.add(type)
546
+ end
547
+
548
+ # Iterates over the system instances.
549
+ #
550
+ # Returns an enumerator if no ruby block is given.
551
+ def each_type(&ruby_block)
552
+ # puts "each_type from scope=#{self}"
553
+ # No ruby block? Return an enumerator.
554
+ return to_enum(:each_type) unless ruby_block
555
+ # A ruby block? Apply it on each system instance.
556
+ @types.each(&ruby_block)
557
+ end
558
+
559
+ # Tells if there is any system instance.
560
+ def has_type?
561
+ return !@types.empty?
562
+ end
563
+
564
+ # Gets a system instance by +name+.
565
+ def get_type(name)
566
+ return @types[name]
567
+ end
568
+
569
+ # # Deletes system instance type.
570
+ # def delete_type(type)
571
+ # if @types.key?(type.name) then
572
+ # # The instance is present, do remove it.
573
+ # @types.delete(type.name)
574
+ # # And remove its parent.
575
+ # type.parent = nil
576
+ # end
577
+ # type
578
+ # end
579
+
580
+
581
+
582
+ # Handling the scopes
583
+
584
+ # Adds a new +scope+.
585
+ def add_scope(scope)
586
+ # Check and add the scope.
587
+ unless scope.is_a?(Scope)
588
+ raise AnyError,
589
+ "Invalid class for a system instance: #{scope.class}"
590
+ end
591
+ if @scopes.include?(scope) then
592
+ raise AnyError, "Scope #{scope} already present."
593
+ end
594
+ # Set the parent of the scope
595
+ scope.parent = self
596
+ # Add the instance
597
+ @scopes << scope
598
+ end
599
+
600
+ # Iterates over the sub scopes.
601
+ #
602
+ # Returns an enumerator if no ruby block is given.
603
+ def each_scope(&ruby_block)
604
+ # No ruby block? Return an enumerator.
605
+ return to_enum(:each_scope) unless ruby_block
606
+ # A ruby block? Apply it on each sub scope.
607
+ @scopes.each(&ruby_block)
608
+ end
609
+
610
+ # Iterates over the scopes deeply.
611
+ #
612
+ # Returns an enumerator if no ruby block is given.
613
+ def each_scope_deep(&ruby_block)
614
+ # No ruby block? Return an enumerator.
615
+ return to_enum(:each_scope_deep) unless ruby_block
616
+ # A ruby block? Apply it on self.
617
+ ruby_block.call(self)
618
+ # And recurse each sub scope.
619
+ @scopes.each {|scope| scope.each_scope_deep(&ruby_block) }
620
+ end
621
+
622
+ # Tells if there is any sub scope.
623
+ def has_scope?
624
+ return !@scopes.empty?
625
+ end
626
+
627
+ # # Deletes a scope.
628
+ # def delete_scope(scope)
629
+ # # Remove the scope from the list
630
+ # @scopes.delete(scope)
631
+ # # And remove its parent.
632
+ # scope.parent = nil
633
+ # # Return the deleted scope
634
+ # scope
635
+ # end
636
+
637
+ # Handling the system instances.
638
+
639
+ # Adds system instance +systemI+.
640
+ def add_systemI(systemI)
641
+ # puts "add_systemI with name #{systemI.name}"
642
+ # Check and add the systemI.
643
+ unless systemI.is_a?(SystemI)
644
+ raise AnyError,
645
+ "Invalid class for a system instance: #{systemI.class}"
646
+ end
647
+ if @systemIs.include?(systemI) then
648
+ raise AnyError, "SystemI #{systemI.name} already present."
649
+ end
650
+ # Set the parent of the instance
651
+ systemI.parent = self
652
+ # puts "systemI = #{systemI}, parent=#{self}"
653
+ # Add the instance
654
+ @systemIs.add(systemI)
655
+ end
656
+
657
+ # Iterates over the system instances.
658
+ #
659
+ # Returns an enumerator if no ruby block is given.
660
+ def each_systemI(&ruby_block)
661
+ # puts "each_systemI from scope=#{self}"
662
+ # No ruby block? Return an enumerator.
663
+ return to_enum(:each_systemI) unless ruby_block
664
+ # A ruby block? Apply it on each system instance.
665
+ @systemIs.each(&ruby_block)
666
+ end
667
+
668
+ # Tells if there is any system instance.
669
+ def has_systemI?
670
+ return !@systemIs.empty?
671
+ end
672
+
673
+ # Gets a system instance by +name+.
674
+ def get_systemI(name)
675
+ return @systemIs[name]
676
+ end
677
+
678
+ # # Deletes system instance systemI.
679
+ # def delete_systemI(systemI)
680
+ # if @systemIs.key?(systemI.name) then
681
+ # # The instance is present, do remove it.
682
+ # @systemIs.delete(systemI.name)
683
+ # # And remove its parent.
684
+ # systemI.parent = nil
685
+ # end
686
+ # systemI
687
+ # end
688
+ #
689
+ # Handling the non-HDLRuby code chunks.
690
+
691
+ # Adds code chunk +code+.
692
+ def add_code(code)
693
+ # Check and add the code chunk.
694
+ unless code.is_a?(Code)
695
+ raise AnyError,
696
+ "Invalid class for a non-hDLRuby code chunk: #{code.class}"
697
+ end
698
+ if @codes.include?(code) then
699
+ raise AnyError, "Code #{code.name} already present."
700
+ end
701
+ # Set the parent of the code chunk.
702
+ code.parent = self
703
+ # puts "code = #{code}, parent=#{self}"
704
+ # Add the code chunk.
705
+ @codes << code
706
+ code
707
+ end
708
+
709
+ # Iterates over the non-HDLRuby code chunks.
710
+ #
711
+ # Returns an enumerator if no ruby block is given.
712
+ def each_code(&ruby_block)
713
+ # puts "each_code from scope=#{self}"
714
+ # No ruby block? Return an enumerator.
715
+ return to_enum(:each_code) unless ruby_block
716
+ # A ruby block? Apply it on each system instance.
717
+ @codes.each(&ruby_block)
718
+ end
719
+
720
+ # Tells if there is any non-HDLRuby code chunk.
721
+ def has_code?
722
+ return !@codes.empty?
723
+ end
724
+
725
+ # Gets a code chunk by +name+.
726
+ def get_code(name)
727
+ return @codes[name]
728
+ end
729
+
730
+ # Handling the signals.
731
+
732
+ # Adds inner signal +signal+.
733
+ def add_inner(signal)
734
+ # Check and add the signal.
735
+ unless signal.is_a?(SignalI)
736
+ raise AnyError,
737
+ "Invalid class for a signal instance: #{signal.class}"
738
+ end
739
+ # if @inners.has_key?(signal.name) then
740
+ if @inners.include?(signal) then
741
+ raise AnyError, "SignalI #{signal.name} already present."
742
+ end
743
+ # @inners[signal.name] = signal
744
+ # Set the parent of the signal.
745
+ signal.parent = self
746
+ # And add the signal.
747
+ @inners.add(signal)
748
+ return signal
749
+ end
750
+
751
+ # Iterates over the inner signals.
752
+ #
753
+ # Returns an enumerator if no ruby block is given.
754
+ def each_inner(&ruby_block)
755
+ # No ruby block? Return an enumerator.
756
+ return to_enum(:each_inner) unless ruby_block
757
+ # A ruby block? Apply it on each inner signal instance.
758
+ # @inners.each_value(&ruby_block)
759
+ @inners.each(&ruby_block)
760
+ end
761
+
762
+ # Iterates over all the signals (Equivalent to each_inner).
763
+ #
764
+ # Returns an enumerator if no ruby block is given.
765
+ def each_signal(&ruby_block)
766
+ # No ruby block? Return an enumerator.
767
+ return to_enum(:each_signal) unless ruby_block
768
+ # A ruby block? Apply it on each signal instance.
769
+ @inners.each(&ruby_block)
770
+ end
771
+
772
+ # Iterates over all the signals of the scope, its behaviors', its
773
+ # instances' and its sub scopes'.
774
+ def each_signal_deep(&ruby_block)
775
+ # No ruby block? Return an enumerator.
776
+ return to_enum(:each_signal_deep) unless ruby_block
777
+ # A ruby block?
778
+ # First iterate over the current system type's signals.
779
+ self.each_signal(&ruby_block)
780
+ # Then apply on the behaviors (since in HDLRuby:High, blocks can
781
+ # include signals).
782
+ self.each_behavior do |behavior|
783
+ behavior.block.each_signal_deep(&ruby_block)
784
+ end
785
+ # Then recurse on the system instances.
786
+ self.each_systemI do |systemI|
787
+ systemI.each_signal_deep(&ruby_block)
788
+ end
789
+ # The recurse on the sub scopes.
790
+ self.each_scope do |scope|
791
+ scope.each_signal_deep(&ruby_block)
792
+ end
793
+ end
794
+
795
+ # Tells if there is any inner.
796
+ def has_inner?
797
+ return !@inners.empty?
798
+ end
799
+
800
+ # Tells if there is any signal, equivalent to has_inner?
801
+ def has_signal?
802
+ return self.has_inner?
803
+ end
804
+
805
+ ## Gets an array containing all the inner signals.
806
+ def get_all_inners
807
+ return each_inner.to_a
808
+ end
809
+
810
+ ## Gets an inner signal by +name+.
811
+ def get_inner(name)
812
+ return @inners[name.to_sym]
813
+ end
814
+
815
+ # ## Gets a signal by +path+.
816
+ # #
817
+ # # NOTE: +path+ can also be a single name or a reference object.
818
+ # def get_signal(path)
819
+ # path = path.path_each if path.respond_to?(:path_each) # Ref case.
820
+ # if path.respond_to?(:each) then
821
+ # # Path is iterable: look for the first name.
822
+ # path = path.each
823
+ # name = path.each.next
824
+ # # Maybe it is a system instance.
825
+ # systemI = self.get_systemI(name)
826
+ # if systemI then
827
+ # # Yes, look for the remaining of the path into the
828
+ # # corresponding system type.
829
+ # return systemI.systemT.get_signal(path)
830
+ # else
831
+ # # Maybe it is a signal name.
832
+ # return self.get_signal(name)
833
+ # end
834
+ # else
835
+ # # Path is a single name, look for the signal in the system's
836
+ # # Try in the inputs.
837
+ # signal = get_input(path)
838
+ # return signal if signal
839
+ # # Try in the outputs.
840
+ # signal = get_output(path)
841
+ # return signal if signal
842
+ # # Try in the inouts.
843
+ # signal = get_inout(path)
844
+ # return signal if signal
845
+ # # Not found yet, look into the inners.
846
+ # return get_inner(path)
847
+ # end
848
+ # end
849
+
850
+ # Gets an inner signal by +name+, equivalent to get_inner.
851
+ def get_signal(name)
852
+ return @inners[name]
853
+ end
854
+
855
+ # # Deletes inner +signal+.
856
+ # def delete_inner(signal)
857
+ # if @inners.key?(signal) then
858
+ # # The signal is present, delete it.
859
+ # @inners.delete(signal.name)
860
+ # # And remove its parent.
861
+ # signal.parent = nil
862
+ # end
863
+ # signal
864
+ # end
865
+
866
+ # Handling the connections.
867
+
868
+ # Adds a +connection+.
869
+ def add_connection(connection)
870
+ unless connection.is_a?(Connection)
871
+ raise AnyError,
872
+ "Invalid class for a connection: #{connection.class}"
873
+ end
874
+ # Set the parent of the connection.
875
+ connection.parent = self
876
+ # And add it.
877
+ @connections << connection
878
+ connection
879
+ end
880
+
881
+ # Iterates over the connections.
882
+ #
883
+ # Returns an enumerator if no ruby block is given.
884
+ def each_connection(&ruby_block)
885
+ # No ruby block? Return an enumerator.
886
+ return to_enum(:each_connection) unless ruby_block
887
+ # A ruby block? Apply it on each connection.
888
+ @connections.each(&ruby_block)
889
+ end
890
+
891
+ # Tells if there is any connection.
892
+ def has_connection?
893
+ return !@connections.empty?
894
+ end
895
+
896
+ # # Deletes +connection+.
897
+ # def delete_connection(connection)
898
+ # if @connections.include?(connection) then
899
+ # # The connection is present, delete it.
900
+ # @connections.delete(connection)
901
+ # # And remove its parent.
902
+ # connection.parent = nil
903
+ # end
904
+ # connection
905
+ # end
906
+
907
+ # Iterates over all the connections of the system type and its system
908
+ # instances.
909
+ def each_connection_deep(&ruby_block)
910
+ # No ruby block? Return an enumerator.
911
+ return to_enum(:each_connection_deep) unless ruby_block
912
+ # A ruby block?
913
+ # First iterate over current system type's connection.
914
+ self.each_connection(&ruby_block)
915
+ # Then recurse on the system instances.
916
+ self.each_systemI do |systemI|
917
+ systemI.each_connection_deep(&ruby_block)
918
+ end
919
+ end
920
+
921
+ # Handling the behaviors.
922
+
923
+ # Adds a +behavior+.
924
+ def add_behavior(behavior)
925
+ unless behavior.is_a?(Behavior)
926
+ raise AnyError,"Invalid class for a behavior: #{behavior.class}"
927
+ end
928
+ # Set its parent
929
+ behavior.parent = self
930
+ # And add it
931
+ @behaviors << behavior
932
+ behavior
933
+ end
934
+
935
+ # Iterates over the behaviors.
936
+ #
937
+ # Returns an enumerator if no ruby block is given.
938
+ def each_behavior(&ruby_block)
939
+ # No ruby block? Return an enumerator.
940
+ return to_enum(:each_behavior) unless ruby_block
941
+ # A ruby block? Apply it on each behavior.
942
+ @behaviors.each(&ruby_block)
943
+ end
944
+
945
+ # Reverse iterates over the behaviors.
946
+ #
947
+ # Returns an enumerator if no ruby block is given.
948
+ def reverse_each_behavior(&ruby_block)
949
+ # No ruby block? Return an enumerator.
950
+ return to_enum(:reverse_each_behavior) unless ruby_block
951
+ # A ruby block? Apply it on each behavior.
952
+ @behaviors.reverse_each(&ruby_block)
953
+ end
954
+
955
+ # Returns the last behavior.
956
+ def last_behavior
957
+ return @behaviors[-1]
958
+ end
959
+
960
+ # BROKEN
961
+ #
962
+ # # Iterates over all the behaviors of the system type and its system
963
+ # # instances.
964
+ # def each_behavior_deep(&ruby_block)
965
+ # # No ruby block? Return an enumerator.
966
+ # return to_enum(:each_behavior_deep) unless ruby_block
967
+ # # A ruby block?
968
+ # # First iterate over current system type's behavior.
969
+ # self.each_behavior(&ruby_block)
970
+ # # Then recurse on the system instances.
971
+ # self.each_systemI do |systemI|
972
+ # systemI.systemT.each_behavior_deep(&ruby_block)
973
+ # end
974
+ # end
975
+
976
+ # Iterates over all the behaviors of the system type and its system
977
+ # instances.
978
+ def each_behavior_deep(&ruby_block)
979
+ # No ruby block? Return an enumerator.
980
+ return to_enum(:each_behavior_deep) unless ruby_block
981
+ # A ruby block?
982
+ # First recurse on the sub scopes.
983
+ self.each_scope_deep do |scope|
984
+ scope.each_behavior(&ruby_block)
985
+ end
986
+ # Then iterate over current system type's behavior.
987
+ self.each_behavior(&ruby_block)
988
+ end
989
+
990
+ # Tells if there is any inner.
991
+ def has_behavior?
992
+ return !@behaviors.empty?
993
+ end
994
+
995
+ # # Deletes +behavior+.
996
+ # def delete_behavior(behavior)
997
+ # if @behaviors.include?(behavior) then
998
+ # # The behavior is present, delete it.
999
+ # @behaviors.delete(behavior)
1000
+ # # And remove its parent.
1001
+ # behavior.parent = nil
1002
+ # end
1003
+ # end
1004
+
1005
+ # Iterates over all the blocks of the system type and its system
1006
+ # instances.
1007
+ def each_block_deep(&ruby_block)
1008
+ # No ruby block? Return an enumerator.
1009
+ return to_enum(:each_block_deep) unless ruby_block
1010
+ # A ruby block?
1011
+ # Then apply on each sub scope.
1012
+ self.each_scope do |scope|
1013
+ scope.each_block_deep(&ruby_block)
1014
+ end
1015
+ # And apply it on each behavior's block deeply.
1016
+ self.each_behavior do |behavior|
1017
+ behavior.each_block_deep(&ruby_block)
1018
+ end
1019
+ end
1020
+
1021
+ # Broken
1022
+ # # Iterates over all the stamements of the system type and its system
1023
+ # # instances.
1024
+ # def each_statement_deep(&ruby_block)
1025
+ # # No ruby block? Return an enumerator.
1026
+ # return to_enum(:each_statement_deep) unless ruby_block
1027
+ # # A ruby block?
1028
+ # # Apply it on each block deeply.
1029
+ # self.each_block do |block|
1030
+ # block.each_statement_deep(&ruby_block)
1031
+ # end
1032
+ # end
1033
+
1034
+ # Iterates over all the stamements of the system type and its system
1035
+ # instances.
1036
+ def each_statement_deep(&ruby_block)
1037
+ # No ruby block? Return an enumerator.
1038
+ return to_enum(:each_statement_deep) unless ruby_block
1039
+ # A ruby block?
1040
+ # Then apply on each sub scope.
1041
+ self.each_scope do |scope|
1042
+ scope.each_statement_deep(&ruby_block)
1043
+ end
1044
+ # And apply it on each behavior's block deeply.
1045
+ self.each_behavior do |behavior|
1046
+ behavior.each_statement_deep(&ruby_block)
1047
+ end
1048
+ end
1049
+
1050
+ # Iterates over all the nodes of the system type and its system
1051
+ # instances.
1052
+ def each_node_deep(&ruby_block)
1053
+ # No ruby block? Return an enumerator.
1054
+ return to_enum(:each_node_deep) unless ruby_block
1055
+ # A ruby block?
1056
+ # Then apply on each sub scope.
1057
+ self.each_scope do |scope|
1058
+ scope.each_node_deep(&ruby_block)
1059
+ end
1060
+ # And apply it on each behavior's block deeply.
1061
+ self.each_behavior do |behavior|
1062
+ behavior.each_node_deep(&ruby_block)
1063
+ end
1064
+ end
1065
+
1066
+ # Broken
1067
+ # # Iterates over all the statements and connections of the system type
1068
+ # # and its system instances.
1069
+ # def each_arrow_deep(&ruby_block)
1070
+ # # No ruby block? Return an enumerator.
1071
+ # return to_enum(:each_arrow_deep) unless ruby_block
1072
+ # # A ruby block?
1073
+ # # First, apply it on each connection.
1074
+ # self.each_connection do |connection|
1075
+ # ruby_block.call(connection)
1076
+ # end
1077
+ # # Then recurse over its blocks.
1078
+ # self.each_behavior do |behavior|
1079
+ # behavior.each_block_deep(&ruby_block)
1080
+ # end
1081
+ # # Finally recurse on its system instances.
1082
+ # self.each_systemI do |systemI|
1083
+ # systemI.each_arrow_deep(&ruby_block)
1084
+ # end
1085
+ # end
1086
+
1087
+ # Broken
1088
+ # # Iterates over all the object executed when a specific event is
1089
+ # # activated (they include the behaviors and the connections).
1090
+ # #
1091
+ # # NOTE: the arguments of the ruby block are the object and an enumerator
1092
+ # # over the set of events it is sensitive to.
1093
+ # def each_sensitive_deep(&ruby_block)
1094
+ # # No ruby block? Return an enumerator.
1095
+ # return to_enum(:each_sensitive_deep) unless ruby_block
1096
+ # # A ruby block?
1097
+ # # First iterate over the current system type's connections.
1098
+ # self.each_connection do |connection|
1099
+ # ruby_block.call(connection,
1100
+ # connection.each_ref_deep.lazy.map do |ref|
1101
+ # Event.new(:change,ref)
1102
+ # end)
1103
+ # end
1104
+ # # First iterate over the current system type's behaviors.
1105
+ # self.each_behavior do |behavior|
1106
+ # ruby_block.call(behavior,behavior.each_event)
1107
+ # end
1108
+ # # Then recurse on the system instances.
1109
+ # self.each_systemI do |systemI|
1110
+ # systemI.each_sensitive_deep(&ruby_block)
1111
+ # end
1112
+ # end
1113
+
1114
+ # Gets the top scope, i.e. the first scope of the current system.
1115
+ def top_scope
1116
+ return self.parent.is_a?(SystemT) ? self : self.parent.top_scope
1117
+ end
1118
+
1119
+
1120
+ end
1121
+
1122
+
1123
+ ##
1124
+ # Describes a data type.
1125
+ class Type
1126
+
1127
+ include Hparent
1128
+
1129
+ # The name of the type
1130
+ attr_reader :name
1131
+
1132
+ # Creates a new type named +name+.
1133
+ def initialize(name)
1134
+ # Check and set the name.
1135
+ @name = name.to_sym
1136
+ end
1137
+
1138
+ # Comparison for hash: structural comparison.
1139
+ def eql?(obj)
1140
+ return false unless obj.is_a?(Type)
1141
+ return false unless @name.eql?(obj.name)
1142
+ return true
1143
+ end
1144
+
1145
+ # Hash function.
1146
+ def hash
1147
+ return [@name].hash
1148
+ end
1149
+
1150
+ # Tells if the type signed.
1151
+ def signed?
1152
+ return false
1153
+ end
1154
+
1155
+ # Tells if the type is unsigned.
1156
+ def unsigned?
1157
+ return false
1158
+ end
1159
+
1160
+ # Tells if the type is fixed point.
1161
+ def fixed?
1162
+ return false
1163
+ end
1164
+
1165
+ # Tells if the type is floating point.
1166
+ def float?
1167
+ return false
1168
+ end
1169
+
1170
+ # Tells if the type is a leaf.
1171
+ def leaf?
1172
+ return false
1173
+ end
1174
+
1175
+ # Gets the bitwidth of the type, by default 0.
1176
+ # Bit, signed, unsigned and Float base have a width of 1.
1177
+ def width
1178
+ if [:bit, :signed, :unsigned, :float ].include?(@name) then
1179
+ return 1
1180
+ else
1181
+ return 0
1182
+ end
1183
+ end
1184
+
1185
+ # Get the direction of the type, little or big endian.
1186
+ def direction
1187
+ # By default, little endian.
1188
+ return :little
1189
+ end
1190
+
1191
+ # Tells if the type has a range.
1192
+ def range?
1193
+ return false
1194
+ end
1195
+
1196
+ # Gets the range of the type, by default range is not defined.
1197
+ def range
1198
+ raise AnyError, "No range for type #{self}"
1199
+ end
1200
+
1201
+ # Tells if the type has a base.
1202
+ def base?
1203
+ return false
1204
+ end
1205
+
1206
+ # Gets the base type, by default base type is not defined.
1207
+ def base
1208
+ raise AnyError, "No base type for type #{self}"
1209
+ end
1210
+
1211
+ # Tells if the type has sub types.
1212
+ def types?
1213
+ return false
1214
+ end
1215
+
1216
+ # Tells if the type is regular (applies for tuples).
1217
+ def regular?
1218
+ return false
1219
+ end
1220
+
1221
+ # Tells if the type has named sub types.
1222
+ def struct?
1223
+ return false
1224
+ end
1225
+
1226
+ # Tell if +type+ is equivalent to current type.
1227
+ #
1228
+ # NOTE: type can be compatible while not being equivalent, please
1229
+ # refer to `hruby_types.rb` for type compatibility.
1230
+ def equivalent?(type)
1231
+ # By default, types are equivalent iff they have the same name.
1232
+ return (type.is_a?(Type) and self.name == type.name)
1233
+ end
1234
+
1235
+ # Iterates over the types deeply if any.
1236
+ def each_type_deep(&ruby_block)
1237
+ # No ruby block? Return an enumerator.
1238
+ return to_enum(:each_type_deep) unless ruby_block
1239
+ # A ruby block? First apply it to current.
1240
+ ruby_block.call(self)
1241
+ # And that's all by default.
1242
+ end
1243
+
1244
+ # Converts to a bit vector.
1245
+ def to_vector
1246
+ return TypeVector.new(:"", Bit, self.width-1..0)
1247
+ end
1248
+ end
1249
+
1250
+
1251
+ # The leaf types.
1252
+
1253
+ ##
1254
+ # The module giving leaf properties to a type.
1255
+ module LLeaf
1256
+ # Tells if the type is a leaf.
1257
+ def leaf?
1258
+ return true
1259
+ end
1260
+ end
1261
+
1262
+
1263
+ ##
1264
+ # The void type.
1265
+ class << (Void = Type.new(:void) )
1266
+ include LLeaf
1267
+ # # Get the base type, actually self for leaf types.
1268
+ # def base
1269
+ # self
1270
+ # end
1271
+ end
1272
+
1273
+ ##
1274
+ # The bit type leaf.
1275
+ class << ( Bit = Type.new(:bit) )
1276
+ include LLeaf
1277
+ # Tells if the type fixed point.
1278
+ def fixed?
1279
+ return true
1280
+ end
1281
+ # Gets the bitwidth of the type, nil for undefined.
1282
+ def width
1283
+ 1
1284
+ end
1285
+ # Gets the range of the type.
1286
+ def range
1287
+ 0..0
1288
+ end
1289
+ # # Get the base type, actually self for leaf types.
1290
+ # def base
1291
+ # self
1292
+ # end
1293
+ end
1294
+
1295
+ ##
1296
+ # The signed types leaf.
1297
+ class << ( Signed = Type.new(:signed) )
1298
+ include LLeaf
1299
+ # Tells if the type is signed.
1300
+ def signed?
1301
+ return true
1302
+ end
1303
+ # Tells if the type is fixed point.
1304
+ def fixed?
1305
+ return true
1306
+ end
1307
+ # Gets the bitwidth of the type, nil for undefined.
1308
+ def width
1309
+ 1
1310
+ end
1311
+ # Gets the range of the type.
1312
+ def range
1313
+ 0..0
1314
+ end
1315
+ # # Get the base type, actually self for leaf types.
1316
+ # def base
1317
+ # self
1318
+ # end
1319
+ end
1320
+
1321
+ ##
1322
+ # The unsigned types leaf.
1323
+ class << ( Unsigned = Type.new(:unsigned) )
1324
+ include LLeaf
1325
+ # Tells if the type is unsigned.
1326
+ def unsigned?
1327
+ return true
1328
+ end
1329
+ # Tells if the type is fixed point.
1330
+ def fixed?
1331
+ return true
1332
+ end
1333
+ # Gets the bitwidth of the type, nil for undefined.
1334
+ def width
1335
+ 1
1336
+ end
1337
+ # Gets the range of the type.
1338
+ def range
1339
+ 0..0
1340
+ end
1341
+ # # Get the base type, actually self for leaf types.
1342
+ # def base
1343
+ # self
1344
+ # end
1345
+ end
1346
+
1347
+ ##
1348
+ # The float types leaf.
1349
+ class << ( Float = Type.new(:float) )
1350
+ include LLeaf
1351
+ # Tells if the type is signed.
1352
+ def signed?
1353
+ return true
1354
+ end
1355
+ # Tells if the type is floating point.
1356
+ def float?
1357
+ return true
1358
+ end
1359
+ # Gets the bitwidth of the type, nil for undefined.
1360
+ def width
1361
+ 1
1362
+ end
1363
+ # Gets the range of the type.
1364
+ def range
1365
+ 0..0
1366
+ end
1367
+ # # Get the base type, actually self for leaf types.
1368
+ # def base
1369
+ # self
1370
+ # end
1371
+ end
1372
+
1373
+
1374
+
1375
+ ##
1376
+ # Describes a high-level type definition.
1377
+ #
1378
+ # NOTE: type definition are actually type with a name refering to another
1379
+ # type (and equivalent to it).
1380
+ class TypeDef < Type
1381
+ extend Forwardable
1382
+
1383
+ # The definition of the type.
1384
+ attr_reader :def
1385
+
1386
+ # Type creation.
1387
+
1388
+ # Creates a new type definition named +name+ from +type+.
1389
+ def initialize(name,type)
1390
+ # Initialize with name.
1391
+ super(name)
1392
+ # Checks the referered type.
1393
+ unless type.is_a?(Type) then
1394
+ raise AnyError, "Invalid class for a type: #{type.class}"
1395
+ end
1396
+ # Set the referened type.
1397
+ @def = type
1398
+ end
1399
+
1400
+ # Comparison for hash: structural comparison.
1401
+ def eql?(obj)
1402
+ # General type comparison.
1403
+ return false unless super(obj)
1404
+ # Specific comparison.
1405
+ return false unless obj.is_a?(TypeDef)
1406
+ return false unless @def.eql?(obj.def)
1407
+ return true
1408
+ end
1409
+
1410
+ # Hash function.
1411
+ def hash
1412
+ return [super,@def].hash
1413
+ end
1414
+
1415
+ # Iterates over the types deeply if any.
1416
+ def each_type_deep(&ruby_block)
1417
+ # No ruby block? Return an enumerator.
1418
+ return to_enum(:each_type_deep) unless ruby_block
1419
+ # A ruby block? First apply it to current.
1420
+ ruby_block.call(self)
1421
+ # And recurse on the definition.
1422
+ @def.each_type_deep(&ruby_block)
1423
+ end
1424
+
1425
+ # Delegate the type methods to the ref.
1426
+ def_delegators :@def,
1427
+ :signed?, :unsigned?, :fixed?, :float?, :leaf?,
1428
+ :width, :range?, :range, :base?, :base, :types?,
1429
+ :get_all_types, :get_type, :each, :each_type,
1430
+ :regular?,
1431
+ :each_name,
1432
+ :equivalent?
1433
+ end
1434
+
1435
+
1436
+
1437
+ ##
1438
+ # Describes a vector type.
1439
+ class TypeVector < Type
1440
+ # The base type of the vector
1441
+ attr_reader :base
1442
+
1443
+ # Tells if the type has a base.
1444
+ def base?
1445
+ return true
1446
+ end
1447
+
1448
+ # The range of the vector.
1449
+ attr_reader :range
1450
+
1451
+ # Creates a new vector type named +name+ from +base+ type and with
1452
+ # +range+.
1453
+ # NOTE: if +range+ is a positive integer it is converted to
1454
+ # (range-1)..0, if it is a negative integer it is converted to
1455
+ # 0..(-range-1)
1456
+ def initialize(name,base,range)
1457
+ # Initialize the type.
1458
+ super(name)
1459
+
1460
+ # Check and set the base
1461
+ unless base.is_a?(Type)
1462
+ raise AnyError,
1463
+ "Invalid class for VectorType base: #{base.class}."
1464
+ end
1465
+ @base = base
1466
+
1467
+ # Check and set the range.
1468
+ if range.respond_to?(:to_i) then
1469
+ # Integer case: convert to 0..(range-1).
1470
+ range = range > 0 ? (range-1)..0 : 0..(-range-1)
1471
+ elsif
1472
+ # Other cases: assume there is a first and a last to create
1473
+ # the range.
1474
+ range = range.first..range.last
1475
+ end
1476
+ @range = range
1477
+ end
1478
+
1479
+ # Comparison for hash: structural comparison.
1480
+ def eql?(obj)
1481
+ # General type comparison.
1482
+ return false unless super(obj)
1483
+ # Specific comparison.
1484
+ return false unless obj.is_a?(TypeVector)
1485
+ return false unless @base.eql?(obj.base)
1486
+ return false unless @range.eql?(obj.range)
1487
+ return true
1488
+ end
1489
+
1490
+ # Hash function.
1491
+ def hash
1492
+ return [super,@base,@range].hash
1493
+ end
1494
+
1495
+ # Gets the size of the type in number of base elements.
1496
+ def size
1497
+ return (@range.first.to_i - @range.last.to_i).abs + 1
1498
+ end
1499
+
1500
+ # Gets the bitwidth of the type, nil for undefined.
1501
+ #
1502
+ # NOTE: must be redefined for specific types.
1503
+ def width
1504
+ first = @range.first.to_i
1505
+ last = @range.last.to_i
1506
+ return @base.width * ((first-last).abs + 1)
1507
+ end
1508
+
1509
+ # Get the direction of the type, little or big endian.
1510
+ def direction
1511
+ return @range.first < @range.last ? :big : :little
1512
+ end
1513
+
1514
+ # Gets the direction of the range.
1515
+ def dir
1516
+ return (@range.last - @range.first)
1517
+ end
1518
+
1519
+ # Tells if the type signed.
1520
+ def signed?
1521
+ return @base.signed?
1522
+ end
1523
+
1524
+ # Tells if the type is unsigned.
1525
+ def unsigned?
1526
+ return @base.unsigned?
1527
+ end
1528
+
1529
+ # Tells if the type is fixed point.
1530
+ def fixed?
1531
+ return @base.signed?
1532
+ end
1533
+
1534
+ # Tells if the type is floating point.
1535
+ def float?
1536
+ return @base.float?
1537
+ end
1538
+
1539
+ # Tell if +type+ is equivalent to current type.
1540
+ #
1541
+ # NOTE: type can be compatible while not being equivalent, please
1542
+ # refer to `hruby_types.rb` for type compatibility.
1543
+ def equivalent?(type)
1544
+ return (type.is_a?(TypeVector) and
1545
+ @range == type.range
1546
+ @base.equivalent?(type.base) )
1547
+ end
1548
+
1549
+ # Iterates over the types deeply if any.
1550
+ def each_type_deep(&ruby_block)
1551
+ # No ruby block? Return an enumerator.
1552
+ return to_enum(:each_type_deep) unless ruby_block
1553
+ # A ruby block? First apply it to current.
1554
+ ruby_block.call(self)
1555
+ # And recurse on the base.
1556
+ @base.each_type_deep(&ruby_block)
1557
+ end
1558
+ end
1559
+
1560
+
1561
+ ##
1562
+ # Describes a signed integer data type.
1563
+ class TypeSigned < TypeVector
1564
+
1565
+ # Creates a new vector type named +name+ from +base+ type and with
1566
+ # +range+.
1567
+ #
1568
+ # NOTE:
1569
+ # * The default range is 32-bit.
1570
+ def initialize(name,range = 31..0)
1571
+ # Initialize the type.
1572
+ super(name,Signed,range)
1573
+ end
1574
+ end
1575
+
1576
+ ##
1577
+ # Describes a unsigned integer data type.
1578
+ class TypeUnsigned < TypeVector
1579
+
1580
+ # Creates a new vector type named +name+ from +base+ type and with
1581
+ # +range+.
1582
+ #
1583
+ # NOTE:
1584
+ # * The default range is 32-bit.
1585
+ def initialize(name,range = 31..0)
1586
+ # Initialize the type.
1587
+ super(name,Unsigned,range)
1588
+ end
1589
+ end
1590
+
1591
+ ##
1592
+ # Describes a float data type.
1593
+ class TypeFloat < TypeVector
1594
+
1595
+ # Creates a new vector type named +name+ from +base+ type and with
1596
+ # +range+.
1597
+ #
1598
+ # NOTE:
1599
+ # * The bits of negative range stands for the exponent
1600
+ # * The default range is for 64-bit IEEE 754 double precision standart
1601
+ def initialize(name,range = 52..-11)
1602
+ # Initialize the type.
1603
+ super(name,Float,range)
1604
+ end
1605
+ end
1606
+
1607
+ # Standard vector types.
1608
+ Integer = TypeSigned.new(:integer)
1609
+ Natural = TypeUnsigned.new(:natural)
1610
+ Bignum = TypeSigned.new(:bignum,HDLRuby::Infinity..0)
1611
+ Real = TypeFloat.new(:float)
1612
+
1613
+
1614
+
1615
+ ##
1616
+ # Describes a tuple type.
1617
+ class TypeTuple < Type
1618
+ # Creates a new tuple type named +name+ width +direction+ and whose
1619
+ # sub types are given by +content+.
1620
+ def initialize(name,direction,*content)
1621
+ # Initialize the type.
1622
+ super(name)
1623
+
1624
+ # Set the direction.
1625
+ @direction = direction.to_sym
1626
+ unless [:little, :big].include?(@direction)
1627
+ raise AnyError, "Invalid direction for a type: #{direction}"
1628
+ end
1629
+
1630
+ # Check and set the content.
1631
+ content.each do |sub|
1632
+ unless sub.is_a?(Type) then
1633
+ raise AnyError, "Invalid class for a type: #{sub.class}"
1634
+ end
1635
+ end
1636
+ @types = content
1637
+ end
1638
+
1639
+
1640
+ # Comparison for hash: structural comparison.
1641
+ def eql?(obj)
1642
+ # General type comparison.
1643
+ return false unless super(obj)
1644
+ # Specific comparison.
1645
+ idx = 0
1646
+ obj.each_type do |type|
1647
+ return false unless @types[idx].eql?(type)
1648
+ idx += 1
1649
+ end
1650
+ return false unless idx == @types.size
1651
+ return true
1652
+ end
1653
+
1654
+ # Hash function.
1655
+ def hash
1656
+ return [super,@types].hash
1657
+ end
1658
+
1659
+ # Tells if the type has sub types.
1660
+ def types?
1661
+ return true
1662
+ end
1663
+
1664
+ # Gets an array containing all the syb types.
1665
+ def get_all_types
1666
+ return @types.clone
1667
+ end
1668
+
1669
+ # Gets a sub type by +index+.
1670
+ def get_type(index)
1671
+ return @types[index.to_i]
1672
+ end
1673
+
1674
+ # Adds a sub +type+.
1675
+ def add_type(type)
1676
+ unless type.is_a?(Type) then
1677
+ raise AnyError,
1678
+ "Invalid class for a type: #{type.class} (#{type})"
1679
+ end
1680
+ @types << type
1681
+ end
1682
+
1683
+ # Iterates over the sub name/type pair.
1684
+ #
1685
+ # Returns an enumerator if no ruby block is given.
1686
+ def each(&ruby_block)
1687
+ # No ruby block? Return an enumerator.
1688
+ return to_enum(:each) unless ruby_block
1689
+ # A ruby block? Apply it on each input signal instance.
1690
+ @types.each(&ruby_block)
1691
+ end
1692
+
1693
+ # Iterates over the sub types.
1694
+ #
1695
+ # Returns an enumerator if no ruby block is given.
1696
+ def each_type(&ruby_block)
1697
+ # No ruby block? Return an enumerator.
1698
+ return to_enum(:each_type) unless ruby_block
1699
+ # A ruby block? Apply it on each input signal instance.
1700
+ @types.each(&ruby_block)
1701
+ end
1702
+
1703
+ # Iterates over the types deeply if any.
1704
+ def each_type_deep(&ruby_block)
1705
+ # No ruby block? Return an enumerator.
1706
+ return to_enum(:each_type_deep) unless ruby_block
1707
+ # A ruby block? First apply it to current.
1708
+ ruby_block.call(self)
1709
+ # And recurse on the sub types.
1710
+ @types.each { |type| type.each_type_deep(&ruby_block) }
1711
+ end
1712
+
1713
+ # Tell if the tuple is regular, i.e., all its sub types are equivalent.
1714
+ #
1715
+ # NOTE: empty tuples are assumed not to be regular.
1716
+ def regular?
1717
+ return false if @types.empty?
1718
+ t0 = @types[0]
1719
+ @types[1..-1].each do |type|
1720
+ return false unless t0.equivalent?(type)
1721
+ end
1722
+ return true
1723
+ end
1724
+
1725
+ # Gets the bitwidth.
1726
+ def width
1727
+ return @types.reduce(0) { |sum,type| sum + type.width }
1728
+ end
1729
+
1730
+ # Get the direction of the type, little or big endian.
1731
+ def direction
1732
+ return @direction
1733
+ end
1734
+
1735
+ # Gets the range of the type.
1736
+ #
1737
+ # NOTE: only valid if the tuple is regular (i.e., all its sub types
1738
+ # are identical)
1739
+ def range
1740
+ if regular? then
1741
+ # Regular tuple, return its range as if it was an array.
1742
+ return 0..@types.size-1
1743
+ else
1744
+ raise AnyError, "No range for type #{self}"
1745
+ end
1746
+ end
1747
+
1748
+ # Tells if the type has a base.
1749
+ #
1750
+ # NOTE: only if the tuple is regular (i.e., all its sub types
1751
+ # are identical)
1752
+ def base?
1753
+ return regular?
1754
+ end
1755
+
1756
+ # Gets the base type.
1757
+ #
1758
+ # NOTE: only valid if the tuple is regular (i.e., all its sub types
1759
+ # are identical)
1760
+ def base
1761
+ if regular? then
1762
+ # Regular tuple, return the type of its first element.
1763
+ return @types[0]
1764
+ else
1765
+ raise AnyError, "No base type for type #{self}"
1766
+ end
1767
+ end
1768
+
1769
+ # Tell if +type+ is equivalent to current type.
1770
+ #
1771
+ # NOTE: type can be compatible while not being equivalent, please
1772
+ # refer to `hruby_types.rb` for type compatibility.
1773
+ def equivalent?(type)
1774
+ return (type.is_a?(TypeTuple) and
1775
+ !@types.zip(type.types).index {|t0,t1| !t0.equivalent?(t1) })
1776
+ end
1777
+ end
1778
+
1779
+
1780
+ ##
1781
+ # Describes a structure type.
1782
+ class TypeStruct < Type
1783
+ # Creates a new structure type named +name+ with +direction+ and
1784
+ # whose hierachy is given by +content+.
1785
+ def initialize(name,direction,content)
1786
+ # Initialize the type.
1787
+ super(name)
1788
+
1789
+ # Set the direction.
1790
+ @direction = direction.to_sym
1791
+ unless [:little, :big].include?(@direction)
1792
+ raise AnyError, "Invalid direction for a type: #{direction}"
1793
+ end
1794
+
1795
+ # Check and set the content.
1796
+ content = Hash[content]
1797
+ @types = content.map do |k,v|
1798
+ unless v.is_a?(Type) then
1799
+ raise AnyError, "Invalid class for a type: #{v.class}"
1800
+ end
1801
+ [ k.to_sym, v ]
1802
+ end.to_h
1803
+ end
1804
+
1805
+ # Comparison for hash: structural comparison.
1806
+ def eql?(obj)
1807
+ # General type comparison.
1808
+ return false unless super(obj)
1809
+ # Specific comparison.
1810
+ idx = 0
1811
+ obj.each_key do |name|
1812
+ return false unless @types[name].eql?(obj.get_type(name))
1813
+ idx += 1
1814
+ end
1815
+ return false unless idx == @types.size
1816
+ return true
1817
+ end
1818
+
1819
+ # Hash function.
1820
+ def hash
1821
+ return [super,@types].hash
1822
+ end
1823
+
1824
+ # Tells if the type has named sub types.
1825
+ def struct?
1826
+ return true
1827
+ end
1828
+
1829
+ # Tells if the type has sub types.
1830
+ def types?
1831
+ return true
1832
+ end
1833
+
1834
+ # Gets an array containing all the syb types.
1835
+ def get_all_types
1836
+ return @types.values
1837
+ end
1838
+
1839
+ # Gets a sub type by +name+.
1840
+ def get_type(name)
1841
+ return @types[name.to_sym]
1842
+ end
1843
+
1844
+ # Iterates over the sub name/type pair.
1845
+ #
1846
+ # Returns an enumerator if no ruby block is given.
1847
+ def each(&ruby_block)
1848
+ # No ruby block? Return an enumerator.
1849
+ return to_enum(:each) unless ruby_block
1850
+ # A ruby block? Apply it on each input signal instance.
1851
+ @types.each(&ruby_block)
1852
+ end
1853
+
1854
+ # Iterates over the sub types.
1855
+ #
1856
+ # Returns an enumerator if no ruby block is given.
1857
+ def each_type(&ruby_block)
1858
+ # No ruby block? Return an enumerator.
1859
+ return to_enum(:each_type) unless ruby_block
1860
+ # A ruby block? Apply it on each input signal instance.
1861
+ @types.each_value(&ruby_block)
1862
+ end
1863
+
1864
+ # Iterates over the sub type names.
1865
+ #
1866
+ # Returns an enumerator if no ruby block is given.
1867
+ def each_name(&ruby_block)
1868
+ # No ruby block? Return an enumerator.
1869
+ return to_enum(:each_name) unless ruby_block
1870
+ # A ruby block? Apply it on each input signal instance.
1871
+ @types.each_key(&ruby_block)
1872
+ end
1873
+
1874
+ # Iterates over the types deeply if any.
1875
+ def each_type_deep(&ruby_block)
1876
+ # No ruby block? Return an enumerator.
1877
+ return to_enum(:each_type_deep) unless ruby_block
1878
+ # A ruby block? First apply it to current.
1879
+ ruby_block.call(self)
1880
+ # And recurse on the sub types.
1881
+ @types.each_value { |type| type.each_type_deep(&ruby_block) }
1882
+ end
1883
+
1884
+ # Gets the bitwidth of the type, nil for undefined.
1885
+ #
1886
+ # NOTE: must be redefined for specific types.
1887
+ def width
1888
+ return @types.reduce(0) {|sum,type| sum + type.width }
1889
+ end
1890
+
1891
+ # # Checks the compatibility with +type+
1892
+ # def compatible?(type)
1893
+ # # # If type is void, compatible anyway.
1894
+ # # return true if type.name == :void
1895
+ # # Not compatible if different types.
1896
+ # return false unless type.is_a?(TypeStruct)
1897
+ # # Not compatibe unless each entry has the same name in same order.
1898
+ # return false unless self.each_name == type.each_name
1899
+ # self.each do |name,sub|
1900
+ # return false unless sub.compatible?(self.get_type(name))
1901
+ # end
1902
+ # return true
1903
+ # end
1904
+
1905
+ # # Merges with +type+
1906
+ # def merge(type)
1907
+ # # # if type is void, return self anyway.
1908
+ # # return self if type.name == :void
1909
+ # # Not compatible if different types.
1910
+ # unless type.is_a?(TypeStruct) then
1911
+ # raise AnyError, "Incompatible types for merging: #{self}, #{type}."
1912
+ # end
1913
+ # # Not compatibe unless each entry has the same name and same order.
1914
+ # unless self.each_name == type.each_name then
1915
+ # raise AnyError, "Incompatible types for merging: #{self}, #{type}."
1916
+ # end
1917
+ # # Creates the new type content
1918
+ # content = {}
1919
+ # self.each do |name,sub|
1920
+ # content[name] = self.get_type(name).merge(sub)
1921
+ # end
1922
+ # return TypeStruct.new(@name,content)
1923
+ # end
1924
+
1925
+ # Tell if +type+ is equivalent to current type.
1926
+ #
1927
+ # NOTE: type can be compatible while not being equivalent, please
1928
+ # refer to `hruby_types.rb` for type compatibility.
1929
+ def equivalent?(type)
1930
+ return (type.is_a?(TypeStruct) and
1931
+ !@types.to_a.zip(type.types.to_a).index do |t0,t1|
1932
+ t0[0] != t1[0] or !t0[1].equivalent?(t1[1])
1933
+ end)
1934
+ end
1935
+ end
1936
+
1937
+
1938
+
1939
+ ##
1940
+ # Describes a behavior.
1941
+ class Behavior
1942
+
1943
+ include Hparent
1944
+
1945
+ # # Creates a new behavior.
1946
+ # def initialize
1947
+ # # Initialize the sensitivity list.
1948
+ # @events = []
1949
+ # # Initialize the block list.
1950
+ # @blocks = []
1951
+ # end
1952
+
1953
+ # The block executed by the behavior.
1954
+ attr_reader :block
1955
+
1956
+ # Creates a new behavior executing +block+.
1957
+ def initialize(block)
1958
+ # Initialize the sensitivity list.
1959
+ @events = []
1960
+ # Check and set the block.
1961
+ return unless block # No block case
1962
+ # There is a block
1963
+ self.block = block
1964
+ # unless block.is_a?(Block)
1965
+ # raise AnyError, "Invalid class for a block: #{block.class}."
1966
+ # end
1967
+ # # Time blocks are only supported in Time Behaviors.
1968
+ # if block.is_a?(TimeBlock)
1969
+ # raise AnyError, "Timed blocks are not supported in common behaviors."
1970
+ # end
1971
+ # # Set the block's parent.
1972
+ # block.parent = self
1973
+ # # And set the block
1974
+ # @block = block
1975
+ end
1976
+
1977
+ # Sets the block if not already set.
1978
+ def block=(block)
1979
+ # Check the block.
1980
+ unless block.is_a?(Block)
1981
+ raise AnyError, "Invalid class for a block: #{block.class}."
1982
+ end
1983
+ # Time blocks are only supported in Time Behaviors.
1984
+ if block.is_a?(TimeBlock)
1985
+ raise AnyError, "Timed blocks are not supported in common behaviors."
1986
+ end
1987
+ # Set the block's parent.
1988
+ block.parent = self
1989
+ # And set the block
1990
+ @block = block
1991
+ end
1992
+ private :block=
1993
+
1994
+ # Comparison for hash: structural comparison.
1995
+ def eql?(obj)
1996
+ return false unless obj.is_a?(Behavior)
1997
+ idx = 0
1998
+ obj.each_event do |event|
1999
+ return false unless @events[idx].eql?(event)
2000
+ idx += 1
2001
+ end
2002
+ return false unless idx == @events.size
2003
+ return false unless @block.eql?(obj.block)
2004
+ return true
2005
+ end
2006
+
2007
+ # Hash function.
2008
+ def hash
2009
+ return [@events,@block].hash
2010
+ end
2011
+
2012
+ # Handle the sensitivity list.
2013
+
2014
+ # Adds an +event+ to the sensitivity list.
2015
+ def add_event(event)
2016
+ unless event.is_a?(Event)
2017
+ raise AnyError, "Invalid class for a event: #{event.class}"
2018
+ end
2019
+ # Set the event's parent.
2020
+ event.parent = self
2021
+ # And add the event.
2022
+ @events << event
2023
+ event
2024
+ end
2025
+
2026
+ # Iterates over the events of the sensitivity list.
2027
+ #
2028
+ # Returns an enumerator if no ruby block is given.
2029
+ def each_event(&ruby_block)
2030
+ # No ruby block? Return an enumerator.
2031
+ return to_enum(:each_event) unless ruby_block
2032
+ # A ruby block? Apply it on each event.
2033
+ @events.each(&ruby_block)
2034
+ end
2035
+
2036
+ # Tells if there is any event.
2037
+ def has_event?
2038
+ return !@events.empty?
2039
+ end
2040
+
2041
+ # Tells if there is a positive or negative edge event.
2042
+ def on_edge?
2043
+ @events.each do |event|
2044
+ return true if event.on_edge?
2045
+ end
2046
+ return false
2047
+ end
2048
+
2049
+ # Iterates over the blocks.
2050
+ def each_block(&ruby_block)
2051
+ # No ruby block? Return an enumerator.
2052
+ return to_enum(:each_block) unless ruby_block
2053
+ # A ruby block?
2054
+ # Apply on it.
2055
+ ruby_block.call(@block)
2056
+ end
2057
+
2058
+ # Iterates over all the blocks of the system type and its system
2059
+ # instances.
2060
+ def each_block_deep(&ruby_block)
2061
+ # No ruby block? Return an enumerator.
2062
+ return to_enum(:each_block_deep) unless ruby_block
2063
+ # A ruby block?
2064
+ # Recurse.
2065
+ @block.each_block_deep(&ruby_block)
2066
+ end
2067
+
2068
+ # Iterates over all the nodes of the system type and its system
2069
+ # instances.
2070
+ def each_node_deep(&ruby_block)
2071
+ # No ruby block? Return an enumerator.
2072
+ return to_enum(:each_node_deep) unless ruby_block
2073
+ # A ruby block?
2074
+ # Recurse on the block.
2075
+ @block.each_node_deep(&ruby_block)
2076
+ end
2077
+
2078
+ # Short cuts to the enclosed block.
2079
+
2080
+ # Iterates over the statements.
2081
+ #
2082
+ # Returns an enumerator if no ruby block is given.
2083
+ def each_statement(&ruby_block)
2084
+ @block.each_statement(&ruby_block)
2085
+ end
2086
+
2087
+ # Reverse iterates over the statements.
2088
+ #
2089
+ # Returns an enumerator if no ruby block is given.
2090
+ def reverse_each_statement(&ruby_block)
2091
+ @block.reverse_each_statement(&ruby_block)
2092
+ end
2093
+
2094
+ # Returns the last statement.
2095
+ def last_statement
2096
+ @block.last_statement
2097
+ end
2098
+
2099
+ # Gets the top scope, i.e. the first scope of the current system.
2100
+ def top_scope
2101
+ return parent.top_scope
2102
+ end
2103
+ end
2104
+
2105
+
2106
+ ##
2107
+ # Describes a timed behavior.
2108
+ #
2109
+ # NOTE:
2110
+ # * this is the only kind of behavior that can include time statements.
2111
+ # * this kind of behavior is not synthesizable!
2112
+ class TimeBehavior < Behavior
2113
+ # Creates a new time behavior executing +block+.
2114
+ def initialize(block)
2115
+ # Initialize the sensitivity list.
2116
+ @events = []
2117
+ # Check and set the block.
2118
+ unless block.is_a?(Block)
2119
+ raise AnyError, "Invalid class for a block: #{block.class}."
2120
+ end
2121
+ # Time blocks are supported here.
2122
+ @block = block
2123
+ block.parent = self
2124
+ end
2125
+
2126
+ # Comparison for hash: structural comparison.
2127
+ def eql?(obj)
2128
+ # Specific comparison.
2129
+ return false unless obj.is_a?(TimeBehavior)
2130
+ # General comparison.
2131
+ return super(obj)
2132
+ end
2133
+
2134
+ # Hash function.
2135
+ def hash
2136
+ super
2137
+ end
2138
+
2139
+ # Time behavior do not have other event than time, so deactivate
2140
+ # the relevant methods.
2141
+ def add_event(event)
2142
+ raise AnyError, "Time behaviors do not have any sensitivity list."
2143
+ end
2144
+ end
2145
+
2146
+
2147
+ ##
2148
+ # Describes an event.
2149
+ class Event
2150
+
2151
+ include Hparent
2152
+
2153
+ # The type of event.
2154
+ attr_reader :type
2155
+
2156
+ # The reference of the event.
2157
+ attr_reader :ref
2158
+
2159
+ # Creates a new +type+ sort of event on signal refered by +ref+.
2160
+ def initialize(type,ref)
2161
+ # Check and set the type.
2162
+ @type = type.to_sym
2163
+ # Check and set the reference.
2164
+ unless ref.is_a?(Ref)
2165
+ raise AnyError, "Invalid class for a reference: #{ref.class}"
2166
+ end
2167
+ @ref = ref
2168
+ # And set the parent of ref.
2169
+ ref.parent = self
2170
+ end
2171
+
2172
+ # Comparison for hash: structural comparison.
2173
+ def eql?(obj)
2174
+ return false unless obj.is_a?(Event)
2175
+ return false unless @type.eql?(obj.type)
2176
+ return false unless @ref.eql?(obj.ref)
2177
+ return true
2178
+ end
2179
+
2180
+ # Hash function.
2181
+ def hash
2182
+ return [@type,@ref].hash
2183
+ end
2184
+
2185
+ # Tells if there is a positive or negative edge event.
2186
+ #
2187
+ # NOTE: checks if the event type is :posedge or :negedge
2188
+ def on_edge?
2189
+ return (@type == :posedge or @type == :negedge)
2190
+ end
2191
+ end
2192
+
2193
+
2194
+ ##
2195
+ # Describes a signal.
2196
+ class SignalI
2197
+
2198
+ include Hparent
2199
+
2200
+ # The name of the signal
2201
+ attr_reader :name
2202
+
2203
+ # The type of the signal
2204
+ attr_reader :type
2205
+
2206
+ # The initial value of the signal if any.
2207
+ attr_reader :value
2208
+
2209
+ # Creates a new signal named +name+ typed as +type+.
2210
+ # If +val+ is provided, it will be the initial value of the
2211
+ # signal.
2212
+ def initialize(name,type,val = nil)
2213
+ # Check and set the name.
2214
+ @name = name.to_sym
2215
+ # Check and set the type.
2216
+ if type.is_a?(Type) then
2217
+ @type = type
2218
+ else
2219
+ raise AnyError, "Invalid class for a type: #{type.class}."
2220
+ end
2221
+ # Check and set the initial value if any.
2222
+ if val then
2223
+ unless val.is_a?(Expression) then
2224
+ raise AnyError, "Invalid class for a constant: #{val.class}"
2225
+ end
2226
+ @value = val
2227
+ val.parent = self
2228
+ else
2229
+ @value = nil
2230
+ end
2231
+ end
2232
+
2233
+ # Comparison for hash: structural comparison.
2234
+ def eql?(obj)
2235
+ return false unless obj.is_a?(SignalI)
2236
+ return false unless @name.eql?(obj.name)
2237
+ return false unless @type.eql?(obj.type)
2238
+ return true
2239
+ end
2240
+
2241
+ # Hash function.
2242
+ def hash
2243
+ return [@name,@type].hash
2244
+ end
2245
+
2246
+ # Gets the bit width.
2247
+ def width
2248
+ return @type.width
2249
+ end
2250
+
2251
+ # Clones (deeply)
2252
+ def clone
2253
+ return SignalI.new(self.name,self.type)
2254
+ end
2255
+ end
2256
+
2257
+ ##
2258
+ # Describes a constant signal.
2259
+ class SignalC < SignalI
2260
+ end
2261
+
2262
+ ##
2263
+ # Describes a system instance.
2264
+ #
2265
+ # NOTE: an instance can actually represented muliple layers
2266
+ # of systems, the first one being the one actually instantiated
2267
+ # in the final RTL code.
2268
+ # This layring can be used for describing software or partial
2269
+ # reconfiguration.
2270
+ class SystemI
2271
+
2272
+ include Hparent
2273
+
2274
+ # The name of the instance if any.
2275
+ attr_reader :name
2276
+
2277
+ # The instantiated system.
2278
+ attr_reader :systemT
2279
+
2280
+ # Creates a new system instance of system type +systemT+ named +name+.
2281
+ def initialize(name, systemT)
2282
+ # Set the name as a symbol.
2283
+ @name = name.to_sym
2284
+ # Check and set the systemT.
2285
+ if !systemT.is_a?(SystemT) then
2286
+ raise AnyError, "Invalid class for a system type: #{systemT.class}"
2287
+ end
2288
+ # Sets the instantiated system.
2289
+ @systemT = systemT
2290
+
2291
+ # Initialize the list of system layers, the first one
2292
+ # being the instantiated system.
2293
+ @systemTs = [ @systemT ]
2294
+ end
2295
+
2296
+ # Comparison for hash: structural comparison.
2297
+ def eql?(obj)
2298
+ return false unless obj.is_a?(SystemI)
2299
+ return false unless @name.eql?(obj.name)
2300
+ return false unless @systemT.eql?(obj.systemT)
2301
+ return true
2302
+ end
2303
+
2304
+ # Hash function.
2305
+ def hash
2306
+ return [@name,@systemT].hash
2307
+ end
2308
+
2309
+ # Rename with +name+
2310
+ #
2311
+ # NOTE: use with care since it can jeopardise the lookup structures.
2312
+ def name=(name)
2313
+ @name = name.to_sym
2314
+ end
2315
+
2316
+ ## Adds a system layer.
2317
+ def add_systemT(systemT)
2318
+ # puts "add_systemT #{systemT.name} to systemI #{self.name}"
2319
+ # Check and add the systemT.
2320
+ if !systemT.is_a?(SystemT) then
2321
+ raise AnyError, "Invalid class for a system type: #{systemT.class}"
2322
+ end
2323
+ @systemTs << systemT
2324
+ end
2325
+
2326
+ ## Iterates over the system layers.
2327
+ def each_systemT(&ruby_block)
2328
+ # No ruby block? Return an enumerator.
2329
+ return to_enum(:each_systemT) unless ruby_block
2330
+ # A ruby block? Apply it on the system layers.
2331
+ @systemTs.each(&ruby_block)
2332
+ end
2333
+
2334
+ # Delegate inner accesses to the system type.
2335
+ extend Forwardable
2336
+
2337
+ # @!method each_input
2338
+ # @see SystemT#each_input
2339
+ # @!method each_output
2340
+ # @see SystemT#each_output
2341
+ # @!method each_inout
2342
+ # @see SystemT#each_inout
2343
+ # @!method each_inner
2344
+ # @see SystemT#each_inner
2345
+ # @!method each_signal
2346
+ # @see SystemT#each_signal
2347
+ # @!method get_input
2348
+ # @see SystemT#get_input
2349
+ # @!method get_output
2350
+ # @see SystemT#get_output
2351
+ # @!method get_inout
2352
+ # @see SystemT#get_inout
2353
+ # @!method get_inner
2354
+ # @see SystemT#get_inner
2355
+ # @!method get_signal
2356
+ # @see SystemT#get_signal
2357
+ # @!method each_signal
2358
+ # @see SystemT#each_signal
2359
+ # @!method each_signal_deep
2360
+ # @see SystemT#each_signal_deep
2361
+ # @!method each_systemI
2362
+ # @see SystemT#each_systemI
2363
+ # @!method get_systemI
2364
+ # @see SystemT#get_systemI
2365
+ # @!method each_statement_deep
2366
+ # @see SystemT#each_statement_deep
2367
+ # @!method each_connection
2368
+ # @see SystemT#each_connection
2369
+ # @!method each_connection_deep
2370
+ # @see SystemT#each_connection_deep
2371
+ # @!method each_arrow_deep
2372
+ # @see SystemT#each_arrow_deep
2373
+ # @!method each_behavior
2374
+ # @see SystemT#each_behavior
2375
+ # @!method each_behavior_deep
2376
+ # @see SystemT#each_behavior_deep
2377
+ # @!method each_block_deep
2378
+ # @see SystemT#each_block_deep
2379
+ # @!method each_sensitive_deep
2380
+ # @see SystemT#each_sensitive_deep
2381
+ def_delegators :@systemT,
2382
+ :each_input, :each_output, :each_inout, :each_inner,
2383
+ :each_signal, :each_signal_deep,
2384
+ :get_input, :get_output, :get_inout, :get_inner,
2385
+ :get_signal, :get_interface,
2386
+ :each_systemI, :get_systemI,
2387
+ :each_connection, :each_connection_deep,
2388
+ :each_statement_deep, :each_arrow_deep,
2389
+ :each_behavior, :each_behavior_deep, :each_block_deep,
2390
+ :each_sensitive_deep
2391
+ end
2392
+
2393
+
2394
+ ##
2395
+ # Describes a non-HDLRuby code chunk.
2396
+ class Chunk
2397
+
2398
+ include Hparent
2399
+
2400
+ # The name of the code chunk.
2401
+ attr_reader :name
2402
+
2403
+ ## Creates new code chunk +name+ with made of +lumps+ piece of text.
2404
+ def initialize(name,*lumps)
2405
+ # Check and set the name.
2406
+ @name = name.to_sym
2407
+ # Set the content.
2408
+ @lumps = []
2409
+ lumps.each { |lump| self.add_lump(lump) }
2410
+ end
2411
+
2412
+ # Adds a +lump+ of code, it is ment to become an expression or
2413
+ # some text.
2414
+ def add_lump(lump)
2415
+ # Set its parent if relevant.
2416
+ lump.parent = self if lump.respond_to?(:parent)
2417
+ # And add it
2418
+ @lumps << lump
2419
+ return lump
2420
+ end
2421
+
2422
+ # Iterates over the code lumps.
2423
+ #
2424
+ # Returns an enumerator if no ruby block is given.
2425
+ def each_lump(&ruby_block)
2426
+ # No ruby block? Return an enumerator.
2427
+ return to_enum(:each_lump) unless ruby_block
2428
+ # A ruby block? Apply it on each lump.
2429
+ @lumps.each(&ruby_block)
2430
+ end
2431
+ end
2432
+
2433
+
2434
+ ##
2435
+ # Decribes a set of non-HDLRuby code chunks.
2436
+ class Code
2437
+
2438
+ include Hparent
2439
+
2440
+ # Creates a new chunk of code.
2441
+ def initialize
2442
+ # Initialize the set of events.
2443
+ @events = []
2444
+ # Initialize the content.
2445
+ @chunks = HashName.new
2446
+ end
2447
+
2448
+ # Adds a +chunk+ to the sensitivity list.
2449
+ def add_chunk(chunk)
2450
+ # Check and add the chunk.
2451
+ unless chunk.is_a?(Chunk)
2452
+ raise AnyError,
2453
+ "Invalid class for a code chunk: #{chunk.class}"
2454
+ end
2455
+ # if @chunks.has_key?(chunk.name) then
2456
+ if @chunks.include?(chunk) then
2457
+ raise AnyError, "Code chunk #{chunk.name} already present."
2458
+ end
2459
+ # Set its parent.
2460
+ chunk.parent = self
2461
+ # And add it
2462
+ @chunks.add(chunk)
2463
+ end
2464
+
2465
+ # Iterates over the code chunks.
2466
+ #
2467
+ # Returns an enumerator if no ruby block is given.
2468
+ def each_chunk(&ruby_block)
2469
+ # No ruby block? Return an enumerator.
2470
+ return to_enum(:each_chunk) unless ruby_block
2471
+ # A ruby block? Apply it on each chunk.
2472
+ @chunks.each(&ruby_block)
2473
+ end
2474
+
2475
+ # Adds an +event+ to the sensitivity list.
2476
+ def add_event(event)
2477
+ unless event.is_a?(Event)
2478
+ raise AnyError, "Invalid class for a event: #{event.class}"
2479
+ end
2480
+ # Set the event's parent.
2481
+ event.parent = self
2482
+ # And add the event.
2483
+ @events << event
2484
+ event
2485
+ end
2486
+
2487
+ # Iterates over the events of the sensitivity list.
2488
+ #
2489
+ # Returns an enumerator if no ruby block is given.
2490
+ def each_event(&ruby_block)
2491
+ # No ruby block? Return an enumerator.
2492
+ return to_enum(:each_event) unless ruby_block
2493
+ # A ruby block? Apply it on each event.
2494
+ @events.each(&ruby_block)
2495
+ end
2496
+
2497
+ # Tells if there is any event.
2498
+ def has_event?
2499
+ return !@events.empty?
2500
+ end
2501
+
2502
+ # Tells if there is a positive or negative edge event.
2503
+ def on_edge?
2504
+ @events.each do |event|
2505
+ return true if event.on_edge?
2506
+ end
2507
+ return false
2508
+ end
2509
+
2510
+ # Comparison for hash: structural comparison.
2511
+ def eql?(obj)
2512
+ return false unless obj.is_a?(Code)
2513
+ idx = 0
2514
+ obj.each_event do |event|
2515
+ return false unless @events[idx].eql?(event)
2516
+ idx += 1
2517
+ end
2518
+ idx = 0
2519
+ obj.each_chunk do |chunk|
2520
+ return false unless @chunks[idx].eql?(chunk)
2521
+ idx += 1
2522
+ end
2523
+ return true
2524
+ end
2525
+
2526
+ # Hash function.
2527
+ def hash
2528
+ return [@events,@chunk].hash
2529
+ end
2530
+ end
2531
+
2532
+
2533
+ ##
2534
+ # Describes a statement.
2535
+ #
2536
+ # NOTE: this is an abstract class which is not to be used directly.
2537
+ class Statement
2538
+ include Hparent
2539
+
2540
+ # Clones (deeply)
2541
+ def clone
2542
+ raise AnyError,
2543
+ "Internal error: clone is not defined for class: #{self.class}"
2544
+ end
2545
+
2546
+ # Comparison for hash: structural comparison.
2547
+ def eql?(obj)
2548
+ raise AnyError,
2549
+ "Internal error: eql? is not defined for class: #{self.class}"
2550
+ end
2551
+
2552
+ # Hash function.
2553
+ def hash
2554
+ raise AnyError,
2555
+ "Internal error: hash is not defined for class: #{self.class}"
2556
+ end
2557
+
2558
+ # Get the block of the statement.
2559
+ def block
2560
+ if self.is_a?(Block)
2561
+ return self
2562
+ else
2563
+ return self.parent.block
2564
+ end
2565
+ end
2566
+
2567
+ # Gets the top block, i.e. the first block of the current behavior.
2568
+ def top_block
2569
+ return self.parent.is_a?(Behavior) ? self : self.parent.top_block
2570
+ end
2571
+
2572
+ # Gets the top scope, i.e. the first scope of the current system.
2573
+ def top_scope
2574
+ return self.top_block.parent.top_scope
2575
+ end
2576
+ end
2577
+
2578
+
2579
+ # ##
2580
+ # # Describes a declare statement.
2581
+ # class Declare < Statement
2582
+ # # The declared signal instance.
2583
+ # attr_reader :signal
2584
+
2585
+ # # Creates a new statement declaring +signal+.
2586
+ # def initialize(signal)
2587
+ # # Check and set the declared signal instance.
2588
+ # unless signal.is_a?(SignalI)
2589
+ # raise AnyError, "Invalid class for declaring a signal: #{signal.class}"
2590
+ # end
2591
+ # @signal = signal
2592
+ # end
2593
+ # end
2594
+
2595
+
2596
+ ##
2597
+ # Decribes a transmission statement.
2598
+ class Transmit < Statement
2599
+
2600
+ # The left reference.
2601
+ attr_reader :left
2602
+
2603
+ # The right expression.
2604
+ attr_reader :right
2605
+
2606
+ # Creates a new transmission from a +right+ expression to a +left+
2607
+ # reference.
2608
+ def initialize(left,right)
2609
+ # Check and set the left reference.
2610
+ unless left.is_a?(Ref)
2611
+ raise AnyError,
2612
+ "Invalid class for a reference (left value): #{left.class}"
2613
+ end
2614
+ @left = left
2615
+ # and set its parent.
2616
+ left.parent = self
2617
+ # Check and set the right expression.
2618
+ unless right.is_a?(Expression)
2619
+ raise AnyError, "Invalid class for an expression (right value): #{right.class}"
2620
+ end
2621
+ @right = right
2622
+ # and set its parent.
2623
+ right.parent = self
2624
+ end
2625
+
2626
+ # Comparison for hash: structural comparison.
2627
+ def eql?(obj)
2628
+ return false unless obj.is_a?(Transmit)
2629
+ return false unless @left.eql?(obj.left)
2630
+ return false unless @right.eql?(obj.right)
2631
+ return true
2632
+ end
2633
+
2634
+ # Hash function.
2635
+ def hash
2636
+ return [@left,@right].hash
2637
+ end
2638
+
2639
+ # Clones the transmit (deeply)
2640
+ def clone
2641
+ return Transmit.new(@left.clone, @right.clone)
2642
+ end
2643
+
2644
+ # Iterates over the children if any.
2645
+ def each_node(&ruby_block)
2646
+ # No ruby block? Return an enumerator.
2647
+ return to_enum(:each_node) unless ruby_block
2648
+ # A ruby block? Apply it on the children.
2649
+ ruby_block.call(@left)
2650
+ ruby_block.call(@right)
2651
+ end
2652
+
2653
+ alias_method :each_expression, :each_node
2654
+
2655
+ # Iterates over the nodes deeply if any.
2656
+ def each_node_deep(&ruby_block)
2657
+ # No ruby block? Return an enumerator.
2658
+ return to_enum(:each_node_deep) unless ruby_block
2659
+ # A ruby block? First apply it to current.
2660
+ ruby_block.call(self)
2661
+ # And recurse on the children
2662
+ @left.each_node_deep(&ruby_block)
2663
+ @right.each_node_deep(&ruby_block)
2664
+ end
2665
+
2666
+ # Iterates over all the stamements of the block and its sub blocks.
2667
+ def each_statement_deep(&ruby_block)
2668
+ # No ruby statement? Return an enumerator.
2669
+ return to_enum(:each_statement_deep) unless ruby_block
2670
+ # A ruby block?
2671
+ # Apply it on self.
2672
+ ruby_block.call(self)
2673
+ end
2674
+
2675
+ # Iterates over the sub blocks.
2676
+ def each_block(&ruby_block)
2677
+ # No ruby block? Return an enumerator.
2678
+ return to_enum(:each_block) unless ruby_block
2679
+ # A ruby block?
2680
+ # Nothing to do.
2681
+ end
2682
+
2683
+ # Iterates over all the blocks contained in the current block.
2684
+ def each_block_deep(&ruby_block)
2685
+ # No ruby block? Return an enumerator.
2686
+ return to_enum(:each_block_deep) unless ruby_block
2687
+ # A ruby block?
2688
+ # Nothing to do.
2689
+ end
2690
+ end
2691
+
2692
+
2693
+ ##
2694
+ # Describes an if statement.
2695
+ class If < Statement
2696
+ # The condition
2697
+ attr_reader :condition
2698
+
2699
+ # The yes and no statements
2700
+ attr_reader :yes, :no
2701
+
2702
+ # Creates a new if statement with a +condition+ and a +yes+ and +no+
2703
+ # blocks.
2704
+ def initialize(condition, yes, no = nil)
2705
+ # Check and set the condition.
2706
+ unless condition.is_a?(Expression)
2707
+ raise AnyError,
2708
+ "Invalid class for a condition: #{condition.class}"
2709
+ end
2710
+ @condition = condition
2711
+ # And set its parent.
2712
+ condition.parent = self
2713
+ # Check and set the yes statement.
2714
+ unless yes.is_a?(Statement)
2715
+ raise AnyError, "Invalid class for a statement: #{yes.class}"
2716
+ end
2717
+ @yes = yes
2718
+ # And set its parent.
2719
+ yes.parent = self
2720
+ # Check and set the yes statement.
2721
+ if no and !no.is_a?(Statement)
2722
+ raise AnyError, "Invalid class for a statement: #{no.class}"
2723
+ end
2724
+ @no = no
2725
+ # And set its parent.
2726
+ no.parent = self if no
2727
+
2728
+ # Initialize the list of alternative if statements (elsif)
2729
+ @noifs = []
2730
+ end
2731
+
2732
+ # Comparison for hash: structural comparison.
2733
+ def eql?(obj)
2734
+ return false unless obj.is_a?(If)
2735
+ return false unless @condition.eql?(obj.condition)
2736
+ return false unless @yes.eql?(obj.yes)
2737
+ return false unless @no.eql?(obj.no)
2738
+ return true
2739
+ end
2740
+
2741
+ # Hash function.
2742
+ def hash
2743
+ return [@condition,@yes,@no].hash
2744
+ end
2745
+
2746
+ # Sets the no block.
2747
+ #
2748
+ # No shoud only be set once, but this is not checked here for
2749
+ # sake of flexibility.
2750
+ def no=(no)
2751
+ # if @no != nil then
2752
+ # raise AnyError, "No already set in if statement."
2753
+ # end # Actually better not lock no here.
2754
+ # Check and set the yes statement.
2755
+ unless no.is_a?(Statement)
2756
+ raise AnyError, "Invalid class for a statement: #{no.class}"
2757
+ end
2758
+ @no = no
2759
+ # And set its parent.
2760
+ no.parent = self
2761
+ end
2762
+
2763
+ # Adds an alternative if statement (elsif) testing +next_cond+
2764
+ # and executing +next_yes+ when the condition is met.
2765
+ def add_noif(next_cond, next_yes)
2766
+ # Check the condition.
2767
+ unless next_cond.is_a?(Expression)
2768
+ raise AnyError,
2769
+ "Invalid class for a condition: #{next_cond.class}"
2770
+ end
2771
+ # And set its parent.
2772
+ next_cond.parent = self
2773
+ # Check yes statement.
2774
+ unless next_yes.is_a?(Statement)
2775
+ raise AnyError,
2776
+ "Invalid class for a statement: #{next_yes.class}"
2777
+ end
2778
+ # And set its parent.
2779
+ next_yes.parent = self
2780
+ # Add the statement.
2781
+ @noifs << [next_cond,next_yes]
2782
+ end
2783
+
2784
+ # Iterates over the alternate if statements (elsif).
2785
+ def each_noif(&ruby_block)
2786
+ # No ruby block? Return an enumerator.
2787
+ return to_enum(:each_noif) unless ruby_block
2788
+ # A ruby block?
2789
+ # Appy it on the alternate if statements.
2790
+ @noifs.each do |next_cond,next_yes|
2791
+ yield(next_cond,next_yes)
2792
+ end
2793
+ end
2794
+
2795
+ # Iterates over the children (including the condition).
2796
+ def each_node(&ruby_block)
2797
+ # No ruby block? Return an enumerator.
2798
+ return to_enum(:each_node) unless ruby_block
2799
+ # A ruby block?
2800
+ # Appy it on the children.
2801
+ ruby_block.call(@condition)
2802
+ ruby_block.call(@yes)
2803
+ self.each_noif do |next_cond,next_yes|
2804
+ ruby_block.call(next_cond)
2805
+ ruby_block.call(next_yes)
2806
+ end
2807
+ ruby_block.call(@no) if @no
2808
+ end
2809
+
2810
+ # Iterates over the nodes deeply if any.
2811
+ def each_node_deep(&ruby_block)
2812
+ # No ruby block? Return an enumerator.
2813
+ return to_enum(:each_node_deep) unless ruby_block
2814
+ # A ruby block? First apply it to current.
2815
+ ruby_block.call(self)
2816
+ # And recurse on the children
2817
+ @condition.each_node_deep(&ruby_block)
2818
+ @yes.each_node_deep(&ruby_block)
2819
+ self.each_noif do |next_cond,next_yes|
2820
+ next_cond.each_node_deep(&ruby_block)
2821
+ next_yes.each_node_deep(&ruby_block)
2822
+ end
2823
+ @no.each_node_deep(&ruby_block) if @no
2824
+ end
2825
+
2826
+ # Iterates over the sub blocks.
2827
+ def each_block(&ruby_block)
2828
+ # No ruby block? Return an enumerator.
2829
+ return to_enum(:each_block) unless ruby_block
2830
+ # A ruby block?
2831
+ # Apply it on the yes, the alternate ifs and the no blocks.
2832
+ ruby_block.call(@yes) if @yes.is_a?(Block)
2833
+ @noifs.each do |next_cond,next_yes|
2834
+ ruby_block.call(next_yes) if next_yes.is_a?(Block)
2835
+ end
2836
+ ruby_block.call(@no) if @no.is_a?(Block)
2837
+ end
2838
+
2839
+ # Iterates over all the stamements of the block and its sub blocks.
2840
+ def each_statement_deep(&ruby_block)
2841
+ # No ruby statement? Return an enumerator.
2842
+ return to_enum(:each_statement_deep) unless ruby_block
2843
+ # A ruby block?
2844
+ # Apply it on self.
2845
+ ruby_block.call(self)
2846
+ # And recurse on the alternate ifs and the no statements.
2847
+ @yes.each_statement_deep(&ruby_block)
2848
+ @noifs.each do |next_cond,next_yes|
2849
+ next_yes.each_statement_deep(&ruby_block)
2850
+ end
2851
+ @no.each_statement_deep(&ruby_block) if @no.is_a?(Block)
2852
+ end
2853
+
2854
+ # Iterates over all the blocks contained in the current block.
2855
+ def each_block_deep(&ruby_block)
2856
+ # No ruby block? Return an enumerator.
2857
+ return to_enum(:each_block_deep) unless ruby_block
2858
+ # A ruby block?
2859
+ # Apply it on the yes, the alternate ifs and the no blocks.
2860
+ @yes.each_block_deep(&ruby_block)
2861
+ @noifs.each do |next_cond,next_yes|
2862
+ next_yes.each_block_deep(&ruby_block)
2863
+ end
2864
+ # @no.each_block_deep(&ruby_block) if @no.is_a?(Block)
2865
+ @no.each_block_deep(&ruby_block) if @no
2866
+ end
2867
+
2868
+ # Clones the If (deeply)
2869
+ def clone
2870
+ # Duplicate the if.
2871
+ res = If.new(@condition.clone, @yes.clone, @no ? @no.clone : nil)
2872
+ # Duplicate the alternate ifs
2873
+ @noifs.each do |next_cond,next_yes|
2874
+ res.add_noif(next_cond.clone,next_yes.clone)
2875
+ end
2876
+ return res
2877
+ end
2878
+ end
2879
+
2880
+ ##
2881
+ # Describes a when for a case statement.
2882
+ class When
2883
+
2884
+ include Hparent
2885
+
2886
+ # The value to match.
2887
+ attr_reader :match
2888
+ # The statement to execute in in case of match.
2889
+ attr_reader :statement
2890
+
2891
+ # Creates a new when for a casde statement that executes +statement+
2892
+ # on +match+.
2893
+ def initialize(match,statement)
2894
+ # Checks the match.
2895
+ unless match.is_a?(Expression)
2896
+ raise AnyError, "Invalid class for a case match: #{match.class}"
2897
+ end
2898
+ # Checks statement.
2899
+ unless statement.is_a?(Statement)
2900
+ raise AnyError,
2901
+ "Invalid class for a statement: #{statement.class}"
2902
+ end
2903
+ # Set the match.
2904
+ @match = match
2905
+ # Set the statement.
2906
+ @statement = statement
2907
+ # And set their parents.
2908
+ match.parent = statement.parent = self
2909
+ end
2910
+
2911
+ # Comparison for hash: structural comparison.
2912
+ def eql?(obj)
2913
+ return false unless obj.is_a?(When)
2914
+ return false unless @match.eql?(obj.match)
2915
+ return false unless @statement.eql?(obj.statement)
2916
+ return true
2917
+ end
2918
+
2919
+ # Hash function.
2920
+ def hash
2921
+ return [@match,@statement].hash
2922
+ end
2923
+
2924
+ # Clones the When (deeply)
2925
+ def clone
2926
+ return When.new(@match.clone,@statement.clone)
2927
+ end
2928
+
2929
+ # Iterates over the sub blocks.
2930
+ def each_block(&ruby_block)
2931
+ # No ruby block? Return an enumerator.
2932
+ return to_enum(:each_block) unless ruby_block
2933
+ # A ruby block?
2934
+ # Apply it on the statement if it is a block.
2935
+ ruby_block.call(@statement) if @statement.is_a?(Block)
2936
+ end
2937
+
2938
+ # Iterates over all the blocks contained in the current block.
2939
+ def each_block_deep(&ruby_block)
2940
+ # No ruby block? Return an enumerator.
2941
+ return to_enum(:each_block_deep) unless ruby_block
2942
+ # A ruby block?
2943
+ # Recurse on the statement.
2944
+ @statement.each_block_deep(&ruby_block)
2945
+ end
2946
+
2947
+ # Iterates over all the stamements of the block and its sub blocks.
2948
+ def each_statement_deep(&ruby_block)
2949
+ # No ruby block? Return an enumerator.
2950
+ return to_enum(:each_statement_deep) unless ruby_block
2951
+ # A ruby block?
2952
+ # Recurse on the statement.
2953
+ @statement.each_statement_deep(&ruby_block)
2954
+ end
2955
+
2956
+ # Interates over the children.
2957
+ def each_node(&ruby_block)
2958
+ # No ruby block? Return an enumerator.
2959
+ return to_enum(:each_node) unless ruby_block
2960
+ # A ruby block?
2961
+ # Appy it on the children.
2962
+ ruby_block.call(@match)
2963
+ ruby_block.call(@statement)
2964
+ end
2965
+
2966
+ # Iterates over the nodes deeply if any.
2967
+ def each_node_deep(&ruby_block)
2968
+ # No ruby block? Return an enumerator.
2969
+ return to_enum(:each_node_deep) unless ruby_block
2970
+ # A ruby block? First apply it to current.
2971
+ ruby_block.call(self)
2972
+ # And recurse on the children
2973
+ @match.each_node_deep(&ruby_block)
2974
+ @statement.each_node_deep(&ruby_block)
2975
+ end
2976
+
2977
+ # Gets the top block, i.e. the first block of the current behavior.
2978
+ def top_block
2979
+ return self.parent.is_a?(Behavior) ? self : self.parent.top_block
2980
+ end
2981
+ end
2982
+
2983
+
2984
+ ##
2985
+ # Describes a case statement.
2986
+ class Case < Statement
2987
+ # The tested value
2988
+ attr_reader :value
2989
+
2990
+ # The default block.
2991
+ attr_reader :default
2992
+
2993
+ # Creates a new case statement whose excution flow is decided from
2994
+ # +value+ with a possible cases given in +whens+ and +default
2995
+ # + (can be set later)
2996
+ def initialize(value, default = nil, whens = [])
2997
+ # Check and set the value.
2998
+ unless value.is_a?(Expression)
2999
+ raise AnyError, "Invalid class for a value: #{value.class}"
3000
+ end
3001
+ @value = value
3002
+ # And set its parent.
3003
+ value.parent = self
3004
+ # Checks and set the default case if any.
3005
+ self.default = default if default
3006
+ # Check and add the whens.
3007
+ @whens = []
3008
+ whens.each { |w| self.add_when(w) }
3009
+ end
3010
+
3011
+ # Comparison for hash: structural comparison.
3012
+ def eql?(obj)
3013
+ return false unless obj.is_a?(Case)
3014
+ return false unless @value.eql?(obj.value)
3015
+ return false unless @whens.eql?(obj.instance_variable_get(:@whens))
3016
+ idx = 0
3017
+ obj.each_when do |w|
3018
+ return false unless @whens[idx].eql?(w)
3019
+ idx += 1
3020
+ end
3021
+ return false unless idx == @whens.size
3022
+ return false unless @default.eql?(obj.default)
3023
+ return true
3024
+ end
3025
+
3026
+ # Hash function.
3027
+ def hash
3028
+ return [@value,@whens,@default].hash
3029
+ end
3030
+
3031
+ # # Adds a possible +match+ for the case's value that lead to the
3032
+ # # execution of +statement+.
3033
+ # def add_when(match,statement)
3034
+ # # Checks the match.
3035
+ # unless match.is_a?(Expression)
3036
+ # raise AnyError, "Invalid class for a case match: #{match.class}"
3037
+ # end
3038
+ # # Checks statement.
3039
+ # unless statement.is_a?(Statement)
3040
+ # raise AnyError, "Invalid class for a statement: #{statement.class}"
3041
+ # end
3042
+ # # Add the case.
3043
+ # @whens << [match,statement]
3044
+ # # And set their parents.
3045
+ # match.parent = statement.parent = self
3046
+ # [match,statement]
3047
+ # end
3048
+
3049
+ # Adds possible when case +w+.
3050
+ def add_when(w)
3051
+ # Check +w+.
3052
+ unless w.is_a?(When)
3053
+ raise AnyError, "Invalid class for a when: #{w.class}"
3054
+ end
3055
+ # Add it.
3056
+ @whens << w
3057
+ # And set the parent of +w+.
3058
+ w.parent = self
3059
+ end
3060
+
3061
+ # Sets the default block.
3062
+ #
3063
+ # No can only be set once.
3064
+ def default=(default)
3065
+ if @default != nil then
3066
+ raise AnyError, "Default already set in if statement."
3067
+ end
3068
+ # Check and set the yes statement.
3069
+ unless default.is_a?(Statement)
3070
+ raise AnyError,"Invalid class for a statement: #{default.class}"
3071
+ end
3072
+ @default = default
3073
+ # And set its parent.
3074
+ default.parent = self
3075
+ @default
3076
+ end
3077
+
3078
+ # Iterates over the match cases.
3079
+ #
3080
+ # Returns an enumerator if no ruby block is given.
3081
+ def each_when(&ruby_block)
3082
+ # No ruby block? Return an enumerator.
3083
+ return to_enum(:each_when) unless ruby_block
3084
+ # A ruby block? Apply it on each when case.
3085
+ @whens.each(&ruby_block)
3086
+ end
3087
+
3088
+ # Iterates over the children (including the value).
3089
+ #
3090
+ # Returns an enumerator if no ruby block is given.
3091
+ def each_node(&ruby_block)
3092
+ # No ruby block? Return an enumerator.
3093
+ return to_enum(:each_node) unless ruby_block
3094
+ # A ruby block? Apply it on each child.
3095
+ ruby_block.call(@value)
3096
+ @whens.each(&ruby_block)
3097
+ ruby_block.call(@default) if @default
3098
+ end
3099
+
3100
+ # Iterates over the nodes deeply if any.
3101
+ def each_node_deep(&ruby_block)
3102
+ # No ruby block? Return an enumerator.
3103
+ return to_enum(:each_node_deep) unless ruby_block
3104
+ # A ruby block? First apply it to current.
3105
+ ruby_block.call(self)
3106
+ # And recurse on the children
3107
+ @value.each_node_deep(&ruby_block)
3108
+ @whens.each { |w| w.each_node_deep(&ruby_block) }
3109
+ @default.each_node_deep(&ruby_block) if @default
3110
+ end
3111
+
3112
+ # Iterates over the sub blocks.
3113
+ def each_block(&ruby_block)
3114
+ # No ruby block? Return an enumerator.
3115
+ return to_enum(:each_block) unless ruby_block
3116
+ # A ruby block?
3117
+ # Apply it on each when's block.
3118
+ self.each_when { |w| w.each_block(&ruby_block) }
3119
+ # And apply it on the default if any.
3120
+ ruby_block.call(@default) if @default
3121
+ end
3122
+
3123
+ # Iterates over all the blocks contained in the current block.
3124
+ def each_block_deep(&ruby_block)
3125
+ # No ruby block? Return an enumerator.
3126
+ return to_enum(:each_block_deep) unless ruby_block
3127
+ # A ruby block?
3128
+ # Apply it on each when's block.
3129
+ self.each_when { |w| w.each_block_deep(&ruby_block) }
3130
+ # And apply it on the default if any.
3131
+ @default.each_block_deep(&ruby_block) if @default
3132
+ end
3133
+
3134
+ # Iterates over all the statements contained in the current statement.
3135
+ def each_statement_deep(&ruby_block)
3136
+ # No ruby statement? Return an enumerator.
3137
+ return to_enum(:each_statement_deep) unless ruby_block
3138
+ # A ruby block?
3139
+ # Apply it on self.
3140
+ ruby_block.call(self)
3141
+ # And apply it on each when's statement.
3142
+ self.each_when { |w| w.each_statement_deep(&ruby_block) }
3143
+ # And apply it on the default if any.
3144
+ @default.each_statement_deep(&ruby_block) if @default
3145
+ end
3146
+
3147
+ # Clones the Case (deeply)
3148
+ def clone
3149
+ return Case.new(@value.clone,@default.clone,(@whens.map do |w|
3150
+ w.clone
3151
+ end) )
3152
+ end
3153
+ end
3154
+
3155
+
3156
+ ##
3157
+ # Describes a delay: not synthesizable.
3158
+ class Delay
3159
+
3160
+ include Hparent
3161
+
3162
+ # The time unit.
3163
+ attr_reader :unit
3164
+
3165
+ # The time value.
3166
+ attr_reader :value
3167
+
3168
+ # Creates a new delay of +value+ +unit+ of time.
3169
+ def initialize(value,unit)
3170
+ # Check and set the value.
3171
+ unless value.is_a?(Numeric)
3172
+ raise AnyError,
3173
+ "Invalid class for a delay value: #{value.class}."
3174
+ end
3175
+ @value = value
3176
+ # Check and set the unit.
3177
+ @unit = unit.to_sym
3178
+ end
3179
+
3180
+ # Comparison for hash: structural comparison.
3181
+ def eql?(obj)
3182
+ return false unless obj.is_a?(Delay)
3183
+ return false unless @unit.eql?(obj.unit)
3184
+ return false unless @value.eql?(obj.value)
3185
+ return true
3186
+ end
3187
+
3188
+ # Hash function.
3189
+ def hash
3190
+ return [@unit,@value].hash
3191
+ end
3192
+
3193
+ # Clones the Delay (deeply)
3194
+ def clone
3195
+ return Delay.new(@value,@unit)
3196
+ end
3197
+ end
3198
+
3199
+
3200
+ ##
3201
+ # Describes a wait statement: not synthesizable!
3202
+ class TimeWait < Statement
3203
+ # The delay to wait.
3204
+ attr_reader :delay
3205
+
3206
+ # Creates a new statement waiting +delay+.
3207
+ def initialize(delay)
3208
+ # Check and set the delay.
3209
+ unless delay.is_a?(Delay)
3210
+ raise AnyError, "Invalid class for a delay: #{delay.class}."
3211
+ end
3212
+ @delay = delay
3213
+ # And set its parent.
3214
+ delay.parent = self
3215
+ end
3216
+
3217
+ # Comparison for hash: structural comparison.
3218
+ def eql?(obj)
3219
+ return false unless obj.is_a?(TimeWait)
3220
+ return false unless @delay.eql?(obj.delay)
3221
+ return true
3222
+ end
3223
+
3224
+ # Hash function.
3225
+ def hash
3226
+ return [@delay].hash
3227
+ end
3228
+
3229
+ # Clones the TimeWait (deeply)
3230
+ def clone
3231
+ return TimeWait.new(@delay.clone)
3232
+ end
3233
+
3234
+ # Iterates over the expression children if any.
3235
+ def each_node(&ruby_block)
3236
+ # No ruby block? Return an enumerator.
3237
+ return to_enum(:each_node) unless ruby_block
3238
+ # A ruby block?
3239
+ # Nothing to do.
3240
+ end
3241
+
3242
+ # Iterates over the nodes deeply if any.
3243
+ def each_node_deep(&ruby_block)
3244
+ # No ruby block? Return an enumerator.
3245
+ return to_enum(:each_node_deep) unless ruby_block
3246
+ # A ruby block? First apply it to current.
3247
+ ruby_block.call(self)
3248
+ end
3249
+
3250
+ # Iterates over the sub blocks.
3251
+ def each_block(&ruby_block)
3252
+ # No ruby block? Return an enumerator.
3253
+ return to_enum(:each_block) unless ruby_block
3254
+ # A ruby block?
3255
+ # Nothing to do.
3256
+ end
3257
+
3258
+ # Iterates over all the blocks contained in the current block.
3259
+ def each_block_deep(&ruby_block)
3260
+ # No ruby block? Return an enumerator.
3261
+ return to_enum(:each_block_deep) unless ruby_block
3262
+ # A ruby block?
3263
+ # Nothing to do.
3264
+ end
3265
+
3266
+ # Iterates over all the statements contained in the current block.
3267
+ def each_statement_deep(&ruby_block)
3268
+ # No ruby block? Return an enumerator.
3269
+ return to_enum(:each_statement_deep) unless ruby_block
3270
+ # A ruby block?
3271
+ # Apply it on self.
3272
+ ruby_block.call(self)
3273
+ end
3274
+
3275
+ end
3276
+
3277
+
3278
+ ##
3279
+ # Describes a timed loop statement: not synthesizable!
3280
+ class TimeRepeat < Statement
3281
+ # The delay until the loop is repeated
3282
+ attr_reader :delay
3283
+
3284
+ # The statement to execute.
3285
+ attr_reader :statement
3286
+
3287
+ # Creates a new timed loop statement execute in a loop +statement+ until
3288
+ # +delay+ has passed.
3289
+ def initialize(statement,delay)
3290
+ # Check and set the statement.
3291
+ unless statement.is_a?(Statement)
3292
+ raise AnyError,
3293
+ "Invalid class for a statement: #{statement.class}."
3294
+ end
3295
+ @statement = statement
3296
+ # And set its parent.
3297
+ statement.parent = self
3298
+
3299
+ # Check and set the delay.
3300
+ unless delay.is_a?(Delay)
3301
+ raise AnyError, "Invalid class for a delay: #{delay.class}."
3302
+ end
3303
+ @delay = delay
3304
+ # And set its parent.
3305
+ delay.parent = self
3306
+ end
3307
+
3308
+ # Comparison for hash: structural comparison.
3309
+ def eql?(obj)
3310
+ return false unless obj.is_a?(TimeRepeat)
3311
+ return false unless @delay.eql?(obj.delay)
3312
+ return false unless @statement.eql?(obj.statement)
3313
+ return true
3314
+ end
3315
+
3316
+ # Hash function.
3317
+ def hash
3318
+ return [@delay,@statement].hash
3319
+ end
3320
+
3321
+ # Clones the TimeRepeat (deeply)
3322
+ def clone
3323
+ return TimeRepeat(@statement.clone,@delay.clone)
3324
+ end
3325
+
3326
+ # Iterates over the expression children if any.
3327
+ def each_node(&ruby_block)
3328
+ # No ruby block? Return an enumerator.
3329
+ return to_enum(:each_node) unless ruby_block
3330
+ # A ruby block? Apply it on the child.
3331
+ ruby_block.call(@statement)
3332
+ end
3333
+
3334
+ # Iterates over the nodes deeply if any.
3335
+ def each_node_deep(&ruby_block)
3336
+ # No ruby block? Return an enumerator.
3337
+ return to_enum(:each_node_deep) unless ruby_block
3338
+ # A ruby block? First apply it to current.
3339
+ ruby_block.call(self)
3340
+ # And recurse on the child
3341
+ @statement.each_node_deep(&ruby_block)
3342
+ end
3343
+
3344
+ # Iterates over the sub blocks.
3345
+ def each_block(&ruby_block)
3346
+ # No ruby block? Return an enumerator.
3347
+ return to_enum(:each_block) unless ruby_block
3348
+ # A ruby block?
3349
+ # Apply it on the statement if it is a block.
3350
+ ruby_block.call(@statement) if statement.is_a?(Block)
3351
+ end
3352
+
3353
+ # Iterates over all the blocks contained in the current block.
3354
+ def each_block_deep(&ruby_block)
3355
+ # No ruby block? Return an enumerator.
3356
+ return to_enum(:each_block_deep) unless ruby_block
3357
+ # A ruby block?
3358
+ # Recurse on the statement.
3359
+ @statement.each_block_deep(&ruby_block)
3360
+ end
3361
+
3362
+ # Iterates over all the statements contained in the current block.
3363
+ def each_statement_deep(&ruby_block)
3364
+ # No ruby block? Return an enumerator.
3365
+ return to_enum(:each_statement_deep) unless ruby_block
3366
+ # A ruby block?
3367
+ # Apply it on self.
3368
+ ruby_block.call(self)
3369
+ # Recurse on the statement.
3370
+ @statement.each_statement_deep(&ruby_block)
3371
+ end
3372
+
3373
+ end
3374
+
3375
+
3376
+ ##
3377
+ # Describes a block.
3378
+ class Block < Statement
3379
+ # The execution mode of the block.
3380
+ attr_reader :mode
3381
+
3382
+ # The name of the block if any
3383
+ attr_reader :name
3384
+
3385
+ # Creates a new +mode+ sort of block with possible +name+.
3386
+ def initialize(mode, name = :"")
3387
+ # puts "new block with mode=#{mode} and name=#{name}"
3388
+ # Check and set the type.
3389
+ @mode = mode.to_sym
3390
+ # Check and set the name.
3391
+ @name = name.to_sym
3392
+ # Initializes the list of inner statements.
3393
+ # @inners = {}
3394
+ @inners = HashName.new
3395
+ # Initializes the list of statements.
3396
+ @statements = []
3397
+ end
3398
+
3399
+ # Comparison for hash: structural comparison.
3400
+ def eql?(obj)
3401
+ return false unless obj.is_a?(Block)
3402
+ return false unless @mode.eql?(obj.mode)
3403
+ return false unless @name.eql?(obj.name)
3404
+ idx = 0
3405
+ obj.each_inner do |inner|
3406
+ return false unless @inners[inner.name].eql?(inner)
3407
+ idx += 1
3408
+ end
3409
+ return false unless idx == @inners.size
3410
+ idx = 0
3411
+ obj.each_statement do |statement|
3412
+ return false unless @statements[idx].eql?(statement)
3413
+ idx += 1
3414
+ end
3415
+ return false unless idx == @statements.size
3416
+ return true
3417
+ end
3418
+
3419
+ # Hash function.
3420
+ def hash
3421
+ return [@mode,@name,@inners,@statements].hash
3422
+ end
3423
+
3424
+ # Adds inner signal +signal+.
3425
+ def add_inner(signal)
3426
+ # Check and add the signal.
3427
+ unless signal.is_a?(SignalI)
3428
+ raise AnyError,
3429
+ "Invalid class for a signal instance: #{signal.class}"
3430
+ end
3431
+ # if @inners.has_key?(signal.name) then
3432
+ if @inners.include?(signal) then
3433
+ raise AnyError, "SignalI #{signal.name} already present."
3434
+ end
3435
+ # @inners[signal.name] = signal
3436
+ # Set its parent.
3437
+ signal.parent = self
3438
+ # And add it
3439
+ @inners.add(signal)
3440
+ end
3441
+
3442
+ # Iterates over the inner signals.
3443
+ #
3444
+ # Returns an enumerator if no ruby block is given.
3445
+ def each_inner(&ruby_block)
3446
+ # No ruby block? Return an enumerator.
3447
+ return to_enum(:each_inner) unless ruby_block
3448
+ # A ruby block? Apply it on each inner signal instance.
3449
+ # @inners.each_value(&ruby_block)
3450
+ @inners.each(&ruby_block)
3451
+ end
3452
+ alias_method :each_signal, :each_inner
3453
+
3454
+ ## Gets an inner signal by +name+.
3455
+ def get_inner(name)
3456
+ return @inners[name.to_sym]
3457
+ end
3458
+ alias_method :get_signal, :get_inner
3459
+
3460
+ # Iterates over all the signals of the block and its sub block's ones.
3461
+ def each_signal_deep(&ruby_block)
3462
+ # No ruby block? Return an enumerator.
3463
+ return to_enum(:each_signal_deep) unless ruby_block
3464
+ # A ruby block?
3465
+ # First, apply on the signals of the block.
3466
+ self.each_signal(&ruby_block)
3467
+ # Then apply on each sub block.
3468
+ self.each_block_deep do |block|
3469
+ block.each_signal_deep(&ruby_block)
3470
+ end
3471
+ end
3472
+
3473
+ # Adds a +statement+.
3474
+ #
3475
+ # NOTE: TimeWait is not supported unless for TimeBlock objects.
3476
+ def add_statement(statement)
3477
+ unless statement.is_a?(Statement) then
3478
+ raise AnyError,
3479
+ "Invalid class for a statement: #{statement.class}"
3480
+ end
3481
+ if statement.is_a?(TimeWait) then
3482
+ raise AnyError,
3483
+ "Timed statements are not supported in common blocks."
3484
+ end
3485
+ @statements << statement
3486
+ # And set its parent.
3487
+ statement.parent = self
3488
+ statement
3489
+ end
3490
+
3491
+ # Gets the number of statements.
3492
+ def num_statements
3493
+ return @statements.size
3494
+ end
3495
+
3496
+ # Iterates over the statements.
3497
+ #
3498
+ # Returns an enumerator if no ruby block is given.
3499
+ def each_statement(&ruby_block)
3500
+ # No ruby block? Return an enumerator.
3501
+ return to_enum(:each_statement) unless ruby_block
3502
+ # A ruby block? Apply it on each statement.
3503
+ @statements.each(&ruby_block)
3504
+ end
3505
+
3506
+ alias_method :each_node, :each_statement
3507
+
3508
+ # Reverse iterates over the statements.
3509
+ #
3510
+ # Returns an enumerator if no ruby block is given.
3511
+ def reverse_each_statement(&ruby_block)
3512
+ # No ruby block? Return an enumerator.
3513
+ return to_enum(:reverse_each_statement) unless ruby_block
3514
+ # A ruby block? Apply it on each statement.
3515
+ @statements.reverse_each(&ruby_block)
3516
+ end
3517
+
3518
+ # Returns the last statement.
3519
+ def last_statement
3520
+ return @statements[-1]
3521
+ end
3522
+
3523
+ # # Deletes +statement+.
3524
+ # def delete_statement(statement)
3525
+ # if @statements.include?(statement) then
3526
+ # # Statement is present, delete it.
3527
+ # @statements.delete(statement)
3528
+ # # And remove its parent.
3529
+ # statement.parent = nil
3530
+ # end
3531
+ # statement
3532
+ # end
3533
+
3534
+ # Iterates over the sub blocks.
3535
+ def each_block(&ruby_block)
3536
+ # No ruby block? Return an enumerator.
3537
+ return to_enum(:each_block) unless ruby_block
3538
+ # A ruby block?
3539
+ # Apply it on each statement which contains blocks.
3540
+ self.each_statement do |statement|
3541
+ ruby_block.call(statement) if statement.is_a?(Block)
3542
+ end
3543
+ end
3544
+
3545
+ # Iterates over all the blocks contained in the current block.
3546
+ def each_block_deep(&ruby_block)
3547
+ # No ruby block? Return an enumerator.
3548
+ return to_enum(:each_block_deep) unless ruby_block
3549
+ # A ruby block?
3550
+ # Apply it on self.
3551
+ ruby_block.call(self)
3552
+ # And apply it on each statement which contains blocks.
3553
+ self.each_statement do |statement|
3554
+ statement.each_block_deep(&ruby_block)
3555
+ end
3556
+ end
3557
+
3558
+ # Iterates over all the stamements of the block and its sub blocks.
3559
+ def each_statement_deep(&ruby_block)
3560
+ # No ruby block? Return an enumerator.
3561
+ return to_enum(:each_statement_deep) unless ruby_block
3562
+ # A ruby block?
3563
+ # Apply it on current.
3564
+ ruby_block.call(self)
3565
+ # And apply it on each statement deeply.
3566
+ self.each_statement do |statement|
3567
+ statement.each_statement_deep(&ruby_block)
3568
+ end
3569
+ end
3570
+
3571
+ # Iterates over all the stamements of the block and its sub blocks.
3572
+ def each_node_deep(&ruby_block)
3573
+ # No ruby block? Return an enumerator.
3574
+ return to_enum(:each_node_deep) unless ruby_block
3575
+ # A ruby block?
3576
+ # Apply it on current.
3577
+ ruby_block.call(self)
3578
+ # And apply it on each statement deeply.
3579
+ self.each_statement do |stmnt|
3580
+ stmnt.each_node_deep(&ruby_block)
3581
+ end
3582
+ end
3583
+
3584
+ # Clones (deeply)
3585
+ def clone
3586
+ # Creates the new block.
3587
+ nblock = Block.new(self.mode,self.name)
3588
+ # Duplicate its content.
3589
+ self.each_statement do |statement|
3590
+ nblock.add_statement(statement.clone)
3591
+ end
3592
+ return nblock
3593
+ end
3594
+ end
3595
+
3596
+ # Describes a timed block.
3597
+ #
3598
+ # NOTE:
3599
+ # * this is the only kind of block that can include time statements.
3600
+ # * this kind of block is not synthesizable!
3601
+ class TimeBlock < Block
3602
+ # Adds a +statement+.
3603
+ #
3604
+ # NOTE: TimeBlock is supported.
3605
+ def add_statement(statement)
3606
+ unless statement.is_a?(Statement) then
3607
+ raise AnyError,
3608
+ "Invalid class for a statement: #{statement.class}"
3609
+ end
3610
+ @statements << statement
3611
+ # And set its parent.
3612
+ statement.parent = self
3613
+ statement
3614
+ end
3615
+
3616
+ # Comparison for hash: structural comparison.
3617
+ def eql?(obj)
3618
+ return false unless obj.is_a?(TimeBlock)
3619
+ return super(obj)
3620
+ end
3621
+
3622
+ # Hash function.
3623
+ def hash
3624
+ return super
3625
+ end
3626
+ end
3627
+
3628
+
3629
+ ##
3630
+ # Describes a connection.
3631
+ #
3632
+ # NOTE: eventhough a connection is semantically different from a
3633
+ # transmission, it has a common structure. Therefore, it is described
3634
+ # as a subclass of a transmit.
3635
+ class Connection < Transmit
3636
+
3637
+ # Comparison for hash: structural comparison.
3638
+ def eql?(obj)
3639
+ return false unless obj.is_a?(Connection)
3640
+ return super(obj)
3641
+ end
3642
+
3643
+ # Hash function.
3644
+ def hash
3645
+ return super
3646
+ end
3647
+ end
3648
+
3649
+
3650
+
3651
+ ##
3652
+ # Describes an expression.
3653
+ #
3654
+ # NOTE: this is an abstract class which is not to be used directly.
3655
+ class Expression
3656
+
3657
+ include Hparent
3658
+
3659
+ # # Gets the type of the expression.
3660
+ # def type
3661
+ # # By default: the void type.
3662
+ # return Void
3663
+ # end
3664
+
3665
+ attr_reader :type
3666
+
3667
+ # Creates a new Expression with +type+
3668
+ def initialize(type = Void)
3669
+ # Check and set the type.
3670
+ if type.is_a?(Type) then
3671
+ @type = type
3672
+ else
3673
+ raise AnyError, "Invalid class for a type: #{type.class}."
3674
+ end
3675
+ end
3676
+
3677
+ # Comparison for hash: structural comparison.
3678
+ def eql?(obj)
3679
+ return false unless obj.is_a?(Expression)
3680
+ return false unless @type.eql?(obj.type)
3681
+ return true
3682
+ end
3683
+
3684
+ # Hash function.
3685
+ def hash
3686
+ return [@type].hash
3687
+ end
3688
+
3689
+ # Tells if the expression is a left value of an assignment.
3690
+ def leftvalue?
3691
+ # Maybe its the left of a left value.
3692
+ if parent.respond_to?(:leftvalue?) && parent.leftvalue? then
3693
+ # Yes so it is also a left value if it is a sub ref.
3694
+ if parent.respond_to?(:ref) then
3695
+ # It might nor be a sub ref.
3696
+ return parent.ref == self
3697
+ else
3698
+ # It is necessarily a sub ref (case of RefConcat for now).
3699
+ return true
3700
+ end
3701
+ end
3702
+ # No, therefore maybe it is directly a left value.
3703
+ return (parent.is_a?(Transmit) || parent.is_a?(Connection)) &&
3704
+ parent.left == self
3705
+ end
3706
+
3707
+ # Tells if the expression is a right value.
3708
+ def rightvalue?
3709
+ return !self.leftvalue?
3710
+ end
3711
+
3712
+ # Iterates over the expression children if any.
3713
+ def each_node(&ruby_block)
3714
+ # By default: no child.
3715
+ end
3716
+
3717
+ alias_method :each_expression, :each_node
3718
+
3719
+ # Iterates over the nodes deeply if any.
3720
+ def each_node_deep(&ruby_block)
3721
+ # No ruby block? Return an enumerator.
3722
+ return to_enum(:each_node_deep) unless ruby_block
3723
+ # A ruby block? First apply it to current.
3724
+ ruby_block.call(self)
3725
+ # And that's all.
3726
+ end
3727
+
3728
+ # Iterates over all the references encountered in the expression.
3729
+ #
3730
+ # NOTE: do not iterate *inside* the references.
3731
+ def each_ref_deep(&ruby_block)
3732
+ # No ruby block? Return an enumerator.
3733
+ return to_enum(:each_ref_deep) unless ruby_block
3734
+ # puts "each_ref_deep for Expression which is:#{self}"
3735
+ # A ruby block?
3736
+ # If the expression is a reference, applies ruby_block on it.
3737
+ ruby_block.call(self) if self.is_a?(Ref)
3738
+ end
3739
+
3740
+ # Get the statement of the expression.
3741
+ def statement
3742
+ if self.parent.is_a?(Statement)
3743
+ return self.parent
3744
+ else
3745
+ return self.parent.statement
3746
+ end
3747
+ end
3748
+
3749
+ # Clones the expression (deeply)
3750
+ def clone
3751
+ raise AnyError,
3752
+ "Internal error: clone not defined for class: #{self.class}"
3753
+ end
3754
+ end
3755
+
3756
+
3757
+ ##
3758
+ # Describes a value.
3759
+ class Value < Expression
3760
+
3761
+ # Moved to Expression
3762
+ # # The type of value.
3763
+ # attr_reader :type
3764
+
3765
+ # The content of the value.
3766
+ attr_reader :content
3767
+
3768
+ # Creates a new value typed +type+ and containing +content+.
3769
+ def initialize(type,content)
3770
+ # Moved to Expression.
3771
+ # # Check and set the type.
3772
+ # if type.is_a?(Type) then
3773
+ # @type = type
3774
+ # else
3775
+ # raise AnyError, "Invalid class for a type: #{type.class}."
3776
+ # end
3777
+ super(type)
3778
+ # Checks and set the content: Ruby Numeric and HDLRuby BitString
3779
+ # are supported. Strings or equivalent are converted to BitString.
3780
+ unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString)
3781
+ content = HDLRuby::BitString.new(content.to_s)
3782
+ end
3783
+ @content = content
3784
+ end
3785
+
3786
+ # Comparison for hash: structural comparison.
3787
+ def eql?(obj)
3788
+ # General comparison.
3789
+ return false unless super(obj)
3790
+ # Specific comparison.
3791
+ return false unless obj.is_a?(Value)
3792
+ return false unless @content.eql?(obj.content)
3793
+ return true
3794
+ end
3795
+
3796
+ # Hash function.
3797
+ def hash
3798
+ return [super,@content].hash
3799
+ end
3800
+
3801
+
3802
+ # Compare values.
3803
+ #
3804
+ # NOTE: mainly used for being supported by ranges.
3805
+ def <=>(value)
3806
+ value = value.content if value.respond_to?(:content)
3807
+ return self.content <=> value
3808
+ end
3809
+
3810
+ # Gets the bit width of the value.
3811
+ def width
3812
+ return @type.width
3813
+ end
3814
+
3815
+ # Tells if the value is even.
3816
+ def even?
3817
+ return @content.even?
3818
+ end
3819
+
3820
+ # Tells if the value is odd.
3821
+ def odd?
3822
+ return @content.odd?
3823
+ end
3824
+
3825
+ # Converts to integer.
3826
+ def to_i
3827
+ return @content.to_i
3828
+ end
3829
+
3830
+ # Clones the value (deeply)
3831
+ def clone
3832
+ return Value.new(@type,@content)
3833
+ end
3834
+ end
3835
+
3836
+ ##
3837
+ # Describes a cast.
3838
+ class Cast < Expression
3839
+ # The child
3840
+ attr_reader :child
3841
+
3842
+ # Creates a new cast of +child+ to +type+.
3843
+ def initialize(type,child)
3844
+ # Create the expression and set the type
3845
+ super(type)
3846
+ # Check and set the child.
3847
+ unless child.is_a?(Expression)
3848
+ raise AnyError,"Invalid class for an expression: #{child.class}"
3849
+ end
3850
+ @child = child
3851
+ # And set its parent.
3852
+ child.parent = self
3853
+ end
3854
+
3855
+ # Comparison for hash: structural comparison.
3856
+ def eql?(obj)
3857
+ # General comparison.
3858
+ return false unless super(obj)
3859
+ # Specific comparison.
3860
+ return false unless obj.is_a?(Cast)
3861
+ return false unless @child.eql?(obj.child)
3862
+ return true
3863
+ end
3864
+
3865
+ # Hash function.
3866
+ def hash
3867
+ return [super,@child].hash
3868
+ end
3869
+
3870
+ # Iterates over the expression children if any.
3871
+ def each_node(&ruby_block)
3872
+ # No ruby block? Return an enumerator.
3873
+ return to_enum(:each_node) unless ruby_block
3874
+ # A ruby block? Apply it on the child.
3875
+ ruby_block.call(@child)
3876
+ end
3877
+
3878
+ alias_method :each_expression, :each_node
3879
+
3880
+ # Iterates over the nodes deeply if any.
3881
+ def each_node_deep(&ruby_block)
3882
+ # No ruby block? Return an enumerator.
3883
+ return to_enum(:each_node_deep) unless ruby_block
3884
+ # A ruby block? First apply it to current.
3885
+ ruby_block.call(self)
3886
+ # And recurse on the child.
3887
+ @child.each_node_deep(&ruby_block)
3888
+ end
3889
+
3890
+ # Iterates over all the references encountered in the expression.
3891
+ #
3892
+ # NOTE: do not iterate *inside* the references.
3893
+ def each_ref_deep(&ruby_block)
3894
+ # No ruby block? Return an enumerator.
3895
+ return to_enum(:each_ref_deep) unless ruby_block
3896
+ # puts "each_ref_deep for Unary"
3897
+ # A ruby block?
3898
+ # Recurse on the child.
3899
+ @child.each_ref_deep(&ruby_block)
3900
+ end
3901
+
3902
+ # Clones the value (deeply)
3903
+ def clone
3904
+ return Cast.new(@type,@child.clone)
3905
+ end
3906
+ end
3907
+
3908
+
3909
+ ##
3910
+ # Describes an operation.
3911
+ #
3912
+ # NOTE: this is an abstract class which is not to be used directly.
3913
+ class Operation < Expression
3914
+
3915
+ # The operator of the operation.
3916
+ attr_reader :operator
3917
+
3918
+ # Creates a new operation with +type+ applying +operator+.
3919
+ # def initialize(operator)
3920
+ def initialize(type,operator)
3921
+ super(type)
3922
+ # Check and set the operator.
3923
+ @operator = operator.to_sym
3924
+ end
3925
+
3926
+ # Comparison for hash: structural comparison.
3927
+ def eql?(obj)
3928
+ # General comparison.
3929
+ return false unless super(obj)
3930
+ # Specific comparison.
3931
+ return false unless obj.is_a?(Operation)
3932
+ return false unless @operator.eql?(obj.operator)
3933
+ return true
3934
+ end
3935
+
3936
+ # Hash function.
3937
+ def hash
3938
+ return [super,@operator].hash
3939
+ end
3940
+ end
3941
+
3942
+
3943
+ ##
3944
+ # Describes an unary operation.
3945
+ class Unary < Operation
3946
+ # The child.
3947
+ attr_reader :child
3948
+
3949
+ # Creates a new unary expression with +type+ applying +operator+ on
3950
+ # +child+ expression.
3951
+ # def initialize(operator,child)
3952
+ def initialize(type,operator,child)
3953
+ # Initialize as a general operation.
3954
+ super(type,operator)
3955
+ # Check and set the child.
3956
+ unless child.is_a?(Expression)
3957
+ raise AnyError,
3958
+ "Invalid class for an expression: #{child.class}"
3959
+ end
3960
+ @child = child
3961
+ # And set its parent.
3962
+ child.parent = self
3963
+ end
3964
+
3965
+ # Comparison for hash: structural comparison.
3966
+ def eql?(obj)
3967
+ # General comparison.
3968
+ return false unless super(obj)
3969
+ # Specific comparison.
3970
+ return false unless obj.is_a?(Unary)
3971
+ return false unless @child.eql?(obj.child)
3972
+ return true
3973
+ end
3974
+
3975
+ # Hash function.
3976
+ def hash
3977
+ return [super,@child].hash
3978
+ end
3979
+
3980
+ # Iterates over the expression children if any.
3981
+ def each_node(&ruby_block)
3982
+ # No ruby block? Return an enumerator.
3983
+ return to_enum(:each_node) unless ruby_block
3984
+ # A ruby block? Apply it on the child.
3985
+ ruby_block.call(@child)
3986
+ end
3987
+
3988
+ alias_method :each_expression, :each_node
3989
+
3990
+ # Iterates over the nodes deeply if any.
3991
+ def each_node_deep(&ruby_block)
3992
+ # No ruby block? Return an enumerator.
3993
+ return to_enum(:each_node_deep) unless ruby_block
3994
+ # A ruby block? First apply it to current.
3995
+ ruby_block.call(self)
3996
+ # And recurse on the child.
3997
+ @child.each_node_deep(&ruby_block)
3998
+ end
3999
+
4000
+ # Iterates over all the references encountered in the expression.
4001
+ #
4002
+ # NOTE: do not iterate *inside* the references.
4003
+ def each_ref_deep(&ruby_block)
4004
+ # No ruby block? Return an enumerator.
4005
+ return to_enum(:each_ref_deep) unless ruby_block
4006
+ # puts "each_ref_deep for Unary"
4007
+ # A ruby block?
4008
+ # Recurse on the child.
4009
+ @child.each_ref_deep(&ruby_block)
4010
+ end
4011
+
4012
+ # Clones the unary operator (deeply)
4013
+ def clone
4014
+ return Unary.new(@type,self.operator,@child.clone)
4015
+ end
4016
+ end
4017
+
4018
+
4019
+ ##
4020
+ # Describes an binary operation.
4021
+ class Binary < Operation
4022
+ # The left child.
4023
+ attr_reader :left
4024
+
4025
+ # The right child.
4026
+ attr_reader :right
4027
+
4028
+ # Creates a new binary expression with +type+ applying +operator+ on
4029
+ # +left+ and +right+ children expressions.
4030
+ # def initialize(operator,left,right)
4031
+ def initialize(type,operator,left,right)
4032
+ # Initialize as a general operation.
4033
+ super(type,operator)
4034
+ # Check and set the children.
4035
+ unless left.is_a?(Expression)
4036
+ raise AnyError, "Invalid class for an expression: #{left.class}"
4037
+ end
4038
+ unless right.is_a?(Expression)
4039
+ raise AnyError,"Invalid class for an expression: #{right.class}"
4040
+ end
4041
+ @left = left
4042
+ @right = right
4043
+ # And set their parents.
4044
+ left.parent = right.parent = self
4045
+ end
4046
+
4047
+ # Comparison for hash: structural comparison.
4048
+ def eql?(obj)
4049
+ # General comparison.
4050
+ return false unless super(obj)
4051
+ # Specific comparison.
4052
+ return false unless obj.is_a?(Binary)
4053
+ return false unless @left.eql?(obj.left)
4054
+ return false unless @right.eql?(obj.right)
4055
+ return true
4056
+ end
4057
+
4058
+ # Hash function.
4059
+ def hash
4060
+ return [super,@left,@right].hash
4061
+ end
4062
+
4063
+ # Iterates over the expression children if any.
4064
+ def each_node(&ruby_block)
4065
+ # No ruby block? Return an enumerator.
4066
+ return to_enum(:each_node) unless ruby_block
4067
+ # A ruby block? Apply it on the children.
4068
+ ruby_block.call(@left)
4069
+ ruby_block.call(@right)
4070
+ end
4071
+
4072
+ alias_method :each_expression, :each_node
4073
+
4074
+ # Iterates over the nodes deeply if any.
4075
+ def each_node_deep(&ruby_block)
4076
+ # No ruby block? Return an enumerator.
4077
+ return to_enum(:each_node_deep) unless ruby_block
4078
+ # A ruby block? First apply it to current.
4079
+ ruby_block.call(self)
4080
+ # And recurse on the children.
4081
+ @left.each_node_deep(&ruby_block)
4082
+ @right.each_node_deep(&ruby_block)
4083
+ end
4084
+
4085
+ # Iterates over all the references encountered in the expression.
4086
+ #
4087
+ # NOTE: do not iterate *inside* the references.
4088
+ def each_ref_deep(&ruby_block)
4089
+ # No ruby block? Return an enumerator.
4090
+ return to_enum(:each_ref_deep) unless ruby_block
4091
+ # puts "each_ref_deep for Binary"
4092
+ # A ruby block?
4093
+ # Recurse on the children.
4094
+ @left.each_ref_deep(&ruby_block)
4095
+ @right.each_ref_deep(&ruby_block)
4096
+ end
4097
+
4098
+ # Clones the binary operator (deeply)
4099
+ def clone
4100
+ return Binary.new(@type, self.operator,
4101
+ @left.clone, @right.clone)
4102
+ end
4103
+ end
4104
+
4105
+
4106
+ ##
4107
+ # Describes a section operation (generalization of the ternary operator).
4108
+ #
4109
+ # NOTE: choice is using the value of +select+ as an index.
4110
+ class Select < Operation
4111
+ # The selection child (connection).
4112
+ attr_reader :select
4113
+
4114
+ # Creates a new operator with +type+ selecting from the value of
4115
+ # +select+ one of the +choices+.
4116
+ # def initialize(operator,select,*choices)
4117
+ def initialize(type,operator,select,*choices)
4118
+ # Initialize as a general operation.
4119
+ # super(operator)
4120
+ super(type,operator)
4121
+ # Check and set the selection.
4122
+ unless select.is_a?(Expression)
4123
+ raise AnyError,
4124
+ "Invalid class for an expression: #{select.class}"
4125
+ end
4126
+ @select = select
4127
+ # And set its parent.
4128
+ select.parent = self
4129
+ # Check and set the choices.
4130
+ @choices = []
4131
+ choices.each do |choice|
4132
+ self.add_choice(choice)
4133
+ end
4134
+ end
4135
+
4136
+ # Comparison for hash: structural comparison.
4137
+ def eql?(obj)
4138
+ # General comparison.
4139
+ return false unless super(obj)
4140
+ # Specific comparison.
4141
+ return false unless obj.is_a?(Select)
4142
+ return false unless @select.eql?(obj.select)
4143
+ idx = 0
4144
+ obj.each_choice do |choice|
4145
+ return false unless @choices[idx].eql?(choice)
4146
+ idx += 1
4147
+ end
4148
+ return false unless idx == @choices.size
4149
+ return true
4150
+ end
4151
+
4152
+ # Hash function.
4153
+ def hash
4154
+ return [super,@select,@choices].hash
4155
+ end
4156
+
4157
+ # Adds a +choice+.
4158
+ def add_choice(choice)
4159
+ unless choice.is_a?(Expression)
4160
+ raise AnyError,
4161
+ "Invalid class for an expression: #{choice.class}"
4162
+ end
4163
+ # Set the parent of the choice.
4164
+ choice.parent = self
4165
+ # And add it.
4166
+ @choices << choice
4167
+ choice
4168
+ end
4169
+
4170
+ # Iterates over the choices.
4171
+ #
4172
+ # Returns an enumerator if no ruby block is given.
4173
+ def each_choice(&ruby_block)
4174
+ # No ruby block? Return an enumerator.
4175
+ return to_enum(:each_choice) unless ruby_block
4176
+ # A ruby block? Apply it on each choice.
4177
+ @choices.each(&ruby_block)
4178
+ end
4179
+
4180
+ # Gets a choice by +index+.
4181
+ def get_choice(index)
4182
+ return @choices[index]
4183
+ end
4184
+
4185
+ # Iterates over the expression children if any.
4186
+ def each_node(&ruby_block)
4187
+ # No ruby block? Return an enumerator.
4188
+ return to_enum(:each_node) unless ruby_block
4189
+ # A ruby block? Apply it on the children.
4190
+ ruby_block.call(@select)
4191
+ @choices.each(&ruby_block)
4192
+ end
4193
+
4194
+ alias_method :each_expression, :each_node
4195
+
4196
+ # Iterates over the nodes deeply if any.
4197
+ def each_node_deep(&ruby_block)
4198
+ # No ruby block? Return an enumerator.
4199
+ return to_enum(:each_node_deep) unless ruby_block
4200
+ # A ruby block? First apply it to current.
4201
+ ruby_block.call(self)
4202
+ # And recurse on the children.
4203
+ @select.each_node_deep(&ruby_block)
4204
+ @choices.each { |choice| choice.each_node_deep(&ruby_block) }
4205
+ end
4206
+
4207
+ # Iterates over all the references encountered in the expression.
4208
+ #
4209
+ # NOTE: do not iterate *inside* the references.
4210
+ def each_ref_deep(&ruby_block)
4211
+ # No ruby block? Return an enumerator.
4212
+ return to_enum(:each_ref_deep) unless ruby_block
4213
+ # puts "each_ref_deep for Select"
4214
+ # A ruby block?
4215
+ # Recurse on the children.
4216
+ self.select.each_ref_deep(&ruby_block)
4217
+ self.each_choice do |choice|
4218
+ choice.each_ref_deep(&ruby_block)
4219
+ end
4220
+ end
4221
+
4222
+ # Clones the select (deeply)
4223
+ def clone
4224
+ return Select.new(@type, self.operator, @select.clone,
4225
+ *@choices.map {|choice| choice.clone } )
4226
+ end
4227
+ end
4228
+
4229
+
4230
+ ##
4231
+ # Describes a concatenation expression.
4232
+ class Concat < Expression
4233
+ # Creates a new concatenation with +type+ of several +expressions+
4234
+ # together.
4235
+ # def initialize(expressions = [])
4236
+ def initialize(type,expressions = [])
4237
+ super(type)
4238
+ # Initialize the array of expressions that are concatenated.
4239
+ @expressions = []
4240
+ # Check and add the expressions.
4241
+ expressions.each { |expression| self.add_expression(expression) }
4242
+ end
4243
+
4244
+ # Comparison for hash: structural comparison.
4245
+ def eql?(obj)
4246
+ # General comparison.
4247
+ return false unless super(obj)
4248
+ # Specific comparison.
4249
+ return false unless obj.is_a?(Concat)
4250
+ idx = 0
4251
+ obj.each_expression do |expression|
4252
+ return false unless @expressions[idx].eql?(expression)
4253
+ idx += 1
4254
+ end
4255
+ return false unless idx == @expressions.size
4256
+ return true
4257
+ end
4258
+
4259
+ # Hash function.
4260
+ def hash
4261
+ return [super,@expressions].hash
4262
+ end
4263
+
4264
+ # Adds an +expression+ to concat.
4265
+ def add_expression(expression)
4266
+ # Check expression.
4267
+ unless expression.is_a?(Expression) then
4268
+ raise AnyError,
4269
+ "Invalid class for an expression: #{expression.class}"
4270
+ end
4271
+ # Add it.
4272
+ @expressions << expression
4273
+ # And set its parent.
4274
+ expression.parent = self
4275
+ expression
4276
+ end
4277
+
4278
+ # Iterates over the concatenated expressions.
4279
+ #
4280
+ # Returns an enumerator if no ruby block is given.
4281
+ def each_expression(&ruby_block)
4282
+ # No ruby block? Return an enumerator.
4283
+ return to_enum(:each_expression) unless ruby_block
4284
+ # A ruby block? Apply it on each children.
4285
+ @expressions.each(&ruby_block)
4286
+ end
4287
+ alias_method :each_node, :each_expression
4288
+
4289
+ # Iterates over the nodes deeply if any.
4290
+ def each_node_deep(&ruby_block)
4291
+ # No ruby block? Return an enumerator.
4292
+ return to_enum(:each_node_deep) unless ruby_block
4293
+ # A ruby block? First apply it to current.
4294
+ ruby_block.call(self)
4295
+ # And recurse on the children.
4296
+ self.each_expression do |expr|
4297
+ expr.each_node_deep(&ruby_block)
4298
+ end
4299
+ end
4300
+
4301
+ # Clones the concatenated expression (deeply)
4302
+ def clone
4303
+ return Concat.new(@type,
4304
+ @expressions.map {|expr| expr.clone } )
4305
+ end
4306
+ end
4307
+
4308
+
4309
+ ##
4310
+ # Describes a reference expression.
4311
+ #
4312
+ # NOTE: this is an abstract class which is not to be used directly.
4313
+ class Ref < Expression
4314
+
4315
+ # Comparison for hash: structural comparison.
4316
+ def eql?(obj)
4317
+ # General comparison.
4318
+ return false unless super(obj)
4319
+ # Specific comparison.
4320
+ return false unless obj.is_a?(Ref)
4321
+ return true
4322
+ end
4323
+
4324
+ # Hash function.
4325
+ def hash
4326
+ super
4327
+ end
4328
+
4329
+ # Iterates over the names of the path indicated by the reference.
4330
+ #
4331
+ # NOTE: this is not a method for iterating over all the names included
4332
+ # in the reference. For instance, this method will return nil without
4333
+ # iterating if a RefConcat or is met.
4334
+ #
4335
+ # Returns an enumerator if no ruby block is given.
4336
+ def path_each(&ruby_block)
4337
+ # No ruby block? Return an enumerator.
4338
+ return to_enum(:path_each) unless ruby_block
4339
+ # A ruby block? Apply it on... nothing by default.
4340
+ return nil
4341
+ end
4342
+
4343
+ # Iterates over the reference children if any.
4344
+ def each_node(&ruby_block)
4345
+ # No ruby block? Return an enumerator.
4346
+ return to_enum(:each_node) unless ruby_block
4347
+ # A ruby block? Apply it on the children: default none.
4348
+ end
4349
+
4350
+ alias_method :each_expression, :each_node
4351
+
4352
+ # Iterates over the nodes deeply if any.
4353
+ def each_node_deep(&ruby_block)
4354
+ # No ruby block? Return an enumerator.
4355
+ return to_enum(:each_node_deep) unless ruby_block
4356
+ # A ruby block? First apply it to current.
4357
+ ruby_block.call(self)
4358
+ # And that's all.
4359
+ end
4360
+ end
4361
+
4362
+
4363
+ ##
4364
+ # Describes concatenation reference.
4365
+ class RefConcat < Ref
4366
+
4367
+ # Creates a new reference with +type+ concatenating the references of
4368
+ # +refs+ together.
4369
+ # def initialize(refs = [])
4370
+ def initialize(type, refs = [])
4371
+ super(type)
4372
+ # Check and set the refs.
4373
+ refs.each do |ref|
4374
+ # puts "ref.class=#{ref.class}"
4375
+ unless ref.is_a?(Ref) then
4376
+ raise AnyError,
4377
+ "Invalid class for an reference: #{ref.class}"
4378
+ end
4379
+ end
4380
+ @refs = refs
4381
+ # And set their parents.
4382
+ refs.each { |ref| ref.parent = self }
4383
+ end
4384
+
4385
+ # Comparison for hash: structural comparison.
4386
+ def eql?(obj)
4387
+ # General comparison.
4388
+ return false unless super(obj)
4389
+ # Specific comparison.
4390
+ return false unless obj.is_a?(RefConcat)
4391
+ idx = 0
4392
+ obj.each_ref do |ref|
4393
+ return false unless @refs[idx].eql?(ref)
4394
+ idx += 1
4395
+ end
4396
+ return false unless idx == @refs.size
4397
+ return false unless @refs.eql?(obj.instance_variable_get(:@refs))
4398
+ return true
4399
+ end
4400
+
4401
+ # Hash function.
4402
+ def hash
4403
+ return [super,@refs].hash
4404
+ end
4405
+
4406
+ # Iterates over the concatenated references.
4407
+ #
4408
+ # Returns an enumerator if no ruby block is given.
4409
+ def each_ref(&ruby_block)
4410
+ # No ruby block? Return an enumerator.
4411
+ return to_enum(:each_ref) unless ruby_block
4412
+ # A ruby block? Apply it on each children.
4413
+ @refs.each(&ruby_block)
4414
+ end
4415
+ alias_method :each_node, :each_ref
4416
+
4417
+ # Adds an +ref+ to concat.
4418
+ def add_ref(ref)
4419
+ # Check ref.
4420
+ unless ref.is_a?(Ref) then
4421
+ raise AnyError,
4422
+ "Invalid class for an ref: #{ref.class}"
4423
+ end
4424
+ # Add it.
4425
+ @refs << ref
4426
+ # And set its parent.
4427
+ ref.parent = self
4428
+ ref
4429
+ end
4430
+
4431
+ # Iterates over the nodes deeply if any.
4432
+ def each_node_deep(&ruby_block)
4433
+ # No ruby block? Return an enumerator.
4434
+ return to_enum(:each_node_deep) unless ruby_block
4435
+ # A ruby block? First apply it to current.
4436
+ ruby_block.call(self)
4437
+ # And recurse on the sub references.
4438
+ self.each_ref do |ref|
4439
+ ref.each_node_deep(&ruby_block)
4440
+ end
4441
+ end
4442
+
4443
+ # Clones the concatenated references (deeply)
4444
+ def clone
4445
+ return RefConcat.new(@type, @refs.map { |ref| ref.clone } )
4446
+ end
4447
+ end
4448
+
4449
+
4450
+ ##
4451
+ # Describes a index reference.
4452
+ class RefIndex < Ref
4453
+ # The accessed reference.
4454
+ attr_reader :ref
4455
+
4456
+ # The access index.
4457
+ attr_reader :index
4458
+
4459
+ # Create a new index reference with +type+ accessing +ref+ at +index+.
4460
+ # def initialize(ref,index)
4461
+ def initialize(type,ref,index)
4462
+ super(type)
4463
+ # Check and set the accessed reference.
4464
+ unless ref.is_a?(Ref) then
4465
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
4466
+ end
4467
+ @ref = ref
4468
+ # And set its parent.
4469
+ ref.parent = self
4470
+ # Check and set the index.
4471
+ unless index.is_a?(Expression) then
4472
+ raise AnyError,
4473
+ "Invalid class for an index reference: #{index.class}."
4474
+ end
4475
+ @index = index
4476
+ # And set its parent.
4477
+ index.parent = self
4478
+ end
4479
+
4480
+ # Comparison for hash: structural comparison.
4481
+ def eql?(obj)
4482
+ # General comparison.
4483
+ return false unless super(obj)
4484
+ # Specific comparison.
4485
+ return false unless obj.is_a?(RefIndex)
4486
+ return false unless @index.eql?(obj.index)
4487
+ return false unless @ref.eql?(obj.ref)
4488
+ return true
4489
+ end
4490
+
4491
+ # Hash function.
4492
+ def hash
4493
+ return [super,@index,@ref].hash
4494
+ end
4495
+
4496
+ # Iterates over the names of the path indicated by the reference.
4497
+ #
4498
+ # Returns an enumerator if no ruby block is given.
4499
+ def path_each(&ruby_block)
4500
+ # Recurse on the base reference.
4501
+ return ref.path_each(&ruby_block)
4502
+ end
4503
+
4504
+ # Iterates over the reference children if any.
4505
+ def each_node(&ruby_block)
4506
+ # No ruby block? Return an enumerator.
4507
+ return to_enum(:each_node) unless ruby_block
4508
+ # A ruby block? Apply it on the index and the ref.
4509
+ ruby_block.call(@index)
4510
+ ruby_block.call(@ref)
4511
+ end
4512
+
4513
+ alias_method :each_expression, :each_node
4514
+
4515
+ # Iterates over the nodes deeply if any.
4516
+ def each_node_deep(&ruby_block)
4517
+ # No ruby block? Return an enumerator.
4518
+ return to_enum(:each_node_deep) unless ruby_block
4519
+ # A ruby block? First apply it to current.
4520
+ ruby_block.call(self)
4521
+ # And recurse on the children.
4522
+ @index.each_node_deep(&ruby_block)
4523
+ @ref.each_node_deep(&ruby_block)
4524
+ end
4525
+
4526
+ # Clones the indexed references (deeply)
4527
+ def clone
4528
+ return RefIndex.new(@type, @ref.clone, @index.clone)
4529
+ end
4530
+ end
4531
+
4532
+
4533
+ ##
4534
+ # Describes a range reference.
4535
+ class RefRange < Ref
4536
+ # The accessed reference.
4537
+ attr_reader :ref
4538
+
4539
+ # The access range.
4540
+ attr_reader :range
4541
+
4542
+ # Create a new range reference with +type+ accessing +ref+ at +range+.
4543
+ # def initialize(ref,range)
4544
+ def initialize(type,ref,range)
4545
+ super(type)
4546
+ # Check and set the refered object.
4547
+ # unless ref.is_a?(Ref) then
4548
+ unless ref.is_a?(Expression) then
4549
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
4550
+ end
4551
+ @ref = ref
4552
+ # And set its parent.
4553
+ ref.parent = self
4554
+ # Check and set the range.
4555
+ first = range.first
4556
+ unless first.is_a?(Expression) then
4557
+ raise AnyError,
4558
+ "Invalid class for a range first: #{first.class}."
4559
+ end
4560
+ last = range.last
4561
+ unless last.is_a?(Expression) then
4562
+ raise AnyError, "Invalid class for a range last: #{last.class}."
4563
+ end
4564
+ @range = first..last
4565
+ # And set their parents.
4566
+ first.parent = last.parent = self
4567
+ end
4568
+
4569
+ # Comparison for hash: structural comparison.
4570
+ #
4571
+ # NOTE: ranges are assumed to be flattened (a range of range is
4572
+ # a range of same level).
4573
+ def eql?(obj)
4574
+ # General comparison.
4575
+ return false unless super(obj)
4576
+ # Specific comparison.
4577
+ return false unless obj.is_a?(RefRange)
4578
+ return false unless @range.first.eql?(obj.range.first)
4579
+ return false unless @range.last.eql?(obj.range.last)
4580
+ return false unless @ref.eql?(obj.ref)
4581
+ return true
4582
+ end
4583
+
4584
+ # Hash function.
4585
+ def hash
4586
+ return [super,@range,@ref].hash
4587
+ end
4588
+
4589
+ # Iterates over the names of the path indicated by the reference.
4590
+ #
4591
+ # Returns an enumerator if no ruby block is given.
4592
+ def path_each(&ruby_block)
4593
+ # Recurse on the base reference.
4594
+ return ref.path_each(&ruby_block)
4595
+ end
4596
+
4597
+ # Iterates over the reference children if any.
4598
+ def each_node(&ruby_block)
4599
+ # No ruby block? Return an enumerator.
4600
+ return to_enum(:each_node) unless ruby_block
4601
+ # A ruby block? Apply it on the ranfe and the ref.
4602
+ ruby_block.call(@range.first)
4603
+ ruby_block.call(@range.last)
4604
+ ruby_block.call(@ref)
4605
+ end
4606
+
4607
+ alias_method :each_expression, :each_node
4608
+
4609
+ # Iterates over the nodes deeply if any.
4610
+ def each_node_deep(&ruby_block)
4611
+ # No ruby block? Return an enumerator.
4612
+ return to_enum(:each_node_deep) unless ruby_block
4613
+ # A ruby block? First apply it to current.
4614
+ ruby_block.call(self)
4615
+ # And recurse on the children.
4616
+ @range.first.each_node_deep(&ruby_block)
4617
+ @range.last.each_node_deep(&ruby_block)
4618
+ @ref.each_node_deep(&ruby_block)
4619
+ end
4620
+
4621
+ # Clones the range references (deeply)
4622
+ def clone
4623
+ return RefRange.new(@type, @ref.clone,
4624
+ (@range.first.clone)..(@range.last.clone) )
4625
+ end
4626
+ end
4627
+
4628
+
4629
+ ##
4630
+ # Describes a name reference.
4631
+ class RefName < Ref
4632
+ # The accessed reference.
4633
+ attr_reader :ref
4634
+
4635
+ # The access name.
4636
+ attr_reader :name
4637
+
4638
+ # Create a new named reference with +type+ accessing +ref+ with +name+.
4639
+ # def initialize(ref,name)
4640
+ def initialize(type,ref,name)
4641
+ super(type)
4642
+ # Check and set the accessed reference.
4643
+ unless ref.is_a?(Ref) then
4644
+ raise AnyError, "Invalid class for a reference: #{ref.class}."
4645
+ end
4646
+ @ref = ref
4647
+ # And set its parent.
4648
+ ref.parent = self
4649
+ # Check and set the symbol.
4650
+ @name = name.to_sym
4651
+ end
4652
+
4653
+ # Get the full name of the reference, i.e. including the sub ref
4654
+ # names if any.
4655
+ def full_name
4656
+ name = self.ref.respond_to?(:full_name) ? self.ref.full_name : :""
4657
+ return :"#{name}::#{self.name}"
4658
+ end
4659
+
4660
+ # Comparison for hash: structural comparison.
4661
+ def eql?(obj)
4662
+ # General comparison.
4663
+ return false unless super(obj)
4664
+ # Specific comparison.
4665
+ return false unless obj.is_a?(RefName)
4666
+ return false unless @name.eql?(obj.name)
4667
+ return false unless @ref.eql?(obj.ref)
4668
+ return true
4669
+ end
4670
+
4671
+ # Hash function.
4672
+ def hash
4673
+ return [super,@name,@ref].hash
4674
+ end
4675
+
4676
+ # Iterates over the names of the path indicated by the reference.
4677
+ #
4678
+ # Returns an enumerator if no ruby block is given.
4679
+ def path_each(&ruby_block)
4680
+ # No ruby block? Return an enumerator.
4681
+ return to_enum(:path_each) unless ruby_block
4682
+ # Recurse on the base reference.
4683
+ ref.path_each(&ruby_block)
4684
+ # Applies the block on the current name.
4685
+ ruby_block.call(@name)
4686
+ end
4687
+
4688
+ # Iterates over the reference children if any.
4689
+ def each_node(&ruby_block)
4690
+ # No ruby block? Return an enumerator.
4691
+ return to_enum(:each_node) unless ruby_block
4692
+ # A ruby block? Apply it on the child.
4693
+ ruby_block.call(@ref)
4694
+ end
4695
+
4696
+ alias_method :each_expression, :each_node
4697
+
4698
+ # Iterates over the nodes deeply if any.
4699
+ def each_node_deep(&ruby_block)
4700
+ # No ruby block? Return an enumerator.
4701
+ return to_enum(:each_node_deep) unless ruby_block
4702
+ # A ruby block? First apply it to current.
4703
+ ruby_block.call(self)
4704
+ # And recurse on the child.
4705
+ @ref.each_node_deep(&ruby_block)
4706
+ end
4707
+
4708
+ # Clones the name references (deeply)
4709
+ def clone
4710
+ return RefName.new(@type, @ref.clone, @name)
4711
+ end
4712
+ end
4713
+
4714
+
4715
+ ##
4716
+ # Describe a this reference.
4717
+ #
4718
+ # This is the current system.
4719
+ class RefThis < Ref
4720
+ # Clones this.
4721
+ def clone
4722
+ return RefThis.new
4723
+ end
4724
+
4725
+ # Comparison for hash: structural comparison.
4726
+ def eql?(obj)
4727
+ return obj.is_a?(RefThis)
4728
+ end
4729
+
4730
+ # Hash function.
4731
+ def hash
4732
+ return super
4733
+ end
4734
+ end
4735
+ end