ParseTree 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/sexp.rb CHANGED
@@ -1,4 +1,3 @@
1
- require 'parse_tree'
2
1
 
3
2
  $TESTING ||= false # unless defined $TESTING
4
3
 
@@ -26,6 +25,7 @@ class Sexp < Array # ZenTest FULL
26
25
  # of +klass+ until a method definition is found.
27
26
 
28
27
  def self.for(klass, method = nil, walk_ancestors = false)
28
+ require 'parse_tree'
29
29
  sexp = if walk_ancestors and method then
30
30
  klass.ancestors.each do |klass|
31
31
  sexp = ParseTree.translate klass, method
@@ -137,13 +137,12 @@ class SexpProcessor
137
137
  @warn_on_default = true
138
138
  @auto_shift_type = false
139
139
  @strict = false
140
- @unsupported = [:alloca, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method] # internal nodes that you can't get to
140
+ @unsupported = [:alloca, :cfunc, :cref, :ifunc, :last, :memo, :newline, :opt_n, :method] # internal nodes that you can't get to
141
141
  @unsupported_checked = false
142
142
  @debug = {}
143
143
  @expected = Sexp
144
144
  @require_empty = true
145
145
  @exceptions = {}
146
- @process_level = 0
147
146
 
148
147
  # we do this on an instance basis so we can subclass it for
149
148
  # different processors.
@@ -170,15 +169,19 @@ class SexpProcessor
170
169
  end
171
170
 
172
171
  def rewrite(exp)
172
+ type = exp.first
173
+
174
+ self.context.unshift type # FIX: first one doubles up because process already unshifted -- look at moving initial rewrite up above
173
175
  exp.map! { |sub| Array === sub ? rewrite(sub) : sub }
174
176
 
175
- type = exp.first
176
177
  begin
177
178
  meth = @rewriters[type]
178
179
  exp = self.send(meth, exp) if meth
179
180
  old_type, type = type, exp.first
180
181
  end until old_type == type
181
182
 
183
+ self.context.shift
184
+
182
185
  exp
183
186
  end
184
187
 
@@ -190,8 +193,6 @@ class SexpProcessor
190
193
  def process(exp)
191
194
  return nil if exp.nil?
192
195
 
193
- @process_level += 1
194
-
195
196
  unless @unsupported_checked then
196
197
  m = public_methods.grep(/^process_/) { |o| o.sub(/^process_/, '').intern }
197
198
  supported = m - (m - @unsupported)
@@ -207,7 +208,7 @@ class SexpProcessor
207
208
  raise "type should be a Symbol, not: #{exp.first.inspect}" unless
208
209
  Symbol === type
209
210
 
210
- @context.unshift type
211
+ self.context.unshift type
211
212
 
212
213
  if @debug.has_key? type then
213
214
  str = exp.inspect
@@ -220,7 +221,7 @@ class SexpProcessor
220
221
 
221
222
  raise UnsupportedNodeError, "'#{type}' is not a supported node type" if @unsupported.include? type
222
223
 
223
- exp = self.rewrite(exp) if @process_level == 1
224
+ exp = self.rewrite(exp) if self.context.size == 1
224
225
 
225
226
  if @debug.has_key? type then
226
227
  str = exp.inspect
@@ -276,9 +277,7 @@ class SexpProcessor
276
277
  end
277
278
  end
278
279
 
279
- @process_level -= 1
280
-
281
- @context.shift
280
+ self.context.shift
282
281
  result
283
282
  end
284
283
 
@@ -291,7 +290,7 @@ class SexpProcessor
291
290
 
292
291
  def assert_type(list, typ)
293
292
  raise SexpTypeError, "Expected type #{typ.inspect} in #{list.inspect}" if
294
- list.first != typ
293
+ not Array === list or list.first != typ
295
294
  end
296
295
 
297
296
  def error_handler(type, exp=nil) # :nodoc:
data/lib/unified_ruby.rb CHANGED
@@ -105,11 +105,17 @@ module UnifiedRuby
105
105
  end
106
106
 
107
107
  def rewrite_defs(exp)
108
- # move args up
109
- args = exp.scope.block.args(true) rescue nil
110
- exp.insert 3, args if args
108
+ receiver = exp.delete_at 1
111
109
 
112
- exp
110
+ # TODO: I think this would be better as rewrite_scope, but that breaks others
111
+ exp = s(exp.shift, exp.shift,
112
+ s(:scope,
113
+ s(:block, exp.scope.args))) if exp.scope.args
114
+
115
+ result = rewrite_defn(exp)
116
+ result.insert 1, receiver
117
+
118
+ result
113
119
  end
114
120
 
115
121
  def rewrite_dmethod(exp)
@@ -180,3 +186,11 @@ module UnifiedRuby
180
186
  rewrite_fcall(exp)
181
187
  end
182
188
  end
189
+
190
+ ##
191
+ # Quick and easy SexpProcessor that unified the sexp structure.
192
+
193
+ class Unifier < SexpProcessor
194
+ include UnifiedRuby
195
+ end
196
+
data/test/pt_testcase.rb CHANGED
@@ -4,6 +4,9 @@ require 'test/unit/testcase'
4
4
  require 'sexp_processor' # for deep_clone
5
5
  require 'unique'
6
6
 
7
+ # key:
8
+ # wwtt = what were they thinking?
9
+
7
10
  class Examples
8
11
  attr_reader :reader
9
12
  attr_writer :writer
@@ -71,12 +74,26 @@ class ParseTreeTestCase < Test::Unit::TestCase
71
74
  "Ruby2Ruby" => "class X\n alias_method :y, :x\nend",
72
75
  },
73
76
 
77
+ "alias_ugh" => {
78
+ "Ruby" => "class X\n alias y x\nend",
79
+ "ParseTree" => [:class, :X, nil,
80
+ [:scope, [:alias, [:lit, :y], [:lit, :x]]]],
81
+ "Ruby2Ruby" => "class X\n alias_method :y, :x\nend",
82
+ },
83
+
74
84
  "and" => {
75
85
  "Ruby" => "(a and b)",
76
86
  "ParseTree" => [:and, [:vcall, :a], [:vcall, :b]],
77
87
  },
78
88
 
79
- "argscat" => {
89
+ "argscat_inside" => {
90
+ "Ruby" => "a = [b, *c]",
91
+ "ParseTree" => [:lasgn, :a,
92
+ [:argscat, [:array, [:vcall, :b]], [:vcall, :c]]],
93
+ "Ruby2Ruby" => "a = b, *c",
94
+ },
95
+
96
+ "argscat_svalue" => {
80
97
  "Ruby" => "a = b, c, *d",
81
98
  "ParseTree" => [:lasgn, :a,
82
99
  [:svalue,
@@ -98,6 +115,14 @@ class ParseTreeTestCase < Test::Unit::TestCase
98
115
  "ParseTree" => [:array, [:lit, 1], [:lit, :b], [:str, "c"]],
99
116
  },
100
117
 
118
+ "array_pct_W" => {
119
+ "Ruby" => "%W[--remove #\{@gem_repo}]",
120
+ "ParseTree" => [:array,
121
+ [:str, "--remove"],
122
+ [:dstr, "", [:evstr, [:ivar, :@gem_repo]]]],
123
+ "Ruby2Ruby" => "[\"--remove\", \"#\{@gem_repo}\"]",
124
+ },
125
+
101
126
  "attrasgn" => {
102
127
  "Ruby" => "y = 0\n42.method = y\n",
103
128
  "ParseTree" => [:block,
@@ -130,8 +155,14 @@ class ParseTreeTestCase < Test::Unit::TestCase
130
155
  "ParseTree" => [:begin, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
131
156
  },
132
157
 
158
+ "begin_def" => {
159
+ "Ruby" => "def m\n begin\n\n end\nend",
160
+ "ParseTree" => [:defn, :m, [:scope, [:block, [:args], [:nil]]]],
161
+ "Ruby2Ruby" => "def m\n # do nothing\nend",
162
+ },
163
+
133
164
  "begin_rescue_ensure" => {
134
- "Ruby" => "begin\n rescue\n # do nothing\n ensure\n nil\nend",
165
+ "Ruby" => "begin\nrescue\n # do nothing\nensure\n nil\nend",
135
166
  "ParseTree" => [:begin,
136
167
  [:ensure,
137
168
  [:rescue,
@@ -139,6 +170,18 @@ class ParseTreeTestCase < Test::Unit::TestCase
139
170
  [:nil]]]
140
171
  },
141
172
 
173
+ "begin_rescue_twice" => { # testing block/begin processing really
174
+ "Ruby" => "begin\nrescue => mes\n # do nothing\nend\nbegin\nrescue => mes\n # do nothing\nend\n",
175
+ "ParseTree" => [:block,
176
+ [:rescue,
177
+ [:resbody, nil,
178
+ [:lasgn, :mes, [:gvar, :$!]]]],
179
+ [:begin,
180
+ [:rescue,
181
+ [:resbody, nil,
182
+ [:lasgn, :mes, [:gvar, :$!]]]]]],
183
+ },
184
+
142
185
  "block_lasgn" => {
143
186
  "Ruby" => "x = (y = 1\n(y + 2))",
144
187
  "ParseTree" => [:lasgn, :x,
@@ -147,9 +190,23 @@ class ParseTreeTestCase < Test::Unit::TestCase
147
190
  [:call, [:lvar, :y], :+, [:array, [:lit, 2]]]]],
148
191
  },
149
192
 
150
- "block_pass" => {
151
- "Ruby" => "a(&b)",
152
- "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]],
193
+ "block_mystery_block" => { # FIX: I don't like that extra return
194
+ "Ruby" => "a(b) do\n if b then\n true\n else\n c = false\n d { |x| c = true }\n c\n \n end\nend",
195
+ "ParseTree" => [:iter,
196
+ [:fcall, :a, [:array, [:vcall, :b]]],
197
+ nil,
198
+ [:block,
199
+ [:dasgn_curr, :c],
200
+ [:if,
201
+ [:vcall, :b],
202
+ [:true],
203
+ [:block,
204
+ [:dasgn_curr, :c, [:false]],
205
+ [:iter,
206
+ [:fcall, :d],
207
+ [:dasgn_curr, :x],
208
+ [:dasgn, :c, [:true]]],
209
+ [:dvar, :c]]]]],
153
210
  },
154
211
 
155
212
  "block_pass_args_and_splat" => {
@@ -165,6 +222,46 @@ class ParseTreeTestCase < Test::Unit::TestCase
165
222
  [:argscat, [:array, [:lit, 42]], [:lvar, :args]]]]]]],
166
223
  },
167
224
 
225
+ "block_pass_call_0" => {
226
+ "Ruby" => "a.b(&c)",
227
+ "ParseTree" => [:block_pass, [:vcall, :c], [:call, [:vcall, :a], :b]],
228
+ },
229
+
230
+ "block_pass_call_1" => {
231
+ "Ruby" => "a.b(4, &c)",
232
+ "ParseTree" => [:block_pass,
233
+ [:vcall, :c],
234
+ [:call, [:vcall, :a], :b, [:array, [:lit, 4]]]],
235
+ },
236
+
237
+ "block_pass_call_n" => {
238
+ "Ruby" => "a.b(1, 2, 3, &c)",
239
+ "ParseTree" => [:block_pass,
240
+ [:vcall, :c],
241
+ [:call, [:vcall, :a], :b,
242
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]],
243
+ },
244
+
245
+ "block_pass_fcall_0" => {
246
+ "Ruby" => "a(&b)",
247
+ "ParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]],
248
+ },
249
+
250
+ "block_pass_fcall_1" => {
251
+ "Ruby" => "a(4, &b)",
252
+ "ParseTree" => [:block_pass,
253
+ [:vcall, :b],
254
+ [:fcall, :a, [:array, [:lit, 4]]]],
255
+ },
256
+
257
+ "block_pass_fcall_n" => {
258
+ "Ruby" => "a(1, 2, 3, &b)",
259
+ "ParseTree" => [:block_pass,
260
+ [:vcall, :b],
261
+ [:fcall, :a,
262
+ [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]],
263
+ },
264
+
168
265
  "block_pass_omgwtf" => {
169
266
  "Ruby" => "define_attr_method(:x, :sequence_name, &Proc.new { |*args| nil })",
170
267
  "ParseTree" => [:block_pass,
@@ -188,6 +285,52 @@ class ParseTreeTestCase < Test::Unit::TestCase
188
285
  [:fcall, :other, [:splat, [:lvar, :args]]]]]]],
189
286
  },
190
287
 
288
+ "block_pass_thingy" => {
289
+ "Ruby" => "r.read_body(dest, &block)",
290
+ "ParseTree" => [:block_pass,
291
+ [:vcall, :block],
292
+ [:call, [:vcall, :r], :read_body,
293
+ [:array, [:vcall, :dest]]]],
294
+ },
295
+
296
+ "block_stmt_after" => {
297
+ "Ruby" => "def f\n begin\n b\n rescue\n c\n end\n\n d\nend",
298
+ "ParseTree" => [:defn,
299
+ :f,
300
+ [:scope,
301
+ [:block,
302
+ [:args],
303
+ [:rescue, [:vcall, :b], [:resbody, nil, [:vcall, :c]]],
304
+ [:vcall, :d]]]],
305
+ "Ruby2Ruby" => "def f\n b rescue c\n d\nend",
306
+ },
307
+
308
+ "block_stmt_before" => {
309
+ "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\nend",
310
+ "ParseTree" => [:defn,
311
+ :f,
312
+ [:scope,
313
+ [:block,
314
+ [:args],
315
+ [:vcall, :a],
316
+ [:begin,
317
+ [:rescue, [:vcall, :b],
318
+ [:resbody, nil, [:vcall, :c]]]]]]],
319
+ },
320
+
321
+ "block_stmt_both" => {
322
+ "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\n d\nend",
323
+ "ParseTree" => [:defn,
324
+ :f,
325
+ [:scope,
326
+ [:block,
327
+ [:args],
328
+ [:vcall, :a],
329
+ [:rescue, [:vcall, :b], [:resbody, nil, [:vcall, :c]]],
330
+ [:vcall, :d]]]],
331
+ "Ruby2Ruby" => "def f\n a\n b rescue c\n d\nend",
332
+ },
333
+
191
334
  "bmethod" => {
192
335
  "Ruby" => [Examples, :unsplatted],
193
336
  "ParseTree" => [:defn,
@@ -238,8 +381,41 @@ class ParseTreeTestCase < Test::Unit::TestCase
238
381
  },
239
382
 
240
383
  "call_arglist" => {
241
- "Ruby" => "puts(42)",
242
- "ParseTree" => [:fcall, :puts, [:array, [:lit, 42]]],
384
+ "Ruby" => "o.puts(42)",
385
+ "ParseTree" => [:call, [:vcall, :o], :puts, [:array, [:lit, 42]]],
386
+ },
387
+
388
+ "call_arglist_hash" => {
389
+ "Ruby" => "o.m(:a => 1, :b => 2)",
390
+ "ParseTree" => [:call,
391
+ [:vcall, :o], :m,
392
+ [:array,
393
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]],
394
+ },
395
+
396
+ "call_arglist_norm_hash" => {
397
+ "Ruby" => "o.m(42, :a => 1, :b => 2)",
398
+ "ParseTree" => [:call,
399
+ [:vcall, :o], :m,
400
+ [:array,
401
+ [:lit, 42],
402
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]],
403
+ },
404
+
405
+ "call_arglist_norm_hash_splat" => {
406
+ "Ruby" => "o.m(42, :a => 1, :b => 2, *c)",
407
+ "ParseTree" => [:call,
408
+ [:vcall, :o], :m,
409
+ [:argscat,
410
+ [:array,
411
+ [:lit, 42],
412
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]],
413
+ [:vcall, :c]]],
414
+ },
415
+
416
+ "call_command" => {
417
+ "Ruby" => "1.b(c)",
418
+ "ParseTree" => [:call, [:lit, 1], :b, [:array, [:vcall, :c]]],
243
419
  },
244
420
 
245
421
  "call_expr" => {
@@ -255,6 +431,19 @@ class ParseTreeTestCase < Test::Unit::TestCase
255
431
  "ParseTree" => [:call, [:vcall, :a], :[], [:array, [:lit, 42]]],
256
432
  },
257
433
 
434
+ "call_index_no_args" => {
435
+ "Ruby" => "a[]",
436
+ "ParseTree" => [:call, [:vcall, :a], :[]],
437
+ },
438
+
439
+ "call_unary_neg" => {
440
+ "Ruby" => "-2**31",
441
+ "ParseTree" => [:call,
442
+ [:call, [:lit, 2], :**, [:array, [:lit, 31]]],
443
+ :-@],
444
+ "Ruby2Ruby" => "-(2 ** 31)",
445
+ },
446
+
258
447
  "case" => {
259
448
  "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",
260
449
  "ParseTree" => [:block,
@@ -310,17 +499,38 @@ class ParseTreeTestCase < Test::Unit::TestCase
310
499
  [:lasgn, :result, [:lit, 7]]]]
311
500
  },
312
501
 
502
+ "case_nested_inner_no_expr" => {
503
+ "Ruby" => "case a\nwhen b then\n case\n when (d and e) then\n f\n else\n # do nothing\n end\nelse\n # do nothing\nend",
504
+ "ParseTree" => [:case, [:vcall, :a],
505
+ [:when, [:array, [:vcall, :b]],
506
+ [:case, nil,
507
+ [:when, [:array, [:and, [:vcall, :d], [:vcall, :e]]],
508
+ [:vcall, :f]],
509
+ nil]],
510
+ nil],
511
+ },
512
+
313
513
  "case_no_expr" => { # TODO: nested
314
- "Ruby" => "case\nwhen 1 then\n :a\nwhen 2 then\n :b\nelse\n :c\nend",
514
+ "Ruby" => "case\nwhen (a == 1) then\n :a\nwhen (a == 2) then\n :b\nelse\n :c\nend",
315
515
  "ParseTree" => [:case, nil,
316
516
  [:when,
317
- [:array, [:lit, 1]],
517
+ [:array, [:call, [:vcall, :a], :==, [:array, [:lit, 1]]]],
318
518
  [:lit, :a]],
319
519
  [:when,
320
- [:array, [:lit, 2]], [:lit, :b]],
520
+ [:array, [:call, [:vcall, :a], :==, [:array, [:lit, 2]]]],
521
+ [:lit, :b]],
321
522
  [:lit, :c]],
322
523
  },
323
524
 
525
+ "case_splat" => {
526
+ "Ruby" => "case a\nwhen :b, *c then\n d\nelse\n e\nend",
527
+ "ParseTree" => [:case, [:vcall, :a],
528
+ [:when,
529
+ [:array, [:lit, :b], [:when, [:vcall, :c], nil]], # wtf?
530
+ [:vcall, :d]],
531
+ [:vcall, :e]],
532
+ },
533
+
324
534
  "cdecl" => {
325
535
  "Ruby" => "X = 42",
326
536
  "ParseTree" => [:cdecl, :X, [:lit, 42]],
@@ -416,6 +626,52 @@ class ParseTreeTestCase < Test::Unit::TestCase
416
626
  "ParseTree" => [:if, [:true], nil, [:if, [:false], [:return], nil]],
417
627
  },
418
628
 
629
+ "conditional_post_if" => {
630
+ "Ruby" => "a if b",
631
+ "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil],
632
+ },
633
+
634
+ "conditional_post_if_not" => {
635
+ "Ruby" => "a if not b",
636
+ "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]],
637
+ "Ruby2Ruby" => "a unless b"
638
+ },
639
+
640
+ "conditional_post_unless" => {
641
+ "Ruby" => "a unless b",
642
+ "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]],
643
+ },
644
+
645
+ "conditional_post_unless_not" => {
646
+ "Ruby" => "a unless not b",
647
+ "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil],
648
+ "Ruby2Ruby" => "a if b"
649
+ },
650
+
651
+ "conditional_pre_if" => {
652
+ "Ruby" => "if b then a end",
653
+ "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil],
654
+ "Ruby2Ruby" => "a if b"
655
+ },
656
+
657
+ "conditional_pre_if_not" => {
658
+ "Ruby" => "if not b then a end",
659
+ "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]],
660
+ "Ruby2Ruby" => "a unless b"
661
+ },
662
+
663
+ "conditional_pre_unless" => {
664
+ "Ruby" => "unless b then a end",
665
+ "ParseTree" => [:if, [:vcall, :b], nil, [:vcall, :a]],
666
+ "Ruby2Ruby" => "a unless b"
667
+ },
668
+
669
+ "conditional_pre_unless_not" => {
670
+ "Ruby" => "unless not b then a end",
671
+ "ParseTree" => [:if, [:vcall, :b], [:vcall, :a], nil],
672
+ "Ruby2Ruby" => "a if b"
673
+ },
674
+
419
675
  "const" => {
420
676
  "Ruby" => "X",
421
677
  "ParseTree" => [:const, :X],
@@ -433,22 +689,81 @@ class ParseTreeTestCase < Test::Unit::TestCase
433
689
  [:block, [:args], [:cvasgn, :@@blah, [:lit, 1]]]]]
434
690
  },
435
691
 
692
+ "cvasgn_cls_method" => {
693
+ "Ruby" => "def self.quiet_mode=(boolean)\n @@quiet_mode = boolean\nend",
694
+ "ParseTree" => [:defs, [:self], :quiet_mode=, [:scope, [:block, [:args, :boolean], [:cvasgn, :@@quiet_mode, [:lvar, :boolean]]]]],
695
+ },
696
+
436
697
  "cvdecl" => {
437
698
  "Ruby" => "class X\n @@blah = 1\nend",
438
699
  "ParseTree" => [:class, :X, nil,
439
700
  [:scope, [:cvdecl, :@@blah, [:lit, 1]]]],
440
701
  },
441
702
 
442
- "dasgn" => {
443
- "Ruby" => "a.each { |x| b.each { |y| x = (x + 1) } }",
703
+ "dasgn_0" => {
704
+ "Ruby" => "a.each { |x| b.each { |y| x = (x + 1) } if true }",
444
705
  "ParseTree" => [:iter,
445
706
  [:call, [:vcall, :a], :each],
446
707
  [:dasgn_curr, :x],
447
- [:iter,
448
- [:call, [:vcall, :b], :each],
449
- [:dasgn_curr, :y],
450
- [:dasgn, :x,
451
- [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]],
708
+ [:if, [:true],
709
+ [:iter,
710
+ [:call, [:vcall, :b], :each],
711
+ [:dasgn_curr, :y],
712
+ [:dasgn, :x,
713
+ [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
714
+ nil]],
715
+ },
716
+
717
+ "dasgn_1" => { # without mystery block / dasgn_curr
718
+ "Ruby" => "a.each { |x| b.each { |y| c = (c + 1) } if true }",
719
+ "ParseTree" => [:iter,
720
+ [:call, [:vcall, :a], :each],
721
+ [:dasgn_curr, :x],
722
+ [:if, [:true],
723
+ [:iter,
724
+ [:call, [:vcall, :b], :each],
725
+ [:dasgn_curr, :y],
726
+ [:dasgn_curr, :c,
727
+ [:call, [:dvar, :c], :+, [:array, [:lit, 1]]]]],
728
+ nil]],
729
+ },
730
+
731
+ "dasgn_2" => { # WITH mystery block / dasgn_curr
732
+ "Ruby" => "a.each do |x|\n if true then\n c = 0\n b.each { |y| c = (c + 1) }\n \n end\nend", # FIX: hate that extra newline!
733
+ "ParseTree" => [:iter,
734
+ [:call, [:vcall, :a], :each],
735
+ [:dasgn_curr, :x],
736
+ [:block,
737
+ [:dasgn_curr, :c],
738
+ [:if, [:true],
739
+ [:block,
740
+ [:dasgn_curr, :c, [:lit, 0]],
741
+ [:iter,
742
+ [:call, [:vcall, :b], :each],
743
+ [:dasgn_curr, :y],
744
+ [:dasgn, :c,
745
+ [:call, [:dvar, :c], :+, [:array, [:lit, 1]]]]]],
746
+ nil]]],
747
+ },
748
+
749
+ "dasgn_icky" => { # WITH mystery block / dasgn_curr
750
+ "Ruby" => "a do\n v = nil\n assert_block(full_message) do\n begin\n yield\n rescue Exception => v\n break\n end\n end\nend",
751
+ "ParseTree" => [:iter,
752
+ [:fcall, :a],
753
+ nil,
754
+ [:block,
755
+ [:dasgn_curr, :v],
756
+ [:dasgn_curr, :v, [:nil]],
757
+ [:iter,
758
+ [:fcall, :assert_block,
759
+ [:array, [:vcall, :full_message]]],
760
+ nil,
761
+ [:begin,
762
+ [:rescue,
763
+ [:yield],
764
+ [:resbody,
765
+ [:array, [:const, :Exception]],
766
+ [:block, [:dasgn, :v, [:gvar, :$!]], [:break]]]]]]]],
452
767
  },
453
768
 
454
769
  "dasgn_curr" => {
@@ -462,32 +777,122 @@ class ParseTreeTestCase < Test::Unit::TestCase
462
777
  [:dasgn_curr, :b, [:dasgn_curr, :a, [:dvar, :x]]]]],
463
778
  },
464
779
 
780
+ "dasgn_mixed" => {
781
+ "Ruby" => "t = 0\nns.each { |n| t += n }\n",
782
+ "ParseTree" => [:block,
783
+ [:lasgn, :t, [:lit, 0]],
784
+ [:iter,
785
+ [:call, [:vcall, :ns], :each],
786
+ [:dasgn_curr, :n],
787
+ [:lasgn, :t,
788
+ [:call, [:lvar, :t], :+, [:array, [:dvar, :n]]]]]],
789
+ "Ruby2Ruby" => "t = 0\nns.each { |n| t = (t + n) }\n",
790
+ },
791
+
465
792
  "defined" => {
466
793
  "Ruby" => "defined? $x",
467
794
  "ParseTree" => [:defined, [:gvar, :$x]],
468
795
  },
469
796
 
470
- "defn_args" => {
797
+ "defn_args_mand_opt_block" => {
798
+ "Ruby" => "def x(a, b = 42, &d)\n p(a, b, d)\nend",
799
+ "ParseTree" => [:defn, :x,
800
+ [:scope,
801
+ [:block,
802
+ [:args, :a, :b,
803
+ [:block, [:lasgn, :b, [:lit, 42]]]],
804
+ [:block_arg, :d],
805
+ [:fcall, :p,
806
+ [:array, [:lvar, :a], [:lvar, :b], [:lvar, :d]]]]]]
807
+ },
808
+
809
+ "defn_args_mand_opt_splat" => {
810
+ "Ruby" => "def x(a, b = 42, *c)\n p(a, b, c)\nend",
811
+ "ParseTree" => [:defn, :x,
812
+ [:scope,
813
+ [:block,
814
+ [:args, :a, :b, :"*c",
815
+ [:block, [:lasgn, :b, [:lit, 42]]]],
816
+ [:fcall, :p,
817
+ [:array, [:lvar, :a], [:lvar, :b], [:lvar, :c]]]]]]
818
+ },
819
+
820
+ "defn_args_mand_opt_splat_block" => {
471
821
  "Ruby" => "def x(a, b = 42, \*c, &d)\n p(a, b, c, d)\nend",
472
822
  "ParseTree" => [:defn, :x,
473
823
  [:scope,
474
824
  [:block,
475
825
  [:args, :a, :b, "*c".intern, # s->e
476
826
  [:block, [:lasgn, :b, [:lit, 42]]]],
477
- [:block_arg, :d],
827
+ [:block_arg, :d],
478
828
  [:fcall, :p,
479
- [:array, [:lvar, :a], [:lvar, :b],
829
+ [:array,
830
+ [:lvar, :a], [:lvar, :b],
480
831
  [:lvar, :c], [:lvar, :d]]]]]]
481
832
  },
482
833
 
834
+ "defn_args_mand_opt_splat_no_name" => {
835
+ "Ruby" => "def x(a, b = 42, *)\n p(a, b)\nend",
836
+ "ParseTree" => [:defn, :x,
837
+ [:scope,
838
+ [:block,
839
+ [:args, :a, :b, :"*",
840
+ [:block, [:lasgn, :b, [:lit, 42]]]],
841
+ [:fcall, :p,
842
+ [:array, [:lvar, :a], [:lvar, :b]]]]]]
843
+ },
844
+
845
+ "defn_args_opt_block" => {
846
+ "Ruby" => "def x(b = 42, &d)\n p(b, d)\nend",
847
+ "ParseTree" => [:defn, :x,
848
+ [:scope,
849
+ [:block,
850
+ [:args, :b,
851
+ [:block, [:lasgn, :b, [:lit, 42]]]],
852
+ [:block_arg, :d],
853
+ [:fcall, :p,
854
+ [:array, [:lvar, :b], [:lvar, :d]]]]]]
855
+ },
856
+
857
+ "defn_args_opt_splat_no_name" => {
858
+ "Ruby" => "def x(b = 42, *)\n p(b)\nend",
859
+ "ParseTree" => [:defn, :x,
860
+ [:scope,
861
+ [:block,
862
+ [:args, :b, :"*",
863
+ [:block, [:lasgn, :b, [:lit, 42]]]],
864
+ [:fcall, :p,
865
+ [:array, [:lvar, :b]]]]]]
866
+ },
867
+
483
868
  "defn_empty" => {
484
869
  "Ruby" => "def empty\n # do nothing\nend",
485
870
  "ParseTree" => [:defn, :empty, [:scope, [:block, [:args], [:nil]]]],
486
871
  },
487
872
 
488
- "defn_is_something" => {
489
- "Ruby" => "def something?\n # do nothing\nend",
490
- "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
873
+ "defn_empty_args" => {
874
+ "Ruby" => "def empty(*)\n # do nothing\nend",
875
+ "ParseTree" => [:defn, :empty, [:scope, [:block, [:args, :*], [:nil]]]],
876
+ },
877
+
878
+ "defn_lvar_boundary" => { # FIX: add do nothing comment to block
879
+ "Ruby" => "mes = 42\ndef instantiate_all\n Thread.new do\n begin\n rescue RuntimeError => mes\n puts(mes)\n end\n end\nend\n",
880
+ "ParseTree" => [:block,
881
+ [:lasgn, :mes, [:lit, 42]],
882
+ [:defn, :instantiate_all,
883
+ [:scope,
884
+ [:block,
885
+ [:args],
886
+ [:iter,
887
+ [:call, [:const, :Thread], :new],
888
+ nil,
889
+ [:begin,
890
+ [:rescue,
891
+ [:resbody,
892
+ [:array, [:const, :RuntimeError]],
893
+ [:block,
894
+ [:dasgn_curr, :mes, [:gvar, :$!]],
895
+ [:fcall, :puts, [:array, [:dvar, :mes]]]]]]]]]]]],
491
896
  },
492
897
 
493
898
  "defn_optargs" => {
@@ -506,7 +911,7 @@ class ParseTreeTestCase < Test::Unit::TestCase
506
911
  },
507
912
 
508
913
  "defn_rescue" => {
509
- "Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid) rescue false\nend",
914
+ "Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid)\nrescue\n false\nend",
510
915
  "ParseTree" => [:defn, :eql?,
511
916
  [:scope,
512
917
  [:block,
@@ -517,6 +922,12 @@ class ParseTreeTestCase < Test::Unit::TestCase
517
922
  :==,
518
923
  [:array, [:call, [:lvar, :resource], :uuid]]],
519
924
  [:resbody, nil, [:false]]]]]],
925
+ "Ruby2Ruby" => "def eql?(resource)\n (self.uuid == resource.uuid) rescue false\nend",
926
+ },
927
+
928
+ "defn_something_eh" => {
929
+ "Ruby" => "def something?\n # do nothing\nend",
930
+ "ParseTree" => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
520
931
  },
521
932
 
522
933
  "defn_splat_no_name" => {
@@ -546,6 +957,29 @@ class ParseTreeTestCase < Test::Unit::TestCase
546
957
  [:call, [:lvar, :y], :+, [:array, [:lit, 1]]]]]],
547
958
  },
548
959
 
960
+ "defs_args_mand_opt_splat_block" => {
961
+ "Ruby" => "def self.x(a, b = 42, \*c, &d)\n (a + b)\nend",
962
+ "ParseTree" => [:defs, [:self], :x,
963
+ [:scope,
964
+ [:block,
965
+ [:args, :a, :b, :"*c",
966
+ [:block, [:lasgn, :b, [:lit, 42]]]],
967
+ [:block_arg, :d],
968
+ [:call, [:lvar, :a], :+, [:array, [:lvar, :b]]]]]],
969
+ },
970
+
971
+ "defs_empty" => {
972
+ "Ruby" => "def self.empty\n # do nothing\nend",
973
+ "ParseTree" => [:defs, [:self], :empty,
974
+ [:scope, [:args]]],
975
+ },
976
+
977
+ "defs_empty_args" => {
978
+ "Ruby" => "def self.empty(*)\n # do nothing\nend",
979
+ "ParseTree" => [:defs, [:self], :empty,
980
+ [:scope, [:args, :*]]],
981
+ },
982
+
549
983
  "dmethod" => {
550
984
  "Ruby" => [Examples, :dmethod_added],
551
985
  "ParseTree" => [:defn,
@@ -572,47 +1006,136 @@ class ParseTreeTestCase < Test::Unit::TestCase
572
1006
  "dregx" => {
573
1007
  "Ruby" => "/x#\{(1 + 1)}y/",
574
1008
  "ParseTree" => [:dregx, "x",
575
- [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
1009
+ [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]],
1010
+ },
1011
+
1012
+ "dregx_interp" => {
1013
+ "Ruby" => "/#\{@rakefile}/",
1014
+ "ParseTree" => [:dregx, '', [:evstr, [:ivar, :@rakefile]]],
1015
+ },
1016
+
1017
+ "dregx_n" => {
1018
+ "Ruby" => '/#{1}/n',
1019
+ "ParseTree" => [:dregx, '', [:evstr, [:lit, 1]], 16], # TODO: use consts
1020
+ "Ruby2Ruby" => "/#\{1}/", # HACK - need to support regexp flags
576
1021
  },
577
1022
 
578
1023
  "dregx_once" => {
579
1024
  "Ruby" => "/x#\{(1 + 1)}y/o",
580
1025
  "ParseTree" => [:dregx_once, "x",
581
- [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
1026
+ [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]],
1027
+ },
1028
+
1029
+ "dregx_once_n_interp" => {
1030
+ "Ruby" => "/#\{IAC}#\{SB}/no",
1031
+ "ParseTree" => [:dregx_once, '', [:evstr, [:const, :IAC]], [:evstr, [:const, :SB]], 16],
1032
+ "Ruby2Ruby" => "/#\{IAC}#\{SB}/o", # HACK
582
1033
  },
583
1034
 
584
1035
  "dstr" => {
585
1036
  "Ruby" => "argl = 1\n\"x#\{argl}y\"\n",
586
1037
  "ParseTree" => [:block,
587
1038
  [:lasgn, :argl, [:lit, 1]],
588
- [:dstr, "x", [:lvar, :argl],
1039
+ [:dstr, "x", [:evstr, [:lvar, :argl]],
589
1040
  [:str, "y"]]],
590
1041
  },
591
1042
 
1043
+ "dstr_2" => {
1044
+ "Ruby" => "argl = 1\n\"x#\{(\"%.2f\" % 3.14159)}y\"\n",
1045
+ "ParseTree" => [:block,
1046
+ [:lasgn, :argl, [:lit, 1]],
1047
+ [:dstr,
1048
+ "x",
1049
+ [:evstr, [:call, [:str, "%.2f"], :%, [:array, [:lit, 3.14159]]]],
1050
+ [:str, "y"]]],
1051
+ },
1052
+
1053
+ "dstr_3" => {
1054
+ "Ruby" => "max = 2\nargl = 1\n\"x#\{(\"%.#\{max}f\" % 3.14159)}y\"\n",
1055
+ "ParseTree" => [:block,
1056
+ [:lasgn, :max, [:lit, 2]],
1057
+ [:lasgn, :argl, [:lit, 1]],
1058
+ [:dstr,
1059
+ "x",
1060
+ [:evstr, [:call,
1061
+ [:dstr, "%.", [:evstr, [:lvar, :max]], [:str, "f"]],
1062
+ :%, [:array, [:lit, 3.14159]]]],
1063
+ [:str, "y"]]],
1064
+ },
1065
+
1066
+ "dstr_concat" => {
1067
+ "Ruby" => '"#{22}aa" "cd#{44}" "55" "#{66}"',
1068
+ "ParseTree" => [:dstr,
1069
+ "",
1070
+ [:evstr, [:lit, 22]],
1071
+ [:str, "aa"],
1072
+ [:str, "cd"],
1073
+ [:evstr, [:lit, 44]],
1074
+ [:str, "55"],
1075
+ [:evstr, [:lit, 66]]],
1076
+ "Ruby2Ruby" => '"#{22}aacd#{44}55#{66}"',
1077
+ },
1078
+
1079
+ "dstr_heredoc_yet_again" => {
1080
+ "Ruby" => "<<-EOF\ns1 '#\{RUBY_PLATFORM}' s2\n#\{__FILE__}\n EOF\n",
1081
+ "ParseTree" => [:dstr, "s1 '",
1082
+ [:evstr, [:const, :RUBY_PLATFORM]],
1083
+ [:str, "' s2\n"],
1084
+ [:str, "(string)"],
1085
+ [:str, "\n"]],
1086
+ "Ruby2Ruby" => "\"s1 '#\{RUBY_PLATFORM}' s2\\n(string)\\n\""
1087
+ },
1088
+
1089
+ "dstr_nest" => {
1090
+ "Ruby" => "%Q[before [#\{nest}] after]",
1091
+ "ParseTree" => [:dstr, "before [",
1092
+ [:evstr, [:vcall, :nest]], [:str, "] after"]],
1093
+ "Ruby2Ruby" => "\"before [#\{nest}] after\"",
1094
+ },
1095
+
1096
+ "dstr_str_lit_start" => {
1097
+ "Ruby" => '"#{"blah"}#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})"',
1098
+ "ParseTree" => [:dstr,
1099
+ "blah(string):",
1100
+ [:evstr, [:lit, 1]],
1101
+ [:str, ": warning: "],
1102
+ [:evstr, [:call, [:gvar, :$!], :message]],
1103
+ [:str, " ("],
1104
+ [:evstr, [:call, [:gvar, :$!], :class]],
1105
+ [:str, ")"]],
1106
+ "Ruby2Ruby" => '"blah(string):#{1}: warning: #{$!.message} (#{$!.class})"',
1107
+ },
1108
+
1109
+ "dstr_the_revenge" => {
1110
+ "Ruby" => '"before #{from} middle #{to} (#{__FILE__}:#{__LINE__})"',
1111
+ "ParseTree" => [:dstr,
1112
+ "before ",
1113
+ [:evstr, [:vcall, :from]],
1114
+ [:str, " middle "],
1115
+ [:evstr, [:vcall, :to]],
1116
+ [:str, " ("],
1117
+ [:str, "(string)"],
1118
+ [:str, ":"],
1119
+ [:evstr, [:lit, 1]],
1120
+ [:str, ")"]],
1121
+ "Ruby2Ruby" => '"before #{from} middle #{to} ((string):#{1})"',
1122
+ },
1123
+
592
1124
  "dsym" => {
593
1125
  "Ruby" => ":\"x#\{(1 + 1)}y\"",
594
1126
  "ParseTree" => [:dsym, "x",
595
- [:call, [:lit, 1], :+, [:array, [:lit, 1]]], [:str, "y"]],
1127
+ [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]], [:str, "y"]],
596
1128
  },
597
1129
 
598
1130
  "dxstr" => {
599
1131
  "Ruby" => "t = 5\n`touch #\{t}`\n",
600
1132
  "ParseTree" => [:block,
601
1133
  [:lasgn, :t, [:lit, 5]],
602
- [:dxstr, 'touch ', [:lvar, :t]]],
1134
+ [:dxstr, 'touch ', [:evstr, [:lvar, :t]]]],
603
1135
  },
604
1136
 
605
1137
  "ensure" => {
606
- "Ruby" => "begin
607
- (1 + 1)
608
- rescue SyntaxError => e1
609
- 2
610
- rescue Exception => e2
611
- 3
612
- else
613
- 4
614
- ensure
615
- 5
1138
+ "Ruby" => "begin\n (1 + 1)\nrescue SyntaxError => e1\n 2\nrescue Exception => e2\n 3\nelse\n 4\nensure\n 5
616
1139
  end",
617
1140
  "ParseTree" => [:begin,
618
1141
  [:ensure,
@@ -644,9 +1167,46 @@ end",
644
1167
  "Ruby2Ruby" => "def an_alias(x)\n (x + 1)\nend"
645
1168
  },
646
1169
 
647
- "fcall" => {
648
- "Ruby" => "p(4)",
649
- "ParseTree" => [:fcall, :p, [:array, [:lit, 4]]],
1170
+ "fcall_arglist" => {
1171
+ "Ruby" => "m(42)",
1172
+ "ParseTree" => [:fcall, :m, [:array, [:lit, 42]]],
1173
+ },
1174
+
1175
+ "fcall_arglist_hash" => {
1176
+ "Ruby" => "m(:a => 1, :b => 2)",
1177
+ "ParseTree" => [:fcall, :m,
1178
+ [:array,
1179
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]],
1180
+ },
1181
+
1182
+ "fcall_arglist_norm_hash" => {
1183
+ "Ruby" => "m(42, :a => 1, :b => 2)",
1184
+ "ParseTree" => [:fcall, :m,
1185
+ [:array,
1186
+ [:lit, 42],
1187
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]]],
1188
+ },
1189
+
1190
+ "fcall_arglist_norm_hash_splat" => {
1191
+ "Ruby" => "m(42, :a => 1, :b => 2, *c)",
1192
+ "ParseTree" => [:fcall, :m,
1193
+ [:argscat,
1194
+ [:array,
1195
+ [:lit, 42],
1196
+ [:hash, [:lit, :a], [:lit, 1], [:lit, :b], [:lit, 2]]],
1197
+ [:vcall, :c]]],
1198
+ },
1199
+
1200
+ "fcall_block" => {
1201
+ "Ruby" => "a(:b) { :c }",
1202
+ "ParseTree" => [:iter,
1203
+ [:fcall, :a, [:array, [:lit, :b]]], nil,
1204
+ [:lit, :c]],
1205
+ },
1206
+
1207
+ "fcall_keyword" => {
1208
+ "Ruby" => "42 if block_given?",
1209
+ "ParseTree" => [:if, [:fcall, :block_given?], [:lit, 42], nil],
650
1210
  },
651
1211
 
652
1212
  "flip2" => {
@@ -667,6 +1227,18 @@ end",
667
1227
  [:nil]]],
668
1228
  },
669
1229
 
1230
+ "flip2_method" => {
1231
+ "Ruby" => "if 1..2.a?(b) then
1232
+ nil
1233
+ end",
1234
+ "ParseTree" => [:if,
1235
+ [:flip2,
1236
+ [:lit, 1],
1237
+ [:call, [:lit, 2], :a?, [:array, [:vcall, :b]]]],
1238
+ [:nil],
1239
+ nil],
1240
+ },
1241
+
670
1242
  "flip3" => {
671
1243
  "Ruby" => "x = if ((i % 4) == 0)...((i % 3) == 0) then\n i\nelse\n nil\nend",
672
1244
  "ParseTree" => [:lasgn,
@@ -686,11 +1258,20 @@ end",
686
1258
  },
687
1259
 
688
1260
  "for" => {
689
- "Ruby" => "for o in ary\n puts(o)\nend\n",
690
- "ParseTree" => [:for, [:vcall, :ary], [:lasgn, :o],
1261
+ "Ruby" => "for o in ary do\n puts(o)\nend",
1262
+ "ParseTree" => [:for,
1263
+ [:vcall, :ary],
1264
+ [:lasgn, :o],
691
1265
  [:fcall, :puts, [:array, [:lvar, :o]]]],
692
1266
  },
693
1267
 
1268
+ "for_no_body" => {
1269
+ "Ruby" => "for i in (0..max) do\n # do nothing\nend",
1270
+ "ParseTree" => [:for,
1271
+ [:dot2, [:lit, 0], [:vcall, :max]],
1272
+ [:lasgn, :i]],
1273
+ },
1274
+
694
1275
  "gasgn" => {
695
1276
  "Ruby" => "$x = 42",
696
1277
  "ParseTree" => [:gasgn, :$x, [:lit, 42]],
@@ -706,6 +1287,16 @@ end",
706
1287
  "ParseTree" => [:gvar, :$x],
707
1288
  },
708
1289
 
1290
+ "gvar_underscore" => {
1291
+ "Ruby" => "$_",
1292
+ "ParseTree" => [:gvar, :$_],
1293
+ },
1294
+
1295
+ "gvar_underscore_blah" => {
1296
+ "Ruby" => "$__blah",
1297
+ "ParseTree" => [:gvar, :$__blah],
1298
+ },
1299
+
709
1300
  "hash" => {
710
1301
  "Ruby" => "{ 1 => 2, 3 => 4 }",
711
1302
  "ParseTree" => [:hash, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4]],
@@ -814,6 +1405,78 @@ end",
814
1405
  [:array, [:call, [:dvar, :y], :to_s]]]]]]],
815
1406
  },
816
1407
 
1408
+ "iteration7" => {
1409
+ "Ruby" => "a { |b, c| p(c) }",
1410
+ "ParseTree" => [:iter,
1411
+ [:fcall, :a],
1412
+ [:masgn,
1413
+ [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]]],
1414
+ [:fcall, :p, [:array, [:dvar, :c]]]],
1415
+ },
1416
+
1417
+ "iteration8" => {
1418
+ "Ruby" => "a { |b, c, *d| p(c) }",
1419
+ "ParseTree" => [:iter,
1420
+ [:fcall, :a],
1421
+ [:masgn,
1422
+ [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]],
1423
+ [:dasgn_curr, :d]],
1424
+ [:fcall, :p, [:array, [:dvar, :c]]]],
1425
+ },
1426
+
1427
+ "iteration9" => {
1428
+ "Ruby" => "a { |b, c, *| p(c) }",
1429
+ "ParseTree" => [:iter,
1430
+ [:fcall, :a],
1431
+ [:masgn,
1432
+ [:array, [:dasgn_curr, :b], [:dasgn_curr, :c]],
1433
+ [:splat]],
1434
+ [:fcall, :p, [:array, [:dvar, :c]]]],
1435
+ },
1436
+
1437
+ "iteration9" => {
1438
+ "Ruby" => "a { |*| p(c) }",
1439
+ "ParseTree" => [:iter,
1440
+ [:fcall, :a],
1441
+ [:masgn,
1442
+ [:splat]],
1443
+ [:fcall, :p, [:array, [:vcall, :c]]]],
1444
+ },
1445
+
1446
+ "iteration_dasgn_curr_dasgn_madness" => {
1447
+ "Ruby" => "as.each { |a|\n b += a.b(false) }",
1448
+ "ParseTree" => [:iter,
1449
+ [:call, [:vcall, :as], :each],
1450
+ [:dasgn_curr, :a],
1451
+ [:dasgn_curr,
1452
+ :b,
1453
+ [:call,
1454
+ [:dvar, :b],
1455
+ :+,
1456
+ [:array,
1457
+ [:call, [:dvar, :a], :b, [:array, [:false]]]]]]],
1458
+ "Ruby2Ruby" => "as.each { |a| b = (b + a.b(false)) }",
1459
+ },
1460
+
1461
+ "iteration_double_var" => {
1462
+ "Ruby" => "a do |x|\n b do |x| \n puts x\n end\nend",
1463
+ "ParseTree" => [:iter,
1464
+ [:fcall, :a],
1465
+ [:dasgn_curr, :x],
1466
+ [:iter,
1467
+ [:fcall, :b],
1468
+ [:dasgn, :x],
1469
+ [:fcall, :puts, [:array, [:dvar, :x]]]]],
1470
+ "Ruby2Ruby" => "a { |x| b { |x| puts(x) } }",
1471
+ },
1472
+
1473
+ "iteration_masgn" => {
1474
+ "Ruby" => "define_method(method) { |*args| }",
1475
+ "ParseTree" => [:iter,
1476
+ [:fcall, :define_method, [:array, [:vcall, :method]]],
1477
+ [:masgn, [:dasgn_curr, :args]]],
1478
+ },
1479
+
817
1480
  "ivar" => {
818
1481
  "Ruby" => [Examples, :reader],
819
1482
  "ParseTree" => [:defn, :reader, [:ivar, :@reader]],
@@ -822,9 +1485,10 @@ end",
822
1485
 
823
1486
  "lasgn_array" => {
824
1487
  "Ruby" => "var = [\"foo\", \"bar\"]",
825
- "ParseTree" => [:lasgn, :var, [:array,
826
- [:str, "foo"],
827
- [:str, "bar"]]],
1488
+ "ParseTree" => [:lasgn, :var,
1489
+ [:array,
1490
+ [:str, "foo"],
1491
+ [:str, "bar"]]],
828
1492
  },
829
1493
 
830
1494
  "lasgn_call" => {
@@ -852,6 +1516,11 @@ end",
852
1516
  "ParseTree" => [:lit, 1],
853
1517
  },
854
1518
 
1519
+ "lit_long_negative" => {
1520
+ "Ruby" => "-1",
1521
+ "ParseTree" => [:lit, -1],
1522
+ },
1523
+
855
1524
  "lit_range2" => {
856
1525
  "Ruby" => "(1..10)",
857
1526
  "ParseTree" => [:lit, 1..10],
@@ -867,9 +1536,20 @@ end",
867
1536
  "ParseTree" => [:lit, /x/],
868
1537
  },
869
1538
 
870
- "lit_str" => {
871
- "Ruby" => "\"x\"",
872
- "ParseTree" => [:str, "x"],
1539
+ "lit_regexp_i_wwtt" => {
1540
+ "Ruby" => 'str.split(//i)',
1541
+ "ParseTree" => [:call, [:vcall, :str], :split, [:array, [:lit, //i]]],
1542
+ },
1543
+
1544
+ "lit_regexp_n" => {
1545
+ "Ruby" => "/x/n",
1546
+ "ParseTree" => [:lit, /x/n],
1547
+ },
1548
+
1549
+ "lit_regexp_once" => {
1550
+ "Ruby" => "/x/o",
1551
+ "ParseTree" => [:lit, /x/],
1552
+ "Ruby2Ruby" => "/x/",
873
1553
  },
874
1554
 
875
1555
  "lit_sym" => {
@@ -877,6 +1557,32 @@ end",
877
1557
  "ParseTree" => [:lit, :x],
878
1558
  },
879
1559
 
1560
+ "lit_sym_splat" => {
1561
+ "Ruby" => ":\"*args\"",
1562
+ "ParseTree" => [:lit, :"*args"],
1563
+ },
1564
+
1565
+ "lvar_def_boundary" => { # HACK: put # do nothing back under begin
1566
+ "Ruby" => "b = 42\ndef a\n c do\n begin\n rescue RuntimeError => b\n puts(b)\n end\n end\nend\n",
1567
+ "ParseTree" => [:block,
1568
+ [:lasgn, :b, [:lit, 42]],
1569
+ [:defn,
1570
+ :a,
1571
+ [:scope,
1572
+ [:block,
1573
+ [:args],
1574
+ [:iter,
1575
+ [:fcall, :c],
1576
+ nil,
1577
+ [:begin,
1578
+ [:rescue,
1579
+ [:resbody,
1580
+ [:array, [:const, :RuntimeError]],
1581
+ [:block,
1582
+ [:dasgn_curr, :b, [:gvar, :$!]],
1583
+ [:fcall, :puts, [:array, [:dvar, :b]]]]]]]]]]]],
1584
+ },
1585
+
880
1586
  "masgn" => {
881
1587
  "Ruby" => "a, b = c, d",
882
1588
  "ParseTree" => [:masgn,
@@ -891,7 +1597,7 @@ end",
891
1597
  [:lasgn, :c],
892
1598
  [:argscat,
893
1599
  [:array, [:lit, 1], [:lit, 2]],
894
- [:array, [:lit, 3], [:lit, 4]]]]
1600
+ [:array, [:lit, 3], [:lit, 4]]]],
895
1601
  },
896
1602
 
897
1603
  "masgn_attrasgn" => {
@@ -936,6 +1642,39 @@ end",
936
1642
  [:vcall, :f], [:vcall, :g]]]
937
1643
  },
938
1644
 
1645
+ "masgn_splat_no_name_to_ary" => {
1646
+ "Ruby" => "a, b, * = c",
1647
+ "ParseTree" => [:masgn,
1648
+ [:array, [:lasgn, :a], [:lasgn, :b]],
1649
+ [:splat],
1650
+ [:to_ary, [:vcall, :c]]],
1651
+ },
1652
+
1653
+ "masgn_splat_no_name_trailing" => {
1654
+ "Ruby" => "a, b, = c",
1655
+ "ParseTree" => [:masgn,
1656
+ [:array, [:lasgn, :a], [:lasgn, :b]],
1657
+ [:to_ary, [:vcall, :c]]],
1658
+ "Ruby2Ruby" => "a, b = c", # TODO: check this is right
1659
+ },
1660
+
1661
+ "masgn_splat_to_ary" => {
1662
+ "Ruby" => "a, b, *c = d",
1663
+ "ParseTree" => [:masgn,
1664
+ [:array, [:lasgn, :a], [:lasgn, :b]],
1665
+ [:lasgn, :c],
1666
+ [:to_ary, [:vcall, :d]]],
1667
+ },
1668
+
1669
+ "masgn_splat_to_ary2" => {
1670
+ "Ruby" => "a, b, *c = d.e(\"f\")",
1671
+ "ParseTree" => [:masgn,
1672
+ [:array, [:lasgn, :a], [:lasgn, :b]],
1673
+ [:lasgn, :c],
1674
+ [:to_ary,
1675
+ [:call, [:vcall, :d], :e, [:array, [:str, 'f']]]]],
1676
+ },
1677
+
939
1678
  "match" => {
940
1679
  "Ruby" => "1 if /x/",
941
1680
  "ParseTree" => [:if, [:match, [:lit, /x/]], [:lit, 1], nil],
@@ -966,6 +1705,14 @@ end",
966
1705
  [:if, [:false], [:next], nil]],
967
1706
  },
968
1707
 
1708
+ "next_arg" => {
1709
+ "Ruby" => "loop { next 42 if false }",
1710
+ "ParseTree" => [:iter,
1711
+ [:fcall, :loop],
1712
+ nil,
1713
+ [:if, [:false], [:next, [:lit, 42]], nil]],
1714
+ },
1715
+
969
1716
  "not" => {
970
1717
  "Ruby" => "(not true)",
971
1718
  "ParseTree" => [:not, [:true]],
@@ -1009,6 +1756,11 @@ end",
1009
1756
  [:lit, 42]]],
1010
1757
  },
1011
1758
 
1759
+ "op_asgn2_self" => {
1760
+ "Ruby" => "self.Bag ||= Bag.new",
1761
+ "ParseTree" => [:op_asgn2, [:self], :"Bag=", :"||", [:call, [:const, :Bag], :new]],
1762
+ },
1763
+
1012
1764
  "op_asgn_and" => {
1013
1765
  "Ruby" => "a = 0\na &&= 2\n",
1014
1766
  "ParseTree" => [:block,
@@ -1016,6 +1768,21 @@ end",
1016
1768
  [:op_asgn_and, [:lvar, :a], [:lasgn, :a, [:lit, 2]]]],
1017
1769
  },
1018
1770
 
1771
+ "op_asgn_and_ivar2" => { # eww... stupid rubygems
1772
+ "Ruby" => "@fetcher &&= new(Gem.configuration[:http_proxy])",
1773
+ "ParseTree" => [:op_asgn_and,
1774
+ [:ivar, :@fetcher],
1775
+ [:iasgn,
1776
+ :@fetcher,
1777
+ [:fcall,
1778
+ :new,
1779
+ [:array,
1780
+ [:call,
1781
+ [:call, [:const, :Gem], :configuration],
1782
+ :[],
1783
+ [:array, [:lit, :http_proxy]]]]]]],
1784
+ },
1785
+
1019
1786
  "op_asgn_or" => {
1020
1787
  "Ruby" => "a = 0\na ||= 1\n",
1021
1788
  "ParseTree" => [:block,
@@ -1023,11 +1790,57 @@ end",
1023
1790
  [:op_asgn_or, [:lvar, :a], [:lasgn, :a, [:lit, 1]]]],
1024
1791
  },
1025
1792
 
1793
+ "op_asgn_or_block" => {
1794
+ "Ruby" => "a ||= begin\n b\n rescue\n c\n end",
1795
+ "ParseTree" => [:op_asgn_or,
1796
+ [:lvar, :a],
1797
+ [:lasgn, :a,
1798
+ [:rescue,
1799
+ [:vcall, :b],
1800
+ [:resbody, nil, [:vcall, :c]]]]],
1801
+ "Ruby2Ruby" => "a ||= b rescue c",
1802
+ },
1803
+
1804
+ "op_asgn_or_ivar" => {
1805
+ "Ruby" => "@v ||= { }",
1806
+ "ParseTree" => [:op_asgn_or, [:ivar, :@v], [:iasgn, :@v, [:hash]]],
1807
+ },
1808
+
1809
+ "op_asgn_or_ivar2" => { # eww... stupid rubygems
1810
+ "Ruby" => "@fetcher ||= new(Gem.configuration[:http_proxy])",
1811
+ "ParseTree" => [:op_asgn_or,
1812
+ [:ivar, :@fetcher],
1813
+ [:iasgn,
1814
+ :@fetcher,
1815
+ [:fcall,
1816
+ :new,
1817
+ [:array,
1818
+ [:call,
1819
+ [:call, [:const, :Gem], :configuration],
1820
+ :[],
1821
+ [:array, [:lit, :http_proxy]]]]]]],
1822
+ },
1823
+
1026
1824
  "or" => {
1027
1825
  "Ruby" => "(a or b)",
1028
1826
  "ParseTree" => [:or, [:vcall, :a], [:vcall, :b]],
1029
1827
  },
1030
1828
 
1829
+ "or_big" => {
1830
+ "Ruby" => "((a or b) or (c and d))",
1831
+ "ParseTree" => [:or,
1832
+ [:or, [:vcall, :a], [:vcall, :b]],
1833
+ [:and, [:vcall, :c], [:vcall, :d]]],
1834
+ },
1835
+
1836
+ "or_big2" => {
1837
+ "Ruby" => "((a || b) || (c && d))",
1838
+ "ParseTree" => [:or,
1839
+ [:or, [:vcall, :a], [:vcall, :b]],
1840
+ [:and, [:vcall, :c], [:vcall, :d]]],
1841
+ "Ruby2Ruby" => "((a or b) or (c and d))",
1842
+ },
1843
+
1031
1844
  "postexe" => {
1032
1845
  "Ruby" => "END { 1 }",
1033
1846
  "ParseTree" => [:iter, [:postexe], nil, [:lit, 1]],
@@ -1049,6 +1862,14 @@ end",
1049
1862
  [:call, [:vcall, :x], :+, [:array, [:lit, 1]]]],
1050
1863
  },
1051
1864
 
1865
+ "proc_zero_args" => {
1866
+ "Ruby" => "proc { || (x + 1) }",
1867
+ "ParseTree" => [:iter,
1868
+ [:fcall, :proc],
1869
+ 0,
1870
+ [:call, [:vcall, :x], :+, [:array, [:lit, 1]]]],
1871
+ },
1872
+
1052
1873
  "redo" => {
1053
1874
  "Ruby" => "loop { redo if false }",
1054
1875
  "ParseTree" => [:iter,
@@ -1061,11 +1882,15 @@ end",
1061
1882
  },
1062
1883
 
1063
1884
  "rescue_block_body" => {
1064
- "Ruby" => "begin\n blah\nrescue\n 42\nend",
1885
+ "Ruby" => "begin\n a\nrescue => e\n c\n d\nend",
1065
1886
  "ParseTree" => [:begin,
1066
1887
  [:rescue,
1067
- [:vcall, :blah],
1068
- [:resbody, nil, [:lit, 42]]]],
1888
+ [:vcall, :a],
1889
+ [:resbody, nil,
1890
+ [:block,
1891
+ [:lasgn, :e, [:gvar, :$!]],
1892
+ [:vcall, :c],
1893
+ [:vcall, :d]]]]],
1069
1894
  },
1070
1895
 
1071
1896
  "rescue_block_nada" => {
@@ -1088,11 +1913,36 @@ end",
1088
1913
  "ParseTree" => [:retry],
1089
1914
  },
1090
1915
 
1916
+ "return_0" => {
1917
+ "Ruby" => "return",
1918
+ "ParseTree" => [:return],
1919
+ },
1920
+
1921
+ "return_1" => {
1922
+ "Ruby" => "return 1",
1923
+ "ParseTree" => [:return, [:lit, 1]],
1924
+ },
1925
+
1926
+ "return_n" => {
1927
+ "Ruby" => "return 1, 2, 3",
1928
+ "ParseTree" => [:return, [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
1929
+ "Ruby2Ruby" => "return [1, 2, 3]",
1930
+ },
1931
+
1091
1932
  "sclass" => {
1092
1933
  "Ruby" => "class << self\n 42\nend",
1093
1934
  "ParseTree" => [:sclass, [:self], [:scope, [:lit, 42]]],
1094
1935
  },
1095
1936
 
1937
+ "sclass_trailing_class" => {
1938
+ "Ruby" => "class A\n class << self\n a\n end\n class B\n end\nend",
1939
+ "ParseTree" => [:class, :A, nil,
1940
+ [:scope,
1941
+ [:block,
1942
+ [:sclass, [:self], [:scope, [:vcall, :a]]],
1943
+ [:class, :B, nil, [:scope]]]]],
1944
+ },
1945
+
1096
1946
  "splat" => {
1097
1947
  "Ruby" => "def x(*b)\n a(*b)\nend",
1098
1948
  "ParseTree" => [:defn, :x,
@@ -1102,6 +1952,125 @@ end",
1102
1952
  [:fcall, :a, [:splat, [:lvar, :b]]]]]],
1103
1953
  },
1104
1954
 
1955
+ "str" => {
1956
+ "Ruby" => '"x"',
1957
+ "ParseTree" => [:str, "x"],
1958
+ },
1959
+
1960
+ "str_concat_newline" => {
1961
+ "Ruby" => '"before" \\
1962
+ " after"',
1963
+ "ParseTree" => [:str, "before after"],
1964
+ "Ruby2Ruby" => '"before after"',
1965
+ },
1966
+
1967
+ "str_concat_space" => {
1968
+ "Ruby" => '"before" " after"',
1969
+ "ParseTree" => [:str, "before after"],
1970
+ "Ruby2Ruby" => '"before after"',
1971
+ },
1972
+
1973
+ "str_heredoc" => {
1974
+ "Ruby" => "<<'EOM'\n blah\nblah\nEOM\n",
1975
+ "ParseTree" => [:str, " blah\nblah\n"],
1976
+ "Ruby2Ruby" => "\" blah\\nblah\\n\"",
1977
+ },
1978
+
1979
+ "str_heredoc_call" => {
1980
+ "Ruby" => "<<'EOM'.strip\n blah\nblah\nEOM\n",
1981
+ "ParseTree" => [:call, [:str, " blah\nblah\n"], :strip],
1982
+ "Ruby2Ruby" => "\" blah\\nblah\\n\".strip",
1983
+ },
1984
+
1985
+ "str_heredoc_double" => {
1986
+ "Ruby" => "a += <<-BEGIN + b + <<-END\n first\nBEGIN\n second\nEND",
1987
+ "ParseTree" => [:lasgn, :a,
1988
+ [:call,
1989
+ [:lvar, :a],
1990
+ :+,
1991
+ [:array,
1992
+ [:call,
1993
+ [:call, [:str, " first\n"], :+,
1994
+ [:array, [:vcall, :b]]],
1995
+ :+,
1996
+ [:array, [:str, " second\n"]]]]]],
1997
+ "Ruby2Ruby" => "a = (a + ((\" first\\n\" + b) + \" second\\n\"))",
1998
+ },
1999
+
2000
+ "dstr_heredoc_expand" => {
2001
+ "Ruby" => "<<EOM\n blah\n#\{1 + 1}blah\nEOM\n",
2002
+ "ParseTree" => [:dstr, " blah\n",
2003
+ [:evstr, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
2004
+ [:str, "blah\n"]],
2005
+ "Ruby2Ruby" => "\" blah\\n#\{(1 + 1)}blah\\n\"",
2006
+ },
2007
+
2008
+ "str_heredoc_indent" => {
2009
+ "Ruby" => "<<-EOM\n blah\nblah\n\n EOM\n",
2010
+ "ParseTree" => [:str, " blah\nblah\n\n"],
2011
+ "Ruby2Ruby" => "\" blah\\nblah\\n\\n\"",
2012
+ },
2013
+
2014
+ "dstr_heredoc_windoze_sucks" => {
2015
+ "Ruby" => "<<-EOF\r\ndef test_#\{action}_valid_feed\r\n EOF\r\n",
2016
+ "ParseTree" => [:dstr,
2017
+ 'def test_',
2018
+ [:evstr, [:vcall, :action]],
2019
+ [:str, "_valid_feed\n"]],
2020
+ "Ruby2Ruby" => "\"def test_#\{action}_valid_feed\\n\"",
2021
+ },
2022
+
2023
+ "str_interp_file" => {
2024
+ "Ruby" => '"file = #{__FILE__}
2025
+ "',
2026
+ "ParseTree" => [:str, "file = (string)\n"],
2027
+ "Ruby2Ruby" => '"file = (string)\\n"',
2028
+ },
2029
+
2030
+ "structure_extra_block_for_dvar_scoping" => {
2031
+ "Ruby" => "a.b do |c, d|\n unless e.f(c) then\n g = false\n d.h { |x, i| g = true }\n \n end\nend", # FIX: don't like the extra return
2032
+ "ParseTree" => [:iter,
2033
+ [:call, [:vcall, :a], :b],
2034
+ [:masgn, [:array, [:dasgn_curr, :c], [:dasgn_curr, :d]]],
2035
+ [:block,
2036
+ [:dasgn_curr, :g],
2037
+ [:if,
2038
+ [:call, [:vcall, :e], :f, [:array, [:dvar, :c]]],
2039
+ nil,
2040
+ [:block,
2041
+ [:dasgn_curr, :g, [:false]],
2042
+ [:iter,
2043
+ [:call, [:dvar, :d], :h],
2044
+ [:masgn, [:array, [:dasgn_curr, :x], [:dasgn_curr, :i]]],
2045
+ [:dasgn, :g, [:true]]]]]]],
2046
+ },
2047
+
2048
+ "structure_remove_begin_1" => {
2049
+ "Ruby" => "a << begin\n b\n rescue\n c\n end",
2050
+ "ParseTree" => [:call, [:vcall, :a], :<<,
2051
+ [:array, [:rescue, [:vcall, :b],
2052
+ [:resbody, nil, [:vcall, :c]]]]],
2053
+ "Ruby2Ruby" => "(a << b rescue c)",
2054
+ },
2055
+
2056
+ "structure_remove_begin_2" => {
2057
+ "Ruby" => "a = if c\n begin\n b\n rescue\n nil\n end\n end\na",
2058
+ "ParseTree" => [:block,
2059
+ [:lasgn,
2060
+ :a,
2061
+ [:if, [:vcall, :c],
2062
+ [:rescue, [:vcall, :b], [:resbody, nil, [:nil]]],
2063
+ nil]],
2064
+ [:lvar, :a]],
2065
+ "Ruby2Ruby" => "a = b rescue nil if c\na\n", # OMG that's awesome
2066
+ },
2067
+
2068
+ "structure_unused_literal_wwtt" => {
2069
+ "Ruby" => "\"prevent the above from infecting rdoc\"\n\nmodule Graffle\nend",
2070
+ "ParseTree" => [:module, :Graffle, [:scope]],
2071
+ "Ruby2Ruby" => "module Graffle\nend",
2072
+ },
2073
+
1105
2074
  # TODO: all supers need to pass args
1106
2075
  "super" => {
1107
2076
  "Ruby" => "def x\n super(4)\nend",
@@ -1112,6 +2081,20 @@ end",
1112
2081
  [:super, [:array, [:lit, 4]]]]]],
1113
2082
  },
1114
2083
 
2084
+ "super_block_pass" => {
2085
+ "Ruby" => "super(a, &b)",
2086
+ "ParseTree" => [:block_pass,
2087
+ [:vcall, :b], [:super, [:array, [:vcall, :a]]]],
2088
+ },
2089
+
2090
+ "super_block_splat" => {
2091
+ "Ruby" => "super(a, *b)",
2092
+ "ParseTree" => [:super,
2093
+ [:argscat,
2094
+ [:array, [:vcall, :a]],
2095
+ [:vcall, :b]]],
2096
+ },
2097
+
1115
2098
  "super_multi" => {
1116
2099
  "Ruby" => "def x\n super(4, 2, 1)\nend",
1117
2100
  "ParseTree" => [:defn, :x,
@@ -1143,7 +2126,15 @@ end",
1143
2126
  "ParseTree" => [:undef, [:lit, :x]],
1144
2127
  },
1145
2128
 
1146
- "undef_multi" => {
2129
+ "undef_2" => {
2130
+ "Ruby" => "undef :x, :y",
2131
+ "ParseTree" => [:block,
2132
+ [:undef, [:lit, :x]],
2133
+ [:undef, [:lit, :y]]],
2134
+ "Ruby2Ruby" => "undef :x\nundef :y\n",
2135
+ },
2136
+
2137
+ "undef_3" => {
1147
2138
  "Ruby" => "undef :x, :y, :z",
1148
2139
  "ParseTree" => [:block,
1149
2140
  [:undef, [:lit, :x]],
@@ -1152,18 +2143,98 @@ end",
1152
2143
  "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\n",
1153
2144
  },
1154
2145
 
2146
+ "undef_block_1" => {
2147
+ "Ruby" => "f1\nundef :x\n", # TODO: don't like the extra return
2148
+ "ParseTree" => [:block,
2149
+ [:vcall, :f1],
2150
+ [:undef, [:lit, :x]]],
2151
+ },
2152
+
2153
+ "undef_block_2" => {
2154
+ "Ruby" => "f1\nundef :x, :y",
2155
+ "ParseTree" => [:block,
2156
+ [:vcall, :f1],
2157
+ [:block,
2158
+ [:undef, [:lit, :x]],
2159
+ [:undef, [:lit, :y]],
2160
+ ]],
2161
+ "Ruby2Ruby" => "f1\n(undef :x\nundef :y)\n",
2162
+ },
2163
+
2164
+ "undef_block_3" => {
2165
+ "Ruby" => "f1\nundef :x, :y, :z",
2166
+ "ParseTree" => [:block,
2167
+ [:vcall, :f1],
2168
+ [:block,
2169
+ [:undef, [:lit, :x]],
2170
+ [:undef, [:lit, :y]],
2171
+ [:undef, [:lit, :z]],
2172
+ ]],
2173
+ "Ruby2Ruby" => "f1\n(undef :x\nundef :y\nundef :z)\n",
2174
+ },
2175
+
2176
+ "undef_block_3_post" => {
2177
+ "Ruby" => "undef :x, :y, :z\nf2",
2178
+ "ParseTree" => [:block,
2179
+ [:undef, [:lit, :x]],
2180
+ [:undef, [:lit, :y]],
2181
+ [:undef, [:lit, :z]],
2182
+ [:vcall, :f2]],
2183
+ "Ruby2Ruby" => "undef :x\nundef :y\nundef :z\nf2\n",
2184
+ },
2185
+
2186
+ "undef_block_wtf" => {
2187
+ "Ruby" => "f1\nundef :x, :y, :z\nf2",
2188
+ "ParseTree" => [:block,
2189
+ [:vcall, :f1],
2190
+ [:block,
2191
+ [:undef, [:lit, :x]],
2192
+ [:undef, [:lit, :y]],
2193
+ [:undef, [:lit, :z]]],
2194
+ [:vcall, :f2]],
2195
+ "Ruby2Ruby" => "f1\n(undef :x\nundef :y\nundef :z)\nf2\n",
2196
+ },
2197
+
1155
2198
  "until_post" => {
1156
2199
  "Ruby" => "begin\n (1 + 1)\nend until false",
1157
2200
  "ParseTree" => [:until, [:false],
1158
2201
  [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
1159
2202
  },
1160
2203
 
2204
+ "until_post_not" => {
2205
+ "Ruby" => "begin\n (1 + 1)\nend until not true",
2206
+ "ParseTree" => [:while, [:true],
2207
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
2208
+ "Ruby2Ruby" => "begin\n (1 + 1)\nend while true",
2209
+ },
2210
+
1161
2211
  "until_pre" => {
1162
2212
  "Ruby" => "until false do\n (1 + 1)\nend",
1163
2213
  "ParseTree" => [:until, [:false],
1164
2214
  [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
1165
2215
  },
1166
2216
 
2217
+ "until_pre_mod" => {
2218
+ "Ruby" => "(1 + 1) until false",
2219
+ "ParseTree" => [:until, [:false],
2220
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2221
+ "Ruby2Ruby" => "until false do\n (1 + 1)\nend",
2222
+ },
2223
+
2224
+ "until_pre_not" => {
2225
+ "Ruby" => "until not true do\n (1 + 1)\nend",
2226
+ "ParseTree" => [:while, [:true],
2227
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2228
+ "Ruby2Ruby" => "while true do\n (1 + 1)\nend",
2229
+ },
2230
+
2231
+ "until_pre_not_mod" => {
2232
+ "Ruby" => "(1 + 1) until not true",
2233
+ "ParseTree" => [:while, [:true],
2234
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2235
+ "Ruby2Ruby" => "while true do\n (1 + 1)\nend",
2236
+ },
2237
+
1167
2238
  "valias" => {
1168
2239
  "Ruby" => "alias $y $x",
1169
2240
  "ParseTree" => [:valias, :$y, :$x],
@@ -1180,17 +2251,45 @@ end",
1180
2251
  [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
1181
2252
  },
1182
2253
 
2254
+ "while_post_not" => {
2255
+ "Ruby" => "begin\n (1 + 1)\nend while not true",
2256
+ "ParseTree" => [:until, [:true],
2257
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
2258
+ "Ruby2Ruby" => "begin\n (1 + 1)\nend until true",
2259
+ },
2260
+
1183
2261
  "while_pre" => {
1184
2262
  "Ruby" => "while false do\n (1 + 1)\nend",
1185
2263
  "ParseTree" => [:while, [:false],
1186
2264
  [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
1187
2265
  },
1188
2266
 
2267
+ "while_pre_mod" => {
2268
+ "Ruby" => "(1 + 1) while false",
2269
+ "ParseTree" => [:while, [:false],
2270
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2271
+ "Ruby2Ruby" => "while false do\n (1 + 1)\nend", # FIX can be one liner
2272
+ },
2273
+
1189
2274
  "while_pre_nil" => {
1190
2275
  "Ruby" => "while false do\nend",
1191
2276
  "ParseTree" => [:while, [:false], nil, true],
1192
2277
  },
1193
2278
 
2279
+ "while_pre_not" => {
2280
+ "Ruby" => "while not true do\n (1 + 1)\nend",
2281
+ "ParseTree" => [:until, [:true],
2282
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2283
+ "Ruby2Ruby" => "until true do\n (1 + 1)\nend",
2284
+ },
2285
+
2286
+ "while_pre_not_mod" => {
2287
+ "Ruby" => "(1 + 1) while not true",
2288
+ "ParseTree" => [:until, [:true],
2289
+ [:call, [:lit, 1], :+, [:array, [:lit, 1]]], true],
2290
+ "Ruby2Ruby" => "until true do\n (1 + 1)\nend", # FIX
2291
+ },
2292
+
1194
2293
  "xstr" => {
1195
2294
  "Ruby" => "`touch 5`",
1196
2295
  "ParseTree" => [:xstr, 'touch 5'],
@@ -1222,35 +2321,6 @@ end",
1222
2321
  },
1223
2322
  }
1224
2323
 
1225
- # def test_audit_nodes
1226
- # # TODO: audit @@testcases.keys against node list - do two way audit, rename everything
1227
- # nodes = ParseTree::NODE_NAMES.map { |s| s.to_s }.sort
1228
- # tested = @@testcases.keys.map { |s| s.to_s }.sort
1229
- # if processor.respond_to? :unsupported then
1230
- # nodes -= processor.unsupported
1231
- # else
1232
- # SexpProcessor.new.unsupported
1233
- # # HACK
1234
- # nodes -= [:alloca, :argspush, :cfunc, :cref, :evstr, :ifunc, :last, :memo, :newline, :opt_n, :method].map { |s| s.to_s }
1235
- # end
1236
-
1237
- # untested = nodes-tested
1238
-
1239
- # puts
1240
- # p :untested_nodes => untested, :extra_nodes => tested-nodes
1241
-
1242
- # untested.each do |node|
1243
- # puts %(
1244
- # "#{node}" => {
1245
- # "Ruby" => "XXX",
1246
- # "ParseTree" => [],
1247
- # },
1248
- # )
1249
- # end
1250
-
1251
- # flunk
1252
- # end
1253
-
1254
2324
  def self.previous(key, extra=0)
1255
2325
  idx = @@testcase_order.index(key)-1-extra
1256
2326
  case key
@@ -1260,18 +2330,6 @@ end",
1260
2330
  @@testcase_order[idx]
1261
2331
  end
1262
2332
 
1263
- # # lets us used unprocessed :self outside of tests, called when subclassed
1264
- # def self.clone_same
1265
- # @@testcases.each do |node, data|
1266
- # data.each do |key, val|
1267
- # if val == :same then
1268
- # prev_key = self.previous(key)
1269
- # data[key] = data[prev_key].deep_clone
1270
- # end
1271
- # end
1272
- # end
1273
- # end
1274
-
1275
2333
  def self.inherited(c)
1276
2334
  output_name = c.name.to_s.sub(/^Test/, '')
1277
2335
  raise "Unknown class #{c} in @@testcase_order" unless
@@ -1322,5 +2380,5 @@ end",
1322
2380
  end
1323
2381
  end
1324
2382
 
1325
- undef_method :default_test
2383
+ undef_method :default_test rescue nil
1326
2384
  end