multiarray 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +61 -0
- data/Rakefile +1 -1
- data/lib/multiarray.rb +28 -0
- data/lib/multiarray/complex.rb +310 -13
- data/lib/multiarray/composite.rb +7 -0
- data/lib/multiarray/diagonal.rb +18 -3
- data/lib/multiarray/elementwise.rb +7 -2
- data/lib/multiarray/float.rb +43 -3
- data/lib/multiarray/gcccache.rb +4 -1
- data/lib/multiarray/gcccontext.rb +119 -21
- data/lib/multiarray/gccfunction.rb +92 -3
- data/lib/multiarray/gcctype.rb +26 -0
- data/lib/multiarray/gccvalue.rb +204 -2
- data/lib/multiarray/histogram.rb +65 -1
- data/lib/multiarray/index.rb +11 -0
- data/lib/multiarray/inject.rb +18 -1
- data/lib/multiarray/int.rb +49 -18
- data/lib/multiarray/integral.rb +65 -1
- data/lib/multiarray/lambda.rb +19 -5
- data/lib/multiarray/list.rb +8 -0
- data/lib/multiarray/lookup.rb +8 -1
- data/lib/multiarray/lut.rb +96 -2
- data/lib/multiarray/methods.rb +13 -3
- data/lib/multiarray/multiarray.rb +11 -0
- data/lib/multiarray/node.rb +52 -9
- data/lib/multiarray/operations.rb +118 -15
- data/lib/multiarray/pointer.rb +35 -1
- data/lib/multiarray/rgb.rb +139 -14
- data/lib/multiarray/sequence.rb +140 -2
- data/lib/multiarray/shortcuts.rb +76 -30
- data/lib/multiarray/store.rb +54 -0
- data/lib/multiarray/variable.rb +19 -0
- data/test/tc_lazy.rb +9 -0
- metadata +3 -3
data/lib/multiarray/gcctype.rb
CHANGED
@@ -17,12 +17,25 @@
|
|
17
17
|
# Namespace of Hornetseye computer vision library
|
18
18
|
module Hornetseye
|
19
19
|
|
20
|
+
# Class for translating native types from Ruby to C
|
21
|
+
#
|
22
|
+
# @private
|
20
23
|
class GCCType
|
21
24
|
|
25
|
+
# Construct GCC type
|
26
|
+
#
|
27
|
+
# @param [Class] typecode Native type (e.g. +UBYTE+).
|
28
|
+
#
|
29
|
+
# @private
|
22
30
|
def initialize( typecode )
|
23
31
|
@typecode = typecode
|
24
32
|
end
|
25
33
|
|
34
|
+
# Get C identifier for native type
|
35
|
+
#
|
36
|
+
# @return [String] String with valid C syntax to declare type.
|
37
|
+
#
|
38
|
+
# @private
|
26
39
|
def identifier
|
27
40
|
case @typecode
|
28
41
|
when nil
|
@@ -56,6 +69,11 @@ module Hornetseye
|
|
56
69
|
end
|
57
70
|
end
|
58
71
|
|
72
|
+
# Get array of C identifiers for native type
|
73
|
+
#
|
74
|
+
# @return [Array<String>] Array of C declarations for the elements of the type.
|
75
|
+
#
|
76
|
+
# @private
|
59
77
|
def identifiers
|
60
78
|
if @typecode < Composite
|
61
79
|
GCCType.new( @typecode.element_type ).identifiers * @typecode.num_elements
|
@@ -64,6 +82,14 @@ module Hornetseye
|
|
64
82
|
end
|
65
83
|
end
|
66
84
|
|
85
|
+
# Get code for converting Ruby VALUE to C value
|
86
|
+
#
|
87
|
+
# This method returns a nameless function. The nameless function is used for
|
88
|
+
# getting the code to convert a given parameter to a C value of this type.
|
89
|
+
#
|
90
|
+
# @return [Proc] Nameless function accepting a C expression to be converted.
|
91
|
+
#
|
92
|
+
# @private
|
67
93
|
def r2c
|
68
94
|
case @typecode
|
69
95
|
when BOOL
|
data/lib/multiarray/gccvalue.rb
CHANGED
@@ -16,12 +16,14 @@
|
|
16
16
|
|
17
17
|
# Namespace of Hornetseye computer vision library
|
18
18
|
module Hornetseye
|
19
|
-
|
19
|
+
|
20
|
+
# Class for generating code handling C values
|
21
|
+
# @private
|
20
22
|
class GCCValue
|
21
23
|
|
22
24
|
class << self
|
23
25
|
|
24
|
-
# Check compatibility of other type
|
26
|
+
# Check compatibility of other type
|
25
27
|
#
|
26
28
|
# This method checks whether binary operations with the other Ruby object can
|
27
29
|
# be performed without requiring coercion.
|
@@ -29,17 +31,35 @@ module Hornetseye
|
|
29
31
|
# @param [Object] value The other Ruby object.
|
30
32
|
#
|
31
33
|
# @return [Boolean] Returns +false+ if Ruby object requires coercion.
|
34
|
+
#
|
35
|
+
# @private
|
32
36
|
def generic?( value )
|
33
37
|
value.is_a?( GCCValue ) or value.is_a?( Fixnum ) or
|
34
38
|
value.is_a?( Float )
|
35
39
|
end
|
36
40
|
|
41
|
+
# Meta-programming method used to define unary operations at the beginning
|
42
|
+
#
|
43
|
+
# @param [Symbol,String] op Name of unary operation.
|
44
|
+
# @param [Symbol,String] opcode Name of unary operation in C.
|
45
|
+
#
|
46
|
+
# @return [Proc] The new method.
|
47
|
+
#
|
48
|
+
# @private
|
37
49
|
def define_unary_op( op, opcode = op )
|
38
50
|
define_method( op ) do
|
39
51
|
GCCValue.new @function, "#{opcode}( #{self} )"
|
40
52
|
end
|
41
53
|
end
|
42
54
|
|
55
|
+
# Meta-programming method used to define unary methods at the beginning
|
56
|
+
#
|
57
|
+
# @param [Symbol,String] op Name of unary method.
|
58
|
+
# @param [Symbol,String] opcode Name of unary method in C.
|
59
|
+
#
|
60
|
+
# @return [Proc] The new method.
|
61
|
+
#
|
62
|
+
# @private
|
43
63
|
def define_unary_method( mod, op, opcode = op )
|
44
64
|
mod.module_eval do
|
45
65
|
define_method( "#{op}_with_gcc" ) do |a|
|
@@ -55,6 +75,14 @@ module Hornetseye
|
|
55
75
|
end
|
56
76
|
end
|
57
77
|
|
78
|
+
# Meta-programming method used to define unary methods at the beginning
|
79
|
+
#
|
80
|
+
# @param [Symbol,String] op Name of unary method.
|
81
|
+
# @param [Symbol,String] opcode Name of unary method in C.
|
82
|
+
#
|
83
|
+
# @return [Proc] The new method.
|
84
|
+
#
|
85
|
+
# @private
|
58
86
|
def define_binary_op( op, opcode = op )
|
59
87
|
define_method( op ) do |other|
|
60
88
|
if GCCValue.generic? other
|
@@ -66,6 +94,14 @@ module Hornetseye
|
|
66
94
|
end
|
67
95
|
end
|
68
96
|
|
97
|
+
# Meta-programming method used to define binary methods at the beginning
|
98
|
+
#
|
99
|
+
# @param [Symbol,String] op Name of binary method.
|
100
|
+
# @param [Symbol,String] opcode Name of binary method in C.
|
101
|
+
#
|
102
|
+
# @return [Proc] The new method.
|
103
|
+
#
|
104
|
+
# @private
|
69
105
|
def define_binary_method( mod, op, opcode = op )
|
70
106
|
mod.module_eval do
|
71
107
|
define_method( "#{op}_with_gcc" ) do |a,b|
|
@@ -84,8 +120,19 @@ module Hornetseye
|
|
84
120
|
|
85
121
|
end
|
86
122
|
|
123
|
+
# Get current function context
|
124
|
+
#
|
125
|
+
# @return [GCCFunction] The function this value is part of.
|
126
|
+
#
|
127
|
+
# @private
|
87
128
|
attr_reader :function
|
88
129
|
|
130
|
+
# Constructor for GCC value
|
131
|
+
#
|
132
|
+
# @param [GCCFunction] function The function context this value is part of.
|
133
|
+
# @param [String] descriptor C code to compute this value.
|
134
|
+
#
|
135
|
+
# @private
|
89
136
|
def initialize( function, descriptor )
|
90
137
|
@function = function
|
91
138
|
@descriptor = descriptor
|
@@ -94,6 +141,8 @@ module Hornetseye
|
|
94
141
|
# Display descriptor of this object
|
95
142
|
#
|
96
143
|
# @return [String] Returns the descriptor of this object.
|
144
|
+
#
|
145
|
+
# @private
|
97
146
|
def inspect
|
98
147
|
@descriptor
|
99
148
|
end
|
@@ -101,6 +150,8 @@ module Hornetseye
|
|
101
150
|
# Get descriptor of this object
|
102
151
|
#
|
103
152
|
# @return [String] Returns the descriptor of this object.
|
153
|
+
#
|
154
|
+
# @private
|
104
155
|
def to_s
|
105
156
|
@descriptor
|
106
157
|
end
|
@@ -110,15 +161,27 @@ module Hornetseye
|
|
110
161
|
# @param [Object] value The new value.
|
111
162
|
#
|
112
163
|
# @return [Object] Returns +value+.
|
164
|
+
#
|
165
|
+
# @private
|
113
166
|
def store( value )
|
114
167
|
@function << "#{@function.indent}#{self} = #{value};\n"
|
115
168
|
value
|
116
169
|
end
|
117
170
|
|
171
|
+
# Indicate whether this object can be compiled
|
172
|
+
#
|
173
|
+
# @return [Boolean] Returns +false+.
|
174
|
+
#
|
175
|
+
# @private
|
118
176
|
def compilable?
|
119
177
|
false
|
120
178
|
end
|
121
179
|
|
180
|
+
# Add code to read all components of a typed value from memory
|
181
|
+
#
|
182
|
+
# @return [Array<GCCValue>] An array of objects referencing values in C.
|
183
|
+
#
|
184
|
+
# @private
|
122
185
|
def load( typecode )
|
123
186
|
offset = 0
|
124
187
|
typecode.typecodes.collect do |t|
|
@@ -129,6 +192,13 @@ module Hornetseye
|
|
129
192
|
end
|
130
193
|
end
|
131
194
|
|
195
|
+
# Add code to write all components of a typed value to memory
|
196
|
+
#
|
197
|
+
# @param [Node] value Value to write to memory.
|
198
|
+
#
|
199
|
+
# @return [Object] The return value should be ignored.
|
200
|
+
#
|
201
|
+
# @private
|
132
202
|
def save( value )
|
133
203
|
offset = 0
|
134
204
|
value.class.typecodes.zip( value.values ).each do |t,v|
|
@@ -137,42 +207,98 @@ module Hornetseye
|
|
137
207
|
end
|
138
208
|
end
|
139
209
|
|
210
|
+
# Complex conjugate of real value
|
211
|
+
#
|
212
|
+
# @return [GCCValue] Returns +self+.
|
213
|
+
#
|
214
|
+
# @private
|
140
215
|
def conj
|
141
216
|
self
|
142
217
|
end
|
143
218
|
|
219
|
+
# Generate code for computing absolute value
|
220
|
+
#
|
221
|
+
# @return [GCCValue] C value referring to the result.
|
222
|
+
#
|
223
|
+
# @private
|
144
224
|
def abs
|
145
225
|
( self >= 0 ).conditional self, -self
|
146
226
|
end
|
147
227
|
|
228
|
+
# Generate code for computing complex argument of real value
|
229
|
+
#
|
230
|
+
# @return [GCCValue] C value referring to the result.
|
231
|
+
#
|
232
|
+
# @private
|
148
233
|
def arg
|
149
234
|
( self >= 0 ).conditional 0, Math::PI
|
150
235
|
end
|
151
236
|
|
237
|
+
# Red colour component of real value
|
238
|
+
#
|
239
|
+
# @return [GCCValue] Returns +self+.
|
240
|
+
#
|
241
|
+
# @private
|
152
242
|
def r
|
153
243
|
self
|
154
244
|
end
|
155
245
|
|
246
|
+
# Green colour component of real value
|
247
|
+
#
|
248
|
+
# @return [GCCValue] Returns +self+.
|
249
|
+
#
|
250
|
+
# @private
|
156
251
|
def g
|
157
252
|
self
|
158
253
|
end
|
159
254
|
|
255
|
+
# Blue colour component of real value
|
256
|
+
#
|
257
|
+
# @return [GCCValue] Returns +self+.
|
258
|
+
#
|
259
|
+
# @private
|
160
260
|
def b
|
161
261
|
self
|
162
262
|
end
|
163
263
|
|
264
|
+
# Real component of real value
|
265
|
+
#
|
266
|
+
# @return [GCCValue] Returns +self+.
|
267
|
+
#
|
268
|
+
# @private
|
164
269
|
def real
|
165
270
|
self
|
166
271
|
end
|
167
272
|
|
273
|
+
# Imaginary component of real value
|
274
|
+
#
|
275
|
+
# @return [Integer] Returns +0+.
|
276
|
+
#
|
277
|
+
# @private
|
168
278
|
def imag
|
169
279
|
0
|
170
280
|
end
|
171
281
|
|
282
|
+
# Create code for conditional selection of value
|
283
|
+
#
|
284
|
+
# @param [GCCValue,Object] a First value.
|
285
|
+
# @param [GCCValue,Object] b Second value.
|
286
|
+
#
|
287
|
+
# @return [GCCValue] C value referring to result.
|
288
|
+
#
|
289
|
+
# @private
|
172
290
|
def conditional( a, b )
|
173
291
|
GCCValue.new @function, "( #{self} ) ? ( #{a} ) : ( #{b} )"
|
174
292
|
end
|
175
293
|
|
294
|
+
# Create code for conditional selection of RGB value
|
295
|
+
#
|
296
|
+
# @param [GCCValue,Object] a First value.
|
297
|
+
# @param [GCCValue,Object] b Second value.
|
298
|
+
#
|
299
|
+
# @return [GCCValue] C value referring to result.
|
300
|
+
#
|
301
|
+
# @private
|
176
302
|
def conditional_with_rgb( a, b )
|
177
303
|
if a.is_a?( RGB ) or b.is_a?( RGB )
|
178
304
|
Hornetseye::RGB( conditional( a.r, b.r ), conditional( a.g, b.g ),
|
@@ -184,6 +310,14 @@ module Hornetseye
|
|
184
310
|
|
185
311
|
alias_method_chain :conditional, :rgb
|
186
312
|
|
313
|
+
# Create code for conditional selection of complex value
|
314
|
+
#
|
315
|
+
# @param [GCCValue,Object] a First value.
|
316
|
+
# @param [GCCValue,Object] b Second value.
|
317
|
+
#
|
318
|
+
# @return [GCCValue] C value referring to result.
|
319
|
+
#
|
320
|
+
# @private
|
187
321
|
def conditional_with_complex( a, b )
|
188
322
|
if a.is_a?( InternalComplex ) or b.is_a?( InternalComplex )
|
189
323
|
InternalComplex.new conditional( a.real, b.real ),
|
@@ -235,26 +369,58 @@ module Hornetseye
|
|
235
369
|
define_binary_method Math, :atan2
|
236
370
|
define_binary_method Math, :hypot
|
237
371
|
|
372
|
+
# Generate code for checking whether value is equal to zero
|
373
|
+
#
|
374
|
+
# @return [GCCValue] C value refering to the result.
|
375
|
+
#
|
376
|
+
# @private
|
238
377
|
def zero?
|
239
378
|
GCCValue.new @function, "( #{self} ) == 0"
|
240
379
|
end
|
241
380
|
|
381
|
+
# Generate code for checking whether value is not equal to zero
|
382
|
+
#
|
383
|
+
# @return [GCCValue] C value refering to the result.
|
384
|
+
#
|
385
|
+
# @private
|
242
386
|
def nonzero?
|
243
387
|
GCCValue.new @function, "( #{self} ) != 0"
|
244
388
|
end
|
245
389
|
|
390
|
+
# Generate code for computing largest integer value not greater than this value
|
391
|
+
#
|
392
|
+
# @return [GCCValue] C value refering to the result.
|
393
|
+
#
|
394
|
+
# @private
|
246
395
|
def floor
|
247
396
|
GCCValue.new @function, "floor( #{self} )"
|
248
397
|
end
|
249
398
|
|
399
|
+
# Generate code for computing smallest integer value not less than this value
|
400
|
+
#
|
401
|
+
# @return [GCCValue] C value refering to the result.
|
402
|
+
#
|
403
|
+
# @private
|
250
404
|
def ceil
|
251
405
|
GCCValue.new @function, "ceil( #{self} )"
|
252
406
|
end
|
253
407
|
|
408
|
+
# Generate code for rounding to nearest integer
|
409
|
+
#
|
410
|
+
# @return [GCCValue] C value refering to the result.
|
411
|
+
#
|
412
|
+
# @private
|
254
413
|
def round
|
255
414
|
GCCValue.new @function, "round( #{self} )"
|
256
415
|
end
|
257
416
|
|
417
|
+
# Generate code for computing exponentiation
|
418
|
+
#
|
419
|
+
# @param [Object,GCCValue] other Second operand for binary operation.
|
420
|
+
#
|
421
|
+
# @return [GCCValue] C value refering to the result.
|
422
|
+
#
|
423
|
+
# @private
|
258
424
|
def **( other )
|
259
425
|
if GCCValue.generic? other
|
260
426
|
GCCValue.new @function, "pow( #{self}, #{other} )"
|
@@ -264,16 +430,37 @@ module Hornetseye
|
|
264
430
|
end
|
265
431
|
end
|
266
432
|
|
433
|
+
# Generate code for selecting larger value
|
434
|
+
#
|
435
|
+
# @param [Object,GCCValue] other Second operand for binary operation.
|
436
|
+
#
|
437
|
+
# @return [GCCValue] C value refering to the result.
|
438
|
+
#
|
439
|
+
# @private
|
267
440
|
def major( other )
|
268
441
|
GCCValue.new @function,
|
269
442
|
"( ( #{self} ) >= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
|
270
443
|
end
|
271
444
|
|
445
|
+
# Generate code for selecting smaller value
|
446
|
+
#
|
447
|
+
# @param [Object,GCCValue] other Second operand for binary operation.
|
448
|
+
#
|
449
|
+
# @return [GCCValue] C value refering to the result.
|
450
|
+
#
|
451
|
+
# @private
|
272
452
|
def minor( other )
|
273
453
|
GCCValue.new @function,
|
274
454
|
"( ( #{self} ) <= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
|
275
455
|
end
|
276
456
|
|
457
|
+
# Generate a +for+ loop in C
|
458
|
+
#
|
459
|
+
# @param [Proc] action Code for generating loop body.
|
460
|
+
#
|
461
|
+
# @return [GCCValue] Returns +self+.
|
462
|
+
#
|
463
|
+
# @private
|
277
464
|
def times( &action )
|
278
465
|
i = @function.variable INT, 'i'
|
279
466
|
@function << "#{@function.indent}for ( #{i} = 0; " +
|
@@ -285,6 +472,14 @@ module Hornetseye
|
|
285
472
|
self
|
286
473
|
end
|
287
474
|
|
475
|
+
# Generate a +for+ loop in C
|
476
|
+
#
|
477
|
+
# @param [GCCValue,Object] other Upper limit for loop.
|
478
|
+
# @param [Proc] action Code for generating loop body.
|
479
|
+
#
|
480
|
+
# @return [GCCValue] Returns +self+.
|
481
|
+
#
|
482
|
+
# @private
|
288
483
|
def upto( other, &action )
|
289
484
|
i = @function.variable INT, 'i'
|
290
485
|
@function << "#{@function.indent}for ( #{i} = #{self}; " +
|
@@ -296,6 +491,13 @@ module Hornetseye
|
|
296
491
|
self
|
297
492
|
end
|
298
493
|
|
494
|
+
# Type coercion for GCC values
|
495
|
+
#
|
496
|
+
# @param [Object] other Other value to coerce with.
|
497
|
+
#
|
498
|
+
# @return [Array<GCCValue>] Result of coercion.
|
499
|
+
#
|
500
|
+
# @private
|
299
501
|
def coerce( other )
|
300
502
|
if other.is_a? GCCValue
|
301
503
|
return other, self
|
data/lib/multiarray/histogram.rb
CHANGED
@@ -14,30 +14,66 @@
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
|
17
|
+
# Namespace of Hornetseye computer vision library
|
17
18
|
module Hornetseye
|
18
19
|
|
20
|
+
# Class for representing histogram computations
|
19
21
|
class Histogram < Node
|
20
22
|
|
21
23
|
class << self
|
22
24
|
|
25
|
+
# Check whether objects of this class are finalised computations
|
26
|
+
#
|
27
|
+
# @return [Boolean] Returns +false+.
|
28
|
+
#
|
29
|
+
# @private
|
23
30
|
def finalised?
|
24
31
|
false
|
25
32
|
end
|
26
33
|
|
27
34
|
end
|
28
35
|
|
36
|
+
# Constructor
|
37
|
+
#
|
38
|
+
# @param [Node] dest Target array to write histogram to.
|
39
|
+
# @param [Node] source Expression to compute histogram of.
|
40
|
+
#
|
41
|
+
# @private
|
29
42
|
def initialize( dest, source )
|
30
43
|
@dest, @source = dest, source
|
31
44
|
end
|
32
45
|
|
46
|
+
# Get unique descriptor of this object
|
47
|
+
#
|
48
|
+
# @param [Hash] hash Labels for any variables.
|
49
|
+
#
|
50
|
+
# @return [String] Descriptor of this object,
|
51
|
+
#
|
52
|
+
# @private
|
33
53
|
def descriptor( hash )
|
34
54
|
"Histogram(#{@dest.descriptor( hash )},#{@source.descriptor( hash )})"
|
35
55
|
end
|
36
56
|
|
57
|
+
# Get type of result of delayed operation
|
58
|
+
#
|
59
|
+
# @return [Class] Type of result.
|
60
|
+
#
|
61
|
+
# @private
|
37
62
|
def array_type
|
38
|
-
@dest.array_type
|
63
|
+
retval = @dest.array_type
|
64
|
+
( class << self; self; end ).instance_eval do
|
65
|
+
define_method( :array_type ) { retval }
|
66
|
+
end
|
67
|
+
retval
|
39
68
|
end
|
40
69
|
|
70
|
+
# Reevaluate computation
|
71
|
+
#
|
72
|
+
# @return [Node,Object] Result of computation
|
73
|
+
#
|
74
|
+
# @see #force
|
75
|
+
#
|
76
|
+
# @private
|
41
77
|
def demand
|
42
78
|
if variables.empty?
|
43
79
|
if @source.dimension > 1
|
@@ -58,20 +94,48 @@ module Hornetseye
|
|
58
94
|
end
|
59
95
|
end
|
60
96
|
|
97
|
+
# Substitute variables
|
98
|
+
#
|
99
|
+
# Substitute the variables with the values given in the hash.
|
100
|
+
#
|
101
|
+
# @param [Hash] hash Substitutions to apply.
|
102
|
+
#
|
103
|
+
# @return [Node] Term with substitutions applied.
|
104
|
+
#
|
105
|
+
# @private
|
61
106
|
def subst( hash )
|
62
107
|
self.class.new @dest.subst( hash ), @source.subst( hash )
|
63
108
|
end
|
64
109
|
|
110
|
+
# Get variables contained in this term
|
111
|
+
#
|
112
|
+
# @return [Set] Returns list of variables.
|
113
|
+
#
|
114
|
+
# @private
|
65
115
|
def variables
|
66
116
|
@dest.variables + @source.variables
|
67
117
|
end
|
68
118
|
|
119
|
+
# Strip of all values
|
120
|
+
#
|
121
|
+
# Split up into variables, values, and a term where all values have been
|
122
|
+
# replaced with variables.
|
123
|
+
#
|
124
|
+
# @return [Array<Array,Node>] Returns an array of variables, an array of
|
125
|
+
# values, and the term based on variables.
|
126
|
+
#
|
127
|
+
# @private
|
69
128
|
def strip
|
70
129
|
vars1, values1, term1 = @dest.strip
|
71
130
|
vars2, values2, term2 = @source.strip
|
72
131
|
return vars1 + vars2, values1 + values2, self.class.new( term1, term2 )
|
73
132
|
end
|
74
133
|
|
134
|
+
# Check whether this term is compilable
|
135
|
+
#
|
136
|
+
# @return [Boolean] Returns whether this term is compilable.
|
137
|
+
#
|
138
|
+
# @private
|
75
139
|
def compilable?
|
76
140
|
@dest.compilable? and @source.compilable?
|
77
141
|
end
|