fastruby 0.0.17 → 0.0.18
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.
- data/CHANGELOG +10 -0
- data/Rakefile +4 -2
- data/benchmarks/benchmark.rb +20 -44
- data/benchmarks/benchmark.rb~ +47 -0
- data/benchmarks/benchmark2.rb +19 -45
- data/benchmarks/benchmark2.rb~ +46 -0
- data/benchmarks/benchmark3.rb +19 -45
- data/benchmarks/benchmark3.rb~ +46 -0
- data/benchmarks/benchmark4.rb +30 -65
- data/benchmarks/benchmark4.rb~ +61 -0
- data/benchmarks/benchmark5.rb +25 -55
- data/benchmarks/benchmark5.rb~ +54 -0
- data/benchmarks/benchmark6.rb +19 -40
- data/benchmarks/benchmark6.rb~ +41 -0
- data/benchmarks/benchmark7.rb +23 -52
- data/benchmarks/benchmark7.rb~ +48 -0
- data/ext/fastruby_base/fastruby_base.inl +1 -0
- data/lib/fastruby/builder.rb +128 -76
- data/lib/fastruby/cache/cache.rb +9 -5
- data/lib/fastruby/fastruby_sexp.rb +18 -0
- data/lib/fastruby/inliner/inliner.rb +68 -0
- data/lib/fastruby/inliner/modules/call.rb +150 -0
- data/lib/fastruby/inliner/modules/recursive.rb +35 -0
- data/lib/fastruby/object.rb +17 -32
- data/lib/fastruby/reductor/modules/case.rb +49 -0
- data/lib/{fastruby.rb~ → fastruby/reductor/modules/for.rb} +11 -13
- data/lib/fastruby/reductor/modules/nontree.rb +31 -0
- data/lib/fastruby/reductor/modules/recursive.rb +31 -0
- data/lib/fastruby/reductor/reductor.rb +39 -0
- data/lib/fastruby/set_tree.rb +7 -1
- data/lib/fastruby/sexp_extension.rb +6 -0
- data/lib/fastruby/translator/modules/block.rb +4 -4
- data/lib/fastruby/translator/modules/call.rb +9 -26
- data/lib/fastruby/translator/modules/defn.rb +5 -3
- data/lib/fastruby/translator/modules/directive.rb +42 -0
- data/lib/fastruby/translator/modules/exceptions.rb +12 -30
- data/lib/fastruby/translator/modules/flow.rb +33 -83
- data/lib/fastruby/translator/modules/iter.rb +4 -7
- data/lib/fastruby/translator/modules/literal.rb +11 -25
- data/lib/fastruby/translator/modules/logical.rb +5 -3
- data/lib/fastruby/translator/modules/method_group.rb +4 -3
- data/lib/fastruby/translator/modules/nonlocal.rb +7 -5
- data/lib/fastruby/translator/modules/static.rb +242 -0
- data/lib/fastruby/translator/modules/variable.rb +16 -9
- data/lib/fastruby/translator/scope_mode_helper.rb +2 -27
- data/lib/fastruby/translator/translator.rb +131 -60
- data/lib/fastruby/translator/translator_modules.rb +6 -2
- data/lib/fastruby.rb +1 -1
- data/spec/reductor/base_spec.rb +46 -0
- data/spec/ruby/base_spec.rb~ +394 -0
- data/spec/ruby/block/arguments_spec.rb~ +214 -0
- data/spec/ruby/block/proc_as_block_spec.rb~ +23 -0
- data/spec/ruby/block/retry_spec.rb~ +43 -0
- data/spec/ruby/block_spec.rb~ +520 -0
- data/spec/ruby/defn/replacement_spec.rb~ +102 -0
- data/spec/ruby/integrity_spec.rb~ +40 -0
- data/spec/ruby/singleton_spec.rb~ +76 -0
- data/spec/scope_mode/base_spec.rb +14 -5
- data/spec/scope_mode/block_spec.rb +18 -9
- data/spec/scope_mode/call_spec.rb +11 -2
- data/spec/scope_mode/exception_spec.rb +11 -2
- data/spec/scope_mode/flow_spec.rb +18 -8
- data/spec/scope_mode/optimization_spec.rb +21 -13
- data/spec/static/base_spec.rb +54 -0
- data/spec/static/flow_spec.rb +48 -0
- data/spec/static/operator_spec.rb +104 -0
- metadata +58 -8
@@ -26,6 +26,7 @@ require "fastruby/set_tree"
|
|
26
26
|
require "fastruby/exceptions"
|
27
27
|
require "fastruby/translator/translator_modules"
|
28
28
|
require "fastruby/translator/scope_mode_helper"
|
29
|
+
require "define_method_handler"
|
29
30
|
|
30
31
|
module FastRuby
|
31
32
|
class Context
|
@@ -39,12 +40,66 @@ module FastRuby
|
|
39
40
|
attr_reader :init_extra
|
40
41
|
attr_reader :extra_code
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
43
|
+
class Value
|
44
|
+
attr_accessor :value
|
45
|
+
def initialize(v); @value = v; end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.define_translator_for(ntype, options = {}, &blk)
|
49
|
+
condition_blk = proc do |*x|
|
50
|
+
tree = x.first; tree.node_type == ntype
|
51
|
+
end
|
52
|
+
|
53
|
+
if options[:arity]
|
54
|
+
if options[:arity] == 1
|
55
|
+
condition_blk = proc do |*x|
|
56
|
+
tree = x.first; x.size == 1 and tree.node_type == ntype
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
define_method_handler(:to_c, options, &blk).condition &condition_blk
|
62
|
+
end
|
63
|
+
|
64
|
+
define_method_handler(:to_c, :priority => 10000){|*x|
|
65
|
+
"Qnil"
|
66
|
+
}.condition{|*x| x.size == 1 and (not x.first)}
|
67
|
+
|
68
|
+
define_method_handler(:to_c, :priority => 1000){|tree, result_var|
|
69
|
+
"#{result_var} = #{to_c(tree)};"
|
70
|
+
}.condition{|*x| x.size == 2 and (not x.first)}
|
71
|
+
|
72
|
+
define_method_handler(:to_c, :priority => -9000){ |tree, result_var|
|
73
|
+
"#{result_var} = #{to_c(tree)};"
|
74
|
+
}.condition{|*x| x.size == 2 }
|
75
|
+
|
76
|
+
define_method_handler(:to_c, :priority => -10000) do |tree, result_var=nil|
|
77
|
+
raise "undefined translator for node type :#{tree.node_type}"
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method_handler(:initialize_to_c){|*x|}.condition{|*x|false}
|
81
|
+
|
82
|
+
define_translator_for(:call, :priority => 100){ |tree, result_var=nil|
|
83
|
+
tree[2] = :fastruby_require
|
84
|
+
to_c(tree)
|
85
|
+
}.condition{|*x|
|
86
|
+
tree = x.first; tree.node_type == :call && tree[2] == :require
|
87
|
+
}
|
88
|
+
|
89
|
+
define_method_handler(:infer_value, :priority => -1000) do |tree|
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
|
93
|
+
TranslatorModules.instance.each_under(FastRuby.fastruby_load_path + "/fastruby/translator/modules/") do |path|
|
94
|
+
groupname = path.split("/").last.split(".").first.to_sym
|
95
|
+
handler_scope(:group => groupname) do
|
96
|
+
require path
|
97
|
+
end
|
45
98
|
end
|
46
99
|
|
47
100
|
def initialize(common_func = true)
|
101
|
+
initialize_to_c
|
102
|
+
|
48
103
|
@infer_lvar_map = Hash.new
|
49
104
|
@no_cache = false
|
50
105
|
@extra_code = ""
|
@@ -183,22 +238,32 @@ module FastRuby
|
|
183
238
|
end
|
184
239
|
end
|
185
240
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
if method(mname).arity == 1
|
193
|
-
"#{result_variable} = #{send(mname, tree)};\n"
|
194
|
-
else
|
195
|
-
send(mname, tree, result_variable)
|
196
|
-
end
|
241
|
+
|
242
|
+
def _raise(class_tree, message_tree = nil)
|
243
|
+
class_tree = to_c class_tree unless class_tree.instance_of? String
|
244
|
+
|
245
|
+
if message_tree.instance_of? String
|
246
|
+
message_tree = "rb_str_new2(#{message_tree.inspect})"
|
197
247
|
else
|
198
|
-
|
248
|
+
message_tree = to_c message_tree
|
249
|
+
end
|
250
|
+
|
251
|
+
if message_tree
|
252
|
+
return inline_block("
|
253
|
+
pframe->thread_data->exception = rb_funcall(#{class_tree}, #{intern_num :exception},1,#{message_tree});
|
254
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
|
255
|
+
return Qnil;
|
256
|
+
")
|
257
|
+
else
|
258
|
+
return inline_block("
|
259
|
+
pframe->thread_data->exception = rb_funcall(#{class_tree}, #{intern_num :exception},0);
|
260
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
|
261
|
+
return Qnil;
|
262
|
+
")
|
199
263
|
end
|
200
|
-
end
|
201
264
|
|
265
|
+
end
|
266
|
+
|
202
267
|
def anonymous_function(*x)
|
203
268
|
|
204
269
|
name = "anonymous" + rand(10000000).to_s
|
@@ -280,7 +345,7 @@ module FastRuby
|
|
280
345
|
|
281
346
|
extra_code << "
|
282
347
|
static VALUE #{@alt_method_name}(VALUE self__);
|
283
|
-
static VALUE main_proc_call(VALUE self__, VALUE class_self_) {
|
348
|
+
static VALUE main_proc_call(VALUE self__, VALUE signature, VALUE class_self_) {
|
284
349
|
#{@alt_method_name}(class_self_);
|
285
350
|
return Qnil;
|
286
351
|
}
|
@@ -290,23 +355,22 @@ module FastRuby
|
|
290
355
|
init_extra << "
|
291
356
|
{
|
292
357
|
VALUE newproc = rb_funcall(rb_cObject,#{intern_num :new},0);
|
293
|
-
rb_define_singleton_method(newproc, \"call\", main_proc_call,
|
358
|
+
rb_define_singleton_method(newproc, \"call\", main_proc_call, 2);
|
294
359
|
rb_gv_set(\"$last_obj_proc\", newproc);
|
295
|
-
|
296
360
|
}
|
297
361
|
"
|
298
362
|
end
|
299
363
|
end
|
300
364
|
|
301
|
-
def define_method_at_init(
|
302
|
-
|
303
|
-
{
|
365
|
+
def define_method_at_init(method_name, size, signature)
|
366
|
+
extra_code << "
|
367
|
+
static VALUE main_proc_call(VALUE self__, VALUE signature, VALUE class_self_) {
|
304
368
|
VALUE method_name = rb_funcall(
|
305
369
|
#{literal_value FastRuby},
|
306
370
|
#{intern_num :make_str_signature},
|
307
371
|
2,
|
308
372
|
#{literal_value method_name},
|
309
|
-
|
373
|
+
signature
|
310
374
|
);
|
311
375
|
|
312
376
|
ID id = rb_intern(RSTRING_PTR(method_name));
|
@@ -315,12 +379,12 @@ module FastRuby
|
|
315
379
|
#{literal_value FastRuby},
|
316
380
|
#{intern_num :set_builder_module},
|
317
381
|
1,
|
318
|
-
|
382
|
+
class_self_
|
319
383
|
);
|
320
384
|
|
321
385
|
VALUE rb_method_hash;
|
322
386
|
void** address = 0;
|
323
|
-
rb_method_hash = rb_funcall(
|
387
|
+
rb_method_hash = rb_funcall(class_self_, #{intern_num :method_hash},1,#{literal_value method_name});
|
324
388
|
|
325
389
|
if (rb_method_hash != Qnil) {
|
326
390
|
VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
|
@@ -335,15 +399,25 @@ module FastRuby
|
|
335
399
|
*address = #{alt_method_name};
|
336
400
|
|
337
401
|
rb_funcall(
|
338
|
-
|
402
|
+
class_self_,
|
339
403
|
#{intern_num :register_method_value},
|
340
404
|
3,
|
341
405
|
#{literal_value method_name},
|
342
406
|
PTR2NUM(id),
|
343
407
|
PTR2NUM(address)
|
344
408
|
);
|
409
|
+
|
410
|
+
return Qnil;
|
345
411
|
}
|
346
412
|
"
|
413
|
+
|
414
|
+
init_extra << "
|
415
|
+
{
|
416
|
+
VALUE newproc = rb_funcall(rb_cObject,#{intern_num :new},0);
|
417
|
+
rb_define_singleton_method(newproc, \"call\", main_proc_call, 2);
|
418
|
+
rb_gv_set(\"$last_obj_proc\", newproc);
|
419
|
+
}
|
420
|
+
"
|
347
421
|
end
|
348
422
|
|
349
423
|
def to_c_method(tree, signature = nil)
|
@@ -359,7 +433,7 @@ module FastRuby
|
|
359
433
|
block_argument = tree[3].find{|x| x.to_s[0] == ?&}
|
360
434
|
impl_tree = tree[4][1]
|
361
435
|
end
|
362
|
-
|
436
|
+
|
363
437
|
args_tree = original_args_tree.select{|x| x.to_s[0] != ?&}
|
364
438
|
|
365
439
|
initialize_method_structs(original_args_tree)
|
@@ -1073,22 +1147,31 @@ fastruby_local_next:
|
|
1073
1147
|
end
|
1074
1148
|
|
1075
1149
|
pureruby_wrapper = anonymous_function{ |funcname| "
|
1076
|
-
static VALUE #{funcname}(VALUE self,void* block,void* frame
|
1150
|
+
static VALUE #{funcname}(VALUE self,void* block,void* frame, int argc, VALUE* argv){
|
1077
1151
|
#{@frame_struct}* pframe = frame;
|
1078
|
-
VALUE method_arguments[
|
1079
|
-
|
1152
|
+
VALUE method_arguments[3];
|
1153
|
+
|
1154
|
+
method_arguments[0] = (VALUE)argc;
|
1155
|
+
method_arguments[1] = (VALUE)argv;
|
1156
|
+
method_arguments[2] = (VALUE)self;
|
1157
|
+
|
1080
1158
|
return #{
|
1081
|
-
protected_block "last_expression =
|
1159
|
+
protected_block "last_expression = rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);", false, "method_arguments"
|
1082
1160
|
};
|
1083
1161
|
}
|
1084
1162
|
"
|
1085
1163
|
}
|
1086
1164
|
|
1087
1165
|
generic_wrapper = anonymous_function{ |funcname| "
|
1088
|
-
static VALUE #{funcname}(VALUE self,void* block,void* frame
|
1166
|
+
static VALUE #{funcname}(VALUE self,void* block,void* frame, int argc, VALUE* argv){
|
1089
1167
|
|
1090
1168
|
#{@frame_struct}* pframe = frame;
|
1091
|
-
VALUE method_arguments[
|
1169
|
+
VALUE method_arguments[4];
|
1170
|
+
|
1171
|
+
method_arguments[0] = (VALUE)argc;
|
1172
|
+
method_arguments[1] = (VALUE)argv;
|
1173
|
+
method_arguments[2] = (VALUE)self;
|
1174
|
+
method_arguments[3] = (VALUE)block;
|
1092
1175
|
|
1093
1176
|
void* fptr = 0;
|
1094
1177
|
|
@@ -1106,40 +1189,30 @@ fastruby_local_next:
|
|
1106
1189
|
|
1107
1190
|
fptr = *#{address_name};
|
1108
1191
|
|
1109
|
-
#{
|
1110
|
-
if args_tree.size < 25
|
1111
|
-
"
|
1112
1192
|
if (fptr == 0) {
|
1113
1193
|
fptr = *#{cfunc_address_name};
|
1114
1194
|
if (fptr != 0) {
|
1115
|
-
VALUE
|
1116
|
-
return ( (VALUE(*)(#{value_cast})) (fptr) )((VALUE)params,(VALUE)block,(VALUE)frame#{inprocstrargs});
|
1195
|
+
return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*) ) (fptr) )(self,(VALUE)block,(VALUE)frame, argc, argv);
|
1117
1196
|
}
|
1118
1197
|
}
|
1119
|
-
|
1120
|
-
end
|
1121
|
-
}
|
1122
|
-
|
1198
|
+
|
1123
1199
|
if (fptr == 0) {
|
1124
1200
|
if (block==0) {
|
1125
1201
|
return #{
|
1126
|
-
protected_block "last_expression =
|
1202
|
+
protected_block "last_expression = rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);", false, "method_arguments"
|
1127
1203
|
};
|
1128
1204
|
|
1129
1205
|
} else {
|
1130
1206
|
return #{
|
1131
1207
|
protected_block "
|
1132
1208
|
#{@block_struct} *pblock;
|
1133
|
-
pblock = (typeof(pblock))( ((VALUE*)method_arguments)[
|
1209
|
+
pblock = (typeof(pblock))( ((VALUE*)method_arguments)[3] );
|
1134
1210
|
last_expression = rb_iterate(
|
1135
1211
|
#{anonymous_function{|name|
|
1136
1212
|
"
|
1137
1213
|
static VALUE #{name} (VALUE data) {
|
1138
1214
|
VALUE* method_arguments = (VALUE*)data;
|
1139
|
-
return
|
1140
|
-
((VALUE*)method_arguments)[0],
|
1141
|
-
#{intern_num mname.to_sym},
|
1142
|
-
#{args_tree.size-1}#{inprocstrargs});
|
1215
|
+
return rb_funcall2(((VALUE*)method_arguments)[2], #{intern_num mname.to_sym}, ((int*)method_arguments)[0], ((VALUE**)method_arguments)[1]);
|
1143
1216
|
}
|
1144
1217
|
"
|
1145
1218
|
}},
|
@@ -1180,19 +1253,20 @@ fastruby_local_next:
|
|
1180
1253
|
}
|
1181
1254
|
|
1182
1255
|
} else {
|
1183
|
-
return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame
|
1256
|
+
return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame,argc,argv);
|
1184
1257
|
}
|
1185
1258
|
}
|
1186
1259
|
"
|
1187
1260
|
}
|
1188
1261
|
|
1189
1262
|
|
1263
|
+
cfuncall1inprocargs = (0..args_tree.size-2).map{|x| "argv[#{x}]"}.join(",")
|
1264
|
+
cfuncall1inprocargs = ","+cfuncall1inprocargs if cfuncall1inprocargs != ""
|
1265
|
+
|
1190
1266
|
cfunc_value_cast = (["VALUE"]*args_tree.size).join(",")
|
1191
1267
|
cfunc_wrapper = anonymous_function{ |funcname| "
|
1192
|
-
static VALUE #{funcname}(VALUE
|
1193
|
-
VALUE self
|
1194
|
-
VALUE method_arguments[#{args_tree.size}] = {#{toprocstrargs}};
|
1195
|
-
return ( (VALUE(*)(#{cfunc_value_cast})) (#{cfunc_real_address_name}) )(self#{inprocstrargs});
|
1268
|
+
static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
|
1269
|
+
return ( (VALUE(*)(#{cfunc_value_cast})) (#{cfunc_real_address_name}) )(self#{cfuncall1inprocargs});
|
1196
1270
|
}
|
1197
1271
|
"
|
1198
1272
|
}
|
@@ -1201,18 +1275,15 @@ fastruby_local_next:
|
|
1201
1275
|
strargs_signature = (0..25).map{|x| "VALUE arg#{x}"}.join(",")
|
1202
1276
|
|
1203
1277
|
cfunc_wrapper_1 = anonymous_function{ |funcname| "
|
1204
|
-
static VALUE #{funcname}(VALUE
|
1205
|
-
VALUE
|
1206
|
-
VALUE method_arguments[26] = {#{toprocstrargs}};
|
1207
|
-
return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(NUM2ULONG(params[1]),method_arguments,self);
|
1278
|
+
static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
|
1279
|
+
return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(argc,argv,self);
|
1208
1280
|
}
|
1209
1281
|
"
|
1210
1282
|
}
|
1211
1283
|
|
1212
1284
|
cfunc_wrapper_2 = anonymous_function{ |funcname| "
|
1213
|
-
static VALUE #{funcname}(VALUE
|
1214
|
-
VALUE
|
1215
|
-
VALUE args = rb_ary_new3(NUM2ULONG(params[1]),#{toprocstrargs});
|
1285
|
+
static VALUE #{funcname}(VALUE self, void* block,void* frame, int argc, VALUE* argv){
|
1286
|
+
VALUE args = rb_ary_new3(argc, argv);
|
1216
1287
|
return ( (VALUE(*)(VALUE,VALUE)) (#{cfunc_real_address_name}) )(self,args);
|
1217
1288
|
}
|
1218
1289
|
"
|
@@ -34,11 +34,15 @@ module FastRuby
|
|
34
34
|
@modls << modl
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def each_under(dir)
|
38
38
|
Dir.glob(dir + "/*.rb") do |x|
|
39
|
-
|
39
|
+
yield x
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
def load_under(dir)
|
44
|
+
each_under(dir, &method(:require))
|
45
|
+
end
|
42
46
|
end
|
43
47
|
end
|
44
48
|
|
data/lib/fastruby.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "fastruby"
|
2
|
+
require "fastruby/reductor/reductor"
|
3
|
+
require "fastruby/sexp_extension"
|
4
|
+
require "ruby_parser"
|
5
|
+
|
6
|
+
describe FastRuby, "fastruby" do
|
7
|
+
|
8
|
+
def self.test_normal_tree(code)
|
9
|
+
unmodified_tree = FastRuby::FastRubySexp.from_sexp RubyParser.new.parse code
|
10
|
+
it "tree for source #{code} should not be changed by reductor" do
|
11
|
+
obtained_tree = FastRuby::Reductor.new.reduce unmodified_tree
|
12
|
+
obtained_tree.should be == unmodified_tree
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should reduce for statements into each calls" do
|
17
|
+
reductor = FastRuby::Reductor.new
|
18
|
+
|
19
|
+
original_tree = fs(:for, fs(:call, nil, :b, fs(:arglist)), fs(:lasgn, :a), fs(:call, nil, :c, fs(:arglist)))
|
20
|
+
expected_tree = fs(:iter, fs(:call, fs(:call, nil, :b, fs(:arglist)), :each, fs(:arglist)), fs(:lasgn, :a), fs(:call, nil, :c, fs(:arglist)))
|
21
|
+
obtained_tree = reductor.reduce original_tree
|
22
|
+
|
23
|
+
obtained_tree.should be == expected_tree
|
24
|
+
end
|
25
|
+
|
26
|
+
test_normal_tree "a.foo(b)"
|
27
|
+
test_normal_tree "if (x); y; else; z; end"
|
28
|
+
|
29
|
+
it "should reduce call statements into if arrays" do
|
30
|
+
reductor = FastRuby::Reductor.new
|
31
|
+
|
32
|
+
original_tree = fs(:case,
|
33
|
+
fs(:call, nil, :a, fs(:arglist)),
|
34
|
+
fs(:when, fs(:array, fs(:call, nil, :b, fs(:arglist))), fs(:call, nil, :c, fs(:arglist))),
|
35
|
+
nil)
|
36
|
+
|
37
|
+
obtained_tree = reductor.reduce original_tree
|
38
|
+
|
39
|
+
obtained_tree.node_type.should be == :block
|
40
|
+
obtained_tree[1].node_type.should be == :lasgn
|
41
|
+
obtained_tree[1].last.should be == s(:call, nil, :a, s(:arglist)).to_fastruby_sexp
|
42
|
+
obtained_tree[2].node_type.should be == :if
|
43
|
+
obtained_tree[2][1].node_type.should be == :or
|
44
|
+
obtained_tree[2][2].should be == original_tree.find_tree(:when).last
|
45
|
+
end
|
46
|
+
end
|