fastruby 0.0.19 → 0.0.20

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.
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