ParseTree 2.0.2 → 2.1.0

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