rubyjs 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/README +128 -0
  2. data/Rakefile +9 -0
  3. data/bin/rubyjs +140 -0
  4. data/examples/ex1/Rakefile +7 -0
  5. data/examples/ex1/ex1.js +771 -0
  6. data/examples/ex1/ex1.rb +42 -0
  7. data/examples/ex1/index.html +7 -0
  8. data/examples/hw/Rakefile +9 -0
  9. data/examples/hw/hw.js +635 -0
  10. data/examples/hw/hw.rb +7 -0
  11. data/examples/hw/index.html +7 -0
  12. data/patches/parse_tree.rb.diff +34 -0
  13. data/rubyjs.gemspec +24 -0
  14. data/src/rubyjs.rb +4 -0
  15. data/src/rubyjs/code_generator.rb +474 -0
  16. data/src/rubyjs/compiler.rb +2007 -0
  17. data/src/rubyjs/debug_name_generator.rb +75 -0
  18. data/src/rubyjs/encoder.rb +171 -0
  19. data/src/rubyjs/eval_into.rb +59 -0
  20. data/src/rubyjs/lib/core.rb +1008 -0
  21. data/src/rubyjs/lib/json.rb +101 -0
  22. data/src/rubyjs/model.rb +287 -0
  23. data/src/rubyjs/name_generator.rb +71 -0
  24. data/src/rwt/AbsolutePanel.rb +161 -0
  25. data/src/rwt/DOM.Konqueror.rb +89 -0
  26. data/src/rwt/DOM.Opera.rb +65 -0
  27. data/src/rwt/DOM.rb +1044 -0
  28. data/src/rwt/Event.Opera.rb +35 -0
  29. data/src/rwt/Event.rb +429 -0
  30. data/src/rwt/HTTPRequest.IE6.rb +5 -0
  31. data/src/rwt/HTTPRequest.rb +74 -0
  32. data/src/rwt/Label.rb +164 -0
  33. data/src/rwt/Panel.rb +90 -0
  34. data/src/rwt/RootPanel.rb +16 -0
  35. data/src/rwt/UIObject.rb +495 -0
  36. data/src/rwt/Widget.rb +193 -0
  37. data/src/rwt/ported-from/AbsolutePanel.java +158 -0
  38. data/src/rwt/ported-from/DOM.java +571 -0
  39. data/src/rwt/ported-from/DOMImpl.java +426 -0
  40. data/src/rwt/ported-from/DOMImplOpera.java +82 -0
  41. data/src/rwt/ported-from/DOMImplStandard.java +234 -0
  42. data/src/rwt/ported-from/HTTPRequest.java +81 -0
  43. data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
  44. data/src/rwt/ported-from/Label.java +163 -0
  45. data/src/rwt/ported-from/Panel.java +99 -0
  46. data/src/rwt/ported-from/UIObject.java +614 -0
  47. data/src/rwt/ported-from/Widget.java +221 -0
  48. data/test/benchmark/bm_call_conv1.js +16 -0
  49. data/test/benchmark/bm_call_conv2.js +14 -0
  50. data/test/benchmark/bm_var_acc1.js +13 -0
  51. data/test/benchmark/bm_var_acc2.js +11 -0
  52. data/test/benchmark/bm_vm1_block.js +15 -0
  53. data/test/benchmark/bm_vm1_block.rb +15 -0
  54. data/test/benchmark/bm_vm1_const.js +13 -0
  55. data/test/benchmark/bm_vm1_const.rb +13 -0
  56. data/test/benchmark/bm_vm1_ensure.js +17 -0
  57. data/test/benchmark/bm_vm1_ensure.rb +15 -0
  58. data/test/benchmark/common.js +4 -0
  59. data/test/benchmark/common.rb +5 -0
  60. data/test/benchmark/params.yaml +7 -0
  61. data/test/browser.test.html +4059 -0
  62. data/test/browser.test.js +3225 -0
  63. data/test/common.Browser.rb +13 -0
  64. data/test/common.rb +8 -0
  65. data/test/gen_browser_test_suite.rb +129 -0
  66. data/test/gen_test_suite.rb +41 -0
  67. data/test/run_benchs.rb +58 -0
  68. data/test/run_tests.rb +22 -0
  69. data/test/test_args.rb +24 -0
  70. data/test/test_array.rb +26 -0
  71. data/test/test_case.rb +35 -0
  72. data/test/test_class.rb +55 -0
  73. data/test/test_eql.rb +9 -0
  74. data/test/test_exception.rb +61 -0
  75. data/test/test_expr.rb +12 -0
  76. data/test/test_hash.rb +29 -0
  77. data/test/test_if.rb +28 -0
  78. data/test/test_inspect.rb +10 -0
  79. data/test/test_lebewesen.rb +39 -0
  80. data/test/test_massign.rb +66 -0
  81. data/test/test_new.rb +12 -0
  82. data/test/test_range.rb +53 -0
  83. data/test/test_regexp.rb +22 -0
  84. data/test/test_send.rb +65 -0
  85. data/test/test_simple_output.rb +5 -0
  86. data/test/test_splat.rb +21 -0
  87. data/test/test_string.rb +51 -0
  88. data/test/test_yield.rb +152 -0
  89. data/utils/js/Makefile +9 -0
  90. data/utils/js/RunScript.class +0 -0
  91. data/utils/js/RunScript.java +73 -0
  92. data/utils/js/js.jar +0 -0
  93. data/utils/js/run.sh +3 -0
  94. data/utils/jsc/Makefile +7 -0
  95. data/utils/jsc/README +3 -0
  96. data/utils/jsc/RunScript.c +93 -0
  97. data/utils/jsc/run.sh +15 -0
  98. data/utils/yuicompressor/README +1 -0
  99. data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
  100. data/vendor/ParseTree-1.7.1-patched/History.txt +217 -0
  101. data/vendor/ParseTree-1.7.1-patched/Manifest.txt +22 -0
  102. data/vendor/ParseTree-1.7.1-patched/README.txt +110 -0
  103. data/vendor/ParseTree-1.7.1-patched/Rakefile +41 -0
  104. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_abc +89 -0
  105. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_audit +28 -0
  106. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_deps +62 -0
  107. data/vendor/ParseTree-1.7.1-patched/bin/parse_tree_show +49 -0
  108. data/vendor/ParseTree-1.7.1-patched/demo/printer.rb +20 -0
  109. data/vendor/ParseTree-1.7.1-patched/lib/composite_sexp_processor.rb +49 -0
  110. data/vendor/ParseTree-1.7.1-patched/lib/parse_tree.rb +1013 -0
  111. data/vendor/ParseTree-1.7.1-patched/lib/sexp.rb +235 -0
  112. data/vendor/ParseTree-1.7.1-patched/lib/sexp_processor.rb +330 -0
  113. data/vendor/ParseTree-1.7.1-patched/lib/unique.rb +15 -0
  114. data/vendor/ParseTree-1.7.1-patched/test/pt_testcase.rb +1221 -0
  115. data/vendor/ParseTree-1.7.1-patched/test/something.rb +53 -0
  116. data/vendor/ParseTree-1.7.1-patched/test/test_all.rb +13 -0
  117. data/vendor/ParseTree-1.7.1-patched/test/test_composite_sexp_processor.rb +69 -0
  118. data/vendor/ParseTree-1.7.1-patched/test/test_parse_tree.rb +216 -0
  119. data/vendor/ParseTree-1.7.1-patched/test/test_sexp.rb +291 -0
  120. data/vendor/ParseTree-1.7.1-patched/test/test_sexp_processor.rb +244 -0
  121. data/vendor/ParseTree-1.7.1-patched/validate.sh +31 -0
  122. data/vendor/ParseTree-1.7.1/History.txt +217 -0
  123. data/vendor/ParseTree-1.7.1/Manifest.txt +22 -0
  124. data/vendor/ParseTree-1.7.1/README.txt +110 -0
  125. data/vendor/ParseTree-1.7.1/Rakefile +41 -0
  126. data/vendor/ParseTree-1.7.1/bin/parse_tree_abc +89 -0
  127. data/vendor/ParseTree-1.7.1/bin/parse_tree_audit +28 -0
  128. data/vendor/ParseTree-1.7.1/bin/parse_tree_deps +62 -0
  129. data/vendor/ParseTree-1.7.1/bin/parse_tree_show +49 -0
  130. data/vendor/ParseTree-1.7.1/demo/printer.rb +20 -0
  131. data/vendor/ParseTree-1.7.1/lib/composite_sexp_processor.rb +49 -0
  132. data/vendor/ParseTree-1.7.1/lib/parse_tree.rb +1004 -0
  133. data/vendor/ParseTree-1.7.1/lib/sexp.rb +235 -0
  134. data/vendor/ParseTree-1.7.1/lib/sexp_processor.rb +330 -0
  135. data/vendor/ParseTree-1.7.1/lib/unique.rb +15 -0
  136. data/vendor/ParseTree-1.7.1/test/pt_testcase.rb +1221 -0
  137. data/vendor/ParseTree-1.7.1/test/something.rb +53 -0
  138. data/vendor/ParseTree-1.7.1/test/test_all.rb +13 -0
  139. data/vendor/ParseTree-1.7.1/test/test_composite_sexp_processor.rb +69 -0
  140. data/vendor/ParseTree-1.7.1/test/test_parse_tree.rb +216 -0
  141. data/vendor/ParseTree-1.7.1/test/test_sexp.rb +291 -0
  142. data/vendor/ParseTree-1.7.1/test/test_sexp_processor.rb +244 -0
  143. data/vendor/ParseTree-1.7.1/validate.sh +31 -0
  144. metadata +230 -0
@@ -0,0 +1,15 @@
1
+ ##
2
+ # Unique creates unique variable names.
3
+
4
+ class Unique
5
+ def self.reset # mostly for testing
6
+ @@curr = 0
7
+ end
8
+
9
+ def self.next
10
+ @@curr += 1
11
+ "temp_#{@@curr}".intern
12
+ end
13
+
14
+ reset
15
+ end
@@ -0,0 +1,1221 @@
1
+ require 'test/unit/testcase'
2
+ require 'sexp_processor' # for deep_clone
3
+ require 'unique'
4
+
5
+ class Examples
6
+ attr_reader :reader
7
+ attr_writer :writer
8
+
9
+ def a_method(x); x+1; end
10
+ alias an_alias a_method
11
+
12
+ define_method(:unsplatted) do |x|
13
+ x + 1
14
+ end
15
+
16
+ define_method :splatted do |*args|
17
+ y = args.first
18
+ y + 42
19
+ end
20
+
21
+ define_method :dmethod_added, instance_method(:a_method) if RUBY_VERSION < "1.9"
22
+ end
23
+
24
+ class ParseTreeTestCase < Test::Unit::TestCase
25
+
26
+ attr_accessor :processor # to be defined by subclass
27
+
28
+ def self.testcase_order; @@testcase_order; end
29
+ def self.testcases; @@testcases; end
30
+
31
+ def setup
32
+ super
33
+ @processor = nil
34
+ Unique.reset
35
+ end
36
+
37
+ def self.add_test name, data, klass = self.name[4..-1]
38
+ name = name.to_s
39
+ klass = klass.to_s
40
+ if testcases.has_key? name then
41
+ if testcases[name].has_key? klass then
42
+ warn "testcase #{klass}##{name} already has data"
43
+ else
44
+ testcases[name][klass] = data
45
+ end
46
+ else
47
+ warn "testcase #{name} does not exist"
48
+ end
49
+ end
50
+
51
+ def self.unsupported_tests *tests
52
+ tests.flatten.each do |name|
53
+ add_test name, :unsupported
54
+ end
55
+ end
56
+
57
+ @@testcase_order = %w(Ruby ParseTree)
58
+
59
+ @@testcases = {
60
+
61
+ "alias" => {
62
+ "Ruby" => "class X\n alias :y :x\nend",
63
+ "ParseTree" => [:class, :X, nil,
64
+ [:scope, [:alias, [:lit, :y], [:lit, :x]]]],
65
+ "Ruby2Ruby" => "class X\n alias_method :y, :x\nend",
66
+ },
67
+
68
+ "and" => {
69
+ "Ruby" => "(a and b)",
70
+ "ParseTree" => [:and, [:vcall, :a], [:vcall, :b]],
71
+ },
72
+
73
+ "argscat" => {
74
+ "Ruby" => "a = b, c, *d",
75
+ "ParseTree" => [:lasgn, :a,
76
+ [:svalue,
77
+ [:argscat,
78
+ [:array, [:vcall, :b], [:vcall, :c]],
79
+ [:vcall, :d]]]],
80
+ },
81
+
82
+ "argspush" => {
83
+ "Ruby" => "a[*b] = c",
84
+ "ParseTree" => [:attrasgn,
85
+ [:vcall, :a],
86
+ :[]=,
87
+ [:argspush, [:splat, [:vcall, :b]], [:vcall, :c]]],
88
+ },
89
+
90
+ "array" => {
91
+ "Ruby" => "[1, :b, \"c\"]",
92
+ "ParseTree" => [:array, [:lit, 1], [:lit, :b], [:str, "c"]],
93
+ },
94
+
95
+ "attrasgn" => {
96
+ "Ruby" => "y = 0\n42.method = y\n",
97
+ "ParseTree" => [:block,
98
+ [:lasgn, :y, [:lit, 0]],
99
+ [:attrasgn, [:lit, 42], :method=, [:array, [:lvar, :y]]]],
100
+ },
101
+
102
+ "attrasgn_index_equals" => {
103
+ "Ruby" => "a[42] = 24",
104
+ "ParseTree" => [:attrasgn, [:vcall, :a], :[]=, [:array, [:lit, 42], [:lit, 24]]],
105
+ },
106
+
107
+ "attrset" => {
108
+ "Ruby" => [Examples, :writer=],
109
+ "ParseTree" => [:defn, :writer=, [:attrset, :@writer]],
110
+ "Ruby2Ruby" => "attr_writer :writer"
111
+ },
112
+
113
+ "back_ref" => {
114
+ "Ruby" => "[$&, $`, $', $+]",
115
+ "ParseTree" => [:array,
116
+ [:back_ref, :&],
117
+ [:back_ref, "`".intern], # symbol was fucking up emacs
118
+ [:back_ref, "'".intern], # s->e
119
+ [:back_ref, :+]],
120
+ },
121
+
122
+ "begin" => {
123
+ "Ruby" => "begin\n (1 + 1)\nend",
124
+ "ParseTree" => [:begin, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
125
+ },
126
+
127
+ "begin_rescue_ensure" => {
128
+ "Ruby" => "begin\n rescue\n # do nothing\n ensure\n nil\nend",
129
+ "ParseTree" => [:begin,
130
+ [:ensure,
131
+ [:rescue,
132
+ [:resbody, nil]],
133
+ [:nil]]]
134
+ },
135
+
136
+ "block_pass" => {
137
+ "Ruby" => "a(&b)",
138
+ "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]],
139
+ },
140
+
141
+ "block_pass_omgwtf" => {
142
+ "Ruby" => "define_attr_method(:x, :sequence_name, &Proc.new { |*args| nil })",
143
+ "ParseTree" => [:block_pass,
144
+ [:iter,
145
+ [:call, [:const, :Proc], :new],
146
+ [:masgn, [:dasgn_curr, :args]],
147
+ [:nil]],
148
+ [:fcall, :define_attr_method,
149
+ [:array, [:lit, :x], [:lit, :sequence_name]]]],
150
+ },
151
+
152
+ "block_pass_splat" => {
153
+ "Ruby" => "def blah(*args, &block)\n other(*args, &block)\nend",
154
+ "ParseTree" => [:defn, :blah,
155
+ [:scope,
156
+ [:block,
157
+ [:args, "*args".intern],
158
+ [:block_arg, :block],
159
+ [:block_pass,
160
+ [:lvar, :block],
161
+ [:fcall, :other, [:splat, [:lvar, :args]]]]]]],
162
+ },
163
+
164
+ "block_pass_args_and_splat" => {
165
+ "Ruby" => "def blah(*args, &block)\n other(42, *args, &block)\nend",
166
+ "ParseTree" => [:defn, :blah,
167
+ [:scope,
168
+ [:block,
169
+ [:args, "*args".intern],
170
+ [:block_arg, :block],
171
+ [:block_pass,
172
+ [:lvar, :block],
173
+ [:fcall, :other,
174
+ [:argscat, [:array, [:lit, 42]], [:lvar, :args]]]]]]],
175
+ },
176
+
177
+ "bmethod" => {
178
+ "Ruby" => [Examples, :unsplatted],
179
+ "ParseTree" => [:defn,
180
+ :unsplatted,
181
+ [:bmethod,
182
+ [:dasgn_curr, :x],
183
+ [:call, [:dvar, :x], "+".intern, [:array, [:lit, 1]]]]],
184
+ "Ruby2Ruby" => "def unsplatted(x)\n (x + 1)\nend"
185
+ },
186
+
187
+ "bmethod_splat" => {
188
+ "Ruby" => [Examples, :splatted],
189
+ "ParseTree" => [:defn, :splatted,
190
+ [:bmethod,
191
+ [:masgn, [:dasgn_curr, :args]],
192
+ [:block,
193
+ [:dasgn_curr, :y, [:call, [:dvar, :args], :first]],
194
+ [:call, [:dvar, :y], :+, [:array, [:lit, 42]]]]]],
195
+ "Ruby2Ruby" => "def splatted(*args)\n y = args.first\n (y + 42)\nend",
196
+ },
197
+
198
+ "break" => {
199
+ "Ruby" => "loop { break if true }",
200
+ "ParseTree" => [:iter,
201
+ [:fcall, :loop], nil, [:if, [:true], [:break], nil]],
202
+ },
203
+
204
+ "break_arg" => {
205
+ "Ruby" => "loop { break 42 if true }",
206
+ "ParseTree" => [:iter,
207
+ [:fcall, :loop], nil,
208
+ [:if, [:true], [:break, [:lit, 42]], nil]],
209
+ },
210
+
211
+ "call" => {
212
+ "Ruby" => "self.method",
213
+ "ParseTree" => [:call, [:self], :method],
214
+ },
215
+
216
+ "call_arglist" => {
217
+ "Ruby" => "puts(42)",
218
+ "ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]],
219
+ },
220
+
221
+ "call_index" => { # see attrasgn_index_equals for opposite
222
+ "Ruby" => "a[42]",
223
+ "ParseTree" => [:call, [:vcall, :a], :[], [:array, [:lit, 42]]],
224
+ },
225
+
226
+ "case" => {
227
+ "Ruby" => "var = 2\nresult = \"\"\ncase var\nwhen 1 then\n puts(\"something\")\n result = \"red\"\nwhen 2, 3 then\n result = \"yellow\"\nwhen 4 then\n # do nothing\nelse\n result = \"green\"\nend\ncase result\nwhen \"red\" then\n var = 1\nwhen \"yellow\" then\n var = 2\nwhen \"green\" then\n var = 3\nelse\n # do nothing\nend\n",
228
+ "ParseTree" => [:block,
229
+ [:lasgn, :var, [:lit, 2]],
230
+ [:lasgn, :result, [:str, ""]],
231
+ [:case,
232
+ [:lvar, :var],
233
+ [:when,
234
+ [:array, [:lit, 1]],
235
+ [:block,
236
+ [:fcall, :puts, [:array, [:str, "something"]]],
237
+ [:lasgn, :result, [:str, "red"]]]],
238
+ [:when,
239
+ [:array, [:lit, 2], [:lit, 3]],
240
+ [:lasgn, :result, [:str, "yellow"]]],
241
+ [:when, [:array, [:lit, 4]], nil],
242
+ [:lasgn, :result, [:str, "green"]]],
243
+ [:case,
244
+ [:lvar, :result],
245
+ [:when, [:array, [:str, "red"]],
246
+ [:lasgn, :var, [:lit, 1]]],
247
+ [:when, [:array, [:str, "yellow"]],
248
+ [:lasgn, :var, [:lit, 2]]],
249
+ [:when, [:array, [:str, "green"]],
250
+ [:lasgn, :var, [:lit, 3]]],
251
+ nil]]
252
+ },
253
+
254
+ "case_nested" => {
255
+ "Ruby" => "var1 = 1\nvar2 = 2\nresult = nil\ncase var1\nwhen 1 then\n case var2\n when 1 then\n result = 1\n when 2 then\n result = 2\n else\n result = 3\n end\nwhen 2 then\n case var2\n when 1 then\n result = 4\n when 2 then\n result = 5\n else\n result = 6\n end\nelse\n result = 7\nend\n",
256
+ "ParseTree" => [:block,
257
+ [:lasgn, :var1, [:lit, 1]],
258
+ [:lasgn, :var2, [:lit, 2]],
259
+ [:lasgn, :result, [:nil]],
260
+ [:case,
261
+ [:lvar, :var1],
262
+ [:when, [:array, [:lit, 1]],
263
+ [:case,
264
+ [:lvar, :var2],
265
+ [:when, [:array, [:lit, 1]],
266
+ [:lasgn, :result, [:lit, 1]]],
267
+ [:when, [:array, [:lit, 2]],
268
+ [:lasgn, :result, [:lit, 2]]],
269
+ [:lasgn, :result, [:lit, 3]]]],
270
+ [:when, [:array, [:lit, 2]],
271
+ [:case,
272
+ [:lvar, :var2],
273
+ [:when, [:array, [:lit, 1]],
274
+ [:lasgn, :result, [:lit, 4]]],
275
+ [:when, [:array, [:lit, 2]],
276
+ [:lasgn, :result, [:lit, 5]]],
277
+ [:lasgn, :result, [:lit, 6]]]],
278
+ [:lasgn, :result, [:lit, 7]]]]
279
+ },
280
+
281
+ "case_no_expr" => { # TODO: nested
282
+ "Ruby" => "case\nwhen 1 then\n :a\nwhen 2 then\n :b\nelse\n :c\nend",
283
+ "ParseTree" => [:case, nil,
284
+ [:when,
285
+ [:array, [:lit, 1]],
286
+ [:lit, :a]],
287
+ [:when,
288
+ [:array, [:lit, 2]], [:lit, :b]],
289
+ [:lit, :c]],
290
+ },
291
+
292
+ "cdecl" => {
293
+ "Ruby" => "X = 42",
294
+ "ParseTree" => [:cdecl, :X, [:lit, 42]],
295
+ },
296
+
297
+ "class_plain" => {
298
+ "Ruby" => "class X\n puts((1 + 1))\n def blah\n puts(\"hello\")\n end\nend",
299
+ "ParseTree" => [:class,
300
+ :X,
301
+ nil,
302
+ [:scope,
303
+ [:block,
304
+ [:fcall, :puts, [:array, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]],
305
+ [:defn,
306
+ :blah,
307
+ [:scope,
308
+ [:block,
309
+ [:args],
310
+ [:fcall, :puts, [:array, [:str, "hello"]]]]]]]]],
311
+ },
312
+
313
+ "class_super_object" => {
314
+ "Ruby" => "class X < Object\nend",
315
+ "ParseTree" => [:class,
316
+ :X,
317
+ [:const, :Object],
318
+ [:scope]],
319
+ },
320
+
321
+ "class_super_array" => {
322
+ "Ruby" => "class X < Array\nend",
323
+ "ParseTree" => [:class,
324
+ :X,
325
+ [:const, :Array],
326
+ [:scope]],
327
+ },
328
+
329
+ "class_super_expr" => {
330
+ "Ruby" => "class X < expr\nend",
331
+ "ParseTree" => [:class,
332
+ :X,
333
+ [:vcall, :expr],
334
+ [:scope]],
335
+ },
336
+
337
+ "colon2" => {
338
+ "Ruby" => "X::Y",
339
+ "ParseTree" => [:colon2, [:const, :X], :Y],
340
+ },
341
+
342
+ "colon3" => {
343
+ "Ruby" => "::X",
344
+ "ParseTree" => [:colon3, :X],
345
+ },
346
+
347
+ "conditional1" => { # TODO: rename
348
+ "Ruby" => "return 1 if (42 == 0)",
349
+ "ParseTree" => [:if,
350
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
351
+ [:return, [:lit, 1]],
352
+ nil],
353
+ },
354
+
355
+ "conditional2" => { # TODO: remove
356
+ "Ruby" => "return 2 unless (42 == 0)",
357
+ "ParseTree" => [:if,
358
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
359
+ nil,
360
+ [:return, [:lit, 2]]],
361
+ },
362
+
363
+ "conditional3" => {
364
+ "Ruby" => "if (42 == 0) then\n return 3\nelse\n return 4\nend",
365
+ "ParseTree" => [:if, [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
366
+ [:return, [:lit, 3]],
367
+ [:return, [:lit, 4]]],
368
+ },
369
+
370
+ "conditional4" => {
371
+ "Ruby" => "if (42 == 0) then\n return 2\nelsif (42 < 0) then\n return 3\nelse\n return 4\nend",
372
+ "ParseTree" => [:if,
373
+ [:call, [:lit, 42], :==, [:array, [:lit, 0]]],
374
+ [:return, [:lit, 2]],
375
+ [:if,
376
+ [:call, [:lit, 42], :<, [:array, [:lit, 0]]],
377
+ [:return, [:lit, 3]],
378
+ [:return, [:lit, 4]]]],
379
+ "Ruby2Ruby" => "if (42 == 0) then\n return 2\nelse\n if (42 < 0) then\n return 3\n else\n return 4\n end\nend",
380
+ },
381
+
382
+ "conditional5" => {
383
+ "Ruby" => "return if false unless true",
384
+ "ParseTree" => [:if, [:true], nil, [:if, [:false], [:return], nil]],
385
+ },
386
+
387
+ "const" => {
388
+ "Ruby" => "X",
389
+ "ParseTree" => [:const, :X],
390
+ },
391
+
392
+ "cvar" => {
393
+ "Ruby" => "@@x",
394
+ "ParseTree" => [:cvar, :@@x],
395
+ },
396
+
397
+ "cvasgn" => {
398
+ "Ruby" => "def x\n @@blah = 1\nend",
399
+ "ParseTree" => [:defn, :x,
400
+ [:scope,
401
+ [:block, [:args], [:cvasgn, :@@blah, [:lit, 1]]]]]
402
+ },
403
+
404
+ "cvdecl" => {
405
+ "Ruby" => "class X\n @@blah = 1\nend",
406
+ "ParseTree" => [:class, :X, nil,
407
+ [:scope, [:cvdecl, :@@blah, [:lit, 1]]]],
408
+ },
409
+
410
+ "dasgn" => {
411
+ "Ruby" => "a.each { |x| b.each { |y| x = (x + 1) } }",
412
+ "ParseTree" => [:iter,
413
+ [:call, [:vcall, :a], :each],
414
+ [:dasgn_curr, :x],
415
+ [:iter,
416
+ [:call, [:vcall, :b], :each],
417
+ [:dasgn_curr, :y],
418
+ [:dasgn, :x,
419
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]],
420
+ },
421
+
422
+ "dasgn_curr" => {
423
+ "Ruby" => "data.each do |x, y|\n a = 1\n b = a\n b = a = x\nend",
424
+ "ParseTree" => [:iter,
425
+ [:call, [:vcall, :data], :each],
426
+ [:masgn, [:array, [:dasgn_curr, :x], [:dasgn_curr, :y]]],
427
+ [:block,
428
+ [:dasgn_curr, :a, [:lit, 1]],
429
+ [:dasgn_curr, :b, [:dvar, :a]],
430
+ [:dasgn_curr, :b, [:dasgn_curr, :a, [:dvar, :x]]]]],
431
+ },
432
+
433
+ "defined" => {
434
+ "Ruby" => "defined? $x",
435
+ "ParseTree" => [:defined, [:gvar, :$x]],
436
+ },
437
+
438
+ "defn_args" => {
439
+ "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend",
440
+ "ParseTree" => [:defn, :x,
441
+ [:scope,
442
+ [:block,
443
+ [:args, :a, :b, "*c".intern, # s->e
444
+ [:block, [:lasgn, :b, [:lit, 42]]]],
445
+ [:block_arg, :d],
446
+ [:fcall, :p,
447
+ [:array, [:lvar, :a], [:lvar, :b],
448
+ [:lvar, :c], [:lvar, :d]]]]]]
449
+ },
450
+
451
+ "defn_empty" => {
452
+ "Ruby" => "def empty\n # do nothing\nend",
453
+ "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]],
454
+ },
455
+
456
+ "defn_is_something" => {
457
+ "Ruby" => "def something?\n # do nothing\nend",
458
+ "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
459
+ },
460
+
461
+ # TODO:
462
+ # add_test("defn_optargs",
463
+ # s(:defn, :x,
464
+ # s(:args, :a, "*args".intern),
465
+ # s(:scope,
466
+ # s(:block,
467
+ # s(:call, nil, :p,
468
+ # s(:arglist, s(:lvar, :a), s(:lvar, :args)))))))
469
+
470
+ "defn_or" => {
471
+ "Ruby" => "def |(o)\n # do nothing\nend",
472
+ "ParseTree" => [:defn, :|, [:scope, [:block, [:args, :o], [:nil]]]],
473
+ },
474
+
475
+ "defn_rescue" => {
476
+ "Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid) rescue false\nend",
477
+ "ParseTree" => [:defn, :eql?,
478
+ [:scope,
479
+ [:block,
480
+ [:args, :resource],
481
+ [:rescue,
482
+ [:call,
483
+ [:call, [:self], :uuid],
484
+ :==,
485
+ [:array, [:call, [:lvar, :resource], :uuid]]],
486
+ [:resbody, nil, [:false]]]]]],
487
+ },
488
+
489
+ "defn_zarray" => { # tests memory allocation for returns
490
+ "Ruby" => "def zarray\n a = []\n return a\nend",
491
+ "ParseTree" => [:defn, :zarray,
492
+ [:scope,
493
+ [:block, [:args],
494
+ [:lasgn, :a, [:zarray]], [:return, [:lvar, :a]]]]],
495
+ },
496
+
497
+ "defs" => {
498
+ "Ruby" => "def self.x(y)\n (y + 1)\nend",
499
+ "ParseTree" => [:defs, [:self], :x,
500
+ [:scope,
501
+ [:block,
502
+ [:args, :y],
503
+ [:call, [:lvar, :y], :+, [:array, [:lit, 1]]]]]],
504
+ },
505
+
506
+ "dmethod" => {
507
+ "Ruby" => [Examples, :dmethod_added],
508
+ "ParseTree" => [:defn,
509
+ :dmethod_added,
510
+ [:dmethod,
511
+ :a_method,
512
+ [:scope,
513
+ [:block,
514
+ [:args, :x],
515
+ [:call, [:lvar, :x], :+, [:array, [:lit, 1]]]]]]],
516
+ "Ruby2Ruby" => "def dmethod_added(x)\n (x + 1)\nend"
517
+ },
518
+
519
+ "dot2" => {
520
+ "Ruby" => "(a..b)",
521
+ "ParseTree" => [:dot2, [:vcall, :a], [:vcall, :b]],
522
+ },
523
+
524
+ "dot3" => {
525
+ "Ruby" => "(a...b)",
526
+ "ParseTree" => [:dot3, [:vcall, :a], [:vcall, :b]],
527
+ },
528
+
529
+ "dregx" => {
530
+ "Ruby" => "/x#\{(1 + 1)}y/",
531
+ "ParseTree" => [:dregx, "x",
532
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
533
+ },
534
+
535
+ "dregx_once" => {
536
+ "Ruby" => "/x#\{(1 + 1)}y/o",
537
+ "ParseTree" => [:dregx_once, "x",
538
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
539
+ },
540
+
541
+ "dstr" => {
542
+ "Ruby" => "argl = 1\n\"x#\{argl}y\"\n",
543
+ "ParseTree" => [:block,
544
+ [:lasgn, :argl, [:lit, 1]],
545
+ [:dstr, "x", [:lvar, :argl],
546
+ [:str, "y"]]],
547
+ },
548
+
549
+ "dsym" => {
550
+ "Ruby" => ":\"x#\{(1 + 1)}y\"",
551
+ "ParseTree" => [:dsym, "x",
552
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
553
+ },
554
+
555
+ "dxstr" => {
556
+ "Ruby" => "t = 5\n`touch #\{t}`\n",
557
+ "ParseTree" => [:block,
558
+ [:lasgn, :t, [:lit, 5]],
559
+ [:dxstr, 'touch ', [:lvar, :t]]],
560
+ },
561
+
562
+ "ensure" => {
563
+ "Ruby" => "begin
564
+ (1 + 1)
565
+ rescue SyntaxError => e1
566
+ 2
567
+ rescue Exception => e2
568
+ 3
569
+ else
570
+ 4
571
+ ensure
572
+ 5
573
+ end",
574
+ "ParseTree" => [:begin,
575
+ [:ensure,
576
+ [:rescue,
577
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]],
578
+ [:resbody,
579
+ [:array, [:const, :SyntaxError]],
580
+ [:block, [:lasgn, :e1, [:gvar, :$!]], [:lit, 2]],
581
+ [:resbody,
582
+ [:array, [:const, :Exception]],
583
+ [:block, [:lasgn, :e2, [:gvar, :$!]], [:lit, 3]]]],
584
+ [:lit, 4]],
585
+ [:lit, 5]]],
586
+ },
587
+
588
+ "false" => {
589
+ "Ruby" => "false",
590
+ "ParseTree" => [:false],
591
+ },
592
+
593
+ "fbody" => {
594
+ "Ruby" => [Examples, :an_alias],
595
+ "ParseTree" => [:defn, :an_alias,
596
+ [:fbody,
597
+ [:scope,
598
+ [:block,
599
+ [:args, :x],
600
+ [:call, [:lvar, :x], :+, [:array, [:lit, 1]]]]]]],
601
+ "Ruby2Ruby" => "def an_alias(x)\n (x + 1)\nend"
602
+ },
603
+
604
+ "fcall" => {
605
+ "Ruby" => "p(4)",
606
+ "ParseTree" => [:fcall, :p, [:array, [:lit, 4]]],
607
+ },
608
+
609
+ "flip2" => {
610
+ "Ruby" => "x = if ((i % 4) == 0)..((i % 3) == 0) then\n i\nelse\n nil\nend",
611
+ "ParseTree" => [:lasgn,
612
+ :x,
613
+ [:if,
614
+ [:flip2,
615
+ [:call,
616
+ [:call, [:vcall, :i], :%, [:array, [:lit, 4]]],
617
+ :==,
618
+ [:array, [:lit, 0]]],
619
+ [:call,
620
+ [:call, [:vcall, :i], :%, [:array, [:lit, 3]]],
621
+ :==,
622
+ [:array, [:lit, 0]]]],
623
+ [:vcall, :i],
624
+ [:nil]]],
625
+ },
626
+
627
+ "flip3" => {
628
+ "Ruby" => "x = if ((i % 4) == 0)...((i % 3) == 0) then\n i\nelse\n nil\nend",
629
+ "ParseTree" => [:lasgn,
630
+ :x,
631
+ [:if,
632
+ [:flip3,
633
+ [:call,
634
+ [:call, [:vcall, :i], :%, [:array, [:lit, 4]]],
635
+ :==,
636
+ [:array, [:lit, 0]]],
637
+ [:call,
638
+ [:call, [:vcall, :i], :%, [:array, [:lit, 3]]],
639
+ :==,
640
+ [:array, [:lit, 0]]]],
641
+ [:vcall, :i],
642
+ [:nil]]],
643
+ },
644
+
645
+ "for" => {
646
+ "Ruby" => "for o in ary\n puts(o)\nend\n",
647
+ "ParseTree" => [:for, [:vcall, :ary], [:lasgn, :o],
648
+ [:fcall, :puts, [:array, [:lvar, :o]]]],
649
+ },
650
+
651
+ "gasgn" => {
652
+ "Ruby" => "$x = 42",
653
+ "ParseTree" => [:gasgn, :$x, [:lit, 42]],
654
+ },
655
+
656
+ "global" => {
657
+ "Ruby" => "$stderr",
658
+ "ParseTree" => [:gvar, :$stderr],
659
+ },
660
+
661
+ "gvar" => {
662
+ "Ruby" => "$x",
663
+ "ParseTree" => [:gvar, :$x],
664
+ },
665
+
666
+ "hash" => {
667
+ "Ruby" => "{ 1 => 2, 3 => 4 }",
668
+ "ParseTree" => [:hash, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4]],
669
+ },
670
+
671
+ "iasgn" => {
672
+ "Ruby" => "@a = 4",
673
+ "ParseTree" => [:iasgn, :@a, [:lit, 4]],
674
+ },
675
+
676
+ "iteration1" => {
677
+ "Ruby" => "loop { }",
678
+ "ParseTree" => [:iter, [:fcall, :loop], nil],
679
+ },
680
+
681
+ "iteration2" => {
682
+ "Ruby" => "array = [1, 2, 3]\narray.each { |x| puts(x.to_s) }\n",
683
+ "ParseTree" => [:block,
684
+ [:lasgn, :array,
685
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
686
+ [:iter,
687
+ [:call, [:lvar, :array], :each],
688
+ [:dasgn_curr, :x],
689
+ [:fcall, :puts, [:array, [:call, [:dvar, :x], :to_s]]]]],
690
+ },
691
+
692
+ "iteration3" => {
693
+ "Ruby" => "1.upto(3) { |n| puts(n.to_s) }",
694
+ "ParseTree" => [:iter,
695
+ [:call, [:lit, 1], :upto, [:array, [:lit, 3]]],
696
+ [:dasgn_curr, :n],
697
+ [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
698
+ },
699
+
700
+ "iteration4" => {
701
+ "Ruby" => "3.downto(1) { |n| puts(n.to_s) }",
702
+ "ParseTree" => [:iter,
703
+ [:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
704
+ [:dasgn_curr, :n],
705
+ [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]],
706
+ },
707
+
708
+ "iteration5" => {
709
+ "Ruby" => "argl = 10\nwhile (argl >= 1) do\n puts(\"hello\")\n argl = (argl - 1)\nend\n",
710
+ "ParseTree" => [:block,
711
+ [:lasgn, :argl, [:lit, 10]],
712
+ [:while,
713
+ [:call, [:lvar, :argl], ">=".intern, [:array, [:lit, 1]]],
714
+ [:block,
715
+ [:fcall, :puts, [:array, [:str, "hello"]]],
716
+ [:lasgn,
717
+ :argl,
718
+ [:call, [:lvar, :argl],
719
+ "-".intern, [:array, [:lit, 1]]]]], true]],
720
+ },
721
+
722
+ "iteration6" => {
723
+ "Ruby" => "array1 = [1, 2, 3]\narray2 = [4, 5, 6, 7]\narray1.each do |x|\n array2.each do |y|\n puts(x.to_s)\n puts(y.to_s)\n end\nend\n",
724
+ "ParseTree" => [:block,
725
+ [:lasgn, :array1,
726
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
727
+ [:lasgn, :array2,
728
+ [:array, [:lit, 4], [:lit, 5], [:lit, 6], [:lit, 7]]],
729
+ [:iter,
730
+ [:call,
731
+ [:lvar, :array1], :each],
732
+ [:dasgn_curr, :x],
733
+ [:iter,
734
+ [:call,
735
+ [:lvar, :array2], :each],
736
+ [:dasgn_curr, :y],
737
+ [:block,
738
+ [:fcall, :puts,
739
+ [:array, [:call, [:dvar, :x], :to_s]]],
740
+ [:fcall, :puts,
741
+ [:array, [:call, [:dvar, :y], :to_s]]]]]]],
742
+ },
743
+
744
+ "ivar" => {
745
+ "Ruby" => [Examples, :reader],
746
+ "ParseTree" => [:defn, :reader, [:ivar, :@reader]],
747
+ "Ruby2Ruby" => "attr_reader :reader"
748
+ },
749
+
750
+ "lasgn_array" => {
751
+ "Ruby" => "var = [\"foo\", \"bar\"]",
752
+ "ParseTree" => [:lasgn, :var, [:array,
753
+ [:str, "foo"],
754
+ [:str, "bar"]]],
755
+ },
756
+
757
+ "lasgn_call" => {
758
+ "Ruby" => "c = (2 + 3)",
759
+ "ParseTree" => [:lasgn, :c, [:call, [:lit, 2], :+, [:array, [:lit, 3]]]],
760
+ },
761
+
762
+ "lit_bool_false" => {
763
+ "Ruby" => "false",
764
+ "ParseTree" => [:false],
765
+ },
766
+
767
+ "lit_bool_true" => {
768
+ "Ruby" => "true",
769
+ "ParseTree" => [:true],
770
+ },
771
+
772
+ "lit_float" => {
773
+ "Ruby" => "1.1",
774
+ "ParseTree" => [:lit, 1.1],
775
+ },
776
+
777
+ "lit_long" => {
778
+ "Ruby" => "1",
779
+ "ParseTree" => [:lit, 1],
780
+ },
781
+
782
+ "lit_range2" => {
783
+ "Ruby" => "(1..10)",
784
+ "ParseTree" => [:lit, 1..10],
785
+ },
786
+
787
+ "lit_range3" => {
788
+ "Ruby" => "(1...10)",
789
+ "ParseTree" => [:lit, 1...10],
790
+ },
791
+
792
+ "lit_regexp" => {
793
+ "Ruby" => "/x/",
794
+ "ParseTree" => [:lit, /x/],
795
+ },
796
+
797
+ "lit_str" => {
798
+ "Ruby" => "\"x\"",
799
+ "ParseTree" => [:str, "x"],
800
+ },
801
+
802
+ "lit_sym" => {
803
+ "Ruby" => ":x",
804
+ "ParseTree" => [:lit, :x],
805
+ },
806
+
807
+ "masgn" => {
808
+ "Ruby" => "a, b = c, d",
809
+ "ParseTree" => [:masgn,
810
+ [:array, [:lasgn, :a], [:lasgn, :b]],
811
+ [:array, [:vcall, :c], [:vcall, :d]]],
812
+ },
813
+
814
+ "masgn_iasgn" => {
815
+ "Ruby" => "a, @b = c, d",
816
+ "ParseTree" => [:masgn,
817
+ [:array, [:lasgn, :a], [:iasgn, "@b".intern]],
818
+ [:array, [:vcall, :c], [:vcall, :d]]],
819
+ },
820
+
821
+ "masgn_attrasgn" => {
822
+ "Ruby" => "a, b.c = d, e",
823
+ "ParseTree" => [:masgn,
824
+ [:array, [:lasgn, :a], [:attrasgn, [:vcall, :b], :c=]],
825
+ [:array, [:vcall, :d], [:vcall, :e]]],
826
+ },
827
+
828
+ "masgn_splat" => {
829
+ "Ruby" => "a, b, *c = d, e, f, g",
830
+ "ParseTree" => [:masgn,
831
+ [:array, [:lasgn, :a], [:lasgn, :b]],
832
+ [:lasgn, :c],
833
+ [:array,
834
+ [:vcall, :d], [:vcall, :e],
835
+ [:vcall, :f], [:vcall, :g]]]
836
+ },
837
+
838
+
839
+ "match" => {
840
+ "Ruby" => "1 if /x/",
841
+ "ParseTree" => [:if, [:match, [:lit, /x/]], [:lit, 1], nil],
842
+ },
843
+
844
+ "match2" => {
845
+ "Ruby" => "/x/ =~ \"blah\"",
846
+ "ParseTree" => [:match2, [:lit, /x/], [:str, "blah"]],
847
+ },
848
+
849
+ "match3" => {
850
+ "Ruby" => "\"blah\" =~ /x/",
851
+ "ParseTree" => [:match3, [:lit, /x/], [:str, "blah"]],
852
+ },
853
+
854
+ "module" => {
855
+ "Ruby" => "module X\n def y\n # do nothing\n end\nend",
856
+ "ParseTree" => [:module, :X,
857
+ [:scope,
858
+ [:defn, :y, [:scope, [:block, [:args], [:nil]]]]]],
859
+ },
860
+
861
+ "next" => {
862
+ "Ruby" => "loop { next if false }",
863
+ "ParseTree" => [:iter,
864
+ [:fcall, :loop],
865
+ nil,
866
+ [:if, [:false], [:next], nil]],
867
+ },
868
+
869
+ "not" => {
870
+ "Ruby" => "(not true)",
871
+ "ParseTree" => [:not, [:true]],
872
+ },
873
+
874
+ "nth_ref" => {
875
+ "Ruby" => "$1",
876
+ "ParseTree" => [:nth_ref, 1],
877
+ },
878
+
879
+ "op_asgn1" => {
880
+ "Ruby" => "b = []\nb[1] ||= 10\nb[2] &&= 11\nb[3] += 12\n",
881
+ "ParseTree" => [:block,
882
+ [:lasgn, :b, [:zarray]],
883
+ [:op_asgn1, [:lvar, :b],
884
+ [:array, [:lit, 1]], "||".intern, [:lit, 10]], # s->e
885
+ [:op_asgn1, [:lvar, :b],
886
+ [:array, [:lit, 2]], "&&".intern, [:lit, 11]], # s->e
887
+ [:op_asgn1, [:lvar, :b],
888
+ [:array, [:lit, 3]], :+, [:lit, 12]]],
889
+ },
890
+
891
+ "op_asgn2" => {
892
+ "Ruby" => "s = Struct.new(:var)\nc = s.new(nil)\nc.var ||= 20\nc.var &&= 21\nc.var += 22\nc.d.e.f ||= 42\n",
893
+ "ParseTree" => [:block,
894
+ [:lasgn, :s,
895
+ [:call, [:const, :Struct],
896
+ :new, [:array, [:lit, :var]]]],
897
+ [:lasgn, :c,
898
+ [:call, [:lvar, :s], :new, [:array, [:nil]]]],
899
+
900
+ [:op_asgn2, [:lvar, :c], :var=, "||".intern, # s->e
901
+ [:lit, 20]],
902
+ [:op_asgn2, [:lvar, :c], :var=, "&&".intern, # s->e
903
+ [:lit, 21]],
904
+ [:op_asgn2, [:lvar, :c], :var=, :+, [:lit, 22]],
905
+
906
+ [:op_asgn2,
907
+ [:call,
908
+ [:call, [:lvar, :c], :d], :e], :f=, "||".intern,
909
+ [:lit, 42]]],
910
+ },
911
+
912
+ "op_asgn_and" => {
913
+ "Ruby" => "a = 0\na &&= 2\n",
914
+ "ParseTree" => [:block,
915
+ [:lasgn, :a, [:lit, 0]],
916
+ [:op_asgn_and, [:lvar, :a], [:lasgn, :a, [:lit, 2]]]],
917
+ },
918
+
919
+ "op_asgn_or" => {
920
+ "Ruby" => "a = 0\na ||= 1\n",
921
+ "ParseTree" => [:block,
922
+ [:lasgn, :a, [:lit, 0]],
923
+ [:op_asgn_or, [:lvar, :a], [:lasgn, :a, [:lit, 1]]]],
924
+ },
925
+
926
+ "or" => {
927
+ "Ruby" => "(a or b)",
928
+ "ParseTree" => [:or, [:vcall, :a], [:vcall, :b]],
929
+ },
930
+
931
+ "postexe" => {
932
+ "Ruby" => "END { 1 }",
933
+ "ParseTree" => [:iter, [:postexe], nil, [:lit, 1]],
934
+ },
935
+
936
+ "proc_args" => {
937
+ "Ruby" => "proc { |x| (x + 1) }",
938
+ "ParseTree" => [:iter,
939
+ [:fcall, :proc],
940
+ [:dasgn_curr, :x],
941
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]],
942
+ },
943
+
944
+ "proc_no_args" => {
945
+ "Ruby" => "proc { (x + 1) }",
946
+ "ParseTree" => [:iter,
947
+ [:fcall, :proc],
948
+ nil,
949
+ [:call, [:vcall, :x], :+, [:array, [:lit, 1]]]],
950
+ },
951
+
952
+ "redo" => {
953
+ "Ruby" => "loop { redo if false }",
954
+ "ParseTree" => [:iter,
955
+ [:fcall, :loop], nil, [:if, [:false], [:redo], nil]],
956
+ },
957
+
958
+ "rescue" => {
959
+ "Ruby" => "blah rescue nil",
960
+ "ParseTree" => [:rescue, [:vcall, :blah], [:resbody, nil, [:nil]]],
961
+ },
962
+
963
+ "rescue_block_body" => {
964
+ "Ruby" => "begin\n blah\nrescue\n 42\nend",
965
+ "ParseTree" => [:begin,
966
+ [:rescue,
967
+ [:vcall, :blah],
968
+ [:resbody, nil, [:lit, 42]]]],
969
+ },
970
+
971
+ "rescue_block_nada" => {
972
+ "Ruby" => "begin\n blah\nrescue\n # do nothing\nend",
973
+ "ParseTree" => [:begin, [:rescue, [:vcall, :blah], [:resbody, nil]]]
974
+ },
975
+
976
+ "rescue_exceptions" => {
977
+ "Ruby" => "begin\n blah\nrescue RuntimeError => r\n # do nothing\nend",
978
+ "ParseTree" => [:begin,
979
+ [:rescue,
980
+ [:vcall, :blah],
981
+ [:resbody,
982
+ [:array, [:const, :RuntimeError]],
983
+ [:lasgn, :r, [:gvar, :$!]]]]],
984
+ },
985
+
986
+ "retry" => {
987
+ "Ruby" => "retry",
988
+ "ParseTree" => [:retry],
989
+ },
990
+
991
+ "sclass" => {
992
+ "Ruby" => "class << self\n 42\nend",
993
+ "ParseTree" => [:sclass, [:self], [:scope, [:lit, 42]]],
994
+ },
995
+
996
+ "splat" => {
997
+ "Ruby" => "a(*b)",
998
+ "ParseTree" => [:fcall, :a, [:splat, [:vcall, :b]]],
999
+ },
1000
+
1001
+ # TODO: all supers need to pass args
1002
+ "super" => {
1003
+ "Ruby" => "def x\n super(4)\nend",
1004
+ "ParseTree" => [:defn, :x,
1005
+ [:scope,
1006
+ [:block,
1007
+ [:args],
1008
+ [:super, [:array, [:lit, 4]]]]]],
1009
+ },
1010
+
1011
+ "super_multi" => {
1012
+ "Ruby" => "def x\n super(4, 2, 1)\nend",
1013
+ "ParseTree" => [:defn, :x,
1014
+ [:scope,
1015
+ [:block,
1016
+ [:args],
1017
+ [:super, [:array, [:lit, 4], [:lit, 2], [:lit, 1]]]]]],
1018
+ },
1019
+
1020
+ "svalue" => {
1021
+ "Ruby" => "a = *b",
1022
+ "ParseTree" => [:lasgn, :a, [:svalue, [:splat, [:vcall, :b]]]],
1023
+ },
1024
+
1025
+ "to_ary" => {
1026
+ "Ruby" => "a, b = c",
1027
+ "ParseTree" => [:masgn,
1028
+ [:array, [:lasgn, :a], [:lasgn, :b]],
1029
+ [:to_ary, [:vcall, :c]]],
1030
+ },
1031
+
1032
+ "true" => {
1033
+ "Ruby" => "true",
1034
+ "ParseTree" => [:true],
1035
+ },
1036
+
1037
+ "undef" => {
1038
+ "Ruby" => "undef :x",
1039
+ "ParseTree" => [:undef, [:lit, :x]],
1040
+ },
1041
+
1042
+ "undef_multi" => {
1043
+ "Ruby" => "undef :x, :y, :z",
1044
+ "ParseTree" => [:block,
1045
+ [:undef, [:lit, :x]],
1046
+ [:undef, [:lit, :y]],
1047
+ [:undef, [:lit, :z]]],
1048
+ "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\n",
1049
+ },
1050
+
1051
+ "until_post" => {
1052
+ "Ruby" => "begin\n (1 + 1)\nend until false",
1053
+ "ParseTree" => [:until, [:false],
1054
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
1055
+ },
1056
+
1057
+ "until_pre" => {
1058
+ "Ruby" => "until false do\n (1 + 1)\nend",
1059
+ "ParseTree" => [:until, [:false],
1060
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
1061
+ },
1062
+
1063
+ "valias" => {
1064
+ "Ruby" => "alias $y $x",
1065
+ "ParseTree" => [:valias, :$y, :$x],
1066
+ },
1067
+
1068
+ "vcall" => {
1069
+ "Ruby" => "method",
1070
+ "ParseTree" => [:vcall, :method],
1071
+ },
1072
+
1073
+ "while_pre" => {
1074
+ "Ruby" => "while false do\n (1 + 1)\nend",
1075
+ "ParseTree" => [:while, [:false],
1076
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
1077
+ },
1078
+
1079
+ "while_pre_nil" => {
1080
+ "Ruby" => "while false do\nend",
1081
+ "ParseTree" => [:while, [:false], nil, true],
1082
+ },
1083
+
1084
+ "while_post" => {
1085
+ "Ruby" => "begin\n (1 + 1)\nend while false",
1086
+ "ParseTree" => [:while, [:false],
1087
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
1088
+ },
1089
+
1090
+ "xstr" => {
1091
+ "Ruby" => "`touch 5`",
1092
+ "ParseTree" => [:xstr, 'touch 5'],
1093
+ },
1094
+
1095
+ "yield" => {
1096
+ "Ruby" => "yield",
1097
+ "ParseTree" => [:yield],
1098
+ },
1099
+
1100
+ "yield_arg" => {
1101
+ "Ruby" => "yield(42)",
1102
+ "ParseTree" => [:yield, [:lit, 42]],
1103
+ },
1104
+
1105
+ "yield_args" => {
1106
+ "Ruby" => "yield(42, 24)",
1107
+ "ParseTree" => [:yield, [:array, [:lit, 42], [:lit, 24]]],
1108
+ },
1109
+
1110
+ "zarray" => {
1111
+ "Ruby" => "a = []",
1112
+ "ParseTree" => [:lasgn, :a, [:zarray]],
1113
+ },
1114
+
1115
+ "zsuper" => {
1116
+ "Ruby" => "def x\n super\nend",
1117
+ "ParseTree" => [:defn, :x, [:scope, [:block, [:args], [:zsuper]]]],
1118
+ },
1119
+ }
1120
+
1121
+ # def test_audit_nodes
1122
+ # # TODO: audit @@testcases.keys against node list - do two way audit, rename everything
1123
+ # nodes = ParseTree::NODE_NAMES.map { |s| s.to_s }.sort
1124
+ # tested = @@testcases.keys.map { |s| s.to_s }.sort
1125
+ # if processor.respond_to? :unsupported then
1126
+ # nodes -= processor.unsupported
1127
+ # else
1128
+ # SexpProcessor.new.unsupported
1129
+ # # HACK
1130
+ # nodes -= [:alloca, :argspush, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method].map { |s| s.to_s }
1131
+ # end
1132
+
1133
+ # untested = nodes-tested
1134
+
1135
+ # puts
1136
+ # p :untested_nodes => untested, :extra_nodes => tested-nodes
1137
+
1138
+ # untested.each do |node|
1139
+ # puts %(
1140
+ # "#{node}" => {
1141
+ # "Ruby" => "XXX",
1142
+ # "ParseTree" => [],
1143
+ # },
1144
+ # )
1145
+ # end
1146
+
1147
+ # flunk
1148
+ # end
1149
+
1150
+ def self.previous(key, extra=0)
1151
+ idx = @@testcase_order.index(key)-1-extra
1152
+ case key
1153
+ when "RubyToRubyC" then
1154
+ idx -= 1
1155
+ end
1156
+ @@testcase_order[idx]
1157
+ end
1158
+
1159
+ # # lets us used unprocessed :self outside of tests, called when subclassed
1160
+ # def self.clone_same
1161
+ # @@testcases.each do |node, data|
1162
+ # data.each do |key, val|
1163
+ # if val == :same then
1164
+ # prev_key = self.previous(key)
1165
+ # data[key] = data[prev_key].deep_clone
1166
+ # end
1167
+ # end
1168
+ # end
1169
+ # end
1170
+
1171
+ def self.inherited(c)
1172
+ output_name = c.name.to_s.sub(/^Test/, '')
1173
+ raise "Unknown class #{c}" unless @@testcase_order.include? output_name
1174
+
1175
+ input_name = self.previous(output_name)
1176
+
1177
+ @@testcases.each do |node, data|
1178
+ next if [:skip, :unsupported].include? data[input_name]
1179
+ next if data[output_name] == :skip
1180
+
1181
+ c.send(:define_method, "test_#{node}".intern) do
1182
+ flunk "Processor is nil" if processor.nil?
1183
+ assert data.has_key?(input_name), "Unknown input data"
1184
+ unless data.has_key?(output_name) then
1185
+ $stderr.puts "add_test(#{node.inspect}, :same)"
1186
+ end
1187
+ assert data.has_key?(output_name), "Missing test data: #{self.class} #{node}"
1188
+ input = data[input_name].deep_clone
1189
+
1190
+ expected = if data[output_name] == :same then
1191
+ input
1192
+ else
1193
+ data[output_name]
1194
+ end.deep_clone
1195
+
1196
+ case expected
1197
+ when :unsupported then
1198
+ assert_raises(UnsupportedNodeError) do
1199
+ processor.process(input)
1200
+ end
1201
+ else
1202
+ extra_expected = []
1203
+ extra_input = []
1204
+
1205
+ _, expected, extra_expected = *expected if Array === expected and expected.first == :defx
1206
+ _, input, extra_input = *input if Array === input and input.first == :defx
1207
+
1208
+ debug = input.deep_clone
1209
+ $-w = nil if node == "match"
1210
+ assert_equal expected, processor.process(input), "failed on input: #{debug.inspect}"
1211
+ $-w = true if node == "match"
1212
+ extra_input.each do |input| processor.process(input) end
1213
+ extra = processor.extra_methods rescue []
1214
+ assert_equal extra_expected, extra
1215
+ end
1216
+ end
1217
+ end
1218
+ end
1219
+
1220
+ undef_method :default_test
1221
+ end