fastruby 0.0.19 → 0.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/CHANGELOG +8 -0
  2. data/{README → README.rdoc} +6 -1
  3. data/Rakefile +7 -7
  4. data/benchmarks/benchmark.rb~ +14 -2
  5. data/ext/fastruby_base/fastruby_base.inl +8 -4
  6. data/lib/fastruby/builder/inference_updater.rb +76 -0
  7. data/lib/fastruby/builder/inference_updater.rb~ +76 -0
  8. data/lib/fastruby/builder/inferencer.rb +38 -0
  9. data/lib/fastruby/{inliner → builder}/inliner.rb +16 -27
  10. data/lib/fastruby/builder/inliner.rb~ +60 -0
  11. data/lib/fastruby/builder/locals_inference.rb +53 -0
  12. data/lib/fastruby/builder/lvar_type.rb +43 -0
  13. data/lib/fastruby/builder/lvar_type.rb~ +44 -0
  14. data/lib/fastruby/builder/pipeline.rb +43 -0
  15. data/lib/fastruby/builder/pipeline.rb~ +43 -0
  16. data/lib/fastruby/{reductor → builder}/reductor.rb +6 -3
  17. data/lib/fastruby/builder/reductor.rb~ +42 -0
  18. data/lib/fastruby/builder.rb +73 -25
  19. data/lib/fastruby/builder.rb~ +311 -0
  20. data/lib/fastruby/corelib/fixnum.rb +75 -0
  21. data/lib/fastruby/corelib/fixnum.rb~ +146 -0
  22. data/lib/fastruby/corelib/integer.rb +96 -0
  23. data/lib/fastruby/corelib/integer.rb~ +96 -0
  24. data/lib/fastruby/corelib.rb +23 -0
  25. data/lib/fastruby/corelib.rb~ +23 -0
  26. data/lib/fastruby/getlocals.rb +3 -1
  27. data/lib/fastruby/logging.rb +2 -2
  28. data/lib/fastruby/modules/inferencer/infer.rb +31 -0
  29. data/lib/fastruby/modules/inferencer/literal.rb +42 -0
  30. data/lib/fastruby/modules/inliner/call.rb +327 -0
  31. data/lib/fastruby/{inliner/modules/call.rb → modules/inliner/call.rb~} +14 -24
  32. data/lib/fastruby/modules/inliner/defn.rb +41 -0
  33. data/lib/fastruby/modules/inliner/defn.rb~ +29 -0
  34. data/lib/fastruby/modules/inliner/recursive.rb +40 -0
  35. data/lib/fastruby/{inliner/modules/recursive.rb → modules/inliner/recursive.rb~} +1 -1
  36. data/lib/fastruby/modules/lvar_type/call.rb +36 -0
  37. data/lib/fastruby/modules/lvar_type/call.rb~ +36 -0
  38. data/lib/fastruby/modules/lvar_type/defn.rb +42 -0
  39. data/lib/fastruby/modules/lvar_type/defn.rb~ +42 -0
  40. data/lib/fastruby/modules/lvar_type/lasgn.rb +41 -0
  41. data/lib/fastruby/modules/lvar_type/lasgn.rb~ +42 -0
  42. data/lib/fastruby/modules/lvar_type/recursive.rb +33 -0
  43. data/lib/fastruby/modules/lvar_type/recursive.rb~ +33 -0
  44. data/lib/fastruby/{reductor/modules → modules/reductor}/case.rb +0 -0
  45. data/lib/fastruby/modules/reductor/fastruby_flag.rb +33 -0
  46. data/lib/fastruby/{reductor/modules → modules/reductor}/for.rb +0 -0
  47. data/lib/fastruby/{reductor/modules → modules/reductor}/nontree.rb +0 -0
  48. data/lib/fastruby/modules/reductor/nontree.rb~ +32 -0
  49. data/lib/fastruby/{reductor/modules → modules/reductor}/recursive.rb +1 -1
  50. data/lib/fastruby/modules/reductor/recursive.rb~ +31 -0
  51. data/lib/fastruby/{translator/modules → modules/translator}/block.rb +0 -0
  52. data/lib/fastruby/modules/translator/call.rb +344 -0
  53. data/lib/fastruby/{translator/modules/call.rb → modules/translator/call.rb~} +24 -3
  54. data/lib/fastruby/{translator/modules → modules/translator}/defn.rb +10 -9
  55. data/lib/fastruby/modules/translator/defn.rb~ +267 -0
  56. data/lib/fastruby/{translator/modules → modules/translator}/directive.rb +3 -1
  57. data/lib/fastruby/modules/translator/directive.rb~ +44 -0
  58. data/lib/fastruby/{translator/modules → modules/translator}/exceptions.rb +3 -1
  59. data/lib/fastruby/modules/translator/exceptions.rb~ +120 -0
  60. data/lib/fastruby/{translator/modules → modules/translator}/flow.rb +0 -0
  61. data/lib/fastruby/modules/translator/iter.rb +745 -0
  62. data/lib/fastruby/{translator/modules/iter.rb → modules/translator/iter.rb~} +103 -48
  63. data/lib/fastruby/modules/translator/literal.rb +150 -0
  64. data/lib/fastruby/{translator/modules/literal.rb → modules/translator/literal.rb~} +3 -3
  65. data/lib/fastruby/{translator/modules → modules/translator}/logical.rb +0 -0
  66. data/lib/fastruby/{translator/modules → modules/translator}/method_group.rb +0 -0
  67. data/lib/fastruby/{translator/modules → modules/translator}/nonlocal.rb +18 -6
  68. data/lib/fastruby/modules/translator/nonlocal.rb~ +298 -0
  69. data/lib/fastruby/modules/translator/static.rb +290 -0
  70. data/lib/fastruby/{translator/modules/static.rb → modules/translator/static.rb~} +66 -17
  71. data/lib/fastruby/modules/translator/variable.rb +280 -0
  72. data/lib/fastruby/{translator/modules/variable.rb → modules/translator/variable.rb~} +14 -44
  73. data/lib/fastruby/modules.rb +30 -0
  74. data/lib/fastruby/object.rb +42 -6
  75. data/lib/fastruby/object.rb~ +159 -0
  76. data/lib/fastruby/set_tree.rb +7 -11
  77. data/lib/fastruby/set_tree.rb~ +71 -0
  78. data/lib/fastruby/sexp_extension.rb +29 -7
  79. data/lib/fastruby/sexp_extension.rb~ +262 -0
  80. data/lib/fastruby/translator/scope_mode_helper.rb~ +138 -0
  81. data/lib/fastruby/translator/translator.rb +87 -92
  82. data/lib/fastruby/translator/translator.rb~ +1600 -0
  83. data/lib/fastruby/translator/translator_modules.rb +3 -1
  84. data/lib/fastruby/translator/translator_modules.rb~ +53 -0
  85. data/lib/fastruby.rb +3 -1
  86. data/lib/fastruby.rb~ +3 -1
  87. data/lib/fastruby_only/base.rb +1 -0
  88. data/spec/corelib/numeric/fixnum_spec.rb +110 -0
  89. data/spec/corelib/numeric/fixnum_spec.rb~ +104 -0
  90. data/spec/corelib/numeric/integer_spec.rb +173 -0
  91. data/spec/corelib/numeric/integer_spec.rb~ +173 -0
  92. data/spec/fastruby_only/base_spec.rb +74 -0
  93. data/spec/graph/base_spec.rb +2 -1
  94. data/spec/graph/base_spec.rb~ +35 -0
  95. data/spec/graph/path_spec.rb +2 -2
  96. data/spec/graph/path_spec.rb~ +48 -0
  97. data/spec/graph/vertex_spec.rb +2 -1
  98. data/spec/graph/vertex_spec.rb~ +58 -0
  99. data/spec/reductor/base_spec.rb +1 -1
  100. data/spec/ruby/block/lambda_spec.rb~ +163 -0
  101. data/spec/ruby/block/proc_as_block_spec.rb~ +69 -1
  102. data/spec/ruby/block_spec.rb~ +2 -494
  103. data/spec/ruby/call/base_call_spec.rb +1 -1
  104. data/spec/ruby/call/base_call_spec.rb~ +2 -60
  105. data/spec/ruby/defn/replacement_spec.rb +26 -14
  106. data/spec/ruby/defn/replacement_spec.rb~ +13 -3
  107. data/spec/ruby/exception/internal_ex_spec.rb~ +86 -0
  108. data/spec/ruby/integrity_spec.rb~ +35 -1
  109. data/spec/ruby/variable_spec.rb~ +31 -0
  110. data/spec/scope_mode/flow_spec.rb +1 -1
  111. data/spec/scope_mode/flow_spec.rb~ +109 -0
  112. data/spec/sugar/base_spec.rb +29 -0
  113. data/spec/sugar/base_spec.rb~ +16 -0
  114. metadata +100 -43
  115. data/spec/fastruby/inliner/modules/call_spec.rb +0 -0
  116. data/spec/fastruby/translator/modules/nonlocal_spec.rb +0 -0
  117. data/spec/fastruby/translator/translator_spec.rb +0 -0
  118. data/spec/ruby/block/arguments_spec.rb~ +0 -214
  119. data/spec/ruby/block/break_spec.rb~ +0 -236
  120. data/spec/ruby/block/next_spec.rb~ +0 -85
  121. data/spec/ruby/block/retry_spec.rb~ +0 -43
@@ -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
+
24
+ define_translator_for(:return, :method => :to_c_return)
25
+ def to_c_return(tree, return_variable = nil)
26
+ code = proc{"
27
+ #{to_c(tree[1],"last_expression")};
28
+ goto local_return;
29
+ return Qnil;
30
+ "}
31
+
32
+ if return_variable
33
+ code.call
34
+ else
35
+ inline_block &code
36
+ end
37
+ end
38
+
39
+ define_translator_for(:break, :method => :to_c_break)
40
+ def to_c_break(tree, result_var = nil)
41
+
42
+ value_tmp_var = "value_" + rand(10000000).to_s
43
+
44
+ code = proc{"
45
+
46
+ {
47
+ VALUE #{value_tmp_var} = Qnil;
48
+ #{
49
+ if tree[1]
50
+ to_c(tree[1], value_tmp_var)
51
+ end
52
+ };
53
+
54
+ typeof(pframe) target_frame_;
55
+ target_frame_ = (void*)plocals->call_frame;
56
+
57
+ if (target_frame_ == 0) {
58
+ #{_raise("rb_eLocalJumpError","illegal break_")};
59
+ }
60
+
61
+ plocals->call_frame = 0;
62
+
63
+ target_frame_->return_value = #{value_tmp_var};
64
+ target_frame_->targetted = 1;
65
+ pframe->thread_data->exception = Qnil;
66
+
67
+ longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);
68
+
69
+ }
70
+ "}
71
+
72
+ if result_var
73
+ code.call
74
+ else
75
+ inline_block code
76
+ end
77
+ end
78
+
79
+ define_translator_for(:retry, :method => :to_c_retry)
80
+ def to_c_retry(tree, result_var = nil)
81
+ code = "
82
+ {
83
+ typeof(pframe) target_frame_;
84
+ target_frame_ = (void*)plocals->call_frame;
85
+
86
+ if (target_frame_ == 0) {
87
+ #{_raise("rb_eLocalJumpError","illegal retry")};
88
+ }
89
+
90
+ target_frame_->targetted = 1;
91
+ longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);
92
+ }
93
+ "
94
+ if result_var
95
+ code
96
+ else
97
+ inline_block code
98
+ end
99
+ end
100
+
101
+ define_translator_for(:redo, :method => :to_c_redo)
102
+ def to_c_redo(tree, result_var = nil)
103
+ if @on_block
104
+ code = "
105
+ goto fastruby_local_redo;
106
+ "
107
+
108
+ if result_var
109
+ code
110
+ else
111
+ inline_block code
112
+ end
113
+ else
114
+ _raise("rb_eLocalJumpError","illegal redo");
115
+ end
116
+ end
117
+
118
+ define_translator_for(:next, :method => :to_c_next)
119
+ def to_c_next(tree, result_var = nil)
120
+ tmp_varname = "_acc_" + rand(10000000).to_s
121
+ if @on_block
122
+ code =proc {"
123
+ {
124
+ last_expression = Qnil;
125
+
126
+ #{
127
+ if tree[1]
128
+ to_c(tree[1],"last_expression")
129
+ end
130
+ }
131
+ pframe->thread_data->accumulator = last_expression;
132
+ goto fastruby_local_next;
133
+ }
134
+ "}
135
+
136
+ if result_var
137
+ code.call
138
+ else
139
+ inline_block &code
140
+ end
141
+ else
142
+ _raise("rb_eLocalJumpError","illegal next");
143
+ end
144
+ end
145
+
146
+ define_method_handler(:to_c, :priority => 100) { |*x|
147
+ tree, result_var = x
148
+
149
+
150
+ call_tree = tree[1]
151
+ catch_tag_id = call_tree[3][1][1]
152
+ included_catch_jmp = false
153
+
154
+ @catch_jmp = @catch_jmp || Set.new
155
+
156
+ begin
157
+ inner_code = catch_block(catch_tag_id) do
158
+ to_c(tree[3],result_var)
159
+ end
160
+
161
+ included_catch_jmp = true if @catch_jmp.include?(catch_tag_id)
162
+ ensure
163
+ @catch_jmp.delete(catch_tag_id)
164
+ end
165
+
166
+ if included_catch_jmp
167
+ new_frame = anonymous_function{ |name| "
168
+ static VALUE #{name}(VALUE param) {
169
+ volatile VALUE last_expression = Qnil;
170
+ #{@frame_struct} frame;
171
+
172
+ typeof(frame)* volatile pframe;
173
+ typeof(frame)* volatile parent_frame;
174
+ #{@locals_struct}* volatile plocals;
175
+
176
+ parent_frame = (void*)param;
177
+
178
+ frame.parent_frame = (void*)param;
179
+ frame.plocals = parent_frame->plocals;
180
+ frame.rescue = parent_frame->rescue;
181
+ frame.targetted = 0;
182
+ frame.thread_data = parent_frame->thread_data;
183
+ frame.return_value = Qnil;
184
+ frame.thread_data->accumulator = Qnil;
185
+ if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
186
+
187
+ plocals = frame.plocals;
188
+ pframe = &frame;
189
+
190
+ volatile int aux = setjmp(frame.jmp);
191
+ if (aux != 0) {
192
+ // restore previous frame
193
+ typeof(pframe) original_frame = pframe;
194
+ pframe = parent_frame;
195
+
196
+ if (aux == (int)#{intern_num catch_tag_id.to_s + "_end"}) {
197
+ return frame.thread_data->accumulator;
198
+ } else if (aux == (int)#{intern_num catch_tag_id.to_s + "_start"}) {
199
+ } else {
200
+ longjmp(pframe->jmp,aux);
201
+ }
202
+
203
+ return last_expression;
204
+ }
205
+
206
+ #{catch_tag_id.to_s}_start:
207
+ #{inner_code};
208
+ #{catch_tag_id.to_s}_end:
209
+ return last_expression;
210
+ #{@catch_blocks.map { |cb|
211
+ "#{cb.to_s}_end:
212
+
213
+ plocals->return_value = last_expression;
214
+ plocals->targetted = 1;
215
+ longjmp(pframe->jmp, #{intern_num( cb.to_s + "_end")});
216
+
217
+ #{cb.to_s}_start:
218
+
219
+ plocals->return_value = last_expression;
220
+ plocals->targetted = 1;
221
+ longjmp(pframe->jmp, #{intern_num( cb.to_s + "_start")});
222
+
223
+ "
224
+
225
+ }.join("\n")
226
+ }
227
+
228
+ }
229
+ "
230
+ } + "((VALUE)pframe)"
231
+
232
+ if result_var
233
+ "#{result_var} = #{new_frame};"
234
+ else
235
+ new_frame
236
+ end
237
+ else
238
+ "
239
+ #{catch_tag_id.to_s}_start:
240
+ #{inner_code};
241
+ #{catch_tag_id.to_s}_end:
242
+
243
+ "
244
+ end
245
+
246
+ }.condition{|*x|
247
+ tree, result_var = x
248
+
249
+ tree.node_type == :iter && tree[1][2] == :_catch
250
+ }
251
+
252
+ define_method_handler(:to_c, :priority => 100) { |*x|
253
+ tree, result_var = x
254
+
255
+ code = ""
256
+
257
+ catch_tag_id = tree[3][1][1]
258
+
259
+ if @catch_jmp_on_throw
260
+ @catch_jmp << catch_tag_id
261
+ end
262
+
263
+ code << to_c(tree[3][2] || fs(:nil), "last_expression")
264
+ code << "pframe->thread_data->accumulator = last_expression;"
265
+ code << "goto #{catch_tag_id.to_s}_end;"
266
+
267
+ if result_var
268
+ code
269
+ else
270
+ inline_block code
271
+ end
272
+ }.condition{|*x|
273
+ tree, result_var = x
274
+
275
+ tree.node_type == :call && tree[2] == :_throw
276
+ }
277
+
278
+ define_method_handler(:to_c, :priority => 100) { |*x|
279
+ tree, result_var = x
280
+
281
+ code = ""
282
+
283
+ catch_tag_id = tree[3][1][1]
284
+ code << "goto #{catch_tag_id.to_s}_start;"
285
+
286
+ if result_var
287
+ code
288
+ else
289
+ inline_block code
290
+ end
291
+ }.condition{|*x|
292
+ tree, result_var = x
293
+
294
+ tree.node_type == :call && tree[2] == :_loop
295
+ }
296
+
297
+ end
298
+ end
@@ -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