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,1803 @@
|
|
|
1
|
+
require "HDLRuby/hruby_error"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Make HDLRuby::Low objects mutable trough "!" methods.
|
|
7
|
+
#
|
|
8
|
+
# NOTE: * should be used with care, since it can comprimize the internal
|
|
9
|
+
# structures.
|
|
10
|
+
# * this is a work in progress.
|
|
11
|
+
#
|
|
12
|
+
########################################################################
|
|
13
|
+
module HDLRuby::Low
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# Describes a system type.
|
|
17
|
+
#
|
|
18
|
+
# NOTE: delegates its content-related methods to its Scope object.
|
|
19
|
+
class SystemT
|
|
20
|
+
|
|
21
|
+
# Sets the +name+.
|
|
22
|
+
def set_name!(name)
|
|
23
|
+
@name = name.to_sym
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Sets the +scope+.
|
|
27
|
+
def set_scope!(scope)
|
|
28
|
+
unless scope.is_a?(Scope) then
|
|
29
|
+
raise AnyError, "Invalid class for a scope: #{scope.class}"
|
|
30
|
+
end
|
|
31
|
+
scope.parent = self
|
|
32
|
+
@scope = scope
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Maps on the inputs.
|
|
36
|
+
def map_inputs!(&ruby_block)
|
|
37
|
+
@inputs.map! do |input|
|
|
38
|
+
input = ruby_block.call(input)
|
|
39
|
+
input.parent = self unless input.parent
|
|
40
|
+
input
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Maps on the outputs.
|
|
45
|
+
def map_outputs!(&ruby_block)
|
|
46
|
+
@outputs.map! do |output|
|
|
47
|
+
output = ruby_block.call(output)
|
|
48
|
+
output.parent = self unless output.parent
|
|
49
|
+
output
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Maps on the inouts.
|
|
54
|
+
def map_inouts!(&ruby_block)
|
|
55
|
+
@inouts.map! do |inout|
|
|
56
|
+
inout = ruby_block.call(inout)
|
|
57
|
+
inout.parent = self unless inout.parent
|
|
58
|
+
inout
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Deletes an input.
|
|
63
|
+
def delete_input!(signal)
|
|
64
|
+
if @inputs.key?(signal.name) then
|
|
65
|
+
# The signal is present, delete it.
|
|
66
|
+
@inputs.delete(signal.name)
|
|
67
|
+
@interface.delete(signal)
|
|
68
|
+
# And remove its parent.
|
|
69
|
+
signal.parent = nil
|
|
70
|
+
end
|
|
71
|
+
signal
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Deletes an output.
|
|
75
|
+
def delete_output!(signal)
|
|
76
|
+
if @outputs.key?(signal.name) then
|
|
77
|
+
# The signal is present, delete it.
|
|
78
|
+
@outputs.delete(signal.name)
|
|
79
|
+
@interface.delete(signal)
|
|
80
|
+
# And remove its parent.
|
|
81
|
+
signal.parent = nil
|
|
82
|
+
end
|
|
83
|
+
signal
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Deletes an inout.
|
|
87
|
+
def delete_inout!(signal)
|
|
88
|
+
if @inouts.key?(signal.name) then
|
|
89
|
+
# The signal is present, delete it.
|
|
90
|
+
@inouts.delete(signal.name)
|
|
91
|
+
@interface.delete(signal)
|
|
92
|
+
# And remove its parent.
|
|
93
|
+
signal.parent = nil
|
|
94
|
+
end
|
|
95
|
+
signal
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Describes scopes of system types.
|
|
102
|
+
class Scope
|
|
103
|
+
|
|
104
|
+
# Maps on the local types.
|
|
105
|
+
def map_types!(&ruby_block)
|
|
106
|
+
@types.map(&ruby_block)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Maps on the local systemTs.
|
|
110
|
+
def map_systemTs!(&ruby_block)
|
|
111
|
+
@systemTs.map(&ruby_block)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Maps on the scopes.
|
|
115
|
+
def map_scopes!(&ruby_block)
|
|
116
|
+
@scopes.map! do |scope|
|
|
117
|
+
scope = ruby_block.call(scope)
|
|
118
|
+
scope.parent = self unless scope.parent
|
|
119
|
+
scope
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Maps on the inners.
|
|
124
|
+
def map_inners!(&ruby_block)
|
|
125
|
+
@inners.map! do |inner|
|
|
126
|
+
inner = ruby_block.call(inner)
|
|
127
|
+
inner.parent = self unless inner.parent
|
|
128
|
+
inner
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Maps on the systemIs.
|
|
133
|
+
def map_systemIs!(&ruby_block)
|
|
134
|
+
@systemIs.map! do |systemI|
|
|
135
|
+
systemI = ruby_block.call(systemI)
|
|
136
|
+
systemI.parent = self unless systemI.parent
|
|
137
|
+
systemI
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Maps on the connections.
|
|
142
|
+
def map_connections!(&ruby_block)
|
|
143
|
+
@connections.map! do |connection|
|
|
144
|
+
connection = ruby_block.call(connection)
|
|
145
|
+
connection.parent = self unless connection.parent
|
|
146
|
+
connection
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Maps on the behaviors.
|
|
151
|
+
def map_behaviors!(&ruby_block)
|
|
152
|
+
@behaviors.map! do |behavior|
|
|
153
|
+
behavior = ruby_block.call(behavior)
|
|
154
|
+
behavior.parent = self unless behavior.parent
|
|
155
|
+
behavior
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Deletes an type.
|
|
160
|
+
def delete_type!(type)
|
|
161
|
+
if @types.key?(type.name) then
|
|
162
|
+
# The type is present, delete it.
|
|
163
|
+
@types.delete(type.name)
|
|
164
|
+
# And remove its parent.
|
|
165
|
+
type.parent = nil
|
|
166
|
+
end
|
|
167
|
+
type
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Deletes an systemT.
|
|
171
|
+
def delete_systemT!(systemT)
|
|
172
|
+
if @systemTs.key?(systemT.name) then
|
|
173
|
+
# The systemT is present, delete it.
|
|
174
|
+
@systemTs.delete(systemT.name)
|
|
175
|
+
# And remove its parent.
|
|
176
|
+
systemT.parent = nil
|
|
177
|
+
end
|
|
178
|
+
systemT
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Deletes a scope.
|
|
182
|
+
def delete_scope!(scope)
|
|
183
|
+
# Remove the scope from the list
|
|
184
|
+
@scopes.delete(scope)
|
|
185
|
+
# And remove its parent.
|
|
186
|
+
scope.parent = nil
|
|
187
|
+
# Return the deleted scope
|
|
188
|
+
scope
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Deletes an inner.
|
|
192
|
+
def delete_inner!(signal)
|
|
193
|
+
if @inners.key?(signal.name) then
|
|
194
|
+
# The signal is present, delete it.
|
|
195
|
+
@inners.delete(signal.name)
|
|
196
|
+
# And remove its parent.
|
|
197
|
+
signal.parent = nil
|
|
198
|
+
end
|
|
199
|
+
signal
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Deletes a systemI.
|
|
203
|
+
def delete_systemI!(systemI)
|
|
204
|
+
if @systemIs.key?(systemI.name) then
|
|
205
|
+
# The instance is present, do remove it.
|
|
206
|
+
@systemIs.delete(systemI.name)
|
|
207
|
+
# And remove its parent.
|
|
208
|
+
systemI.parent = nil
|
|
209
|
+
end
|
|
210
|
+
systemI
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Deletes a connection.
|
|
214
|
+
def delete_connection!(connection)
|
|
215
|
+
if @connections.include?(connection) then
|
|
216
|
+
# The connection is present, delete it.
|
|
217
|
+
@connections.delete(connection)
|
|
218
|
+
# And remove its parent.
|
|
219
|
+
connection.parent = nil
|
|
220
|
+
end
|
|
221
|
+
connection
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Deletes a behavior.
|
|
225
|
+
def delete_behavior!(behavior)
|
|
226
|
+
if @behaviors.include?(behavior) then
|
|
227
|
+
# The behavior is present, delete it.
|
|
228
|
+
@behaviors.delete(behavior)
|
|
229
|
+
# And remove its parent.
|
|
230
|
+
behavior.parent = nil
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
##
|
|
237
|
+
# Describes a data type.
|
|
238
|
+
class Type
|
|
239
|
+
|
|
240
|
+
# Sets the +name+.
|
|
241
|
+
def set_name!(name)
|
|
242
|
+
@name = name.to_sym
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
##
|
|
248
|
+
# Describes a high-level type definition.
|
|
249
|
+
#
|
|
250
|
+
# NOTE: type definition are actually type with a name refering to another
|
|
251
|
+
# type (and equivalent to it).
|
|
252
|
+
class TypeDef
|
|
253
|
+
|
|
254
|
+
# Sets the type definition to +type+.
|
|
255
|
+
def set_def!(type)
|
|
256
|
+
# Checks the referered type.
|
|
257
|
+
unless type.is_a?(Type) then
|
|
258
|
+
raise AnyError, "Invalid class for a type: #{type.class}"
|
|
259
|
+
end
|
|
260
|
+
# Set the referened type.
|
|
261
|
+
@def = type
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
##
|
|
268
|
+
# Describes a vector type.
|
|
269
|
+
class TypeVector
|
|
270
|
+
|
|
271
|
+
# Sets the +base+ type.
|
|
272
|
+
def set_base!(type)
|
|
273
|
+
# Check and set the base
|
|
274
|
+
unless type.is_a?(Type)
|
|
275
|
+
raise AnyError,
|
|
276
|
+
"Invalid class for VectorType base: #{base.class}."
|
|
277
|
+
end
|
|
278
|
+
@base = type
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Sets the +range+.
|
|
282
|
+
def set_range!(ranage)
|
|
283
|
+
# Check and set the range.
|
|
284
|
+
if range.respond_to?(:to_i) then
|
|
285
|
+
# Integer case: convert to 0..(range-1).
|
|
286
|
+
range = (range-1)..0
|
|
287
|
+
elsif
|
|
288
|
+
# Other cases: assume there is a first and a last to create
|
|
289
|
+
# the range.
|
|
290
|
+
range = range.first..range.last
|
|
291
|
+
end
|
|
292
|
+
@range = range
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
##
|
|
298
|
+
# Describes a tuple type.
|
|
299
|
+
class TypeTuple
|
|
300
|
+
|
|
301
|
+
# Maps on the sub types.
|
|
302
|
+
def map_types!(&ruby_block)
|
|
303
|
+
@types.map(&ruby_block)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Deletes a type.
|
|
307
|
+
def delete_type!(type)
|
|
308
|
+
if @types.include?(type) then
|
|
309
|
+
# The type is present, delete it.
|
|
310
|
+
@types.delete(type)
|
|
311
|
+
# And remove its parent.
|
|
312
|
+
type.parent = nil
|
|
313
|
+
end
|
|
314
|
+
type
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
##
|
|
320
|
+
# Describes a structure type.
|
|
321
|
+
class TypeStruct
|
|
322
|
+
|
|
323
|
+
# Maps on the sub types.
|
|
324
|
+
def map_types!(&ruby_block)
|
|
325
|
+
@types.map(&ruby_block)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Deletes a sub type by +key+.
|
|
329
|
+
def delete_type!(key)
|
|
330
|
+
if @types.include?(key) then
|
|
331
|
+
# The type is present, delete it.
|
|
332
|
+
type = @types.delete(key)
|
|
333
|
+
# And remove its parent.
|
|
334
|
+
type.parent = nil
|
|
335
|
+
end
|
|
336
|
+
type
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
##
|
|
343
|
+
# Describes a behavior.
|
|
344
|
+
class Behavior
|
|
345
|
+
|
|
346
|
+
# Sets the block.
|
|
347
|
+
def set_block!(block)
|
|
348
|
+
self.block = block
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Maps on the events.
|
|
352
|
+
def map_events!(&ruby_block)
|
|
353
|
+
@events.map! do |event|
|
|
354
|
+
event = ruby_block.call(event)
|
|
355
|
+
event.parent = self unless event.parent
|
|
356
|
+
event
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# Deletes a event.
|
|
361
|
+
def delete_event!(event)
|
|
362
|
+
if @events.include?(event) then
|
|
363
|
+
# The event is present, delete it.
|
|
364
|
+
@events.delete(event)
|
|
365
|
+
# And remove its parent.
|
|
366
|
+
event.parent = nil
|
|
367
|
+
end
|
|
368
|
+
event
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
##
|
|
374
|
+
# Describes a timed behavior.
|
|
375
|
+
#
|
|
376
|
+
# NOTE:
|
|
377
|
+
# * this is the only kind of behavior that can include time statements.
|
|
378
|
+
# * this kind of behavior is not synthesizable!
|
|
379
|
+
class TimeBehavior
|
|
380
|
+
|
|
381
|
+
# Sets the block.
|
|
382
|
+
def set_block!(block)
|
|
383
|
+
# Check and set the block.
|
|
384
|
+
unless block.is_a?(Block)
|
|
385
|
+
raise AnyError, "Invalid class for a block: #{block.class}."
|
|
386
|
+
end
|
|
387
|
+
# Time blocks are supported here.
|
|
388
|
+
@block = block
|
|
389
|
+
block.parent = self
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
##
|
|
395
|
+
# Describes an event.
|
|
396
|
+
class Event
|
|
397
|
+
# Sets the type.
|
|
398
|
+
def set_type!(type)
|
|
399
|
+
# Check and set the type.
|
|
400
|
+
@type = type.to_sym
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Sets the reference to +ref+.
|
|
404
|
+
def set_ref!(ref)
|
|
405
|
+
# Check and set the reference.
|
|
406
|
+
unless ref.is_a?(Ref)
|
|
407
|
+
raise AnyError, "Invalid class for a reference: #{ref.class}"
|
|
408
|
+
end
|
|
409
|
+
@ref = ref
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
# Replace node by corresponding replacement from +node2reassign+ that
|
|
413
|
+
# is a table whose entries are:
|
|
414
|
+
# +node+ the node to replace
|
|
415
|
+
# +rep+ the replacement of the node
|
|
416
|
+
# +ref+ the reference where to reassign the node.
|
|
417
|
+
def reassign_expressions!(node2reassign)
|
|
418
|
+
# Build the replacement table.
|
|
419
|
+
node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
|
|
420
|
+
|
|
421
|
+
# Performs the replacement.
|
|
422
|
+
node2rep_done = {} # The performed replacements.
|
|
423
|
+
# Replace on the sons of the reference.
|
|
424
|
+
node2rep_done.merge!(self.ref.replace_expressions!(node2rep))
|
|
425
|
+
# Shall we replace the ref?
|
|
426
|
+
rep = node2rep[self.ref]
|
|
427
|
+
if rep then
|
|
428
|
+
# Yes, do it.
|
|
429
|
+
rep = rep.clone
|
|
430
|
+
node = self.ref
|
|
431
|
+
# node.set_parent!(nil)
|
|
432
|
+
self.set_ref!(rep)
|
|
433
|
+
node2rep_done[node] = rep
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Assign the replaced nodes.
|
|
437
|
+
node2rep_done.each do |node,rep|
|
|
438
|
+
reassign = node2reassign[node][1].clone
|
|
439
|
+
self.parent.
|
|
440
|
+
add_connection(Connection.new(reassign,node.clone))
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
##
|
|
447
|
+
# Describes a signal.
|
|
448
|
+
class SignalI
|
|
449
|
+
|
|
450
|
+
# Sets the name.
|
|
451
|
+
def set_name!(name)
|
|
452
|
+
# Check and set the name.
|
|
453
|
+
@name = name.to_sym
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
# Sets the type.
|
|
457
|
+
def set_type!(type)
|
|
458
|
+
# Check and set the type.
|
|
459
|
+
if type.is_a?(Type) then
|
|
460
|
+
@type = type
|
|
461
|
+
else
|
|
462
|
+
raise AnyError, "Invalid class for a type: #{type.class}."
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
# Sets the value.
|
|
467
|
+
def set_value!(value)
|
|
468
|
+
# Check and set teh value.
|
|
469
|
+
unless value.is_a?(Expression) then
|
|
470
|
+
raise AnyError, "Invalid class for a constant: #{val.class}"
|
|
471
|
+
end
|
|
472
|
+
@value = value
|
|
473
|
+
value.parent = self
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
##
|
|
480
|
+
# Describes a system instance.
|
|
481
|
+
class SystemI
|
|
482
|
+
|
|
483
|
+
# Sets the name.
|
|
484
|
+
def set_name!(name)
|
|
485
|
+
# Set the name as a symbol.
|
|
486
|
+
@name = name.to_sym
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Sets the systemT.
|
|
490
|
+
def set_systemT(systemT)
|
|
491
|
+
# Check and set the systemT.
|
|
492
|
+
if !systemT.is_a?(SystemT) then
|
|
493
|
+
raise AnyError, "Invalid class for a system type: #{systemT.class}"
|
|
494
|
+
end
|
|
495
|
+
@systemT = systemT
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
##
|
|
503
|
+
# Describes a statement.
|
|
504
|
+
#
|
|
505
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
|
506
|
+
class Statement
|
|
507
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
508
|
+
# node to replace and the corresponding replacement.
|
|
509
|
+
# Returns the actually replaced nodes and their corresponding
|
|
510
|
+
# replacement.
|
|
511
|
+
#
|
|
512
|
+
# NOTE: the replacement is duplicated.
|
|
513
|
+
def replace_expressions!(node2rep)
|
|
514
|
+
# By default: nothing to do.
|
|
515
|
+
return {}
|
|
516
|
+
end
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
##
|
|
523
|
+
# Decribes a transmission statement.
|
|
524
|
+
class Transmit
|
|
525
|
+
# Sets the left.
|
|
526
|
+
def set_left!(left)
|
|
527
|
+
# Check and set the left reference.
|
|
528
|
+
unless left.is_a?(Ref)
|
|
529
|
+
raise AnyError,
|
|
530
|
+
"Invalid class for a reference (left value): #{left.class}"
|
|
531
|
+
end
|
|
532
|
+
@left = left
|
|
533
|
+
# and set its parent.
|
|
534
|
+
left.parent = self
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
# Sets the right.
|
|
538
|
+
def set_right!(right)
|
|
539
|
+
# Check and set the right expression.
|
|
540
|
+
unless right.is_a?(Expression)
|
|
541
|
+
raise AnyError, "Invalid class for an expression (right value): #{right.class}"
|
|
542
|
+
end
|
|
543
|
+
@right = right
|
|
544
|
+
# and set its parent.
|
|
545
|
+
right.parent = self
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
# Maps on the children.
|
|
549
|
+
def map_nodes!(&ruby_block)
|
|
550
|
+
@left = ruby_block.call(@left)
|
|
551
|
+
left.parent = self unless left.parent
|
|
552
|
+
@right = ruby_block.call(@right)
|
|
553
|
+
right.parent = self unless right.parent
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
557
|
+
# node to replace and the corresponding replacement.
|
|
558
|
+
# Returns the actually replaced nodes and their corresponding
|
|
559
|
+
# replacement.
|
|
560
|
+
#
|
|
561
|
+
# NOTE: the replacement is duplicated.
|
|
562
|
+
def replace_expressions!(node2rep)
|
|
563
|
+
# First recurse on the children.
|
|
564
|
+
res = self.left.replace_expressions!(node2rep)
|
|
565
|
+
res.merge!(self.right.replace_expressions!(node2rep))
|
|
566
|
+
# Is there a replacement to do on the left?
|
|
567
|
+
rep = node2rep[self.left]
|
|
568
|
+
if rep then
|
|
569
|
+
# Yes, do it.
|
|
570
|
+
rep = rep.clone
|
|
571
|
+
node = self.left
|
|
572
|
+
# node.set_parent!(nil)
|
|
573
|
+
self.set_left!(rep)
|
|
574
|
+
# And register the replacement.
|
|
575
|
+
res[node] = rep
|
|
576
|
+
end
|
|
577
|
+
# Is there a replacement to do on the right?
|
|
578
|
+
rep = node2rep[self.right]
|
|
579
|
+
if rep then
|
|
580
|
+
# Yes, do it.
|
|
581
|
+
rep = rep.clone
|
|
582
|
+
node = self.right
|
|
583
|
+
# node.set_parent!(nil)
|
|
584
|
+
self.set_right!(rep)
|
|
585
|
+
# And register the replacement.
|
|
586
|
+
res[node] = rep
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
return res
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
##
|
|
595
|
+
# Describes an if statement.
|
|
596
|
+
class If
|
|
597
|
+
|
|
598
|
+
# Sets the condition.
|
|
599
|
+
def set_condition!(condition)
|
|
600
|
+
# Check and set the condition.
|
|
601
|
+
unless condition.is_a?(Expression)
|
|
602
|
+
raise AnyError,
|
|
603
|
+
"Invalid class for a condition: #{condition.class}"
|
|
604
|
+
end
|
|
605
|
+
@condition = condition
|
|
606
|
+
# And set its parent.
|
|
607
|
+
condition.parent = self
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
# Sets the yes block.
|
|
611
|
+
def set_yes!(yes)
|
|
612
|
+
# Check and set the yes statement.
|
|
613
|
+
unless yes.is_a?(Statement)
|
|
614
|
+
raise AnyError, "Invalid class for a statement: #{yes.class}"
|
|
615
|
+
end
|
|
616
|
+
@yes = yes
|
|
617
|
+
# And set its parent.
|
|
618
|
+
yes.parent = self
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
# Sets the no block.
|
|
622
|
+
def set_no!(no)
|
|
623
|
+
# Check and set the yes statement.
|
|
624
|
+
if no and !no.is_a?(Statement)
|
|
625
|
+
raise AnyError, "Invalid class for a statement: #{no.class}"
|
|
626
|
+
end
|
|
627
|
+
@no = no
|
|
628
|
+
# And set its parent.
|
|
629
|
+
no.parent = self if no
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
# Deletes an alternate if.
|
|
633
|
+
def delete_noif!(noif)
|
|
634
|
+
if @noifs.include?(noif) then
|
|
635
|
+
# The noif is present, delete it.
|
|
636
|
+
@noifs.delete(noif)
|
|
637
|
+
# And remove its parent.
|
|
638
|
+
noif.parent = nil
|
|
639
|
+
end
|
|
640
|
+
noif
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
# Maps on the noifs.
|
|
644
|
+
def map_noifs!(&ruby_block)
|
|
645
|
+
@noifs.map! do |cond,stmnt|
|
|
646
|
+
cond,stmnt = ruby_block.call(cond,stmnt)
|
|
647
|
+
# cond, stmnt = ruby_block.call(cond), ruby_block.call(stmnt)
|
|
648
|
+
cond.parent = self unless cond.parent
|
|
649
|
+
stmnt.parent = self unless stmnt.parent
|
|
650
|
+
[cond,stmnt]
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
# Maps on the children (including the condition).
|
|
655
|
+
def map_nodes!(&ruby_block)
|
|
656
|
+
@condition = ruby_block.call(@condition)
|
|
657
|
+
@yes = ruby_block.call(@yes)
|
|
658
|
+
self.map_noifs! do |cond,stmnt|
|
|
659
|
+
[ruby_block.call(cond), ruby_block.call(stmnt)]
|
|
660
|
+
end
|
|
661
|
+
# @noifs.map! do |cond,stmnt|
|
|
662
|
+
# cond = ruby_block.call(cond)
|
|
663
|
+
# stmnt = ruby_block.call(stmnt)
|
|
664
|
+
# cond.parent = self unless cond.parent
|
|
665
|
+
# stmnt.parent = self unless stmnt.parent
|
|
666
|
+
# [cond,stmnt]
|
|
667
|
+
# end
|
|
668
|
+
@no = ruby_block.call(@no) if @no
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
672
|
+
# node to replace and the corresponding replacement.
|
|
673
|
+
# Returns the actually replaced nodes and their corresponding
|
|
674
|
+
# replacement.
|
|
675
|
+
#
|
|
676
|
+
# NOTE: the replacement is duplicated.
|
|
677
|
+
def replace_expressions!(node2rep)
|
|
678
|
+
# First recurse on the children.
|
|
679
|
+
res = {}
|
|
680
|
+
self.each_node do |node|
|
|
681
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
682
|
+
end
|
|
683
|
+
# Is there a replacement to do on the condition?
|
|
684
|
+
rep = node2rep[self.condition]
|
|
685
|
+
if rep then
|
|
686
|
+
# Yes, do it.
|
|
687
|
+
rep = rep.clone
|
|
688
|
+
node = self.condition
|
|
689
|
+
# node.set_parent!(nil)
|
|
690
|
+
self.set_condition!(rep)
|
|
691
|
+
# And register the replacement.
|
|
692
|
+
res[node] = rep
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
return res
|
|
696
|
+
end
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
##
|
|
700
|
+
# Describes a when for a case statement.
|
|
701
|
+
class When
|
|
702
|
+
# Sets the match.
|
|
703
|
+
def set_match!(match)
|
|
704
|
+
# Checks the match.
|
|
705
|
+
unless match.is_a?(Expression)
|
|
706
|
+
raise AnyError, "Invalid class for a case match: #{match.class}"
|
|
707
|
+
end
|
|
708
|
+
# Set the match.
|
|
709
|
+
@match = match
|
|
710
|
+
# And set their parents.
|
|
711
|
+
match.parent = self
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
# Sets the statement.
|
|
715
|
+
def set_statement!(statement)
|
|
716
|
+
# Checks statement.
|
|
717
|
+
unless statement.is_a?(Statement)
|
|
718
|
+
raise AnyError,
|
|
719
|
+
"Invalid class for a statement: #{statement.class}"
|
|
720
|
+
end
|
|
721
|
+
# Set the statement.
|
|
722
|
+
@statement = statement
|
|
723
|
+
# And set their parents.
|
|
724
|
+
statement.parent = self
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
# Maps on the children (including the match).
|
|
728
|
+
def map_nodes!(&ruby_block)
|
|
729
|
+
@match = ruby_block.call(@match)
|
|
730
|
+
@match.parent = self unless @match.parent
|
|
731
|
+
@statement = ruby_block.call(@statement)
|
|
732
|
+
@statement.parent = self unless @statement.parent
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
736
|
+
# node to replace and the corresponding replacement.
|
|
737
|
+
# Returns the actually replaced nodes and their corresponding
|
|
738
|
+
# replacement.
|
|
739
|
+
#
|
|
740
|
+
# NOTE: the replacement is duplicated.
|
|
741
|
+
def replace_expressions!(node2rep)
|
|
742
|
+
# First recurse on the children.
|
|
743
|
+
res = {}
|
|
744
|
+
self.each_node do |node|
|
|
745
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
746
|
+
end
|
|
747
|
+
# Is there a replacement to do on the value?
|
|
748
|
+
rep = node2rep[self.match]
|
|
749
|
+
if rep then
|
|
750
|
+
# Yes, do it.
|
|
751
|
+
rep = rep.clone
|
|
752
|
+
node = self.match
|
|
753
|
+
# node.set_parent!(nil)
|
|
754
|
+
self.set_match!(rep)
|
|
755
|
+
# And register the replacement.
|
|
756
|
+
res[node] = rep
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
return res
|
|
760
|
+
end
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
##
|
|
765
|
+
# Describes a case statement.
|
|
766
|
+
class Case
|
|
767
|
+
|
|
768
|
+
# Sets the value.
|
|
769
|
+
def set_value!(value)
|
|
770
|
+
# Check and set the value.
|
|
771
|
+
unless value.is_a?(Expression)
|
|
772
|
+
raise AnyError, "Invalid class for a value: #{value.class}"
|
|
773
|
+
end
|
|
774
|
+
@value = value
|
|
775
|
+
# And set its parent.
|
|
776
|
+
value.parent = self
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
# Sets the default.
|
|
780
|
+
def set_default!(default)
|
|
781
|
+
# Checks and set the default case if any.
|
|
782
|
+
self.default = default
|
|
783
|
+
end
|
|
784
|
+
|
|
785
|
+
# Maps on the whens.
|
|
786
|
+
def map_whens!(&ruby_block)
|
|
787
|
+
@whens.map! do |w|
|
|
788
|
+
w = ruby_block.call(w)
|
|
789
|
+
w.parent = self unless w.parent
|
|
790
|
+
w
|
|
791
|
+
end
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
# Delete a when.
|
|
795
|
+
def delete_when!(w)
|
|
796
|
+
@whens.delete(w)
|
|
797
|
+
end
|
|
798
|
+
|
|
799
|
+
# Maps on the children (including the value).
|
|
800
|
+
def map_nodes!(&ruby_block)
|
|
801
|
+
# A block? Apply it on each child.
|
|
802
|
+
@value = ruby_block.call(@value)
|
|
803
|
+
map_whens!(&ruby_block)
|
|
804
|
+
if @default then
|
|
805
|
+
@default = ruby_block.call(@default)
|
|
806
|
+
@default.parent = self unless @default.parent
|
|
807
|
+
end
|
|
808
|
+
end
|
|
809
|
+
|
|
810
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
811
|
+
# node to replace and the corresponding replacement.
|
|
812
|
+
# Returns the actually replaced nodes and their corresponding
|
|
813
|
+
# replacement.
|
|
814
|
+
#
|
|
815
|
+
# NOTE: the replacement is duplicated.
|
|
816
|
+
def replace_expressions!(node2rep)
|
|
817
|
+
# First recurse on the children.
|
|
818
|
+
res = {}
|
|
819
|
+
self.each_node do |node|
|
|
820
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
821
|
+
end
|
|
822
|
+
# Is there a replacement to do on the value?
|
|
823
|
+
rep = node2rep[self.value]
|
|
824
|
+
if rep then
|
|
825
|
+
# Yes, do it.
|
|
826
|
+
rep = rep.clone
|
|
827
|
+
node = self.value
|
|
828
|
+
# node.set_parent!(nil)
|
|
829
|
+
self.set_value!(rep)
|
|
830
|
+
# And register the replacement.
|
|
831
|
+
res[node] = rep
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
return res
|
|
835
|
+
end
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
|
|
839
|
+
##
|
|
840
|
+
# Describes a delay: not synthesizable.
|
|
841
|
+
class Delay
|
|
842
|
+
|
|
843
|
+
# Sets the value.
|
|
844
|
+
def set_value!(value)
|
|
845
|
+
# Check and set the value.
|
|
846
|
+
unless value.is_a?(Numeric)
|
|
847
|
+
raise AnyError,
|
|
848
|
+
"Invalid class for a delay value: #{value.class}."
|
|
849
|
+
end
|
|
850
|
+
@value = value
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
# Sets the unit.
|
|
854
|
+
def set_unit!(unit)
|
|
855
|
+
# Check and set the unit.
|
|
856
|
+
@unit = unit.to_sym
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
860
|
+
# node to replace and the corresponding replacement.
|
|
861
|
+
# Returns the actually replaced nodes and their corresponding
|
|
862
|
+
# replacement.
|
|
863
|
+
#
|
|
864
|
+
# NOTE: the replacement is duplicated.
|
|
865
|
+
def replace_expressions!(node2rep)
|
|
866
|
+
# First recurse on the children.
|
|
867
|
+
res = self.value.replace_expressions!
|
|
868
|
+
# Is there a replacement to do on the value?
|
|
869
|
+
rep = node2rep[self.value]
|
|
870
|
+
if rep then
|
|
871
|
+
# Yes, do it.
|
|
872
|
+
rep = rep.clone
|
|
873
|
+
node = self.value
|
|
874
|
+
# node.set_parent!(nil)
|
|
875
|
+
self.set_value!(rep)
|
|
876
|
+
# And register the replacement.
|
|
877
|
+
res[node] = rep
|
|
878
|
+
end
|
|
879
|
+
|
|
880
|
+
return res
|
|
881
|
+
end
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
##
|
|
886
|
+
# Describes a wait statement: not synthesizable!
|
|
887
|
+
class TimeWait
|
|
888
|
+
|
|
889
|
+
# Sets the delay.
|
|
890
|
+
def set_delay!(delay)
|
|
891
|
+
# Check and set the delay.
|
|
892
|
+
unless delay.is_a?(Delay)
|
|
893
|
+
raise AnyError, "Invalid class for a delay: #{delay.class}."
|
|
894
|
+
end
|
|
895
|
+
@delay = delay
|
|
896
|
+
# And set its parent.
|
|
897
|
+
delay.parent = self
|
|
898
|
+
end
|
|
899
|
+
|
|
900
|
+
# Maps on the children (including the condition).
|
|
901
|
+
def map_nodes!(&ruby_block)
|
|
902
|
+
# Nothing to do.
|
|
903
|
+
end
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
##
|
|
908
|
+
# Describes a timed loop statement: not synthesizable!
|
|
909
|
+
class TimeRepeat
|
|
910
|
+
|
|
911
|
+
# Sets the statement.
|
|
912
|
+
def set_statement!(statement)
|
|
913
|
+
# Check and set the statement.
|
|
914
|
+
unless statement.is_a?(Statement)
|
|
915
|
+
raise AnyError,
|
|
916
|
+
"Invalid class for a statement: #{statement.class}."
|
|
917
|
+
end
|
|
918
|
+
@statement = statement
|
|
919
|
+
# And set its parent.
|
|
920
|
+
statement.parent = self
|
|
921
|
+
end
|
|
922
|
+
|
|
923
|
+
# Sets the delay.
|
|
924
|
+
def set_delay!(delay)
|
|
925
|
+
# Check and set the delay.
|
|
926
|
+
unless delay.is_a?(Delay)
|
|
927
|
+
raise AnyError, "Invalid class for a delay: #{delay.class}."
|
|
928
|
+
end
|
|
929
|
+
@delay = delay
|
|
930
|
+
# And set its parent.
|
|
931
|
+
delay.parent = self
|
|
932
|
+
end
|
|
933
|
+
|
|
934
|
+
# Maps on the child.
|
|
935
|
+
def map_nodes!(&ruby_block)
|
|
936
|
+
@statement = ruby_block.call(@statement)
|
|
937
|
+
@statement.parent = self unless @statement.parent
|
|
938
|
+
end
|
|
939
|
+
|
|
940
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
941
|
+
# node to replace and the corresponding replacement.
|
|
942
|
+
# Returns the actually replaced nodes and their corresponding
|
|
943
|
+
# replacement.
|
|
944
|
+
#
|
|
945
|
+
# NOTE: the replacement is duplicated.
|
|
946
|
+
def replace_expressions!(node2rep)
|
|
947
|
+
res = {}
|
|
948
|
+
# Recurse on the children.
|
|
949
|
+
self.each_node do |node|
|
|
950
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
951
|
+
end
|
|
952
|
+
return res
|
|
953
|
+
end
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
##
|
|
958
|
+
# Describes a block.
|
|
959
|
+
class Block
|
|
960
|
+
|
|
961
|
+
# Sets the mode.
|
|
962
|
+
def set_mode!(mode)
|
|
963
|
+
# Check and set the type.
|
|
964
|
+
@mode = mode.to_sym
|
|
965
|
+
end
|
|
966
|
+
|
|
967
|
+
# Sets the name.
|
|
968
|
+
def set_name!(name)
|
|
969
|
+
# Check and set the name.
|
|
970
|
+
@name = name.to_sym
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
# Maps on the inners.
|
|
974
|
+
def map_inners!(&ruby_block)
|
|
975
|
+
@inners.map! do |inner|
|
|
976
|
+
inner = ruby_block.call(inner)
|
|
977
|
+
inner.parent = self unless inner.parent
|
|
978
|
+
inner
|
|
979
|
+
end
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
# Deletes an inner.
|
|
983
|
+
def delete_inner!(signal)
|
|
984
|
+
if @inners.key?(signal.name) then
|
|
985
|
+
# The signal is present, delete it.
|
|
986
|
+
@inners.delete(signal.name)
|
|
987
|
+
# And remove its parent.
|
|
988
|
+
signal.parent = nil
|
|
989
|
+
end
|
|
990
|
+
signal
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
# Inserts statement *stmnt+ at index +idx+.
|
|
994
|
+
def insert_statement!(idx,stmnt)
|
|
995
|
+
# Checks the index.
|
|
996
|
+
if idx > @statements.size then
|
|
997
|
+
raise AryError, "Index out of range: #{idx}"
|
|
998
|
+
end
|
|
999
|
+
# Checks the statement.
|
|
1000
|
+
unless stmnt.is_a?(Statement)
|
|
1001
|
+
raise AnyError, "Invalid type for a statement: #{stmnt.class}"
|
|
1002
|
+
end
|
|
1003
|
+
# Inserts the statement.
|
|
1004
|
+
@statements.insert(idx,stmnt)
|
|
1005
|
+
stmnt.parent = self
|
|
1006
|
+
end
|
|
1007
|
+
|
|
1008
|
+
# Sets statement +stmnt+ at index +idx+.
|
|
1009
|
+
def set_statement!(idx,stmnt)
|
|
1010
|
+
# Checks the index.
|
|
1011
|
+
if idx > @statements.size then
|
|
1012
|
+
raise AryError, "Index out of range: #{idx}"
|
|
1013
|
+
end
|
|
1014
|
+
# Checks the statement.
|
|
1015
|
+
unless stmnt.is_a?(Statement)
|
|
1016
|
+
raise AnyError, "Invalid type for a statement: #{stmnt.class}"
|
|
1017
|
+
end
|
|
1018
|
+
# Detach the previous statement if any.
|
|
1019
|
+
@statements[idx].parent = nil if @statements[idx]
|
|
1020
|
+
# Set the new statement.
|
|
1021
|
+
@statements[idx] = stmnt
|
|
1022
|
+
stmnt.parent = self
|
|
1023
|
+
end
|
|
1024
|
+
|
|
1025
|
+
# Maps on the statements.
|
|
1026
|
+
def map_statements!(&ruby_block)
|
|
1027
|
+
@statements.map! do |stmnt|
|
|
1028
|
+
stmnt = ruby_block.call(stmnt)
|
|
1029
|
+
stmnt.parent = self unless stmnt.parent
|
|
1030
|
+
stmnt
|
|
1031
|
+
end
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
alias_method :map_nodes!, :map_statements!
|
|
1035
|
+
|
|
1036
|
+
# Deletes a statement.
|
|
1037
|
+
def delete_statement!(statement)
|
|
1038
|
+
if @statements.include?(statement) then
|
|
1039
|
+
# Statement is present, delete it.
|
|
1040
|
+
@statements.delete(statement)
|
|
1041
|
+
# And remove its parent.
|
|
1042
|
+
statement.parent = nil
|
|
1043
|
+
end
|
|
1044
|
+
statement
|
|
1045
|
+
end
|
|
1046
|
+
|
|
1047
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1048
|
+
# node to replace and the corresponding replacement.
|
|
1049
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1050
|
+
# replacement.
|
|
1051
|
+
#
|
|
1052
|
+
# NOTE: the replacement is duplicated.
|
|
1053
|
+
def replace_expressions!(node2rep)
|
|
1054
|
+
res = {}
|
|
1055
|
+
# Recurse on the children.
|
|
1056
|
+
self.each_node do |node|
|
|
1057
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
1058
|
+
end
|
|
1059
|
+
return res
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
# Replace node by corresponding replacement from +node2reassign+ that
|
|
1063
|
+
# is a table whose entries are:
|
|
1064
|
+
# +node+ the node to replace
|
|
1065
|
+
# +rep+ the replacement of the node
|
|
1066
|
+
# +ref+ the reference where to reassign the node.
|
|
1067
|
+
def reassign_expressions!(node2reassign)
|
|
1068
|
+
# Build the replacement table.
|
|
1069
|
+
node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
|
|
1070
|
+
|
|
1071
|
+
# First recurse on the sub blocks.
|
|
1072
|
+
self.each_block { |block| block.reassign_expressions!(node2rep) }
|
|
1073
|
+
|
|
1074
|
+
# Now work on the block.
|
|
1075
|
+
# Replace on the statements.
|
|
1076
|
+
self.map_statements! do |statement|
|
|
1077
|
+
# Do the replacement
|
|
1078
|
+
node2rep_done = statement.replace_expressions!(node2rep)
|
|
1079
|
+
# Assign the replaced nodes in a new block.
|
|
1080
|
+
unless node2rep_done.empty?
|
|
1081
|
+
blk = Block.new(:seq)
|
|
1082
|
+
node2rep_done.each do |node,rep|
|
|
1083
|
+
reassign = node2reassign[node][1].clone
|
|
1084
|
+
blk.add_statement(Transmit.new(reassign,node.clone))
|
|
1085
|
+
end
|
|
1086
|
+
blk.add_statement(statement.clone)
|
|
1087
|
+
blk
|
|
1088
|
+
else
|
|
1089
|
+
statement
|
|
1090
|
+
end
|
|
1091
|
+
end
|
|
1092
|
+
end
|
|
1093
|
+
end
|
|
1094
|
+
|
|
1095
|
+
# Describes a timed block.
|
|
1096
|
+
#
|
|
1097
|
+
# NOTE:
|
|
1098
|
+
# * this is the only kind of block that can include time statements.
|
|
1099
|
+
# * this kind of block is not synthesizable!
|
|
1100
|
+
class TimeBlock
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
|
|
1104
|
+
##
|
|
1105
|
+
# Decribes a piece of software code.
|
|
1106
|
+
class Code
|
|
1107
|
+
# Sets the type.
|
|
1108
|
+
def set_type!(type)
|
|
1109
|
+
# Check and set type.
|
|
1110
|
+
@type = type.to_sym
|
|
1111
|
+
end
|
|
1112
|
+
|
|
1113
|
+
# Sets the content.
|
|
1114
|
+
def set_content!(content)
|
|
1115
|
+
@content = content
|
|
1116
|
+
# Freeze it to avoid dynamic tempering of the hardware.
|
|
1117
|
+
content.freeze
|
|
1118
|
+
end
|
|
1119
|
+
end
|
|
1120
|
+
|
|
1121
|
+
|
|
1122
|
+
##
|
|
1123
|
+
# Describes a connection.
|
|
1124
|
+
#
|
|
1125
|
+
# NOTE: eventhough a connection is semantically different from a
|
|
1126
|
+
# transmission, it has a common structure. Therefore, it is described
|
|
1127
|
+
# as a subclass of a transmit.
|
|
1128
|
+
class Connection
|
|
1129
|
+
|
|
1130
|
+
# Replace node by corresponding replacement from +node2reassign+ that
|
|
1131
|
+
# is a table whose entries are:
|
|
1132
|
+
# +node+ the node to replace
|
|
1133
|
+
# +rep+ the replacement of the node
|
|
1134
|
+
# +ref+ the reference where to reassign the node.
|
|
1135
|
+
def reassign_expressions!(node2reassign)
|
|
1136
|
+
# Build the replacement table.
|
|
1137
|
+
node2rep = node2reassign.map {|n,r| [n,r[0]] }.to_h
|
|
1138
|
+
|
|
1139
|
+
# Performs the replacements.
|
|
1140
|
+
node2rep_done = {} # The performed replacements.
|
|
1141
|
+
# Replace on the sons of the left.
|
|
1142
|
+
node2rep_done.merge!(self.left.replace_expressions!(node2rep))
|
|
1143
|
+
# Replace on the sons of the left.
|
|
1144
|
+
node2rep_done.merge!(self.right.replace_expressions!(node2rep))
|
|
1145
|
+
# Shall we replace the right?
|
|
1146
|
+
rep = node2rep[self.right]
|
|
1147
|
+
if rep then
|
|
1148
|
+
# Yes, do it.
|
|
1149
|
+
rep = rep.clone
|
|
1150
|
+
node = self.right
|
|
1151
|
+
# node.set_parent!(nil)
|
|
1152
|
+
self.set_right!(rep)
|
|
1153
|
+
node2rep_done[node] = rep
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1156
|
+
# Assign the replaced nodes.
|
|
1157
|
+
node2rep_done.each do |node,rep|
|
|
1158
|
+
reassign = node2reassign[node][1].clone
|
|
1159
|
+
self.parent.add_connection(
|
|
1160
|
+
Connection.new(reassign,node.clone))
|
|
1161
|
+
end
|
|
1162
|
+
end
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
##
|
|
1168
|
+
# Describes an expression.
|
|
1169
|
+
#
|
|
1170
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
|
1171
|
+
class Expression
|
|
1172
|
+
|
|
1173
|
+
# Sets the type.
|
|
1174
|
+
def set_type!(type)
|
|
1175
|
+
# Check and set the type.
|
|
1176
|
+
if type.is_a?(Type) then
|
|
1177
|
+
@type = type
|
|
1178
|
+
else
|
|
1179
|
+
raise AnyError, "Invalid class for a type: #{type.class}."
|
|
1180
|
+
end
|
|
1181
|
+
end
|
|
1182
|
+
|
|
1183
|
+
# Maps on the children.
|
|
1184
|
+
def map_nodes!(&ruby_block)
|
|
1185
|
+
# By default, nothing to do.
|
|
1186
|
+
end
|
|
1187
|
+
|
|
1188
|
+
alias_method :map_expressions!, :map_nodes!
|
|
1189
|
+
|
|
1190
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1191
|
+
# node to replace and the corresponding replacement.
|
|
1192
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1193
|
+
# replacement.
|
|
1194
|
+
#
|
|
1195
|
+
# NOTE: the replacement is duplicated.
|
|
1196
|
+
def replace_expressions!(node2rep)
|
|
1197
|
+
# By default, nothing to do.
|
|
1198
|
+
return {}
|
|
1199
|
+
end
|
|
1200
|
+
end
|
|
1201
|
+
|
|
1202
|
+
|
|
1203
|
+
##
|
|
1204
|
+
# Describes a value.
|
|
1205
|
+
class Value
|
|
1206
|
+
|
|
1207
|
+
# Sets the content.
|
|
1208
|
+
def set_content!(content)
|
|
1209
|
+
unless content.is_a?(Numeric) or content.is_a?(HDLRuby::BitString)
|
|
1210
|
+
content = HDLRuby::BitString.new(content.to_s)
|
|
1211
|
+
end
|
|
1212
|
+
@content = content
|
|
1213
|
+
end
|
|
1214
|
+
end
|
|
1215
|
+
|
|
1216
|
+
# Module for mutable expressions with one child.
|
|
1217
|
+
module OneChildMutable
|
|
1218
|
+
# Sets the child.
|
|
1219
|
+
def set_child!(child)
|
|
1220
|
+
# Check and set the child.
|
|
1221
|
+
unless child.is_a?(Expression)
|
|
1222
|
+
raise AnyError,"Invalid class for an expression: #{child.class}"
|
|
1223
|
+
end
|
|
1224
|
+
@child = child
|
|
1225
|
+
# And set its parent.
|
|
1226
|
+
child.parent = self
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
# Maps on the child.
|
|
1230
|
+
def map_nodes!(&ruby_block)
|
|
1231
|
+
@child = ruby_block.call(@child)
|
|
1232
|
+
@child.parent = self unless @child.parent
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1236
|
+
# node to replace and the corresponding replacement.
|
|
1237
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1238
|
+
# replacement.
|
|
1239
|
+
#
|
|
1240
|
+
# NOTE: the replacement is duplicated.
|
|
1241
|
+
def replace_expressions!(node2rep)
|
|
1242
|
+
# First recurse on the child.
|
|
1243
|
+
res = self.child.replace_expressions!(node2rep)
|
|
1244
|
+
# Is there a replacement to do?
|
|
1245
|
+
rep = node2rep[self.child]
|
|
1246
|
+
if rep then
|
|
1247
|
+
# Yes, do it.
|
|
1248
|
+
rep = rep.clone
|
|
1249
|
+
node = self.child
|
|
1250
|
+
# node.set_parent!(nil)
|
|
1251
|
+
self.set_child!(rep)
|
|
1252
|
+
# And register the replacement.
|
|
1253
|
+
res[node] = rep
|
|
1254
|
+
end
|
|
1255
|
+
return res
|
|
1256
|
+
end
|
|
1257
|
+
end
|
|
1258
|
+
|
|
1259
|
+
##
|
|
1260
|
+
# Describes a cast.
|
|
1261
|
+
class Cast
|
|
1262
|
+
include OneChildMutable
|
|
1263
|
+
end
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
##
|
|
1267
|
+
# Describes an operation.
|
|
1268
|
+
#
|
|
1269
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
|
1270
|
+
class Operation
|
|
1271
|
+
|
|
1272
|
+
# Sets the operator.
|
|
1273
|
+
def set_operator!(operator)
|
|
1274
|
+
# Check and set the operator.
|
|
1275
|
+
@operator = operator.to_sym
|
|
1276
|
+
end
|
|
1277
|
+
end
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
##
|
|
1281
|
+
# Describes an unary operation.
|
|
1282
|
+
class Unary
|
|
1283
|
+
include OneChildMutable
|
|
1284
|
+
|
|
1285
|
+
# Moved to OneChildMutable
|
|
1286
|
+
# # Sets the child.
|
|
1287
|
+
# def set_child!(child)
|
|
1288
|
+
# # Check and set the child.
|
|
1289
|
+
# unless child.is_a?(Expression)
|
|
1290
|
+
# raise AnyError,"Invalid class for an expression: #{child.class}"
|
|
1291
|
+
# end
|
|
1292
|
+
# @child = child
|
|
1293
|
+
# # And set its parent.
|
|
1294
|
+
# child.parent = self
|
|
1295
|
+
# end
|
|
1296
|
+
|
|
1297
|
+
# # Maps on the child.
|
|
1298
|
+
# def map_nodes!(&ruby_block)
|
|
1299
|
+
# @child = ruby_block.call(@child)
|
|
1300
|
+
# @child.parent = self unless @child.parent
|
|
1301
|
+
# end
|
|
1302
|
+
end
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
##
|
|
1306
|
+
# Describes an binary operation.
|
|
1307
|
+
class Binary
|
|
1308
|
+
|
|
1309
|
+
# Sets the left.
|
|
1310
|
+
def set_left!(left)
|
|
1311
|
+
# Check and set the left.
|
|
1312
|
+
unless left.is_a?(Expression)
|
|
1313
|
+
raise AnyError,"Invalid class for an expression: #{left.class}"
|
|
1314
|
+
end
|
|
1315
|
+
@left = left
|
|
1316
|
+
# And set its parent.
|
|
1317
|
+
left.parent = self
|
|
1318
|
+
end
|
|
1319
|
+
|
|
1320
|
+
# Sets the right.
|
|
1321
|
+
def set_right!(right)
|
|
1322
|
+
# Check and set the right.
|
|
1323
|
+
unless right.is_a?(Expression)
|
|
1324
|
+
raise AnyError,"Invalid class for an expression: #{right.class}"
|
|
1325
|
+
end
|
|
1326
|
+
@right = right
|
|
1327
|
+
# And set its parent.
|
|
1328
|
+
right.parent = self
|
|
1329
|
+
end
|
|
1330
|
+
|
|
1331
|
+
# Maps on the child.
|
|
1332
|
+
def map_nodes!(&ruby_block)
|
|
1333
|
+
@left = ruby_block.call(@left)
|
|
1334
|
+
@left.parent = self unless @left.parent
|
|
1335
|
+
@right = ruby_block.call(@right)
|
|
1336
|
+
@right.parent = self unless @right.parent
|
|
1337
|
+
end
|
|
1338
|
+
|
|
1339
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1340
|
+
# node to replace and the corresponding replacement.
|
|
1341
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1342
|
+
# replacement.
|
|
1343
|
+
#
|
|
1344
|
+
# NOTE: the replacement is duplicated.
|
|
1345
|
+
def replace_expressions!(node2rep)
|
|
1346
|
+
# First recurse on the children.
|
|
1347
|
+
res = self.left.replace_expressions!(node2rep)
|
|
1348
|
+
res.merge!(self.right.replace_expressions!(node2rep))
|
|
1349
|
+
# Is there a replacement to do on the left?
|
|
1350
|
+
rep = node2rep[self.left]
|
|
1351
|
+
if rep then
|
|
1352
|
+
# Yes, do it.
|
|
1353
|
+
rep = rep.clone
|
|
1354
|
+
node = self.left
|
|
1355
|
+
# node.set_parent!(nil)
|
|
1356
|
+
self.set_left!(rep)
|
|
1357
|
+
# And register the replacement.
|
|
1358
|
+
res[node] = rep
|
|
1359
|
+
end
|
|
1360
|
+
# Is there a replacement to do on the right?
|
|
1361
|
+
rep = node2rep[self.right]
|
|
1362
|
+
if rep then
|
|
1363
|
+
# Yes, do it.
|
|
1364
|
+
rep = rep.clone
|
|
1365
|
+
node = self.right
|
|
1366
|
+
# node.set_parent!(nil)
|
|
1367
|
+
self.set_right!(rep)
|
|
1368
|
+
# And register the replacement.
|
|
1369
|
+
res[node] = rep
|
|
1370
|
+
end
|
|
1371
|
+
|
|
1372
|
+
return res
|
|
1373
|
+
end
|
|
1374
|
+
end
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
##
|
|
1378
|
+
# Describes a section operation (generalization of the ternary operator).
|
|
1379
|
+
#
|
|
1380
|
+
# NOTE: choice is using the value of +select+ as an index.
|
|
1381
|
+
class Select
|
|
1382
|
+
|
|
1383
|
+
# Sets the select.
|
|
1384
|
+
def set_select!(select)
|
|
1385
|
+
# Check and set the selection.
|
|
1386
|
+
unless select.is_a?(Expression)
|
|
1387
|
+
raise AnyError,
|
|
1388
|
+
"Invalid class for an expression: #{select.class}"
|
|
1389
|
+
end
|
|
1390
|
+
@select = select
|
|
1391
|
+
# And set its parent.
|
|
1392
|
+
select.parent = self
|
|
1393
|
+
end
|
|
1394
|
+
|
|
1395
|
+
# Maps on the choices.
|
|
1396
|
+
def map_choices!(&ruby_block)
|
|
1397
|
+
@choices.map! do |choice|
|
|
1398
|
+
choice = ruby_block.call(choice)
|
|
1399
|
+
choice.parent = self unless choice.parent
|
|
1400
|
+
choice
|
|
1401
|
+
end
|
|
1402
|
+
end
|
|
1403
|
+
|
|
1404
|
+
# Deletes a choice.
|
|
1405
|
+
def delete_choice!(choice)
|
|
1406
|
+
if @choices.include?(choice) then
|
|
1407
|
+
# The choice is present, delete it.
|
|
1408
|
+
@choices.delete(choice)
|
|
1409
|
+
# And remove its parent.
|
|
1410
|
+
choice.parent = nil
|
|
1411
|
+
end
|
|
1412
|
+
choice
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1415
|
+
# Maps on the children.
|
|
1416
|
+
def map_nodes!(&ruby_block)
|
|
1417
|
+
@select = ruby_block.call(@select)
|
|
1418
|
+
@select.parent = self unless @select.parent
|
|
1419
|
+
map_choices!(&ruby_block)
|
|
1420
|
+
end
|
|
1421
|
+
|
|
1422
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1423
|
+
# node to replace and the corresponding replacement.
|
|
1424
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1425
|
+
# replacement.
|
|
1426
|
+
#
|
|
1427
|
+
# NOTE: the replacement is duplicated.
|
|
1428
|
+
def replace_expressions!(node2rep)
|
|
1429
|
+
# First recurse on the children.
|
|
1430
|
+
res = {}
|
|
1431
|
+
self.each_node do |node|
|
|
1432
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
1433
|
+
end
|
|
1434
|
+
# Is there a replacement to do on the select?
|
|
1435
|
+
rep = node2rep[self.select]
|
|
1436
|
+
if rep then
|
|
1437
|
+
# Yes, do it.
|
|
1438
|
+
rep = rep.clone
|
|
1439
|
+
node = self.select
|
|
1440
|
+
# node.set_parent!(nil)
|
|
1441
|
+
self.set_select!(rep)
|
|
1442
|
+
# And register the replacement.
|
|
1443
|
+
res[node] = rep
|
|
1444
|
+
end
|
|
1445
|
+
# Is there a replacement of on a choice.
|
|
1446
|
+
self.map_choices! do |choice|
|
|
1447
|
+
rep = node2rep[choice]
|
|
1448
|
+
if rep then
|
|
1449
|
+
# Yes, do it.
|
|
1450
|
+
rep = rep.clone
|
|
1451
|
+
node = choice
|
|
1452
|
+
# node.set_parent!(nil)
|
|
1453
|
+
# And register the replacement.
|
|
1454
|
+
res[node] = rep
|
|
1455
|
+
rep
|
|
1456
|
+
else
|
|
1457
|
+
choice
|
|
1458
|
+
end
|
|
1459
|
+
end
|
|
1460
|
+
return res
|
|
1461
|
+
end
|
|
1462
|
+
end
|
|
1463
|
+
|
|
1464
|
+
# Module adding some (but not all) mutable methods to Concat and
|
|
1465
|
+
# RefConcat.
|
|
1466
|
+
module MutableConcat
|
|
1467
|
+
|
|
1468
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1469
|
+
# node to replace and the corresponding replacement.
|
|
1470
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1471
|
+
# replacement.
|
|
1472
|
+
#
|
|
1473
|
+
# NOTE: the replacement is duplicated.
|
|
1474
|
+
def replace_expressions!(node2rep)
|
|
1475
|
+
# First recurse on the children.
|
|
1476
|
+
res = {}
|
|
1477
|
+
self.each_node do |node|
|
|
1478
|
+
res.merge!(node.replace_expressions!(node2rep))
|
|
1479
|
+
end
|
|
1480
|
+
# Is there a replacement of on a sub node?
|
|
1481
|
+
self.map_nodes! do |sub|
|
|
1482
|
+
rep = node2rep[sub]
|
|
1483
|
+
if rep then
|
|
1484
|
+
# Yes, do it.
|
|
1485
|
+
rep = rep.clone
|
|
1486
|
+
node = sub
|
|
1487
|
+
# node.set_parent!(nil)
|
|
1488
|
+
# And register the replacement.
|
|
1489
|
+
res[node] = rep
|
|
1490
|
+
rep
|
|
1491
|
+
else
|
|
1492
|
+
sub
|
|
1493
|
+
end
|
|
1494
|
+
end
|
|
1495
|
+
return res
|
|
1496
|
+
end
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
##
|
|
1501
|
+
# Describes a concatenation expression.
|
|
1502
|
+
class Concat
|
|
1503
|
+
include MutableConcat
|
|
1504
|
+
|
|
1505
|
+
# Maps on the expression.
|
|
1506
|
+
def map_expressions!(&ruby_block)
|
|
1507
|
+
@expressions.map! do |expression|
|
|
1508
|
+
expression = ruby_block.call(expression)
|
|
1509
|
+
expression.parent = self unless expression.parent
|
|
1510
|
+
expression
|
|
1511
|
+
end
|
|
1512
|
+
end
|
|
1513
|
+
|
|
1514
|
+
alias_method :map_nodes!, :map_expressions!
|
|
1515
|
+
|
|
1516
|
+
# Delete an expression.
|
|
1517
|
+
def delete_expression!(expression)
|
|
1518
|
+
if @expressions.include?(expression) then
|
|
1519
|
+
# The expression is present, delete it.
|
|
1520
|
+
@expressions.delete(expression)
|
|
1521
|
+
# And remove its parent.
|
|
1522
|
+
expression.parent = nil
|
|
1523
|
+
end
|
|
1524
|
+
expression
|
|
1525
|
+
end
|
|
1526
|
+
|
|
1527
|
+
end
|
|
1528
|
+
|
|
1529
|
+
|
|
1530
|
+
##
|
|
1531
|
+
# Describes a reference expression.
|
|
1532
|
+
#
|
|
1533
|
+
# NOTE: this is an abstract class which is not to be used directly.
|
|
1534
|
+
class Ref
|
|
1535
|
+
# Maps on the children.
|
|
1536
|
+
def map_nodes!(&ruby_block)
|
|
1537
|
+
# Nothing to do.
|
|
1538
|
+
end
|
|
1539
|
+
end
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
##
|
|
1543
|
+
# Describes concatenation reference.
|
|
1544
|
+
class RefConcat
|
|
1545
|
+
include MutableConcat
|
|
1546
|
+
|
|
1547
|
+
# Maps on the references.
|
|
1548
|
+
def map_refs!(&ruby_block)
|
|
1549
|
+
@refs.map! do |ref|
|
|
1550
|
+
ref = ruby_block.call(ref)
|
|
1551
|
+
ref.parent = self unless ref.parent
|
|
1552
|
+
ref
|
|
1553
|
+
end
|
|
1554
|
+
end
|
|
1555
|
+
|
|
1556
|
+
alias_method :map_nodes!, :map_refs!
|
|
1557
|
+
|
|
1558
|
+
# Delete a reference.
|
|
1559
|
+
def delete_ref!(ref)
|
|
1560
|
+
if @refs.include?(ref) then
|
|
1561
|
+
# The ref is present, delete it.
|
|
1562
|
+
@refs.delete(ref)
|
|
1563
|
+
# And remove its parent.
|
|
1564
|
+
ref.parent = nil
|
|
1565
|
+
end
|
|
1566
|
+
ref
|
|
1567
|
+
end
|
|
1568
|
+
|
|
1569
|
+
end
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
##
|
|
1573
|
+
# Describes a index reference.
|
|
1574
|
+
class RefIndex
|
|
1575
|
+
|
|
1576
|
+
# Sets the base reference.
|
|
1577
|
+
def set_ref!(ref)
|
|
1578
|
+
# Check and set the accessed reference.
|
|
1579
|
+
unless ref.is_a?(Ref) then
|
|
1580
|
+
raise AnyError, "Invalid class for a reference: #{ref.class}."
|
|
1581
|
+
end
|
|
1582
|
+
@ref = ref
|
|
1583
|
+
# And set its parent.
|
|
1584
|
+
ref.parent = self
|
|
1585
|
+
end
|
|
1586
|
+
|
|
1587
|
+
# Sets the index.
|
|
1588
|
+
def set_index!(ref)
|
|
1589
|
+
# Check and set the index.
|
|
1590
|
+
unless index.is_a?(Expression) then
|
|
1591
|
+
raise AnyError,
|
|
1592
|
+
"Invalid class for an index reference: #{index.class}."
|
|
1593
|
+
end
|
|
1594
|
+
@index = index
|
|
1595
|
+
# And set its parent.
|
|
1596
|
+
index.parent = self
|
|
1597
|
+
end
|
|
1598
|
+
|
|
1599
|
+
# Maps on the children.
|
|
1600
|
+
def map_nodes!(&ruby_block)
|
|
1601
|
+
@index = ruby_block.call(@index)
|
|
1602
|
+
@index.parent = self unless @index.parent
|
|
1603
|
+
@ref = ruby_block.call(@ref)
|
|
1604
|
+
@ref.parent = self unless @ref.parent
|
|
1605
|
+
end
|
|
1606
|
+
|
|
1607
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1608
|
+
# node to replace and the corresponding replacement.
|
|
1609
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1610
|
+
# replacement.
|
|
1611
|
+
#
|
|
1612
|
+
# NOTE: the replacement is duplicated.
|
|
1613
|
+
def replace_expressions!(node2rep)
|
|
1614
|
+
# First recurse on the ref.
|
|
1615
|
+
res = self.ref.replace_expressions!(node2rep)
|
|
1616
|
+
# And and the index.
|
|
1617
|
+
res = self.index.replace_expressions!(node2rep)
|
|
1618
|
+
|
|
1619
|
+
# Is there a replacement to on the ref?
|
|
1620
|
+
rep = node2rep[self.ref]
|
|
1621
|
+
if rep then
|
|
1622
|
+
# Yes, do it.
|
|
1623
|
+
rep = rep.clone
|
|
1624
|
+
node = self.ref
|
|
1625
|
+
# node.set_parent!(nil)
|
|
1626
|
+
self.set_ref!(rep)
|
|
1627
|
+
# And register the replacement.
|
|
1628
|
+
res[node] = rep
|
|
1629
|
+
end
|
|
1630
|
+
# Is there a replacement to on the index?
|
|
1631
|
+
rep = node2rep[self.index]
|
|
1632
|
+
if rep then
|
|
1633
|
+
# Yes, do it.
|
|
1634
|
+
rep = rep.clone
|
|
1635
|
+
node = self.index
|
|
1636
|
+
# node.set_parent!(nil)
|
|
1637
|
+
self.set_index!(rep)
|
|
1638
|
+
# And register the replacement.
|
|
1639
|
+
res[node] = rep
|
|
1640
|
+
end
|
|
1641
|
+
return res
|
|
1642
|
+
end
|
|
1643
|
+
end
|
|
1644
|
+
|
|
1645
|
+
|
|
1646
|
+
##
|
|
1647
|
+
# Describes a range reference.
|
|
1648
|
+
class RefRange
|
|
1649
|
+
|
|
1650
|
+
# Sets the base reference.
|
|
1651
|
+
def set_ref!(ref)
|
|
1652
|
+
# Check and set the refered object.
|
|
1653
|
+
# unless ref.is_a?(Ref) then
|
|
1654
|
+
unless ref.is_a?(Expression) then
|
|
1655
|
+
raise AnyError, "Invalid class for a reference: #{ref.class}."
|
|
1656
|
+
end
|
|
1657
|
+
@ref = ref
|
|
1658
|
+
# And set its parent.
|
|
1659
|
+
ref.parent = self
|
|
1660
|
+
end
|
|
1661
|
+
|
|
1662
|
+
# Sets the range.
|
|
1663
|
+
def set_range!(range)
|
|
1664
|
+
# Check and set the range.
|
|
1665
|
+
first = range.first
|
|
1666
|
+
unless first.is_a?(Expression) then
|
|
1667
|
+
raise AnyError,
|
|
1668
|
+
"Invalid class for a range first: #{first.class}."
|
|
1669
|
+
end
|
|
1670
|
+
last = range.last
|
|
1671
|
+
unless last.is_a?(Expression) then
|
|
1672
|
+
raise AnyError, "Invalid class for a range last: #{last.class}."
|
|
1673
|
+
end
|
|
1674
|
+
@range = first..last
|
|
1675
|
+
# And set their parents.
|
|
1676
|
+
first.parent = last.parent = self
|
|
1677
|
+
end
|
|
1678
|
+
|
|
1679
|
+
# Maps on the children.
|
|
1680
|
+
def map_nodes!(&ruby_block)
|
|
1681
|
+
@range = ruby_block.call(@range.first)..ruby_block.call(@range.last)
|
|
1682
|
+
@range.first.parent = self unless @range.first.parent
|
|
1683
|
+
@range.last.parent = self unless @range.last.parent
|
|
1684
|
+
@ref = ruby_block.call(@ref)
|
|
1685
|
+
@ref.parent = self unless @ref.parent
|
|
1686
|
+
end
|
|
1687
|
+
|
|
1688
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1689
|
+
# node to replace and the corresponding replacement.
|
|
1690
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1691
|
+
# replacement.
|
|
1692
|
+
#
|
|
1693
|
+
# NOTE: the replacement is duplicated.
|
|
1694
|
+
def replace_expressions!(node2rep)
|
|
1695
|
+
# First recurse on the ref.
|
|
1696
|
+
res = self.ref.replace_expressions!(node2rep)
|
|
1697
|
+
# And and the range.
|
|
1698
|
+
res = self.range.first.replace_expressions!(node2rep)
|
|
1699
|
+
res = self.range.last.replace_expressions!(node2rep)
|
|
1700
|
+
|
|
1701
|
+
# Is there a replacement to on the ref?
|
|
1702
|
+
rep = node2rep[self.ref]
|
|
1703
|
+
if rep then
|
|
1704
|
+
# Yes, do it.
|
|
1705
|
+
rep = rep.clone
|
|
1706
|
+
node = self.ref
|
|
1707
|
+
# node.set_parent!(nil)
|
|
1708
|
+
self.set_ref!(rep)
|
|
1709
|
+
# And register the replacement.
|
|
1710
|
+
res[node] = rep
|
|
1711
|
+
end
|
|
1712
|
+
# Is there a replacement to on the range first?
|
|
1713
|
+
range = self.range
|
|
1714
|
+
rep = node2rep[range.first]
|
|
1715
|
+
if rep then
|
|
1716
|
+
# Yes, do it.
|
|
1717
|
+
rep = rep.clone
|
|
1718
|
+
node = range.first
|
|
1719
|
+
# node.set_parent!(nil)
|
|
1720
|
+
range.first = rep
|
|
1721
|
+
# And register the replacement.
|
|
1722
|
+
res[node] = rep
|
|
1723
|
+
end
|
|
1724
|
+
rep = node2rep[range.last]
|
|
1725
|
+
if rep then
|
|
1726
|
+
# Yes, do it.
|
|
1727
|
+
rep = rep.clone
|
|
1728
|
+
node = range.last
|
|
1729
|
+
# node.set_parent!(nil)
|
|
1730
|
+
range.last = rep
|
|
1731
|
+
# And register the replacement.
|
|
1732
|
+
res[node] = rep
|
|
1733
|
+
end
|
|
1734
|
+
self.set_range!(range)
|
|
1735
|
+
return res
|
|
1736
|
+
end
|
|
1737
|
+
end
|
|
1738
|
+
|
|
1739
|
+
|
|
1740
|
+
##
|
|
1741
|
+
# Describes a name reference.
|
|
1742
|
+
class RefName
|
|
1743
|
+
# Sets the base reference.
|
|
1744
|
+
def set_ref!(ref)
|
|
1745
|
+
# Check and set the accessed reference.
|
|
1746
|
+
unless ref.is_a?(Ref) then
|
|
1747
|
+
raise AnyError, "Invalid class for a reference: #{ref.class}."
|
|
1748
|
+
end
|
|
1749
|
+
@ref = ref
|
|
1750
|
+
# And set its parent.
|
|
1751
|
+
ref.parent = self
|
|
1752
|
+
end
|
|
1753
|
+
|
|
1754
|
+
# Sets the name.
|
|
1755
|
+
def set_name!(name)
|
|
1756
|
+
# Check and set the symbol.
|
|
1757
|
+
@name = name.to_sym
|
|
1758
|
+
end
|
|
1759
|
+
|
|
1760
|
+
# Maps on the children.
|
|
1761
|
+
def map_nodes!(&ruby_block)
|
|
1762
|
+
@ref = ruby_block.call(@ref)
|
|
1763
|
+
@ref.parent = self unless @ref.parent
|
|
1764
|
+
end
|
|
1765
|
+
|
|
1766
|
+
# Replaces sub expressions using +node2rep+ table indicating the
|
|
1767
|
+
# node to replace and the corresponding replacement.
|
|
1768
|
+
# Returns the actually replaced nodes and their corresponding
|
|
1769
|
+
# replacement.
|
|
1770
|
+
#
|
|
1771
|
+
# NOTE: the replacement is duplicated.
|
|
1772
|
+
def replace_expressions!(node2rep)
|
|
1773
|
+
# First recurse on the ref.
|
|
1774
|
+
res = self.ref.replace_expressions!(node2rep)
|
|
1775
|
+
|
|
1776
|
+
# Is there a replacement to on the ref?
|
|
1777
|
+
rep = node2rep[self.ref]
|
|
1778
|
+
if rep then
|
|
1779
|
+
# Yes, do it.
|
|
1780
|
+
rep = rep.clone
|
|
1781
|
+
node = self.ref
|
|
1782
|
+
# node.set_parent!(nil)
|
|
1783
|
+
self.set_ref!(rep)
|
|
1784
|
+
# And register the replacement.
|
|
1785
|
+
res[node] = rep
|
|
1786
|
+
end
|
|
1787
|
+
return res
|
|
1788
|
+
end
|
|
1789
|
+
end
|
|
1790
|
+
|
|
1791
|
+
|
|
1792
|
+
##
|
|
1793
|
+
# Describe a this reference.
|
|
1794
|
+
#
|
|
1795
|
+
# This is the current system.
|
|
1796
|
+
class RefThis
|
|
1797
|
+
|
|
1798
|
+
# Maps on the children.
|
|
1799
|
+
def map_nodes!(&ruby_block)
|
|
1800
|
+
# Nothing to do.
|
|
1801
|
+
end
|
|
1802
|
+
end
|
|
1803
|
+
end
|