multiarray 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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