multiarray 0.5.0 → 0.5.1

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.
@@ -27,8 +27,8 @@ module Hornetseye
27
27
  retval = block.pointer_type.new
28
28
  retval_keys, retval_values, retval_term = retval.strip
29
29
  method_name = '_' + term.descriptor( labels ).
30
- tr( '(),+\-*/.@?~&|^<>',
31
- '0123\456789ABCDEF' )
30
+ tr( '(),+\-*/.@?~&|^<=>',
31
+ '0123\456789ABCDEFG' )
32
32
  unless GCCCache.respond_to? method_name
33
33
  GCCContext.build do |context|
34
34
  function = new context, method_name,
@@ -39,14 +39,16 @@ module Hornetseye
39
39
  retval_subst = ( 0 ... retval_keys.size ).collect do |i|
40
40
  { retval_keys[ i ] => function.param( i ) }
41
41
  end.inject( {} ) { |a,b| a.merge b }
42
+ Thread.current[ :function ] = function
42
43
  Hornetseye::lazy do
43
44
  retval_term.subst( retval_subst ).store term.subst( term_subst )
44
45
  end
46
+ Thread.current[ :function ] = nil
45
47
  function.insn_return
46
48
  function.compile
47
49
  end
48
50
  end
49
- args = ( retval_values + values ).collect { |arg| arg.get }
51
+ args = ( retval_values + values ).collect { |arg| arg.values }.flatten
50
52
  GCCCache.send method_name, *args
51
53
  retval.simplify
52
54
  end
@@ -74,9 +76,19 @@ module Hornetseye
74
76
  end
75
77
 
76
78
  def variable( typecode, prefix )
77
- retval = typecode.new GCCValue.new( self, id( prefix ) )
78
- self << "#{indent}#{GCCType.new( typecode ).identifier} #{retval.get};\n"
79
- retval
79
+ #if typecode == INTRGB
80
+ # r = GCCValue.new( self, id( prefix ) )
81
+ # g = GCCValue.new( self, id( prefix ) )
82
+ # b = GCCValue.new( self, id( prefix ) )
83
+ # self << "#{indent}#{GCCType.new( INT ).identifier} #{r};\n"
84
+ # self << "#{indent}#{GCCType.new( INT ).identifier} #{g};\n"
85
+ # self << "#{indent}#{GCCType.new( INT ).identifier} #{b};\n"
86
+ # INTRGB.new RGB.new( r, g, b )
87
+ #else
88
+ retval = typecode.new GCCValue.new( self, id( prefix ) )
89
+ self << "#{indent}#{GCCType.new( typecode ).identifiers.first} #{retval.get};\n" # !!!
90
+ retval
91
+ #end
80
92
  end
81
93
 
82
94
  def indent
@@ -88,7 +100,12 @@ module Hornetseye
88
100
  end
89
101
 
90
102
  def param( i )
91
- @param_types[ i ].new GCCValue.new( self, "param#{i}" )
103
+ offset = ( 0 ... i ).inject( 0 ) do |s,idx|
104
+ s + GCCType.new( @param_types[ idx ] ).identifiers.size
105
+ end
106
+ args = ( 0 ... GCCType.new( @param_types[ i ] ).identifiers.size ).
107
+ collect { |idx| GCCValue.new self, "param#{ offset + idx }" }
108
+ @param_types[ i ].construct *args
92
109
  end
93
110
 
94
111
  def call( *args )
@@ -23,44 +23,54 @@ module Hornetseye
23
23
  @typecode = typecode
24
24
  end
25
25
 
26
- def identifier
26
+ def identifiers
27
27
  case @typecode
28
28
  when nil
29
- 'void'
29
+ [ 'void' ]
30
30
  when BOOL
31
- 'char'
31
+ [ 'char' ]
32
32
  when BYTE
33
- 'char'
33
+ [ 'char' ]
34
34
  when UBYTE
35
- 'unsigned char'
35
+ [ 'unsigned char' ]
36
36
  when SINT
37
- 'short int'
37
+ [ 'short int' ]
38
38
  when USINT
39
- 'unsigned short int'
39
+ [ 'unsigned short int' ]
40
40
  when INT
41
- 'int'
41
+ [ 'int' ]
42
42
  when UINT
43
- 'unsigned int'
43
+ [ 'unsigned int' ]
44
+ when SFLOAT
45
+ [ 'float' ]
46
+ when DFLOAT
47
+ [ 'double' ]
44
48
  else
45
49
  if @typecode < Pointer_
46
- 'void *'
50
+ [ 'void *' ]
47
51
  elsif @typecode < INDEX_
48
- 'int'
52
+ [ 'int' ]
53
+ elsif @typecode < RGB_
54
+ GCCType.new( @typecode.element_type ).identifiers * 3
49
55
  else
50
56
  raise "No identifier available for #{@typecode.inspect}"
51
57
  end
52
58
  end
53
59
  end
54
60
 
55
- def r2c( expr )
61
+ def r2c
56
62
  case @typecode
57
63
  when BOOL
58
- "( #{expr} ) != Qfalse"
64
+ [ proc { |expr| "( #{expr} ) != Qfalse" } ]
59
65
  when BYTE, UBYTE, SINT, USINT, INT, UINT
60
- "NUM2INT( #{expr} )"
66
+ [ proc { |expr| "NUM2INT( #{expr} )" } ]
67
+ when SFLOAT, DFLOAT
68
+ [ proc { |expr| "NUM2DBL( #{expr} )" } ]
61
69
  else
62
70
  if @typecode < Pointer_
63
- "(#{identifier})mallocToPtr( #{expr} )"
71
+ [ proc { |expr| "(#{identifiers.first})mallocToPtr( #{expr} )" } ] # !!!
72
+ elsif @typecode < RGB_
73
+ GCCType.new( @typecode.element_type ).r2c * 3
64
74
  else
65
75
  raise "No conversion available for #{@typecode.inspect}"
66
76
  end
@@ -70,4 +80,4 @@ module Hornetseye
70
80
  end
71
81
 
72
82
  end
73
-
83
+
@@ -19,6 +19,64 @@ module Hornetseye
19
19
 
20
20
  class GCCValue
21
21
 
22
+ class << self
23
+
24
+ def generic?( value )
25
+ value.is_a?( GCCValue ) or value.is_a?( Fixnum ) or
26
+ value.is_a?( Float )
27
+ end
28
+
29
+ def define_unary_op( op, opcode = op )
30
+ define_method( op ) do
31
+ GCCValue.new @function, "#{opcode}( #{self} )"
32
+ end
33
+ end
34
+
35
+ def define_unary_method( mod, op, opcode = op )
36
+ mod.module_eval do
37
+ define_method( "#{op}_with_gcc" ) do |a|
38
+ if a.is_a? GCCValue
39
+ GCCValue.new a.function, "#{opcode}( #{a} )"
40
+ else
41
+ send "#{op}_without_gcc", a
42
+ end
43
+ end
44
+ alias_method_chain op, :gcc
45
+ module_function "#{op}_without_gcc"
46
+ module_function op
47
+ end
48
+ end
49
+
50
+ def define_binary_op( op, opcode = op )
51
+ define_method( op ) do |other|
52
+ if GCCValue.generic? other
53
+ GCCValue.new @function, "( #{self} ) #{opcode} ( #{other} )"
54
+ else
55
+ x, y = other.coerce self
56
+ x.send op, y
57
+ end
58
+ end
59
+ end
60
+
61
+ def define_binary_method( mod, op, opcode = op )
62
+ mod.module_eval do
63
+ define_method( "#{op}_with_gcc" ) do |a,b|
64
+ if a.is_a? GCCValue or b.is_a? GCCValue
65
+ GCCValue.new a.function, "#{opcode}( #{a}, #{b} )"
66
+ else
67
+ send "#{op}_without_gcc", a, b
68
+ end
69
+ end
70
+ alias_method_chain op, :gcc
71
+ module_function "#{op}_without_gcc"
72
+ module_function op
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ attr_reader :function
79
+
22
80
  def initialize( function, descriptor )
23
81
  @function = function
24
82
  @descriptor = descriptor
@@ -32,19 +90,6 @@ module Hornetseye
32
90
  @descriptor
33
91
  end
34
92
 
35
- # Store result of computation in new variable
36
- #
37
- # @return [Node,Object] Result of computation
38
- #
39
- # @see #force
40
- #
41
- # @private
42
- def duplicate( typecode )
43
- result = @function.variable( typecode, 'v' ).get
44
- result.store self
45
- result
46
- end
47
-
48
93
  def store( value )
49
94
  @function << "#{@function.indent}#{self} = #{value};\n"
50
95
  value
@@ -55,79 +100,83 @@ module Hornetseye
55
100
  end
56
101
 
57
102
  def load( typecode )
58
- GCCValue.new @function, "*(#{GCCType.new( typecode ).identifier} *)( #{self} )"
103
+ offset = 0
104
+ typecode.typecodes.collect do |t|
105
+ value = GCCValue.new @function,
106
+ "*(#{GCCType.new( t ).identifiers.first} *)( #{self} + #{offset} )" # !!!
107
+ offset += t.storage_size
108
+ value
109
+ end
59
110
  end
60
111
 
61
112
  def save( value )
62
- @function << "#{@function.indent}*(#{GCCType.new( value.typecode ).identifier} *)( #{self} ) = #{value.get};\n"
63
- end
64
-
65
- def eq( other )
66
- GCCValue.new @function, "( #{self} ) == ( #{other} )"
67
- end
68
-
69
- def ne( other )
70
- GCCValue.new @function, "( #{self} ) != ( #{other} )"
71
- end
72
-
73
- def conditional( a, b )
74
- GCCValue.new @function, "( #{self} ) ? ( #{a} ) : ( #{b} )"
75
- end
76
-
77
- def not
78
- GCCValue.new @function, "!( #{self} )"
79
- end
80
-
81
- def ~
82
- GCCValue.new @function, "~( #{self} )"
83
- end
84
-
85
- def and( other )
86
- GCCValue.new @function, "( #{self} ) && ( #{other} )"
87
- end
88
-
89
- def or( other )
90
- GCCValue.new @function, "( #{self} ) || ( #{other} )"
91
- end
92
-
93
- def &( other )
94
- GCCValue.new @function, "( #{self} ) & ( #{other} )"
95
- end
96
-
97
- def |( other )
98
- GCCValue.new @function, "( #{self} ) | ( #{other} )"
99
- end
100
-
101
- def ^( other )
102
- GCCValue.new @function, "( #{self} ) ^ ( #{other} )"
113
+ offset = 0
114
+ value.class.typecodes.zip( value.values ).each do |t,v|
115
+ @function << "#{@function.indent}*(#{GCCType.new( t ).identifiers.first} *)( #{self} + #{offset} ) = #{v};\n" # !!!
116
+ offset += t.storage_size
117
+ end
103
118
  end
104
119
 
105
- def <<( other )
106
- GCCValue.new @function, "( #{self} ) << ( #{other} )"
120
+ def r
121
+ self
107
122
  end
108
123
 
109
- def >>( other )
110
- GCCValue.new @function, "( #{self} ) >> ( #{other} )"
124
+ def g
125
+ self
111
126
  end
112
127
 
113
- def -@
114
- GCCValue.new @function, "-( #{self} )"
128
+ def b
129
+ self
115
130
  end
116
131
 
117
- def +( other )
118
- GCCValue.new @function, "( #{self} ) + ( #{other} )"
119
- end
120
-
121
- def -( other )
122
- GCCValue.new @function, "( #{self} ) - ( #{other} )"
123
- end
124
-
125
- def *( other )
126
- GCCValue.new @function, "( #{self} ) * ( #{other} )"
132
+ def conditional( a, b )
133
+ GCCValue.new @function, "( #{self} ) ? ( #{a} ) : ( #{b} )"
127
134
  end
128
135
 
129
- def /( other )
130
- GCCValue.new @function, "( #{self} ) / ( #{other} )"
136
+ define_unary_op :not, '!'
137
+ define_unary_op :~
138
+ define_unary_op :-@, :-
139
+ define_binary_op :and, '&&'
140
+ define_binary_op :or, '||'
141
+ define_binary_op :&
142
+ define_binary_op :|
143
+ define_binary_op :^
144
+ define_binary_op :<<
145
+ define_binary_op :>>
146
+ define_binary_op :+
147
+ define_binary_op :-
148
+ define_binary_op :*
149
+ define_binary_op :/
150
+ define_binary_op :eq, :==
151
+ define_binary_op :ne, '!='
152
+ define_binary_op :<
153
+ define_binary_op :<=
154
+ define_binary_op :>
155
+ define_binary_op :>=
156
+ define_unary_method Math, :sqrt
157
+ define_unary_method Math, :log
158
+ define_unary_method Math, :exp
159
+ define_unary_method Math, :cos
160
+ define_unary_method Math, :sin
161
+ define_unary_method Math, :tan
162
+ define_unary_method Math, :acos
163
+ define_unary_method Math, :asin
164
+ define_unary_method Math, :atan
165
+ define_unary_method Math, :cosh
166
+ define_unary_method Math, :sinh
167
+ define_unary_method Math, :tanh
168
+ define_binary_method Math, :atan2
169
+ define_binary_method Math, :hypot
170
+
171
+
172
+ def major( other )
173
+ GCCValue.new @function,
174
+ "( ( #{self} ) >= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
175
+ end
176
+
177
+ def minor( other )
178
+ GCCValue.new @function,
179
+ "( ( #{self} ) <= ( #{other} ) ) ? ( #{self} ) : ( #{other} )"
131
180
  end
132
181
 
133
182
  def zero?
@@ -140,11 +189,32 @@ module Hornetseye
140
189
 
141
190
  def times( &action )
142
191
  i = @function.variable INT, 'i'
143
- @function << "#{@function.indent}for ( #{i.get} = 0; #{i.get} != #{self}; #{i.get}++ ) {\n"
192
+ @function << "#{@function.indent}for ( #{i.get} = 0; " +
193
+ "#{i.get} != #{self}; #{i.get}++ ) {\n"
194
+ @function.indent_offset +1
195
+ action.call i.get
196
+ @function.indent_offset -1
197
+ @function << "#{@function.indent}};\n"
198
+ self
199
+ end
200
+
201
+ def upto( other, &action )
202
+ i = @function.variable INT, 'i'
203
+ @function << "#{@function.indent}for ( #{i.get} = #{self}; " +
204
+ "#{i.get} != #{ other + 1 }; #{i.get}++ ) {\n"
144
205
  @function.indent_offset +1
145
206
  action.call i.get
146
207
  @function.indent_offset -1
147
208
  @function << "#{@function.indent}};\n"
209
+ self
210
+ end
211
+
212
+ def coerce( other )
213
+ if other.is_a? GCCValue
214
+ return other, self
215
+ else
216
+ return GCCValue.new( @function, "( #{other} )" ), self
217
+ end
148
218
  end
149
219
 
150
220
  end
@@ -35,7 +35,9 @@ module Hornetseye
35
35
  hash = hash.merge @index => ( ( hash.values.max || 0 ) + 1 )
36
36
  hash = hash.merge @var1 => ( ( hash.values.max || 0 ) + 1 )
37
37
  hash = hash.merge @var2 => ( ( hash.values.max || 0 ) + 1 )
38
- "Inject(#{@value.descriptor( hash )},#{@initial ? @initial.descriptor( hash ) : 'nil'},#{@index.descriptor( hash )},#{@block.descriptor( hash )})"
38
+ "Inject(#{@value.descriptor( hash )}," +
39
+ "#{@initial ? @initial.descriptor( hash ) : 'nil'}," +
40
+ "#{@index.descriptor( hash )},#{@block.descriptor( hash )})"
39
41
  end
40
42
 
41
43
  def array_type
@@ -52,18 +54,14 @@ module Hornetseye
52
54
  def demand
53
55
  if @initial
54
56
  retval = @initial.simplify # !!!
55
- @index.size.get.times do |i|
56
- sub = @value.subst( @index => INT.new( i ) ).simplify # !!!
57
- retval.store @block.subst( @var1 => retval,
58
- @var2 => sub ).simplify
59
- end
57
+ offset = INT.new 0
60
58
  else
61
59
  retval = @value.subst( @index => INT.new( 0 ) ).simplify # !!!
62
- ( @index.size - 1 ).get.times do |i|
63
- sub = @value.subst( @index => INT.new( i ) + 1 ).simplify # !!!
64
- retval.store @block.subst( @var1 => retval,
65
- @var2 => sub ).simplify
66
- end
60
+ offset = INT.new 1
61
+ end
62
+ offset.upto @index.size - 1 do |i|
63
+ sub = @value.subst @index => INT.new( i )
64
+ retval.store @block.subst( @var1 => retval, @var2 => sub )
67
65
  end
68
66
  retval
69
67
  end
@@ -97,18 +95,17 @@ module Hornetseye
97
95
  #
98
96
  # @private
99
97
  def strip
100
- vars1, values1, term1 = @value.strip
98
+ meta_vars, meta_values, var = @index.strip
99
+ vars1, values1, term1 = @value.subst( @index => var ).strip
101
100
  if @initial
102
101
  vars2, values2, term2 = @initial.strip
103
102
  else
104
103
  vars2, values2 = [], [], nil
105
104
  end
106
105
  vars3, values3, term3 = @block.strip
107
- meta_vars, meta_values, var = @index.strip
108
106
  return vars1 + vars2 + vars3 + meta_vars,
109
107
  values1 + values2 + values3 + meta_values,
110
- Inject.new( term1.subst( @index => var ),
111
- var, term2, term3, @var1, @var2 )
108
+ Inject.new( term1, var, term2, term3, @var1, @var2 )
112
109
  end
113
110
 
114
111
  # Substitute variables