Class: Hornetseye::GCCValue

Inherits:
Object show all
Defined in:
lib/multiarray/gccvalue.rb

Overview

Class for generating code handling C values

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(function, descriptor) ⇒ GCCValue

Constructor for GCC value

Parameters:

  • function (GCCFunction)

    The function context this value is part of.

  • descriptor (String)

    C code to compute this value.



136
137
138
139
# File 'lib/multiarray/gccvalue.rb', line 136

def initialize( function, descriptor ) 
  @function = function
  @descriptor = descriptor
end

Instance Attribute Details

#functionGCCFunction (readonly)

Get current function context

Returns:

  • (GCCFunction)

    The function this value is part of.



128
129
130
# File 'lib/multiarray/gccvalue.rb', line 128

def function
  @function
end

Class Method Details

.define_binary_method(mod, op, opcode = op) ⇒ Proc

Meta-programming method used to define binary methods at the beginning

Parameters:

  • op (Symbol, String)

    Name of binary method.

  • opcode (Symbol, String) (defaults to: op)

    Name of binary method in C.

Returns:

  • (Proc)

    The new method.



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/multiarray/gccvalue.rb', line 105

def define_binary_method( mod, op, opcode = op )
  mod.module_eval do
    define_method "#{op}_with_gcc" do |a,b|
      if a.is_a? GCCValue or b.is_a? GCCValue
        function = a.is_a?( GCCValue ) ? a.function : b.function
        GCCValue.new function, "#{opcode}( #{a}, #{b} )"
      else
        send "#{op}_without_gcc", a, b
      end
    end
    alias_method_chain op, :gcc
    module_function "#{op}_without_gcc"
    module_function op
  end
end

.define_binary_op(op, opcode = op) ⇒ Proc

Meta-programming method used to define unary methods at the beginning

Parameters:

  • op (Symbol, String)

    Name of unary method.

  • opcode (Symbol, String) (defaults to: op)

    Name of unary method in C.

Returns:

  • (Proc)

    The new method.



86
87
88
89
90
91
92
93
94
95
# File 'lib/multiarray/gccvalue.rb', line 86

def define_binary_op( op, opcode = op )
  define_method op do |other|
    if GCCValue.generic? other
      GCCValue.new @function, "( #{self} ) #{opcode} ( #{other} )"
    else
      x, y = other.coerce self
      x.send op, y
    end
  end
end

.define_unary_method(mod, op, opcode = op) ⇒ Proc

Meta-programming method used to define unary methods at the beginning

Parameters:

  • op (Symbol, String)

    Name of unary method.

  • opcode (Symbol, String) (defaults to: op)

    Name of unary method in C.

Returns:

  • (Proc)

    The new method.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/multiarray/gccvalue.rb', line 63

def define_unary_method( mod, op, opcode = op )
  mod.module_eval do
    define_method "#{op}_with_gcc" do |a|
      if a.is_a? GCCValue
        GCCValue.new a.function, "#{opcode}( #{a} )"
      else
        send "#{op}_without_gcc", a
      end
    end
    alias_method_chain op, :gcc
    module_function "#{op}_without_gcc"
    module_function op
  end
end

.define_unary_op(op, opcode = op) ⇒ Proc

Meta-programming method used to define unary operations at the beginning

Parameters:

  • op (Symbol, String)

    Name of unary operation.

  • opcode (Symbol, String) (defaults to: op)

    Name of unary operation in C.

Returns:

  • (Proc)

    The new method.



49
50
51
52
53
# File 'lib/multiarray/gccvalue.rb', line 49

def define_unary_op( op, opcode = op )
  define_method op do
    GCCValue.new @function, "#{opcode}( #{self} )"
  end
end

.generic?(value) ⇒ Boolean

Check compatibility of other type

This method checks whether binary operations with the other Ruby object can be performed without requiring coercion.

Parameters:

  • value (Object)

    The other Ruby object.

Returns:

  • (Boolean)

    Returns false if Ruby object requires coercion.



36
37
38
39
# File 'lib/multiarray/gccvalue.rb', line 36

def generic?( value )
  value.is_a?( GCCValue ) or value.is_a?( Fixnum ) or
    value.is_a?( Float )
end

Instance Method Details

#**(other) ⇒ GCCValue

Generate code for computing exponentiation

Parameters:

Returns:

  • (GCCValue)

    C value refering to the result.



437
438
439
440
441
442
443
444
# File 'lib/multiarray/gccvalue.rb', line 437

def **( other )
  if GCCValue.generic? other
    GCCValue.new @function, "pow( #{self}, #{other} )"
  else
    x, y = other.coerce self
    x ** y
  end
end

#absGCCValue

Generate code for computing absolute value

Returns:

  • (GCCValue)

    C value referring to the result.



224
225
226
# File 'lib/multiarray/gccvalue.rb', line 224

def abs
  ( self >= 0 ).conditional self, -self
end

#argGCCValue

Generate code for computing complex argument of real value

Returns:

  • (GCCValue)

    C value referring to the result.



233
234
235
# File 'lib/multiarray/gccvalue.rb', line 233

def arg
  ( self >= 0 ).conditional 0, Math::PI
end

#assign(value) ⇒ Object

Store new value in this object

Parameters:

  • value (Object)

    The new value.

Returns:



166
167
168
169
# File 'lib/multiarray/gccvalue.rb', line 166

def assign( value )
  @function << "#{@function.indent}#{self} = #{value};\n"
  value
end

#bGCCValue

Blue colour component of real value

Returns:



260
261
262
# File 'lib/multiarray/gccvalue.rb', line 260

def b
  self
end

#ceilGCCValue

Generate code for computing smallest integer value not less than this value

Returns:

  • (GCCValue)

    C value refering to the result.



417
418
419
# File 'lib/multiarray/gccvalue.rb', line 417

def ceil
  GCCValue.new @function, "ceil( #{self} )"
end

#coerce(other) ⇒ Array<GCCValue>

Type coercion for GCC values

Parameters:

  • other (Object)

    Other value to coerce with.

Returns:



589
590
591
592
593
594
595
# File 'lib/multiarray/gccvalue.rb', line 589

def coerce( other )
  if other.is_a? GCCValue
    return other, self
  else
    return GCCValue.new( @function, "( #{other} )" ), self
  end
end

#compilable?Boolean

Indicate whether this object can be compiled

Returns:

  • (Boolean)

    Returns false.



176
177
178
# File 'lib/multiarray/gccvalue.rb', line 176

def compilable?
  false
end

#conditional(a, b) ⇒ GCCValue

Create code for conditional selection of value

Parameters:

Returns:

  • (GCCValue)

    C value referring to result.



299
300
301
302
303
304
305
# File 'lib/multiarray/gccvalue.rb', line 299

def conditional( a, b )
  if a.is_a?( Proc ) and b.is_a?( Proc )
    conditional a.call, b.call
  else
    GCCValue.new @function, "( #{self} ) ? ( #{a} ) : ( #{b} )"
  end
end

#conditional_with_complex(a, b) ⇒ GCCValue

Create code for conditional selection of complex value

Parameters:

Returns:

  • (GCCValue)

    C value referring to result.



514
515
516
517
518
519
520
521
# File 'lib/multiarray/gccvalue.rb', line 514

def conditional_with_complex( a, b )
  if a.is_a?( InternalComplex ) or b.is_a?( InternalComplex )
    InternalComplex.new conditional( a.real, b.real ),
                        conditional( a.imag, b.imag )
  else
    conditional_without_complex a, b
  end
end

#conditional_with_rgb(a, b) ⇒ GCCValue

Create code for conditional selection of RGB value

Parameters:

Returns:

  • (GCCValue)

    C value referring to result.



496
497
498
499
500
501
502
# File 'lib/multiarray/gccvalue.rb', line 496

def conditional_with_rgb( a, b )
  if a.is_a?(RGB) or b.is_a?(RGB)
    Hornetseye::RGB conditional(a.r, b.r), conditional(a.g, b.g), conditional(a.b, b.b)
  else
    conditional_without_rgb a, b
  end
end

#conjGCCValue

Complex conjugate of real value

Returns:



215
216
217
# File 'lib/multiarray/gccvalue.rb', line 215

def conj
  self
end

#drandGCCValue

Generate floating point random number

Returns:

  • (GCCValue)

    C value refering to the result.



451
452
453
# File 'lib/multiarray/gccvalue.rb', line 451

def drand
  GCCValue.new @function, "( rb_genrand_real() * ( #{self} ) )"
end

#floorGCCValue

Generate code for computing largest integer value not greater than this value

Returns:

  • (GCCValue)

    C value refering to the result.



408
409
410
# File 'lib/multiarray/gccvalue.rb', line 408

def floor
  GCCValue.new @function, "floor( #{self} )"
end

#fmod(other) ⇒ Object



282
283
284
285
286
287
288
289
# File 'lib/multiarray/gccvalue.rb', line 282

def fmod( other )
  if GCCValue.generic? other
    GCCValue.new @function, "fmod( #{self}, #{other} )"
  else
    x, y = other.coerce self
    x.send op, y
  end
end

#gGCCValue

Green colour component of real value

Returns:



251
252
253
# File 'lib/multiarray/gccvalue.rb', line 251

def g
  self
end

#if(&action) ⇒ Object

Generate code for conditional statement

Parameters:

  • action (Proc)

    Block of conditional.

Returns:



314
315
316
317
318
319
320
321
# File 'lib/multiarray/gccvalue.rb', line 314

def if( &action )
  @function << "#{@function.indent}if ( #{self} ) {\n"
  @function.indent_offset +1
  action.call
  @function.indent_offset -1
  @function << "#{@function.indent}};\n"
  self
end

#if_else(action1, action2) ⇒ Object

Generate code for conditional statement

Parameters:

  • action1 (Proc)

    Block to run when condition is fullfilled.

  • action2 (Proc)

    Block to run otherwise.

Returns:



331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/multiarray/gccvalue.rb', line 331

def if_else( action1, action2 )
  @function << "#{@function.indent}if ( #{self} ) {\n"
  @function.indent_offset +1
  action1.call
  @function.indent_offset -1
  @function << "#{@function.indent}} else {\n"
  @function.indent_offset +1
  action2.call
  @function.indent_offset -1
  @function << "#{@function.indent}};\n"
  self
end

#imagInteger

Imaginary component of real value

Returns:

  • (Integer)

    Returns 0.



278
279
280
# File 'lib/multiarray/gccvalue.rb', line 278

def imag
  0
end

#inspectString

Display descriptor of this object

Returns:

  • (String)

    Returns the descriptor of this object.



146
147
148
# File 'lib/multiarray/gccvalue.rb', line 146

def inspect
  @descriptor
end

#load(typecode) ⇒ Array<GCCValue>

Add code to read all components of a typed value from memory

Returns:

  • (Array<GCCValue>)

    An array of objects referencing values in C.



185
186
187
188
189
190
191
192
193
# File 'lib/multiarray/gccvalue.rb', line 185

def load( typecode )
  offset = 0
  typecode.typecodes.collect do |t|
    value = GCCValue.new @function,
      "*(#{GCCType.new( t ).identifier} *)( #{self} + #{offset} )"
    offset += t.storage_size
    value
  end
end

#lrandGCCValue

Generate integer random number

Returns:

  • (GCCValue)

    C value refering to the result.



460
461
462
# File 'lib/multiarray/gccvalue.rb', line 460

def lrand
  GCCValue.new @function, "limited_rand( #{self} )"
end

#major(other) ⇒ GCCValue

Generate code for selecting larger value

Parameters:

Returns:

  • (GCCValue)

    C value refering to the result.



471
472
473
474
# File 'lib/multiarray/gccvalue.rb', line 471

def major( other )
  GCCValue.new @function,
    "( ( #{self} ) >= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
end

#major_with_rgb(other) ⇒ Object



525
526
527
528
529
530
531
# File 'lib/multiarray/gccvalue.rb', line 525

def major_with_rgb(other)
  if other.is_a?(RGB)
    Hornetseye::RGB r.major(other.r), g.major(other.g), b.major(other.b)
  else
    major_without_rgb other
  end
end

#minor(other) ⇒ GCCValue

Generate code for selecting smaller value

Parameters:

Returns:

  • (GCCValue)

    C value refering to the result.



483
484
485
486
# File 'lib/multiarray/gccvalue.rb', line 483

def minor( other )
  GCCValue.new @function,
    "( ( #{self} ) <= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
end

#minor_with_rgb(other) ⇒ Object



535
536
537
538
539
540
541
# File 'lib/multiarray/gccvalue.rb', line 535

def minor_with_rgb(other)
  if other.is_a?(RGB)
    Hornetseye::RGB r.minor(other.r), g.minor(other.g), b.minor(other.b)
  else
    minor_without_rgb other
  end
end

#nonzero?GCCValue

Generate code for checking whether value is not equal to zero

Returns:

  • (GCCValue)

    C value refering to the result.



399
400
401
# File 'lib/multiarray/gccvalue.rb', line 399

def nonzero?
  GCCValue.new @function, "( #{self} ) != 0"
end

#rGCCValue

Red colour component of real value

Returns:



242
243
244
# File 'lib/multiarray/gccvalue.rb', line 242

def r
  self
end

#realGCCValue

Real component of real value

Returns:



269
270
271
# File 'lib/multiarray/gccvalue.rb', line 269

def real
  self
end

#roundGCCValue

Generate code for rounding to nearest integer

Returns:

  • (GCCValue)

    C value refering to the result.



426
427
428
# File 'lib/multiarray/gccvalue.rb', line 426

def round
  GCCValue.new @function, "round( #{self} )"
end

#save(value) ⇒ Object

Add code to write all components of a typed value to memory

Parameters:

  • value (Node)

    Value to write to memory.

Returns:

  • (Object)

    The return value should be ignored.



202
203
204
205
206
207
208
# File 'lib/multiarray/gccvalue.rb', line 202

def save( value )
  offset = 0
  value.class.typecodes.zip( value.values ).each do |t,v|
    @function << "#{@function.indent}*(#{GCCType.new( t ).identifier} *)( #{self} + #{offset} ) = #{v};\n"
    offset += t.storage_size
  end
end

#times(&action) ⇒ GCCValue

Generate a for loop in C

Parameters:

  • action (Proc)

    Code for generating loop body.

Returns:



552
553
554
555
556
557
558
559
560
561
# File 'lib/multiarray/gccvalue.rb', line 552

def times( &action )
  i = @function.variable INT, 'i'
  @function << "#{@function.indent}for ( #{i} = 0; " +
               "#{i} != #{self}; #{i}++ ) {\n"
  @function.indent_offset +1
  action.call i
  @function.indent_offset -1
  @function << "#{@function.indent}};\n"
  self
end

#to_sString

Get descriptor of this object

Returns:

  • (String)

    Returns the descriptor of this object.



155
156
157
# File 'lib/multiarray/gccvalue.rb', line 155

def to_s
  @descriptor
end

#upto(other, &action) ⇒ GCCValue

Generate a for loop in C

Parameters:

  • other (GCCValue, Object)

    Upper limit for loop.

  • action (Proc)

    Code for generating loop body.

Returns:



571
572
573
574
575
576
577
578
579
580
# File 'lib/multiarray/gccvalue.rb', line 571

def upto( other, &action )
  i = @function.variable INT, 'i'
  @function << "#{@function.indent}for ( #{i} = #{self}; " +
               "#{i} != #{ other + 1 }; #{i}++ ) {\n"
  @function.indent_offset +1
  action.call i
  @function.indent_offset -1
  @function << "#{@function.indent}};\n"
  self
end

#zero?GCCValue

Generate code for checking whether value is equal to zero

Returns:

  • (GCCValue)

    C value refering to the result.



390
391
392
# File 'lib/multiarray/gccvalue.rb', line 390

def zero?
  GCCValue.new @function, "( #{self} ) == 0"
end