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