HDLRuby 2.0.8

Sign up to get free protection for your applications and to get access to all the features.
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