fastruby 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Rakefile +1 -1
  2. data/benchmarks/benchmark.rb +3 -0
  3. data/benchmarks/benchmark.rb~ +3 -12
  4. data/benchmarks/benchmark8.rb +48 -0
  5. data/benchmarks/benchmark8.rb~ +46 -0
  6. data/lib/fastruby.rb +2 -1
  7. data/lib/fastruby.rb~ +2 -1
  8. data/lib/fastruby/builder.rb +18 -1
  9. data/lib/fastruby/builder.rb~ +18 -5
  10. data/lib/fastruby/modules/lvar_type/lasgn.rb~ +41 -0
  11. data/lib/fastruby/modules/translator/block.rb +1 -1
  12. data/lib/fastruby/modules/translator/block.rb~ +128 -0
  13. data/lib/fastruby/modules/translator/call.rb +62 -139
  14. data/lib/fastruby/modules/translator/call.rb~ +61 -140
  15. data/lib/fastruby/modules/translator/defn.rb +49 -105
  16. data/lib/fastruby/modules/translator/defn.rb~ +211 -0
  17. data/lib/fastruby/modules/translator/exceptions.rb +1 -0
  18. data/lib/fastruby/modules/translator/exceptions.rb~ +120 -0
  19. data/lib/fastruby/modules/translator/iter.rb +13 -20
  20. data/lib/fastruby/modules/translator/iter.rb~ +738 -0
  21. data/lib/fastruby/modules/translator/literal.rb +8 -1
  22. data/lib/fastruby/modules/translator/literal.rb~ +157 -0
  23. data/lib/fastruby/modules/translator/nonlocal.rb +7 -0
  24. data/lib/fastruby/modules/translator/nonlocal.rb~ +304 -0
  25. data/lib/fastruby/modules/translator/static.rb +1 -0
  26. data/lib/fastruby/modules/translator/static.rb~ +290 -0
  27. data/lib/fastruby/modules/translator/variable.rb +24 -6
  28. data/lib/fastruby/modules/translator/variable.rb~ +298 -0
  29. data/lib/fastruby/translator/translator.rb +411 -284
  30. data/lib/fastruby/translator/translator.rb~ +1728 -0
  31. data/spec/fastruby_only/base_spec.rb~ +74 -0
  32. data/spec/ruby/base_spec.rb~ +1 -338
  33. data/spec/ruby/block/break_spec.rb~ +21 -0
  34. data/spec/ruby/block/callcc_spec.rb~ +236 -0
  35. data/spec/ruby/block/lambda_spec.rb~ +1 -178
  36. data/spec/ruby/block/next_spec.rb~ +85 -0
  37. data/spec/ruby/block/proc_spec.rb~ +22 -0
  38. data/spec/ruby/block/redo_spec.rb~ +133 -0
  39. data/spec/ruby/block/retry_spec.rb~ +135 -0
  40. data/spec/ruby/block_spec.rb~ +494 -2
  41. data/spec/ruby/call/base_call_spec.rb~ +60 -2
  42. data/spec/ruby/defn/default_args_spec.rb~ +303 -0
  43. data/spec/ruby/defn/multiple_args_spec.rb~ +317 -0
  44. data/spec/ruby/defn/replacement_spec.rb +29 -1
  45. data/spec/ruby/defn/replacement_spec.rb~ +52 -21
  46. data/spec/ruby/exception/internal_ex_spec.rb~ +2 -2
  47. data/spec/ruby/variable_spec.rb~ +46 -23
  48. data/spec/static/flow_spec.rb~ +48 -0
  49. metadata +34 -12
@@ -58,6 +58,7 @@ module FastRuby
58
58
  end
59
59
 
60
60
  if method_name == "inline_c"
61
+ @has_inline_c = true
61
62
  arg = tree[3][1]
62
63
 
63
64
  if arg.node_type != :str
@@ -0,0 +1,290 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module FastRuby
22
+ class Context
23
+ define_translator_for(:iter, :arity => 1, :priority => 1) { |*x|
24
+ ret = nil
25
+ tree = x.first
26
+ enable_handler_group(:static_call, :to_c) do
27
+ ret = x.size == 1 ? to_c(tree[3]) : to_c(tree[3], x.last)
28
+ end
29
+ ret
30
+ }.condition{ |*x|
31
+ tree = x.first
32
+ tree.node_type == :iter && tree[1][2] == :_static
33
+ }
34
+
35
+ define_translator_for(:iter, :arity => 1, :priority => 1) { |*x|
36
+ ret = nil
37
+ tree = x.first
38
+
39
+ disable_handler_group(:static_call, :to_c) do
40
+ ret = x.size == 1 ? to_c(tree[3]) : to_c(tree[3], x.last)
41
+ end
42
+ ret
43
+ }.condition{ |*x|
44
+ tree = x.first
45
+ tree.node_type == :iter && tree[1][2] == :_dynamic
46
+ }
47
+
48
+ handler_scope(:group => :static_call, :priority => 1000) do
49
+ define_translator_for(:call) do |*x|
50
+ tree, result = x
51
+
52
+ method_name = tree[2].to_s
53
+ recv_tree = tree[1]
54
+
55
+ if method_name == "c_address_of"
56
+ arg = tree[3][1]
57
+ return "&"+to_c(arg)
58
+ end
59
+
60
+ if method_name == "inline_c"
61
+ arg = tree[3][1]
62
+
63
+ if arg.node_type != :str
64
+ raise RuntimeError, "invalid node for inline_c directive #{arg}"
65
+ end
66
+
67
+ next arg[1]
68
+ end
69
+
70
+ if recv_tree and recv_tree.node_type != :self
71
+ if (not tree[2].to_s =~ /^[a-zA-Z]/) and tree[2].to_s.size <= 3
72
+ c_op = tree[2].to_s
73
+ c_op = '==' if tree[2] == :===
74
+ code = "( ( #{to_c(tree[1])} )#{c_op}(#{to_c(tree[3][1])}) )"
75
+ elsif tree[2] == :_invariant
76
+ name = self.add_global_name("VALUE", "Qnil");
77
+
78
+ init_extra << "
79
+ #{name} = #{to_c tree[1]};
80
+ rb_funcall(#{name},#{intern_num :gc_register_object},0);
81
+ "
82
+
83
+ code = name;
84
+ else
85
+ args = tree[3][1..-1].map{|st| to_c(st)}.join(",")
86
+ code = "#{method_name}( #{args} )"
87
+ end
88
+ else
89
+ args = tree[3][1..-1].map{|st| to_c(st)}.join(",")
90
+ code = "#{method_name}( #{args} )"
91
+ end
92
+
93
+ if result
94
+ "#{result} = #{code};"
95
+ else
96
+ code
97
+ end
98
+ end
99
+
100
+ define_translator_for(:lit) do |*x|
101
+ tree, result = x
102
+
103
+ if result
104
+ "#{result} = #{tree[1]};"
105
+ else
106
+ tree[1].to_s
107
+ end
108
+ end
109
+
110
+ define_translator_for(:if) do |*x|
111
+ tree, result_variable_ = x
112
+
113
+ condition_tree = tree[1]
114
+ impl_tree = tree[2]
115
+ else_tree = tree[3]
116
+
117
+ result_variable = result_variable_ || "last_expression"
118
+
119
+ code = proc {"
120
+ {
121
+ VALUE condition_result;
122
+ #{to_c condition_tree, "condition_result"};
123
+ if (condition_result) {
124
+ #{to_c impl_tree, result_variable};
125
+ }#{else_tree ?
126
+ " else {
127
+ #{to_c else_tree, result_variable};
128
+ }
129
+ " : ""
130
+ }
131
+ }
132
+ "}
133
+
134
+ if result_variable_
135
+ code.call
136
+ else
137
+ inline_block(&code) + "; return last_expression;"
138
+ end
139
+ end
140
+
141
+ define_translator_for(:const) do |*x|
142
+ tree, result_var = x
143
+
144
+ if result_var
145
+ "#{result_var} = #{tree[1].to_s};"
146
+ else
147
+ "#{tree[1].to_s}"
148
+ end
149
+ end
150
+
151
+ define_translator_for(:while) do |*x|
152
+ tree, result_var = x
153
+
154
+ begin_while = "begin_while_"+rand(10000000).to_s
155
+ end_while = "end_while_"+rand(10000000).to_s
156
+ aux_varname = "_aux_" + rand(10000000).to_s
157
+ code = proc {"
158
+ {
159
+ VALUE while_condition;
160
+ VALUE #{aux_varname};
161
+
162
+ #{begin_while}:
163
+ #{to_c tree[1], "while_condition"};
164
+ if (!(while_condition)) goto #{end_while};
165
+ #{to_c tree[2], aux_varname};
166
+ goto #{begin_while};
167
+ #{end_while}:
168
+
169
+ #{
170
+ if result_var
171
+ "#{result_var} = Qnil;"
172
+ else
173
+ "return Qnil;"
174
+ end
175
+ }
176
+ }
177
+ "}
178
+
179
+ if result_var
180
+ code.call
181
+ else
182
+ inline_block &code
183
+ end
184
+
185
+ end
186
+
187
+ define_translator_for(:and) do |*x|
188
+ tree, return_var = x
189
+
190
+ if return_var
191
+ "
192
+ {
193
+ VALUE op1 = Qnil;
194
+ VALUE op2 = Qnil;
195
+ #{to_c tree[1], "op1"};
196
+ #{to_c tree[2], "op2"};
197
+ #{return_var} = ((op1) &&(op2));
198
+ }
199
+ "
200
+ else
201
+ "((#{to_c tree[1]}) && (#{to_c tree[2]}))"
202
+ end
203
+
204
+ end
205
+
206
+ define_translator_for(:or) do |*x|
207
+ tree, return_var = x
208
+
209
+ if return_var
210
+ "
211
+ {
212
+ VALUE op1 = Qnil;
213
+ VALUE op2 = Qnil;
214
+ #{to_c tree[1], "op1"};
215
+ #{to_c tree[2], "op2"};
216
+ #{return_var} = ((op1) ||(op2));
217
+ }
218
+ "
219
+ else
220
+ "((#{to_c tree[1]}) || (#{to_c tree[2]}))"
221
+ end
222
+
223
+ end
224
+
225
+ define_translator_for(:not) do |*x|
226
+ tree, return_var = x
227
+
228
+ if return_var
229
+ "
230
+ {
231
+ VALUE op1 = Qnil;
232
+ #{to_c tree[1], "op1"};
233
+ #{return_var} = ((op1) ? 0: 1);
234
+ }
235
+ "
236
+ else
237
+ "((#{to_c tree[1]}) ? 0 : 1)"
238
+ end
239
+ end
240
+
241
+ end
242
+
243
+ define_method_handler(:initialize_to_c){|*x|}.condition do |*x|
244
+ disable_handler_group(:static_call, :to_c); false
245
+ end
246
+
247
+
248
+ define_method_handler(:infer_value) { |*x| tree = x.first;
249
+ Value.new(eval(tree[1].to_s))
250
+ }.condition{|*x| tree = x.first; tree.node_type == :const}
251
+
252
+ define_method_handler(:infer_value) { |*x| tree = x.first;
253
+ args_tree = tree[3]
254
+ receiver_tree = tree[1]
255
+
256
+ value_1 = infer_value(receiver_tree)
257
+ value_2 = infer_value(args_tree[1])
258
+
259
+ next false unless (value_1 and value_2)
260
+
261
+ Value.new(value_1.value == value_2.value)
262
+ }.condition{|*x| tree = x.first;
263
+ next false unless tree.node_type == :call
264
+
265
+ args_tree = tree[3]
266
+ method_name = tree[2]
267
+
268
+ next false unless method_name == :==
269
+ next false if args_tree.size < 2
270
+
271
+ true
272
+ }
273
+ define_method_handler(:infer_value) { |*x| tree = x.first;
274
+ args_tree = tree[3]
275
+ receiver_tree = tree[1]
276
+ infered_type = infer_type(receiver_tree)
277
+
278
+ if infered_type
279
+ Value.new(infered_type)
280
+ else
281
+ nil
282
+ end
283
+ }.condition{|*x| tree = x.first;
284
+ next false unless tree.node_type == :call
285
+ method_name = tree[2]
286
+ next false unless method_name == :_class
287
+ true
288
+ }
289
+ end
290
+ end
@@ -22,7 +22,7 @@ module FastRuby
22
22
  class Context
23
23
  define_translator_for(:cvar, :method => :to_c_cvar, :arity => 1)
24
24
  def to_c_cvar(tree)
25
- "rb_cvar_get(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]})"
25
+ "rb_cvar_get(CLASS_OF(#{var_self}) != rb_cClass ? CLASS_OF(#{var_self}) : #{var_self},#{intern_num tree[1]})"
26
26
  end
27
27
 
28
28
  define_translator_for(:cvasgn, :method => :to_c_cvasgn)
@@ -30,7 +30,7 @@ module FastRuby
30
30
  if result_var
31
31
  "
32
32
  {
33
- VALUE recv = CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self;
33
+ VALUE recv = CLASS_OF(#{var_self}) != rb_cClass ? CLASS_OF(#{var_self}) : #{var_self};
34
34
 
35
35
  #{to_c tree[2], result_var};
36
36
 
@@ -45,7 +45,7 @@ module FastRuby
45
45
  }
46
46
  "
47
47
  else
48
- "__rb_cvar_set(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]},#{to_c tree[2]},Qfalse)"
48
+ "__rb_cvar_set(CLASS_OF(#{var_self}) != rb_cClass ? CLASS_OF(#{var_self}) : #{var_self},#{intern_num tree[1]},#{to_c tree[2]},Qfalse)"
49
49
  end
50
50
  end
51
51
 
@@ -92,7 +92,7 @@ module FastRuby
92
92
  end
93
93
 
94
94
  define_translator_for(:const, :arity => 1) do |*x| tree = x.first;
95
- "rb_const_get(CLASS_OF(plocals->self), #{intern_num(tree[1])})"
95
+ "rb_const_get(CLASS_OF(#{var_self}), #{intern_num(tree[1])})"
96
96
  end
97
97
 
98
98
  define_translator_for(:cdecl, :method => :to_c_cdecl)
@@ -215,9 +215,27 @@ module FastRuby
215
215
  "_lvar_assing(&#{locals_accessor}#{tree[1]},#{to_c tree[2]})"
216
216
  end
217
217
  end
218
+
219
+ def is_argument(variable)
220
+ @method_arguments.include?(variable)
221
+ end
218
222
 
219
223
  define_translator_for(:lvar, :arity => 1) do |*x| tree = x.first;
220
- locals_accessor + tree[1].to_s
224
+ if @has_inline_block or (not is_argument(tree[1]))
225
+ locals_accessor + tree[1].to_s
226
+ else
227
+ # search in arguments
228
+ index = @method_arguments.find_index{|argument| argument == tree[1]}
229
+ if index
230
+ "argv[#{index}]"
231
+ else
232
+ locals_accessor + tree[1].to_s
233
+ end
234
+ end
235
+ end
236
+
237
+ def var_self
238
+ @has_inline_block ? locals_accessor + "self" : "self";
221
239
  end
222
240
 
223
241
  define_translator_for(:defined, :method => :to_c_defined, :arity => 1)
@@ -253,7 +271,7 @@ module FastRuby
253
271
  elsif nt == :yield
254
272
  "rb_block_given_p() ? #{literal_value "yield"} : Qnil"
255
273
  elsif nt == :ivar
256
- "rb_ivar_defined(plocals->self,#{intern_num obj_tree[1]}) ? #{literal_value "instance-variable"} : Qnil"
274
+ "rb_ivar_defined(#{var_self},#{intern_num obj_tree[1]}) ? #{literal_value "instance-variable"} : Qnil"
257
275
  elsif nt == :attrset or
258
276
  nt == :op_asgn1 or
259
277
  nt == :op_asgn2 or
@@ -0,0 +1,298 @@
1
+ =begin
2
+
3
+ This file is part of the fastruby project, http://github.com/tario/fastruby
4
+
5
+ Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ fastruby is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ fastruby is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module FastRuby
22
+ class Context
23
+ define_translator_for(:cvar, :method => :to_c_cvar, :arity => 1)
24
+ def to_c_cvar(tree)
25
+ "rb_cvar_get(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]})"
26
+ end
27
+
28
+ define_translator_for(:cvasgn, :method => :to_c_cvasgn)
29
+ def to_c_cvasgn(tree, result_var = nil)
30
+ if result_var
31
+ "
32
+ {
33
+ VALUE recv = CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self;
34
+
35
+ #{to_c tree[2], result_var};
36
+
37
+ #{if RUBY_VERSION =~ /^1\.9/
38
+ "rb_cvar_set(recv,#{intern_num tree[1]},#{result_var});"
39
+ elsif RUBY_VERSION =~ /^1\.8/
40
+ "rb_cvar_set(recv,#{intern_num tree[1]},#{result_var},Qfalse);"
41
+ else
42
+ raise RuntimeError, "unsupported ruby version #{RUBY_VERSION}"
43
+ end
44
+ }
45
+ }
46
+ "
47
+ else
48
+ "__rb_cvar_set(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]},#{to_c tree[2]},Qfalse)"
49
+ end
50
+ end
51
+
52
+ define_translator_for(:gvar, :method => :to_c_gvar, :arity => 1)
53
+ def to_c_gvar(tree)
54
+ if (tree[1] == :$!)
55
+ "pframe->thread_data->exception"
56
+ else
57
+ "rb_gvar_get((struct global_entry*)#{global_entry(tree[1])})"
58
+ end
59
+ end
60
+
61
+ define_translator_for(:gasgn, :method => :to_c_gasgn)
62
+ def to_c_gasgn(tree, result_var = nil)
63
+ if result_var
64
+ "
65
+ {
66
+ #{to_c tree[2], result_var};
67
+ rb_gvar_set((void*)#{global_entry(tree[1])},#{result_var});
68
+ }
69
+ "
70
+ else
71
+ "_rb_gvar_set((void*)#{global_entry(tree[1])}, #{to_c tree[2]})"
72
+ end
73
+ end
74
+
75
+ define_translator_for(:ivar, :method => :to_c_ivar, :arity => 1)
76
+ def to_c_ivar(tree)
77
+ "rb_ivar_get(#{locals_accessor}self,#{intern_num tree[1]})"
78
+ end
79
+
80
+ define_translator_for(:iasgn, :method => :to_c_iasgn)
81
+ def to_c_iasgn(tree, result_var = nil)
82
+ if result_var
83
+ "
84
+ {
85
+ #{to_c tree[2], result_var};
86
+ rb_ivar_set(#{locals_accessor}self,#{intern_num tree[1]},#{result_var});
87
+ }
88
+ "
89
+ else
90
+ "_rb_ivar_set(#{locals_accessor}self,#{intern_num tree[1]},#{to_c tree[2]})"
91
+ end
92
+ end
93
+
94
+ define_translator_for(:const, :arity => 1) do |*x| tree = x.first;
95
+ "rb_const_get(CLASS_OF(plocals->self), #{intern_num(tree[1])})"
96
+ end
97
+
98
+ define_translator_for(:cdecl, :method => :to_c_cdecl)
99
+ def to_c_cdecl(tree, result_var_ = nil)
100
+
101
+ result_var = result_var_ || "value"
102
+
103
+ if tree[1].instance_of? Symbol
104
+ code = proc{"
105
+ {
106
+ // set constant #{tree[1].to_s}
107
+ #{to_c tree[2], result_var};
108
+ rb_const_set(rb_cObject, #{intern_num tree[1]}, #{result_var});
109
+ }
110
+ "}
111
+ elsif tree[1].instance_of? FastRuby::FastRubySexp
112
+
113
+ if tree[1].node_type == :colon2
114
+ code = proc{"
115
+ {
116
+ // set constant #{tree[1].to_s}
117
+ #{to_c tree[2], result_var};
118
+ VALUE klass = Qnil;
119
+ #{to_c tree[1][1], "klass"};
120
+ rb_const_set(klass, #{intern_num tree[1][2]}, #{result_var});
121
+ }
122
+ "}
123
+ elsif tree[1].node_type == :colon3
124
+ code = proc{"
125
+ {
126
+ // set constant #{tree[1].to_s}
127
+ #{to_c tree[2], result_var};
128
+ rb_const_set(rb_cObject, #{intern_num tree[1][1]}, #{result_var});
129
+ }
130
+ "}
131
+ end
132
+ end
133
+
134
+ if result_var_
135
+ code.call
136
+ else
137
+ inline_block{"VALUE #{result_var} = Qnil;\n" + code.call + "
138
+ return #{result_var};
139
+ "}
140
+ end
141
+ end
142
+
143
+ define_translator_for(:colon3, :method => :to_c_colon3, :arity => 1)
144
+ def to_c_colon3(tree)
145
+ "rb_const_get_from(rb_cObject, #{intern_num tree[1]})"
146
+ end
147
+
148
+ define_translator_for(:colon2, :method => :to_c_colon2)
149
+ def to_c_colon2(tree, result_var = nil)
150
+ code = proc{ "
151
+ {
152
+ VALUE klass = Qnil;
153
+
154
+ #{to_c tree[1],"klass"};
155
+ #{
156
+ if result_var
157
+ "#{result_var} = Qnil;"
158
+ end
159
+ }
160
+
161
+ if (rb_is_const_id(#{intern_num tree[2]})) {
162
+ switch (TYPE(klass)) {
163
+ case T_CLASS:
164
+ case T_MODULE:
165
+ #{
166
+ if result_var
167
+ "#{result_var} = rb_const_get_from(klass, #{intern_num tree[2]});"
168
+ else
169
+ "return rb_const_get_from(klass, #{intern_num tree[2]});"
170
+ end
171
+ }
172
+ break;
173
+ default:
174
+ #{_raise("rb_eTypeError","not a class/module")};
175
+ break;
176
+ }
177
+ }
178
+ else {
179
+ #{
180
+ if result_var
181
+ "#{result_var} = rb_funcall(klass, #{intern_num tree[2]}, 0, 0);"
182
+ else
183
+ "return rb_funcall(klass, #{intern_num tree[2]}, 0, 0);"
184
+ end
185
+ }
186
+ }
187
+
188
+ #{
189
+ unless result_var
190
+ "return Qnil;"
191
+ end
192
+ }
193
+ }
194
+ "}
195
+
196
+ if result_var
197
+ code.call
198
+ else
199
+ inline_block &code
200
+ end
201
+ end
202
+
203
+ define_translator_for(:lasgn, :method => :to_c_lasgn)
204
+ def to_c_lasgn(tree, result_var = nil)
205
+ code = "
206
+ {
207
+ #{to_c tree[2], result_var};
208
+ #{locals_accessor}#{tree[1]} = #{result_var};
209
+ }
210
+ "
211
+
212
+ if result_var
213
+ code
214
+ else
215
+ "_lvar_assing(&#{locals_accessor}#{tree[1]},#{to_c tree[2]})"
216
+ end
217
+ end
218
+
219
+ def is_argument(variable)
220
+ @method_arguments.include?(variable)
221
+ end
222
+
223
+ define_translator_for(:lvar, :arity => 1) do |*x| tree = x.first;
224
+ if @has_inline_block or (not is_argument(tree[1]))
225
+ locals_accessor + tree[1].to_s
226
+ else
227
+ # search in arguments
228
+ index = @method_arguments.find_index{|argument| argument == tree[1]}
229
+ if index
230
+ "argv[#{index}]"
231
+ else
232
+ locals_accessor + tree[1].to_s
233
+ end
234
+ end
235
+ end
236
+
237
+ def var_self
238
+ @has_inline_block ? locals_accessor + "self" : "self";
239
+ end
240
+
241
+ define_translator_for(:defined, :method => :to_c_defined, :arity => 1)
242
+ def to_c_defined(tree)
243
+ obj_tree = tree[1]
244
+
245
+ if obj_tree[0] == :call && obj_tree[2] == :infer
246
+ obj_tree = obj_tree[1]
247
+ end
248
+
249
+ nt = obj_tree.node_type
250
+
251
+ if nt == :self
252
+ 'rb_str_new2("self")'
253
+ elsif nt == :true
254
+ 'rb_str_new2("true")'
255
+ elsif nt == :false
256
+ 'rb_str_new2("false")'
257
+ elsif nt == :nil
258
+ 'rb_str_new2("nil")'
259
+ elsif nt == :lvar
260
+ 'rb_str_new2("local-variable")'
261
+ elsif nt == :gvar
262
+ "rb_gvar_defined((struct global_entry*)#{global_entry(obj_tree[1])}) ? #{literal_value "global-variable"} : Qnil"
263
+ elsif nt == :const
264
+ "rb_const_defined(rb_cObject, #{intern_num obj_tree[1]}) ? #{literal_value "constant"} : Qnil"
265
+ elsif nt == :call
266
+ if RUBY_VERSION =~ /^1\.8/
267
+ "rb_method_node(CLASS_OF(#{to_c obj_tree[1]}), #{intern_num obj_tree[2]}) ? #{literal_value "method"} : Qnil"
268
+ else
269
+ "rb_method_entry(CLASS_OF(#{to_c obj_tree[1]}), #{intern_num obj_tree[2]}) ? #{literal_value "method"} : Qnil"
270
+ end
271
+ elsif nt == :yield
272
+ "rb_block_given_p() ? #{literal_value "yield"} : Qnil"
273
+ elsif nt == :ivar
274
+ "rb_ivar_defined(#{var_self},#{intern_num obj_tree[1]}) ? #{literal_value "instance-variable"} : Qnil"
275
+ elsif nt == :attrset or
276
+ nt == :op_asgn1 or
277
+ nt == :op_asgn2 or
278
+ nt == :op_asgn_or or
279
+ nt == :op_asgn_and or
280
+ nt == :op_asgn_masgn or
281
+ nt == :masgn or
282
+ nt == :lasgn or
283
+ nt == :dasgn or
284
+ nt == :dasgn_curr or
285
+ nt == :gasgn or
286
+ nt == :iasgn or
287
+ nt == :cdecl or
288
+ nt == :cvdecl or
289
+ nt == :cvasgn
290
+ literal_value "assignment"
291
+ else
292
+ literal_value "expression"
293
+ end
294
+ end
295
+
296
+
297
+ end
298
+ end