HDLRuby 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/HDLRuby.gemspec +36 -0
- data/LICENSE.txt +21 -0
- data/README.md +2774 -0
- data/README.pdf +0 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/hdrcc +3 -0
- data/lib/HDLRuby/alcc.rb +137 -0
- data/lib/HDLRuby/backend/hruby_allocator.rb +69 -0
- data/lib/HDLRuby/backend/hruby_c_allocator.rb +76 -0
- data/lib/HDLRuby/hdr_samples/adder.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_assign_error.rb +11 -0
- data/lib/HDLRuby/hdr_samples/adder_bench.rb +27 -0
- data/lib/HDLRuby/hdr_samples/adder_gen.rb +7 -0
- data/lib/HDLRuby/hdr_samples/adder_nodef_error.rb +7 -0
- data/lib/HDLRuby/hdr_samples/addsub.rb +19 -0
- data/lib/HDLRuby/hdr_samples/addsubz.rb +22 -0
- data/lib/HDLRuby/hdr_samples/alu.rb +47 -0
- data/lib/HDLRuby/hdr_samples/calculator.rb +48 -0
- data/lib/HDLRuby/hdr_samples/counter_bench.rb +83 -0
- data/lib/HDLRuby/hdr_samples/dff.rb +9 -0
- data/lib/HDLRuby/hdr_samples/dff_bench.rb +66 -0
- data/lib/HDLRuby/hdr_samples/dff_counter.rb +20 -0
- data/lib/HDLRuby/hdr_samples/include.rb +14 -0
- data/lib/HDLRuby/hdr_samples/instance_open.rb +23 -0
- data/lib/HDLRuby/hdr_samples/mei8.rb +256 -0
- data/lib/HDLRuby/hdr_samples/mei8_bench.rb +309 -0
- data/lib/HDLRuby/hdr_samples/multer_gen.rb +8 -0
- data/lib/HDLRuby/hdr_samples/multer_seq.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/a.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/a_sub.rb +5 -0
- data/lib/HDLRuby/hdr_samples/neural/bw.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/counter.rb +16 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz.rb +9 -0
- data/lib/HDLRuby/hdr_samples/neural/dadz_sub.rb +4 -0
- data/lib/HDLRuby/hdr_samples/neural/forward.rb +153 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub.rb +62 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand.rb +41 -0
- data/lib/HDLRuby/hdr_samples/neural/forward_sub_rand_typedef.rb +47 -0
- data/lib/HDLRuby/hdr_samples/neural/mem.rb +30 -0
- data/lib/HDLRuby/hdr_samples/neural/random.rb +23 -0
- data/lib/HDLRuby/hdr_samples/neural/selector.rb +29 -0
- data/lib/HDLRuby/hdr_samples/neural/sigmoid.rb +20 -0
- data/lib/HDLRuby/hdr_samples/neural/z.rb +33 -0
- data/lib/HDLRuby/hdr_samples/prog.obj +256 -0
- data/lib/HDLRuby/hdr_samples/ram.rb +18 -0
- data/lib/HDLRuby/hdr_samples/register_with_code_bench.rb +98 -0
- data/lib/HDLRuby/hdr_samples/rom.rb +10 -0
- data/lib/HDLRuby/hdr_samples/struct.rb +14 -0
- data/lib/HDLRuby/hdr_samples/sumprod.rb +29 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_bench.rb +103 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpu_bench.rb +261 -0
- data/lib/HDLRuby/hdr_samples/sw_encrypt_cpusim_bench.rb +302 -0
- data/lib/HDLRuby/hdr_samples/system_open.rb +11 -0
- data/lib/HDLRuby/hdr_samples/tuple.rb +16 -0
- data/lib/HDLRuby/hdr_samples/with_channel.rb +118 -0
- data/lib/HDLRuby/hdr_samples/with_class.rb +199 -0
- data/lib/HDLRuby/hdr_samples/with_decoder.rb +17 -0
- data/lib/HDLRuby/hdr_samples/with_fsm.rb +34 -0
- data/lib/HDLRuby/hdr_samples/with_reconf.rb +103 -0
- data/lib/HDLRuby/hdrcc.rb +623 -0
- data/lib/HDLRuby/high_samples/_adder_fault.rb +23 -0
- data/lib/HDLRuby/high_samples/_generic_transmission2.rb +146 -0
- data/lib/HDLRuby/high_samples/adder.rb +21 -0
- data/lib/HDLRuby/high_samples/adder_common_errors.rb +25 -0
- data/lib/HDLRuby/high_samples/addsub.rb +33 -0
- data/lib/HDLRuby/high_samples/addsubz.rb +37 -0
- data/lib/HDLRuby/high_samples/after.rb +28 -0
- data/lib/HDLRuby/high_samples/all_signals.rb +29 -0
- data/lib/HDLRuby/high_samples/alu.rb +61 -0
- data/lib/HDLRuby/high_samples/anonymous.rb +41 -0
- data/lib/HDLRuby/high_samples/before.rb +28 -0
- data/lib/HDLRuby/high_samples/blockblock.rb +26 -0
- data/lib/HDLRuby/high_samples/bugs/dadz.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/misample_instan.rb +20 -0
- data/lib/HDLRuby/high_samples/bugs/misample_updown.rb +22 -0
- data/lib/HDLRuby/high_samples/bugs/sample_add.rb +16 -0
- data/lib/HDLRuby/high_samples/bugs/sample_barrel.rb +13 -0
- data/lib/HDLRuby/high_samples/bugs/sample_daice.rb +57 -0
- data/lib/HDLRuby/high_samples/bugs/sample_kumiawase.rb +52 -0
- data/lib/HDLRuby/high_samples/bugs/sample_multi.rb +18 -0
- data/lib/HDLRuby/high_samples/bugs/sample_sub.rb +14 -0
- data/lib/HDLRuby/high_samples/bugs/z2.rb +32 -0
- data/lib/HDLRuby/high_samples/case.rb +32 -0
- data/lib/HDLRuby/high_samples/case2.rb +30 -0
- data/lib/HDLRuby/high_samples/change.rb +23 -0
- data/lib/HDLRuby/high_samples/clocks.rb +35 -0
- data/lib/HDLRuby/high_samples/comparer.rb +21 -0
- data/lib/HDLRuby/high_samples/conditionals.rb +29 -0
- data/lib/HDLRuby/high_samples/dff.rb +23 -0
- data/lib/HDLRuby/high_samples/each.rb +28 -0
- data/lib/HDLRuby/high_samples/exporter.rb +42 -0
- data/lib/HDLRuby/high_samples/functions.rb +60 -0
- data/lib/HDLRuby/high_samples/if_seq.rb +26 -0
- data/lib/HDLRuby/high_samples/inherit_as_dff.rb +32 -0
- data/lib/HDLRuby/high_samples/inherit_dff.rb +36 -0
- data/lib/HDLRuby/high_samples/instance.rb +37 -0
- data/lib/HDLRuby/high_samples/memory.rb +64 -0
- data/lib/HDLRuby/high_samples/multi_file.rb +27 -0
- data/lib/HDLRuby/high_samples/overload.rb +32 -0
- data/lib/HDLRuby/high_samples/paper_after.rb +49 -0
- data/lib/HDLRuby/high_samples/ram.rb +27 -0
- data/lib/HDLRuby/high_samples/registers.rb +139 -0
- data/lib/HDLRuby/high_samples/rom.rb +23 -0
- data/lib/HDLRuby/high_samples/scopeblockname.rb +37 -0
- data/lib/HDLRuby/high_samples/scopescope.rb +26 -0
- data/lib/HDLRuby/high_samples/shift.rb +31 -0
- data/lib/HDLRuby/high_samples/shift2.rb +40 -0
- data/lib/HDLRuby/high_samples/simple_instance.rb +31 -0
- data/lib/HDLRuby/high_samples/test_all.sh +10 -0
- data/lib/HDLRuby/high_samples/typedef.rb +24 -0
- data/lib/HDLRuby/high_samples/values.rb +70 -0
- data/lib/HDLRuby/high_samples/vector.rb +22 -0
- data/lib/HDLRuby/high_samples/with_decoder.rb +30 -0
- data/lib/HDLRuby/high_samples/with_fsm.rb +46 -0
- data/lib/HDLRuby/high_samples/with_pipe.rb +43 -0
- data/lib/HDLRuby/high_samples/with_seq.rb +25 -0
- data/lib/HDLRuby/hruby_bstr.rb +1085 -0
- data/lib/HDLRuby/hruby_check.rb +317 -0
- data/lib/HDLRuby/hruby_db.rb +432 -0
- data/lib/HDLRuby/hruby_error.rb +44 -0
- data/lib/HDLRuby/hruby_high.rb +4103 -0
- data/lib/HDLRuby/hruby_low.rb +4735 -0
- data/lib/HDLRuby/hruby_low2c.rb +1986 -0
- data/lib/HDLRuby/hruby_low2high.rb +738 -0
- data/lib/HDLRuby/hruby_low2seq.rb +248 -0
- data/lib/HDLRuby/hruby_low2sym.rb +126 -0
- data/lib/HDLRuby/hruby_low2vhd.rb +1437 -0
- data/lib/HDLRuby/hruby_low_bool2select.rb +295 -0
- data/lib/HDLRuby/hruby_low_cleanup.rb +193 -0
- data/lib/HDLRuby/hruby_low_fix_types.rb +437 -0
- data/lib/HDLRuby/hruby_low_mutable.rb +1803 -0
- data/lib/HDLRuby/hruby_low_resolve.rb +165 -0
- data/lib/HDLRuby/hruby_low_skeleton.rb +129 -0
- data/lib/HDLRuby/hruby_low_with_bool.rb +141 -0
- data/lib/HDLRuby/hruby_low_with_port.rb +167 -0
- data/lib/HDLRuby/hruby_low_with_var.rb +302 -0
- data/lib/HDLRuby/hruby_low_without_bit2vector.rb +88 -0
- data/lib/HDLRuby/hruby_low_without_concat.rb +162 -0
- data/lib/HDLRuby/hruby_low_without_connection.rb +113 -0
- data/lib/HDLRuby/hruby_low_without_namespace.rb +718 -0
- data/lib/HDLRuby/hruby_low_without_outread.rb +107 -0
- data/lib/HDLRuby/hruby_low_without_select.rb +206 -0
- data/lib/HDLRuby/hruby_serializer.rb +398 -0
- data/lib/HDLRuby/hruby_tools.rb +37 -0
- data/lib/HDLRuby/hruby_types.rb +239 -0
- data/lib/HDLRuby/hruby_values.rb +64 -0
- data/lib/HDLRuby/hruby_verilog.rb +1888 -0
- data/lib/HDLRuby/hruby_verilog_name.rb +52 -0
- data/lib/HDLRuby/low_samples/adder.yaml +97 -0
- data/lib/HDLRuby/low_samples/after.yaml +228 -0
- data/lib/HDLRuby/low_samples/before.yaml +223 -0
- data/lib/HDLRuby/low_samples/blockblock.yaml +48 -0
- data/lib/HDLRuby/low_samples/bugs/sample_add.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/sample_daice.yaml +444 -0
- data/lib/HDLRuby/low_samples/bugs/sample_kumiawase.yaml +332 -0
- data/lib/HDLRuby/low_samples/bugs/sample_sub.yaml +97 -0
- data/lib/HDLRuby/low_samples/bugs/seqpar.yaml +184 -0
- data/lib/HDLRuby/low_samples/case.yaml +327 -0
- data/lib/HDLRuby/low_samples/change.yaml +135 -0
- data/lib/HDLRuby/low_samples/clocks.yaml +674 -0
- data/lib/HDLRuby/low_samples/cloner.rb +22 -0
- data/lib/HDLRuby/low_samples/comparer.yaml +85 -0
- data/lib/HDLRuby/low_samples/conditionals.yaml +133 -0
- data/lib/HDLRuby/low_samples/dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/each.yaml +1328 -0
- data/lib/HDLRuby/low_samples/exporter.yaml +226 -0
- data/lib/HDLRuby/low_samples/functions.yaml +298 -0
- data/lib/HDLRuby/low_samples/generic_transmission.yaml +597 -0
- data/lib/HDLRuby/low_samples/inherit_as_dff.yaml +125 -0
- data/lib/HDLRuby/low_samples/inherit_dff.yaml +107 -0
- data/lib/HDLRuby/low_samples/load_yaml.rb +11 -0
- data/lib/HDLRuby/low_samples/memory.yaml +678 -0
- data/lib/HDLRuby/low_samples/namespace_extractor.rb +23 -0
- data/lib/HDLRuby/low_samples/overload.yaml +226 -0
- data/lib/HDLRuby/low_samples/paper_after.yaml +431 -0
- data/lib/HDLRuby/low_samples/port_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/ram.yaml +207 -0
- data/lib/HDLRuby/low_samples/registers.yaml +228 -0
- data/lib/HDLRuby/low_samples/rom.yaml +2950 -0
- data/lib/HDLRuby/low_samples/shift.yaml +230 -0
- data/lib/HDLRuby/low_samples/shift2.yaml +2095 -0
- data/lib/HDLRuby/low_samples/simple_instance.yaml +102 -0
- data/lib/HDLRuby/low_samples/test_all.sh +43 -0
- data/lib/HDLRuby/low_samples/typedef.yaml +115 -0
- data/lib/HDLRuby/low_samples/values.yaml +577 -0
- data/lib/HDLRuby/low_samples/variable_maker.rb +14 -0
- data/lib/HDLRuby/low_samples/vector.yaml +56 -0
- data/lib/HDLRuby/low_samples/with_seq.yaml +188 -0
- data/lib/HDLRuby/low_samples/yaml2hdr.rb +10 -0
- data/lib/HDLRuby/low_samples/yaml2vhd.rb +19 -0
- data/lib/HDLRuby/sim/Makefile +19 -0
- data/lib/HDLRuby/sim/hruby_sim.h +590 -0
- data/lib/HDLRuby/sim/hruby_sim_calc.c +2362 -0
- data/lib/HDLRuby/sim/hruby_sim_core.c +589 -0
- data/lib/HDLRuby/sim/hruby_sim_list.c +93 -0
- data/lib/HDLRuby/sim/hruby_sim_vizualize.c +91 -0
- data/lib/HDLRuby/sim/hruby_value_pool.c +64 -0
- data/lib/HDLRuby/std/channel.rb +354 -0
- data/lib/HDLRuby/std/clocks.rb +165 -0
- data/lib/HDLRuby/std/counters.rb +82 -0
- data/lib/HDLRuby/std/decoder.rb +214 -0
- data/lib/HDLRuby/std/fsm.rb +516 -0
- data/lib/HDLRuby/std/pipeline.rb +220 -0
- data/lib/HDLRuby/std/reconf.rb +309 -0
- data/lib/HDLRuby/test_hruby_bstr.rb +2259 -0
- data/lib/HDLRuby/test_hruby_high.rb +594 -0
- data/lib/HDLRuby/test_hruby_high_low.rb +99 -0
- data/lib/HDLRuby/test_hruby_low.rb +934 -0
- data/lib/HDLRuby/v_samples/adder.v +10 -0
- data/lib/HDLRuby/v_samples/dff.v +12 -0
- data/lib/HDLRuby/v_samples/ram.v +20 -0
- data/lib/HDLRuby/v_samples/rom.v +270 -0
- data/lib/HDLRuby/version.rb +3 -0
- data/lib/HDLRuby.rb +11 -0
- data/makedoc +1 -0
- data/metadata.yaml +4 -0
- 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
|