ZenHacks 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Manifest.txt +29 -0
- data/README.txt +84 -0
- data/bin/macgraph +18 -0
- data/bin/parse_tree_graph +161 -0
- data/bin/test_stats +42 -0
- data/fixloops-demo.sh +3 -0
- data/lib/OrderedHash.rb +37 -0
- data/lib/class-path.rb +20 -0
- data/lib/discover.rb +15 -0
- data/lib/fixloops.rb +79 -0
- data/lib/graph.rb +66 -0
- data/lib/muffdaddy.rb +84 -0
- data/lib/r2c_hacks.rb +36 -0
- data/lib/ruby2ruby.rb +306 -0
- data/lib/timezones.rb +11 -0
- data/lib/zendebug.rb +1037 -0
- data/lib/zenoptimize.rb +149 -0
- data/lib/zenprofile.rb +170 -0
- data/misc/factorial.rb +26 -0
- data/misc/find_c_methods +49 -0
- data/misc/fixloops-bad.rb +62 -0
- data/r2c_hacks-demo.rb +23 -0
- data/test/TestOrderedHash.rb +43 -0
- data/test/r2ctestcase.rb +1076 -0
- data/test/test_parse_tree_graph.rb +47 -0
- data/zendebug-demo.sh +86 -0
- data/zenoptimize-demo.sh +22 -0
- data/zenprofile-demo.sh +29 -0
- metadata +69 -0
data/r2c_hacks-demo.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
|
3
|
+
ENV['GEM_SKIP'] = 'ParseTree:RubyInline'
|
4
|
+
$:.push 'lib', '../../ParseTree/dev/lib', '../../RubyInline/dev', '../../ruby_to_c/dev'
|
5
|
+
|
6
|
+
require 'r2c_hacks'
|
7
|
+
|
8
|
+
class Example
|
9
|
+
def example(arg1)
|
10
|
+
return "Blah: " + arg1.to_s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
e = Example.new
|
15
|
+
puts "Code (via cat):"
|
16
|
+
puts `cat #{$0}`
|
17
|
+
puts "sexp:"
|
18
|
+
p e.method(:example).to_sexp
|
19
|
+
puts "C:"
|
20
|
+
puts e.method(:example).to_c
|
21
|
+
puts "Ruby:"
|
22
|
+
puts e.method(:example).to_ruby
|
23
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
|
+
# Code Generated by ZenTest v. 2.2.0
|
3
|
+
# classname: asrt / meth = ratio%
|
4
|
+
# OrderedHash: 1 / 6 = 16.67%
|
5
|
+
# Number of errors detected: 0
|
6
|
+
|
7
|
+
#require 'test/unit' unless defined? $ZENTEST and $ZENTEST
|
8
|
+
require 'test/unit/testcase'
|
9
|
+
require 'OrderedHash'
|
10
|
+
|
11
|
+
class TestOrderedHash < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@k = %w(z y x)
|
15
|
+
@h = OrderedHash.new
|
16
|
+
|
17
|
+
@k.each_with_index do |key, val|
|
18
|
+
@h[key] = val + 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_keys
|
23
|
+
assert_equal @k, @h.keys
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_each
|
27
|
+
assert_equal 1, 2
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_each_key
|
31
|
+
raise NotImplementedError, 'Need to write test_each_key'
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_each_value
|
35
|
+
raise NotImplementedError, 'Need to write test_each_value'
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_index_equals
|
39
|
+
raise NotImplementedError, 'Need to write test_index_equals'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Number of errors detected: 1
|
data/test/r2ctestcase.rb
ADDED
@@ -0,0 +1,1076 @@
|
|
1
|
+
require 'test/unit/testcase'
|
2
|
+
|
3
|
+
require 'sexp_processor'
|
4
|
+
require 'typed_sexp_processor'
|
5
|
+
require 'support'
|
6
|
+
|
7
|
+
class R2CTestCase < Test::Unit::TestCase
|
8
|
+
|
9
|
+
attr_accessor :processor # to be defined by subclass
|
10
|
+
|
11
|
+
def setup
|
12
|
+
super
|
13
|
+
@processor = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
@@testcase_order = [
|
17
|
+
"ParseTree",
|
18
|
+
"Rewriter",
|
19
|
+
"TypeChecker",
|
20
|
+
"R2CRewriter",
|
21
|
+
"Ruby2RubyC",
|
22
|
+
]
|
23
|
+
|
24
|
+
@@testcases = {
|
25
|
+
|
26
|
+
"accessor" => {
|
27
|
+
"ParseTree" => [:defn, :accessor, [:ivar, :@accessor]],
|
28
|
+
"Rewriter" => s(:defn, :accessor, s(:args),
|
29
|
+
s(:scope,
|
30
|
+
s(:block, s(:return, s(:ivar, :@accessor))))),
|
31
|
+
"TypeChecker" => :skip,
|
32
|
+
"R2CRewriter" => :skip,
|
33
|
+
"Ruby2RubyC" => :skip,
|
34
|
+
},
|
35
|
+
|
36
|
+
"accessor_equals" => {
|
37
|
+
"ParseTree" => [:defn, :accessor=, [:attrset, :@accessor]],
|
38
|
+
"Rewriter" => s(:defn,
|
39
|
+
:accessor=,
|
40
|
+
s(:args, :arg),
|
41
|
+
s(:scope,
|
42
|
+
s(:block,
|
43
|
+
s(:return,
|
44
|
+
s(:iasgn, :@accessor, s(:lvar, :arg)))))),
|
45
|
+
"TypeChecker" => :skip,
|
46
|
+
"R2CRewriter" => :skip,
|
47
|
+
"Ruby2RubyC" => :skip,
|
48
|
+
},
|
49
|
+
|
50
|
+
"defn_bbegin" => {
|
51
|
+
"ParseTree" => [:defn, :bbegin,
|
52
|
+
[:scope,
|
53
|
+
[:block,
|
54
|
+
[:args],
|
55
|
+
[:begin,
|
56
|
+
[:ensure,
|
57
|
+
[:rescue,
|
58
|
+
[:call, [:lit, 1], :+, [:array, [:lit, 1]]],
|
59
|
+
[:resbody,
|
60
|
+
[:array, [:const, :SyntaxError]],
|
61
|
+
[:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]],
|
62
|
+
[:resbody,
|
63
|
+
[:array, [:const, :Exception]],
|
64
|
+
[:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]],
|
65
|
+
[:lit, 4]],
|
66
|
+
[:lit, 5]]]]]],
|
67
|
+
"Rewriter" => s(:defn, :bbegin,
|
68
|
+
s(:args),
|
69
|
+
s(:scope,
|
70
|
+
s(:block,
|
71
|
+
s(:begin,
|
72
|
+
s(:ensure,
|
73
|
+
s(:rescue,
|
74
|
+
s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1))),
|
75
|
+
s(:resbody,
|
76
|
+
s(:array, s(:const, :SyntaxError)),
|
77
|
+
s(:block, s(:lasgn, :e1, s(:gvar, :$!)),
|
78
|
+
s(:lit, 2)),
|
79
|
+
s(:resbody,
|
80
|
+
s(:array, s(:const, :Exception)),
|
81
|
+
s(:block, s(:lasgn, :e2, s(:gvar, :$!)),
|
82
|
+
s(:lit, 3)))),
|
83
|
+
s(:lit, 4)),
|
84
|
+
s(:lit, 5)))))),
|
85
|
+
"TypeChecker" => t(:defn, :bbegin,
|
86
|
+
t(:args),
|
87
|
+
t(:scope,
|
88
|
+
t(:block,
|
89
|
+
t(:begin,
|
90
|
+
t(:ensure,
|
91
|
+
t(:rescue,
|
92
|
+
t(:call,
|
93
|
+
t(:lit, 1, Type.long),
|
94
|
+
:+,
|
95
|
+
t(:arglist, t(:lit, 1, Type.long)), Type.long),
|
96
|
+
t(:resbody,
|
97
|
+
t(:array, t(:const, :SyntaxError, Type.fucked)),
|
98
|
+
t(:block,
|
99
|
+
t(:lasgn, :e1, t(:gvar, :$!, Type.unknown),
|
100
|
+
Type.unknown),
|
101
|
+
t(:lit, 2, Type.long), Type.unknown),
|
102
|
+
t(:resbody,
|
103
|
+
t(:array, t(:const, :Exception, Type.fucked)),
|
104
|
+
t(:block,
|
105
|
+
t(:lasgn, :e2, t(:gvar, :$!, Type.unknown),
|
106
|
+
Type.unknown),
|
107
|
+
t(:lit, 3, Type.long), Type.unknown),
|
108
|
+
Type.unknown), Type.long),
|
109
|
+
t(:lit, 4, Type.long), Type.long),
|
110
|
+
t(:lit, 5, Type.long))), Type.unknown),
|
111
|
+
Type.void),
|
112
|
+
Type.function(Type.unknown, [], Type.void)),
|
113
|
+
"R2CRewriter" => :same,
|
114
|
+
"Ruby2RubyC" => :unsupported,
|
115
|
+
},
|
116
|
+
|
117
|
+
"defn_bmethod_added" => {
|
118
|
+
"ParseTree" => [:defn, :bmethod_added,
|
119
|
+
[:bmethod,
|
120
|
+
[:dasgn_curr, :x],
|
121
|
+
[:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
|
122
|
+
"Rewriter" => s(:defn,
|
123
|
+
:bmethod_added,
|
124
|
+
s(:args, :x),
|
125
|
+
s(:scope,
|
126
|
+
s(:block,
|
127
|
+
s(:call, s(:lvar, :x), :+, s(:arglist, s(:lit, 1)))))),
|
128
|
+
"TypeChecker" => :skip,
|
129
|
+
"R2CRewriter" => :skip,
|
130
|
+
"Ruby2RubyC" => :skip,
|
131
|
+
},
|
132
|
+
|
133
|
+
"bools" => {
|
134
|
+
"ParseTree" => [:defn, :bools,
|
135
|
+
[:scope,
|
136
|
+
[:block,
|
137
|
+
[:args, :arg1],
|
138
|
+
[:if,
|
139
|
+
[:call, [:lvar, :arg1], "nil?".intern], # emacs is freakin'
|
140
|
+
[:return, [:false]],
|
141
|
+
[:return, [:true]]]]]],
|
142
|
+
"Rewriter" => s(:defn, :bools,
|
143
|
+
s(:args, :arg1),
|
144
|
+
s(:scope,
|
145
|
+
s(:block,
|
146
|
+
s(:if,
|
147
|
+
s(:call,
|
148
|
+
s(:lvar, :arg1),
|
149
|
+
:nil?,
|
150
|
+
nil),
|
151
|
+
s(:return, s(:false)),
|
152
|
+
s(:return, s(:true)))))),
|
153
|
+
# TODO: why does return false have type void?
|
154
|
+
"TypeChecker" => t(:defn, :bools,
|
155
|
+
t(:args, t(:arg1, Type.value)),
|
156
|
+
t(:scope,
|
157
|
+
t(:block,
|
158
|
+
t(:if,
|
159
|
+
t(:call,
|
160
|
+
t(:lvar, :arg1, Type.value),
|
161
|
+
:nil?,
|
162
|
+
nil,
|
163
|
+
Type.bool),
|
164
|
+
t(:return,
|
165
|
+
t(:false, Type.bool),
|
166
|
+
Type.void),
|
167
|
+
t(:return,
|
168
|
+
t(:true, Type.bool),
|
169
|
+
Type.void),
|
170
|
+
Type.void),
|
171
|
+
Type.unknown),
|
172
|
+
Type.void),
|
173
|
+
Type.function(Type.unknown, [Type.value], Type.bool)),
|
174
|
+
"R2CRewriter" => :same,
|
175
|
+
"Ruby2RubyC" => "static VALUE\nrrc_c_bools(VALUE self, VALUE arg1) {\nif (RTEST(NIL_P(arg1))) {\nreturn Qfalse;\n} else {\nreturn Qtrue;\n}\n}",
|
176
|
+
},
|
177
|
+
|
178
|
+
# TODO: move all call tests here
|
179
|
+
"call_arglist" => {
|
180
|
+
"ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]],
|
181
|
+
"Rewriter" => s(:call, nil, :puts, s(:arglist, s(:lit, 42))),
|
182
|
+
"TypeChecker" => :skip,
|
183
|
+
"R2CRewriter" => :skip,
|
184
|
+
"Ruby2RubyC" => :skip,
|
185
|
+
},
|
186
|
+
|
187
|
+
"call_attrasgn" => {
|
188
|
+
"ParseTree" => [:attrasgn, [:lit, 42], :method=, [:array, [:lvar, :y]]],
|
189
|
+
"Rewriter" => s(:call, s(:lit, 42), :method=, s(:arglist, s(:lvar, :y))),
|
190
|
+
"TypeChecker" => :skip,
|
191
|
+
"R2CRewriter" => :skip,
|
192
|
+
"Ruby2RubyC" => :skip,
|
193
|
+
},
|
194
|
+
|
195
|
+
"call_self" => {
|
196
|
+
"ParseTree" => [:call, [:self], :method],
|
197
|
+
"Rewriter" => s(:call, s(:lvar, :self), :method, nil),
|
198
|
+
"TypeChecker" => :skip,
|
199
|
+
"R2CRewriter" => :skip,
|
200
|
+
"Ruby2RubyC" => :skip,
|
201
|
+
},
|
202
|
+
|
203
|
+
"case_stmt" => {
|
204
|
+
"ParseTree" => [:defn, :case_stmt,
|
205
|
+
[:scope,
|
206
|
+
[:block,
|
207
|
+
[:args],
|
208
|
+
[:lasgn, :var, [:lit, 2]],
|
209
|
+
[:lasgn, :result, [:str, ""]],
|
210
|
+
[:case,
|
211
|
+
[:lvar, :var],
|
212
|
+
[:when,
|
213
|
+
[:array, [:lit, 1]],
|
214
|
+
[:block,
|
215
|
+
[:fcall, :puts, [:array, [:str, "something"]]],
|
216
|
+
[:lasgn, :result, [:str, "red"]]]],
|
217
|
+
[:when,
|
218
|
+
[:array, [:lit, 2], [:lit, 3]],
|
219
|
+
[:lasgn, :result, [:str, "yellow"]]],
|
220
|
+
[:when, [:array, [:lit, 4]], nil],
|
221
|
+
[:lasgn, :result, [:str, "green"]]],
|
222
|
+
[:case,
|
223
|
+
[:lvar, :result],
|
224
|
+
[:when, [:array, [:str, "red"]], [:lasgn, :var, [:lit, 1]]],
|
225
|
+
[:when, [:array, [:str, "yellow"]], [:lasgn, :var, [:lit, 2]]],
|
226
|
+
[:when, [:array, [:str, "green"]], [:lasgn, :var, [:lit, 3]]],
|
227
|
+
nil],
|
228
|
+
[:return, [:lvar, :result]]]]],
|
229
|
+
"Rewriter" => s(:defn, :case_stmt,
|
230
|
+
s(:args),
|
231
|
+
s(:scope,
|
232
|
+
s(:block,
|
233
|
+
s(:lasgn, :var, s(:lit, 2)),
|
234
|
+
s(:lasgn, :result, s(:str, "")),
|
235
|
+
s(:if,
|
236
|
+
s(:call,
|
237
|
+
s(:lvar, :var),
|
238
|
+
:===,
|
239
|
+
s(:arglist, s(:lit, 1))),
|
240
|
+
s(:block,
|
241
|
+
s(:call,
|
242
|
+
nil,
|
243
|
+
:puts,
|
244
|
+
s(:arglist, s(:str, "something"))),
|
245
|
+
s(:lasgn, :result, s(:str, "red"))),
|
246
|
+
s(:if,
|
247
|
+
s(:or,
|
248
|
+
s(:call,
|
249
|
+
s(:lvar, :var),
|
250
|
+
:===,
|
251
|
+
s(:arglist, s(:lit, 2))),
|
252
|
+
s(:call,
|
253
|
+
s(:lvar, :var),
|
254
|
+
:===,
|
255
|
+
s(:arglist, s(:lit, 3)))),
|
256
|
+
s(:lasgn, :result, s(:str, "yellow")),
|
257
|
+
s(:if,
|
258
|
+
s(:call,
|
259
|
+
s(:lvar, :var),
|
260
|
+
:===,
|
261
|
+
s(:arglist, s(:lit, 4))),
|
262
|
+
nil,
|
263
|
+
s(:lasgn, :result, s(:str, "green"))))),
|
264
|
+
s(:if,
|
265
|
+
s(:call,
|
266
|
+
s(:lvar, :result),
|
267
|
+
:===,
|
268
|
+
s(:arglist, s(:str, "red"))),
|
269
|
+
s(:lasgn, :var, s(:lit, 1)),
|
270
|
+
s(:if,
|
271
|
+
s(:call,
|
272
|
+
s(:lvar, :result),
|
273
|
+
:===,
|
274
|
+
s(:arglist, s(:str, "yellow"))),
|
275
|
+
s(:lasgn, :var, s(:lit, 2)),
|
276
|
+
s(:if,
|
277
|
+
s(:call,
|
278
|
+
s(:lvar, :result),
|
279
|
+
:===,
|
280
|
+
s(:arglist, s(:str, "green"))),
|
281
|
+
s(:lasgn, :var, s(:lit, 3)),
|
282
|
+
nil))),
|
283
|
+
s(:return, s(:lvar, :result))))),
|
284
|
+
"TypeChecker" => t(:defn, :case_stmt,
|
285
|
+
t(:args),
|
286
|
+
t(:scope,
|
287
|
+
t(:block,
|
288
|
+
t(:lasgn,
|
289
|
+
:var,
|
290
|
+
t(:lit, 2, Type.long),
|
291
|
+
Type.long),
|
292
|
+
t(:lasgn,
|
293
|
+
:result,
|
294
|
+
t(:str, "", Type.str),
|
295
|
+
Type.str),
|
296
|
+
t(:if,
|
297
|
+
t(:call,
|
298
|
+
t(:lvar, :var, Type.long),
|
299
|
+
:case_equal_long,
|
300
|
+
t(:arglist, t(:lit, 1, Type.long)),
|
301
|
+
Type.bool),
|
302
|
+
t(:block,
|
303
|
+
t(:call,
|
304
|
+
nil,
|
305
|
+
:puts,
|
306
|
+
t(:arglist,
|
307
|
+
t(:str, "something", Type.str)),
|
308
|
+
Type.void),
|
309
|
+
t(:lasgn,
|
310
|
+
:result,
|
311
|
+
t(:str, "red", Type.str),
|
312
|
+
Type.str),
|
313
|
+
Type.str),
|
314
|
+
t(:if,
|
315
|
+
t(:or,
|
316
|
+
t(:call,
|
317
|
+
t(:lvar, :var, Type.long),
|
318
|
+
:case_equal_long,
|
319
|
+
t(:arglist, t(:lit, 2, Type.long)),
|
320
|
+
Type.bool),
|
321
|
+
t(:call,
|
322
|
+
t(:lvar, :var, Type.long),
|
323
|
+
:case_equal_long,
|
324
|
+
t(:arglist, t(:lit, 3, Type.long)),
|
325
|
+
Type.bool),
|
326
|
+
Type.bool),
|
327
|
+
t(:lasgn,
|
328
|
+
:result,
|
329
|
+
t(:str, "yellow", Type.str),
|
330
|
+
Type.str),
|
331
|
+
t(:if,
|
332
|
+
t(:call,
|
333
|
+
t(:lvar, :var, Type.long),
|
334
|
+
:case_equal_long,
|
335
|
+
t(:arglist, t(:lit, 4, Type.long)),
|
336
|
+
Type.bool),
|
337
|
+
nil,
|
338
|
+
t(:lasgn,
|
339
|
+
:result,
|
340
|
+
t(:str, "green", Type.str),
|
341
|
+
Type.str),
|
342
|
+
Type.str),
|
343
|
+
Type.str),
|
344
|
+
Type.str),
|
345
|
+
t(:if,
|
346
|
+
t(:call,
|
347
|
+
t(:lvar, :result, Type.str),
|
348
|
+
:case_equal_str,
|
349
|
+
t(:arglist, t(:str, "red", Type.str)),
|
350
|
+
Type.bool),
|
351
|
+
t(:lasgn, :var, t(:lit, 1, Type.long), Type.long),
|
352
|
+
t(:if,
|
353
|
+
t(:call,
|
354
|
+
t(:lvar, :result, Type.str),
|
355
|
+
:case_equal_str,
|
356
|
+
t(:arglist, t(:str, "yellow", Type.str)),
|
357
|
+
Type.bool),
|
358
|
+
t(:lasgn, :var, t(:lit, 2, Type.long), Type.long),
|
359
|
+
t(:if,
|
360
|
+
t(:call,
|
361
|
+
t(:lvar, :result, Type.str),
|
362
|
+
:case_equal_str,
|
363
|
+
t(:arglist,
|
364
|
+
t(:str, "green", Type.str)),
|
365
|
+
Type.bool),
|
366
|
+
t(:lasgn,
|
367
|
+
:var,
|
368
|
+
t(:lit, 3, Type.long),
|
369
|
+
Type.long),
|
370
|
+
nil,
|
371
|
+
Type.long),
|
372
|
+
Type.long),
|
373
|
+
Type.long),
|
374
|
+
t(:return,
|
375
|
+
t(:lvar, :result, Type.str),
|
376
|
+
Type.void),
|
377
|
+
Type.unknown),
|
378
|
+
Type.void),
|
379
|
+
Type.function(Type.unknown, [], Type.str)),
|
380
|
+
"R2CRewriter" => :same,
|
381
|
+
# HACK: I don't like the semis after the if blocks, but it is a compromise right now
|
382
|
+
"Ruby2RubyC" => "static VALUE
|
383
|
+
rrc_c_case_stmt(VALUE self) {
|
384
|
+
VALUE result;
|
385
|
+
VALUE var;
|
386
|
+
var = LONG2FIX(2);
|
387
|
+
result = rb_str_new2(\"\");
|
388
|
+
if (RTEST(rb_funcall(var, rb_intern(\"case_equal_long\"), 1, LONG2FIX(1)))) {
|
389
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"something\"));
|
390
|
+
result = rb_str_new2(\"red\");
|
391
|
+
} else {
|
392
|
+
if (RTEST(RTEST(rb_funcall(var, rb_intern(\"case_equal_long\"), 1, LONG2FIX(2))) || RTEST(rb_funcall(var, rb_intern(\"case_equal_long\"), 1, LONG2FIX(3))))) {
|
393
|
+
result = rb_str_new2(\"yellow\");
|
394
|
+
} else {
|
395
|
+
if (RTEST(rb_funcall(var, rb_intern(\"case_equal_long\"), 1, LONG2FIX(4)))) {
|
396
|
+
;
|
397
|
+
} else {
|
398
|
+
result = rb_str_new2(\"green\");
|
399
|
+
}
|
400
|
+
}
|
401
|
+
};
|
402
|
+
if (RTEST(rb_funcall(result, rb_intern(\"case_equal_str\"), 1, rb_str_new2(\"red\")))) {
|
403
|
+
var = LONG2FIX(1);
|
404
|
+
} else {
|
405
|
+
if (RTEST(rb_funcall(result, rb_intern(\"case_equal_str\"), 1, rb_str_new2(\"yellow\")))) {
|
406
|
+
var = LONG2FIX(2);
|
407
|
+
} else {
|
408
|
+
if (RTEST(rb_funcall(result, rb_intern(\"case_equal_str\"), 1, rb_str_new2(\"green\")))) {
|
409
|
+
var = LONG2FIX(3);
|
410
|
+
}
|
411
|
+
}
|
412
|
+
};
|
413
|
+
return result;
|
414
|
+
}",
|
415
|
+
},
|
416
|
+
|
417
|
+
"conditional1" => {
|
418
|
+
"ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]], [:return, [:lit, 1]], nil],
|
419
|
+
"Rewriter" => s(:if, s(:call, s(:lit, 42), :==, s(:arglist, s(:lit, 0))), s(:return, s(:lit, 1)), nil),
|
420
|
+
"TypeChecker" => t(:if,
|
421
|
+
t(:call, t(:lit, 42, Type.long), :==,
|
422
|
+
t(:arglist, t(:lit, 0, Type.long)),
|
423
|
+
Type.bool),
|
424
|
+
t(:return, t(:lit, 1, Type.long), Type.void),
|
425
|
+
nil,
|
426
|
+
Type.void),
|
427
|
+
"R2CRewriter" => t(:if,
|
428
|
+
t(:call, t(:lit, 42, Type.long), :==,
|
429
|
+
t(:arglist, t(:lit, 0, Type.long)),
|
430
|
+
Type.bool),
|
431
|
+
t(:return, t(:lit, 1, Type.long), Type.void),
|
432
|
+
nil,
|
433
|
+
Type.void),
|
434
|
+
"Ruby2RubyC" => "if (RTEST(rb_funcall(LONG2FIX(42), rb_intern(\"==\"), 1, LONG2FIX(0)))) {\nreturn LONG2FIX(1);\n}",
|
435
|
+
},
|
436
|
+
|
437
|
+
"conditional2" => {
|
438
|
+
"ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]], nil, [:return, [:lit, 2]]],
|
439
|
+
"Rewriter" => s(:if,
|
440
|
+
s(:call, s(:lit, 42),
|
441
|
+
:==, s(:arglist, s(:lit, 0))),
|
442
|
+
nil,
|
443
|
+
s(:return, s(:lit, 2))),
|
444
|
+
"TypeChecker" => t(:if,
|
445
|
+
t(:call,
|
446
|
+
t(:lit, 42, Type.long),
|
447
|
+
:==,
|
448
|
+
t(:arglist,
|
449
|
+
t(:lit, 0, Type.long)),
|
450
|
+
Type.bool),
|
451
|
+
nil,
|
452
|
+
t(:return, t(:lit, 2, Type.long), Type.void),
|
453
|
+
Type.void),
|
454
|
+
"R2CRewriter" => :same,
|
455
|
+
"Ruby2RubyC" => "if (RTEST(rb_funcall(LONG2FIX(42), rb_intern(\"==\"), 1, LONG2FIX(0)))) {\n;\n} else {\nreturn LONG2FIX(2);\n}",
|
456
|
+
},
|
457
|
+
|
458
|
+
"conditional3" => {
|
459
|
+
"ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
|
460
|
+
[:return, [:lit, 3]],
|
461
|
+
[:return, [:lit, 4]]],
|
462
|
+
"Rewriter" => s(:if,
|
463
|
+
s(:call,
|
464
|
+
s(:lit, 42),
|
465
|
+
:==,
|
466
|
+
s(:arglist, s(:lit, 0))),
|
467
|
+
s(:return, s(:lit, 3)),
|
468
|
+
s(:return, s(:lit, 4))),
|
469
|
+
"TypeChecker" => t(:if,
|
470
|
+
t(:call,
|
471
|
+
t(:lit, 42, Type.long),
|
472
|
+
:==,
|
473
|
+
t(:arglist,
|
474
|
+
t(:lit, 0, Type.long)),
|
475
|
+
Type.bool),
|
476
|
+
t(:return,
|
477
|
+
t(:lit, 3, Type.long),
|
478
|
+
|
479
|
+
Type.void),
|
480
|
+
t(:return,
|
481
|
+
t(:lit, 4, Type.long),
|
482
|
+
Type.void),
|
483
|
+
Type.void),
|
484
|
+
"R2CRewriter" => :same,
|
485
|
+
"Ruby2RubyC" => "if (RTEST(rb_funcall(LONG2FIX(42), rb_intern(\"==\"), 1, LONG2FIX(0)))) {\nreturn LONG2FIX(3);\n} else {\nreturn LONG2FIX(4);\n}",
|
486
|
+
},
|
487
|
+
|
488
|
+
"conditional4" => {
|
489
|
+
"ParseTree" => [:if,
|
490
|
+
[:call, [:lit, 42], :==, [:array, [:lit, 0]]],
|
491
|
+
[:return, [:lit, 2]],
|
492
|
+
[:if,
|
493
|
+
[:call, [:lit, 42], :<, [:array, [:lit, 0]]],
|
494
|
+
[:return, [:lit, 3]],
|
495
|
+
[:return, [:lit, 4]]]],
|
496
|
+
"Rewriter" => s(:if,
|
497
|
+
s(:call,
|
498
|
+
s(:lit, 42),
|
499
|
+
:==,
|
500
|
+
s(:arglist, s(:lit, 0))),
|
501
|
+
s(:return, s(:lit, 2)),
|
502
|
+
s(:if,
|
503
|
+
s(:call,
|
504
|
+
s(:lit, 42),
|
505
|
+
:<,
|
506
|
+
s(:arglist, s(:lit, 0))),
|
507
|
+
s(:return, s(:lit, 3)),
|
508
|
+
s(:return, s(:lit, 4)))),
|
509
|
+
"TypeChecker" => t(:if,
|
510
|
+
t(:call,
|
511
|
+
t(:lit, 42, Type.long),
|
512
|
+
:==,
|
513
|
+
t(:arglist,
|
514
|
+
t(:lit, 0, Type.long)),
|
515
|
+
Type.bool),
|
516
|
+
t(:return,
|
517
|
+
t(:lit, 2, Type.long),
|
518
|
+
Type.void),
|
519
|
+
t(:if,
|
520
|
+
t(:call,
|
521
|
+
t(:lit, 42, Type.long),
|
522
|
+
:<,
|
523
|
+
t(:arglist,
|
524
|
+
t(:lit, 0, Type.long)),
|
525
|
+
Type.bool),
|
526
|
+
t(:return,
|
527
|
+
t(:lit, 3, Type.long),
|
528
|
+
Type.void),
|
529
|
+
t(:return,
|
530
|
+
t(:lit, 4, Type.long),
|
531
|
+
Type.void),
|
532
|
+
Type.void),
|
533
|
+
Type.void),
|
534
|
+
"R2CRewriter" => :same,
|
535
|
+
"Ruby2RubyC" => "if (RTEST(rb_funcall(LONG2FIX(42), rb_intern(\"==\"), 1, LONG2FIX(0)))) {\nreturn LONG2FIX(2);\n} else {\nif (RTEST(rb_funcall(LONG2FIX(42), rb_intern(\"<\"), 1, LONG2FIX(0)))) {\nreturn LONG2FIX(3);\n} else {\nreturn LONG2FIX(4);\n}\n}",
|
536
|
+
},
|
537
|
+
|
538
|
+
"defn_empty" => {
|
539
|
+
"ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]],
|
540
|
+
"Rewriter" => s(:defn, :empty,
|
541
|
+
s(:args), s(:scope, s(:block, s(:nil)))),
|
542
|
+
"TypeChecker" => t(:defn, :empty,
|
543
|
+
t(:args),
|
544
|
+
t(:scope,
|
545
|
+
t(:block,
|
546
|
+
t(:nil, Type.value),
|
547
|
+
Type.unknown),
|
548
|
+
Type.void),
|
549
|
+
Type.function(Type.unknown, [], Type.void)),
|
550
|
+
"R2CRewriter" => :same,
|
551
|
+
"Ruby2RubyC" => "static VALUE\nrrc_c_empty(VALUE self) {\nQnil;\n}",
|
552
|
+
},
|
553
|
+
|
554
|
+
"defn_fbody" => {
|
555
|
+
"ParseTree" => [:defn, :aliased,
|
556
|
+
[:fbody,
|
557
|
+
[:scope,
|
558
|
+
[:block,
|
559
|
+
[:args],
|
560
|
+
[:fcall, :puts, [:array, [:lit, 42]]]]]]],
|
561
|
+
"Rewriter" => s(:defn, :aliased,
|
562
|
+
s(:args),
|
563
|
+
s(:scope,
|
564
|
+
s(:block,
|
565
|
+
s(:call, nil, :puts, s(:arglist, s(:lit, 42)))))),
|
566
|
+
"TypeChecker" => :skip,
|
567
|
+
"R2CRewriter" => :skip,
|
568
|
+
"Ruby2RubyC" => :skip,
|
569
|
+
},
|
570
|
+
|
571
|
+
"dmethod_added" => {
|
572
|
+
"ParseTree" => [:defn,
|
573
|
+
:dmethod_added,
|
574
|
+
[:dmethod,
|
575
|
+
:bmethod_maker,
|
576
|
+
[:scope,
|
577
|
+
[:block,
|
578
|
+
[:args],
|
579
|
+
[:iter,
|
580
|
+
[:fcall, :define_method, [:array, [:lit, :bmethod_added]]],
|
581
|
+
[:dasgn_curr, :x],
|
582
|
+
[:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]]]],
|
583
|
+
"Rewriter" => s(:defn,
|
584
|
+
:dmethod_added,
|
585
|
+
s(:args, :x),
|
586
|
+
s(:scope,
|
587
|
+
s(:block,
|
588
|
+
s(:call, s(:lvar, :x), :+,
|
589
|
+
s(:arglist, s(:lit, 1)))))),
|
590
|
+
"TypeChecker" => :skip,
|
591
|
+
"R2CRewriter" => :skip,
|
592
|
+
"Ruby2RubyC" => :skip,
|
593
|
+
},
|
594
|
+
|
595
|
+
"global" => {
|
596
|
+
"ParseTree" => [:gvar, :$stderr],
|
597
|
+
"Rewriter" => s(:gvar, :$stderr),
|
598
|
+
# TODO: test s(:gvar, :$stderr) != t(:gvar, $stderr, Type.file)
|
599
|
+
"TypeChecker" => t(:gvar, :$stderr, Type.file),
|
600
|
+
"R2CRewriter" => :same,
|
601
|
+
"Ruby2RubyC" => "stderr",
|
602
|
+
},
|
603
|
+
|
604
|
+
"interpolated" => {
|
605
|
+
"ParseTree" => [:dstr,
|
606
|
+
"var is ", [:lvar, :argl], [:str, ". So there."]],
|
607
|
+
"Rewriter" => s(:dstr,
|
608
|
+
"var is ", s(:lvar, :argl), s(:str, ". So there.")),
|
609
|
+
"TypeChecker" => t(:dstr,
|
610
|
+
"var is ",
|
611
|
+
t(:lvar, :argl, Type.long),
|
612
|
+
t(:str, ". So there.", Type.str),
|
613
|
+
Type.str),
|
614
|
+
"R2CRewriter" => :same,
|
615
|
+
"Ruby2RubyC" => :unsupported,
|
616
|
+
},
|
617
|
+
|
618
|
+
"iteration1" => {
|
619
|
+
"ParseTree" => [:iter,
|
620
|
+
[:call, [:lvar, :arrayl], :each],
|
621
|
+
[:dasgn_curr, :x],
|
622
|
+
[:fcall, :puts, [:arrayl, [:call, [:dvar, :x], :to_s]]]],
|
623
|
+
"Rewriter" => s(:iter,
|
624
|
+
s(:call,
|
625
|
+
s(:lvar, :arrayl),
|
626
|
+
:each,
|
627
|
+
nil),
|
628
|
+
s(:dasgn_curr, :x),
|
629
|
+
s(:call,
|
630
|
+
nil,
|
631
|
+
:puts,
|
632
|
+
s(:arglist,
|
633
|
+
s(:call,
|
634
|
+
s(:dvar, :x),
|
635
|
+
:to_s,
|
636
|
+
nil)))),
|
637
|
+
"TypeChecker" => t(:iter,
|
638
|
+
t(:call,
|
639
|
+
t(:lvar, :arrayl, Type.long_list),
|
640
|
+
:each,
|
641
|
+
nil, Type.unknown),
|
642
|
+
t(:dasgn_curr, :x, Type.long),
|
643
|
+
t(:call,
|
644
|
+
nil,
|
645
|
+
:puts,
|
646
|
+
t(:arglist,
|
647
|
+
t(:call,
|
648
|
+
t(:dvar, :x, Type.long),
|
649
|
+
:to_s,
|
650
|
+
nil,
|
651
|
+
Type.str)),
|
652
|
+
Type.void),
|
653
|
+
Type.void),
|
654
|
+
"R2CRewriter" => :same,
|
655
|
+
"Ruby2RubyC" => "unsigned long index_x;\nfor (index_x = 0; index_x < arrayl.length; ++index_x) {\nVALUE x = arrayl.contents[index_x];\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(x, rb_intern(\"to_s\"), 0));\n}",
|
656
|
+
},
|
657
|
+
|
658
|
+
"iteration2" => {
|
659
|
+
"ParseTree" => [:iter,
|
660
|
+
[:call, [:lvar, :arrays], :each],
|
661
|
+
[:dasgn_curr, :x],
|
662
|
+
[:fcall, :puts, [:arrays, [:dvar, :x]]]],
|
663
|
+
"Rewriter" => s(:iter,
|
664
|
+
s(:call, s(:lvar, :arrays), :each, nil),
|
665
|
+
s(:dasgn_curr, :x),
|
666
|
+
s(:call, nil, :puts, s(:arglist, s(:dvar, :x)))),
|
667
|
+
"TypeChecker" => t(:iter,
|
668
|
+
t(:call,
|
669
|
+
t(:lvar, :arrays, Type.str_list),
|
670
|
+
:each,
|
671
|
+
nil, Type.unknown),
|
672
|
+
t(:dasgn_curr, :x, Type.str),
|
673
|
+
t(:call, nil, :puts,
|
674
|
+
t(:arglist, t(:dvar, :x, Type.str)),
|
675
|
+
Type.void),
|
676
|
+
Type.void),
|
677
|
+
"R2CRewriter" => :same,
|
678
|
+
"Ruby2RubyC" => "unsigned long index_x;\nfor (index_x = 0; index_x < arrays.length; ++index_x) {\nVALUE x = arrays.contents[index_x];\nrb_funcall(self, rb_intern(\"puts\"), 1, x);\n}",
|
679
|
+
},
|
680
|
+
|
681
|
+
"iteration3" => {
|
682
|
+
"ParseTree" => [:iter,
|
683
|
+
[:call, [:lvar, :arrayl], :each],
|
684
|
+
[:dasgn_curr, :x],
|
685
|
+
[:iter,
|
686
|
+
[:call, [:lvar, :arrayl2], :each],
|
687
|
+
[:dasgn_curr, :y],
|
688
|
+
[:block,
|
689
|
+
[:fcall, :puts, [:array, [:call, [:dvar, :x], :to_s]]],
|
690
|
+
[:fcall, :puts, [:array, [:call, [:dvar, :y], :to_s]]]]]],
|
691
|
+
"Rewriter" => s(:iter, s(:call, s(:lvar, :arrayl), :each, nil),
|
692
|
+
s(:dasgn_curr, :x),
|
693
|
+
s(:iter,
|
694
|
+
s(:call, s(:lvar, :arrayl2), :each, nil),
|
695
|
+
s(:dasgn_curr, :y),
|
696
|
+
s(:block,
|
697
|
+
s(:call,
|
698
|
+
nil,
|
699
|
+
:puts,
|
700
|
+
s(:arglist, s(:call, s(:dvar, :x), :to_s, nil))),
|
701
|
+
s(:call,
|
702
|
+
nil,
|
703
|
+
:puts,
|
704
|
+
s(:arglist,
|
705
|
+
s(:call, s(:dvar, :y), :to_s, nil)))))),
|
706
|
+
"TypeChecker" => t(:iter,
|
707
|
+
t(:call,
|
708
|
+
t(:lvar, :arrayl, Type.long_list),
|
709
|
+
:each, nil, Type.unknown),
|
710
|
+
t(:dasgn_curr, :x, Type.long),
|
711
|
+
t(:iter,
|
712
|
+
t(:call,
|
713
|
+
t(:lvar, :arrayl2, Type.long_list),
|
714
|
+
:each, nil, Type.unknown),
|
715
|
+
t(:dasgn_curr, :y, Type.long),
|
716
|
+
t(:block,
|
717
|
+
t(:call, nil, :puts,
|
718
|
+
t(:arglist,
|
719
|
+
t(:call,
|
720
|
+
t(:dvar, :x, Type.long),
|
721
|
+
:to_s, nil, Type.str)),
|
722
|
+
Type.void),
|
723
|
+
t(:call,
|
724
|
+
nil,
|
725
|
+
:puts,
|
726
|
+
t(:arglist,
|
727
|
+
t(:call,
|
728
|
+
t(:dvar, :y, Type.long), :to_s,
|
729
|
+
nil, Type.str)),
|
730
|
+
Type.void),
|
731
|
+
Type.unknown),
|
732
|
+
Type.void),
|
733
|
+
Type.void),
|
734
|
+
"R2CRewriter" => :same,
|
735
|
+
"Ruby2RubyC" => "unsigned long index_x;\nfor (index_x = 0; index_x < arrayl.length; ++index_x) {\nVALUE x = arrayl.contents[index_x];\nunsigned long index_y;\nfor (index_y = 0; index_y < arrayl2.length; ++index_y) {\nVALUE y = arrayl2.contents[index_y];\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(x, rb_intern(\"to_s\"), 0));\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(y, rb_intern(\"to_s\"), 0));\n}\n}",
|
736
|
+
},
|
737
|
+
|
738
|
+
"iteration4" => {
|
739
|
+
"ParseTree" => [:iter,
|
740
|
+
[:call, [:lit, 1], :upto, [:array, [:lit, 3]]],
|
741
|
+
[:dasgn_curr, :n],
|
742
|
+
[:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
|
743
|
+
"Rewriter" => s(:dummy,
|
744
|
+
s(:lasgn, :n, s(:lit, 1)),
|
745
|
+
s(:while,
|
746
|
+
s(:call, s(:lvar, :n), :<=, s(:arglist, s(:lit, 3))),
|
747
|
+
s(:block,
|
748
|
+
s(:call,
|
749
|
+
nil,
|
750
|
+
:puts,
|
751
|
+
s(:arglist, s(:call, s(:lvar, :n), :to_s, nil))),
|
752
|
+
s(:lasgn, :n,
|
753
|
+
s(:call, s(:lvar, :n),
|
754
|
+
:+,
|
755
|
+
s(:arglist, s(:lit, 1))))), true)),
|
756
|
+
"TypeChecker" => t(:dummy, t(:lasgn, :n, t(:lit, 1, Type.long), Type.long),
|
757
|
+
t(:while,
|
758
|
+
t(:call,
|
759
|
+
t(:lvar, :n, Type.long),
|
760
|
+
:<=,
|
761
|
+
t(:arglist, t(:lit, 3, Type.long)), Type.bool),
|
762
|
+
t(:block,
|
763
|
+
t(:call, nil, :puts,
|
764
|
+
t(:arglist,
|
765
|
+
t(:call,
|
766
|
+
t(:lvar, :n, Type.long),
|
767
|
+
:to_s,
|
768
|
+
nil, Type.str)), Type.void),
|
769
|
+
t(:lasgn, :n,
|
770
|
+
t(:call,
|
771
|
+
t(:lvar, :n, Type.long),
|
772
|
+
:+,
|
773
|
+
t(:arglist,
|
774
|
+
t(:lit,
|
775
|
+
1, Type.long)),
|
776
|
+
Type.long), Type.long), Type.unknown), true)),
|
777
|
+
"R2CRewriter" => :same,
|
778
|
+
"Ruby2RubyC" => "n = LONG2FIX(1);
|
779
|
+
while (RTEST(rb_funcall(n, rb_intern(\"<=\"), 1, LONG2FIX(3)))) {
|
780
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(n, rb_intern(\"to_s\"), 0));
|
781
|
+
n = rb_funcall(n, rb_intern(\"+\"), 1, LONG2FIX(1));
|
782
|
+
}",
|
783
|
+
},
|
784
|
+
|
785
|
+
"iteration5" => {
|
786
|
+
"ParseTree" => [:iter,
|
787
|
+
[:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
|
788
|
+
[:dasgn_curr, :n],
|
789
|
+
[:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
|
790
|
+
"Rewriter" => s(:dummy, s(:lasgn, :n, s(:lit, 3)), s(:while,
|
791
|
+
s(:call, s(:lvar, :n), :>=, s(:arglist, s(:lit, 1))),
|
792
|
+
s(:block,
|
793
|
+
s(:call, nil, :puts,
|
794
|
+
s(:arglist, s(:call, s(:lvar, :n), :to_s, nil))),
|
795
|
+
s(:lasgn, :n, s(:call, s(:lvar, :n),
|
796
|
+
:-, s(:arglist, s(:lit, 1))))), true)),
|
797
|
+
"TypeChecker" => t(:dummy,
|
798
|
+
t(:lasgn, :n, t(:lit, 3, Type.long), Type.long),
|
799
|
+
t(:while,
|
800
|
+
t(:call,
|
801
|
+
t(:lvar, :n, Type.long),
|
802
|
+
:>=,
|
803
|
+
t(:arglist, t(:lit, 1, Type.long)), Type.bool),
|
804
|
+
t(:block,
|
805
|
+
t(:call, nil, :puts,
|
806
|
+
t(:arglist,
|
807
|
+
t(:call,
|
808
|
+
t(:lvar, :n, Type.long),
|
809
|
+
:to_s,
|
810
|
+
nil, Type.str)), Type.void),
|
811
|
+
t(:lasgn, :n,
|
812
|
+
t(:call,
|
813
|
+
t(:lvar, :n, Type.long),
|
814
|
+
:-,
|
815
|
+
t(:arglist, t(:lit, 1, Type.long)),
|
816
|
+
Type.long),
|
817
|
+
Type.long),
|
818
|
+
Type.unknown), true)),
|
819
|
+
"R2CRewriter" => :same,
|
820
|
+
"Ruby2RubyC" => "n = LONG2FIX(3);
|
821
|
+
while (RTEST(rb_funcall(n, rb_intern(\">=\"), 1, LONG2FIX(1)))) {
|
822
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(n, rb_intern(\"to_s\"), 0));
|
823
|
+
n = rb_funcall(n, rb_intern(\"-\"), 1, LONG2FIX(1));
|
824
|
+
}",
|
825
|
+
},
|
826
|
+
|
827
|
+
"iteration6" => {
|
828
|
+
"ParseTree" => [:while, [:call, [:lvar, :argl],
|
829
|
+
:>=, [:arglist, [:lit, 1]]], [:block,
|
830
|
+
[:call, nil, :puts, [:arglist, [:str, "hello"]]],
|
831
|
+
[:lasgn,
|
832
|
+
:argl,
|
833
|
+
[:call, [:lvar, :argl],
|
834
|
+
:-, [:arglist, [:lit, 1]]]]], true],
|
835
|
+
"Rewriter" => s(:while,
|
836
|
+
s(:call, s(:lvar, :argl),
|
837
|
+
:>=, s(:arglist, s(:lit, 1))),
|
838
|
+
s(:block,
|
839
|
+
s(:call, nil, :puts, s(:arglist, s(:str, "hello"))),
|
840
|
+
s(:lasgn,
|
841
|
+
:argl,
|
842
|
+
s(:call, s(:lvar, :argl),
|
843
|
+
:-, s(:arglist, s(:lit, 1))))), true),
|
844
|
+
"TypeChecker" => t(:while,
|
845
|
+
t(:call, t(:lvar, :argl, Type.long),
|
846
|
+
:>=,
|
847
|
+
t(:arglist, t(:lit, 1, Type.long)), Type.bool),
|
848
|
+
t(:block,
|
849
|
+
t(:call, nil, :puts,
|
850
|
+
t(:arglist, t(:str, "hello", Type.str)),
|
851
|
+
Type.void),
|
852
|
+
t(:lasgn,
|
853
|
+
:argl,
|
854
|
+
t(:call, t(:lvar, :argl, Type.long),
|
855
|
+
:-,
|
856
|
+
t(:arglist, t(:lit, 1, Type.long)), Type.long),
|
857
|
+
Type.long),
|
858
|
+
Type.unknown), true),
|
859
|
+
"R2CRewriter" => :same,
|
860
|
+
"Ruby2RubyC" => "while (RTEST(rb_funcall(argl, rb_intern(\">=\"), 1, LONG2FIX(1)))) {
|
861
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"hello\"));
|
862
|
+
argl = rb_funcall(argl, rb_intern(\"-\"), 1, LONG2FIX(1));
|
863
|
+
}",
|
864
|
+
},
|
865
|
+
|
866
|
+
# TODO: this might still be too much
|
867
|
+
"lasgn_call" => {
|
868
|
+
"ParseTree" => [:lasgn, :c, [:call, [:lit, 2], :+, [:arglist, [:lit, 3]]]],
|
869
|
+
"Rewriter" => s(:lasgn, :c, s(:call, s(:lit, 2), :+, s(:arglist, s(:lit, 3)))),
|
870
|
+
"TypeChecker" => t(:lasgn, :c,
|
871
|
+
t(:call,
|
872
|
+
t(:lit, 2, Type.long),
|
873
|
+
:+,
|
874
|
+
t(:arglist,
|
875
|
+
t(:lit, 3, Type.long)),
|
876
|
+
Type.long),
|
877
|
+
Type.long),
|
878
|
+
"R2CRewriter" => :same,
|
879
|
+
"Ruby2RubyC" => "c = rb_funcall(LONG2FIX(2), rb_intern(\"+\"), 1, LONG2FIX(3))",
|
880
|
+
},
|
881
|
+
|
882
|
+
"multi_args" => {
|
883
|
+
"ParseTree" => [:defn, :multi_args,
|
884
|
+
[:scope,
|
885
|
+
[:block,
|
886
|
+
[:args, :arg1, :arg2],
|
887
|
+
[:lasgn,
|
888
|
+
:arg3,
|
889
|
+
[:call,
|
890
|
+
[:call, [:lvar, :arg1], :*, [:array, [:lvar, :arg2]]],
|
891
|
+
:*,
|
892
|
+
[:array, [:lit, 7]]]],
|
893
|
+
[:fcall, :puts, [:array, [:call, [:lvar, :arg3], :to_s]]],
|
894
|
+
[:return, [:str, "foo"]]]]],
|
895
|
+
"Rewriter" => s(:defn, :multi_args,
|
896
|
+
s(:args, :arg1, :arg2),
|
897
|
+
s(:scope,
|
898
|
+
s(:block,
|
899
|
+
s(:lasgn, :arg3,
|
900
|
+
s(:call,
|
901
|
+
s(:call,
|
902
|
+
s(:lvar, :arg1),
|
903
|
+
:*,
|
904
|
+
s(:arglist, s(:lvar, :arg2))),
|
905
|
+
:*,
|
906
|
+
s(:arglist, s(:lit, 7)))),
|
907
|
+
s(:call,
|
908
|
+
nil,
|
909
|
+
:puts,
|
910
|
+
s(:arglist,
|
911
|
+
s(:call,
|
912
|
+
s(:lvar, :arg3),
|
913
|
+
:to_s,
|
914
|
+
nil))),
|
915
|
+
s(:return, s(:str, "foo"))))),
|
916
|
+
"TypeChecker" => t(:defn, :multi_args,
|
917
|
+
t(:args,
|
918
|
+
t(:arg1, Type.long),
|
919
|
+
t(:arg2, Type.long)),
|
920
|
+
t(:scope,
|
921
|
+
t(:block,
|
922
|
+
t(:lasgn,
|
923
|
+
:arg3,
|
924
|
+
t(:call,
|
925
|
+
t(:call,
|
926
|
+
t(:lvar, :arg1, Type.long),
|
927
|
+
:*,
|
928
|
+
t(:arglist,
|
929
|
+
t(:lvar,
|
930
|
+
:arg2,
|
931
|
+
Type.long)),
|
932
|
+
Type.long),
|
933
|
+
:*,
|
934
|
+
t(:arglist,
|
935
|
+
t(:lit, 7, Type.long)),
|
936
|
+
Type.long),
|
937
|
+
Type.long),
|
938
|
+
t(:call,
|
939
|
+
nil,
|
940
|
+
:puts,
|
941
|
+
t(:arglist,
|
942
|
+
t(:call,
|
943
|
+
t(:lvar, :arg3, Type.long),
|
944
|
+
:to_s,
|
945
|
+
nil,
|
946
|
+
Type.str)),
|
947
|
+
Type.void),
|
948
|
+
t(:return, t(:str, "foo", Type.str),
|
949
|
+
Type.void),
|
950
|
+
Type.unknown),
|
951
|
+
Type.void),
|
952
|
+
Type.function(Type.unknown,
|
953
|
+
[Type.long, Type.long], Type.str)),
|
954
|
+
"R2CRewriter" => :same,
|
955
|
+
"Ruby2RubyC" => "static VALUE\nrrc_c_multi_args(VALUE self, VALUE arg1, VALUE arg2) {\nVALUE arg3;\narg3 = rb_funcall(rb_funcall(arg1, rb_intern(\"*\"), 1, arg2), rb_intern(\"*\"), 1, LONG2FIX(7));\nrb_funcall(self, rb_intern(\"puts\"), 1, rb_funcall(arg3, rb_intern(\"to_s\"), 0));\nreturn rb_str_new2(\"foo\");\n}",
|
956
|
+
},
|
957
|
+
|
958
|
+
"vcall" => {
|
959
|
+
"ParseTree" => [:vcall, :method],
|
960
|
+
"Rewriter" => s(:call, nil, :method, nil),
|
961
|
+
"TypeChecker" => t(:call, nil, :method, nil, Type.unknown),
|
962
|
+
"R2CRewriter" => :same,
|
963
|
+
"Ruby2RubyC" => "rb_funcall(self, rb_intern(\"method\"), 0)",
|
964
|
+
},
|
965
|
+
|
966
|
+
"whiles" => {
|
967
|
+
"ParseTree" => [:defn,
|
968
|
+
:whiles,
|
969
|
+
[:scope,
|
970
|
+
[:block,
|
971
|
+
[:args],
|
972
|
+
[:while, [:false],
|
973
|
+
[:fcall, :puts, [:array, [:str, "false"]]], true],
|
974
|
+
[:while, [:false],
|
975
|
+
[:fcall, :puts, [:array, [:str, "true"]]], false]]]],
|
976
|
+
"Rewriter" => s(:defn,
|
977
|
+
:whiles,
|
978
|
+
s(:args),
|
979
|
+
s(:scope,
|
980
|
+
s(:block,
|
981
|
+
s(:while,
|
982
|
+
s(:false),
|
983
|
+
s(:call, nil, :puts, s(:arglist, s(:str, "false"))),
|
984
|
+
true),
|
985
|
+
s(:while,
|
986
|
+
s(:false),
|
987
|
+
s(:call, nil, :puts, s(:arglist, s(:str, "true"))),
|
988
|
+
false)))),
|
989
|
+
"TypeChecker" => t(:defn,
|
990
|
+
:whiles,
|
991
|
+
t(:args),
|
992
|
+
t(:scope,
|
993
|
+
t(:block,
|
994
|
+
t(:while,
|
995
|
+
t(:false, Type.bool),
|
996
|
+
t(:call,
|
997
|
+
nil,
|
998
|
+
:puts,
|
999
|
+
t(:arglist, t(:str, "false", Type.str)), Type.void),
|
1000
|
+
true),
|
1001
|
+
t(:while,
|
1002
|
+
t(:false, Type.bool),
|
1003
|
+
t(:call,
|
1004
|
+
nil,
|
1005
|
+
:puts,
|
1006
|
+
t(:arglist, t(:str, "true", Type.str)), Type.void),
|
1007
|
+
false),
|
1008
|
+
Type.unknown),
|
1009
|
+
Type.void),
|
1010
|
+
Type.function(Type.unknown, [], Type.void)),
|
1011
|
+
"R2CRewriter" => :same,
|
1012
|
+
"Ruby2RubyC" => "static VALUE
|
1013
|
+
rrc_c_whiles(VALUE self) {
|
1014
|
+
while (RTEST(Qfalse)) {
|
1015
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"false\"))
|
1016
|
+
};
|
1017
|
+
{
|
1018
|
+
rb_funcall(self, rb_intern(\"puts\"), 1, rb_str_new2(\"true\"))
|
1019
|
+
} while (RTEST(Qfalse));
|
1020
|
+
}",
|
1021
|
+
},
|
1022
|
+
|
1023
|
+
"zarray" => {
|
1024
|
+
"ParseTree" => [:lasgn, :a, [:zarray]],
|
1025
|
+
"Rewriter" => s(:lasgn, :a, s(:array)),
|
1026
|
+
"TypeChecker" => t(:lasgn, :a, t(:array), Type.unknown_list),
|
1027
|
+
"R2CRewriter" => :same,
|
1028
|
+
# TODO: we need to do something w/ said array because this is dumb:
|
1029
|
+
# TODO: ewww
|
1030
|
+
"Ruby2RubyC" => "a = rb_ary_new()",
|
1031
|
+
},
|
1032
|
+
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
@@testcases.each do |node, data|
|
1036
|
+
data.each do |key, val|
|
1037
|
+
if val == :same then
|
1038
|
+
prev_key = @@testcase_order[@@testcase_order.index(key)-1]
|
1039
|
+
data[key] = data[prev_key].deep_clone
|
1040
|
+
end
|
1041
|
+
end
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
def self.inherited(c)
|
1045
|
+
output_name = c.name.to_s.sub(/^Test/, '')
|
1046
|
+
raise "Unknown class #{c}" unless @@testcase_order.include? output_name
|
1047
|
+
input_name = @@testcase_order[@@testcase_order.index(output_name)-1]
|
1048
|
+
|
1049
|
+
@@testcases.each do |node, data|
|
1050
|
+
next if data[input_name] == :skip
|
1051
|
+
next if data[output_name] == :skip
|
1052
|
+
|
1053
|
+
c.send(:define_method, "test_#{node}".intern) do
|
1054
|
+
flunk "Processor is nil" if processor.nil?
|
1055
|
+
assert data.has_key?(input_name), "Unknown input data"
|
1056
|
+
assert data.has_key?(output_name), "Unknown expected data"
|
1057
|
+
input = data[input_name].deep_clone
|
1058
|
+
expected = data[output_name].deep_clone
|
1059
|
+
|
1060
|
+
case expected
|
1061
|
+
when :unsupported then
|
1062
|
+
assert_raises(UnsupportedNodeError) do
|
1063
|
+
processor.process(input)
|
1064
|
+
end
|
1065
|
+
else
|
1066
|
+
assert_equal expected, processor.process(input)
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
def test_stoopid
|
1073
|
+
# do nothing - shuts up empty test class requirement
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
end
|