ruby2ruby 1.1.1 → 1.1.2

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.
Files changed (4) hide show
  1. data/History.txt +10 -0
  2. data/lib/ruby2ruby.rb +76 -55
  3. data/test/test_ruby2ruby.rb +23 -14
  4. metadata +2 -2
data/History.txt CHANGED
@@ -1,3 +1,13 @@
1
+ == 1.1.2 / 2006-12-19
2
+
3
+ * 2 minor enhancements
4
+ * Improved []= and [] to be more idiomatic.
5
+ * Support for nested whens (from when case has no expression).
6
+ * 3 bug fixes
7
+ * Fixed case output when there is no case expression.
8
+ * NEARLY have RubyToRuby self-cloning and passing tests again.
9
+ * Minor cleanup
10
+
1
11
  == 1.1.1 / 2006-11-13
2
12
 
3
13
  * 3 bug fixes
data/lib/ruby2ruby.rb CHANGED
@@ -11,7 +11,7 @@ class NilClass # Objective-C trick
11
11
  end
12
12
 
13
13
  class RubyToRuby < SexpProcessor
14
- VERSION = '1.1.1'
14
+ VERSION = '1.1.2'
15
15
 
16
16
  def self.translate(klass_or_str, method=nil)
17
17
  self.new.process(ParseTree.translate(klass_or_str, method))
@@ -24,7 +24,7 @@ class RubyToRuby < SexpProcessor
24
24
  self.strict = true
25
25
  self.expected = String
26
26
  end
27
-
27
+
28
28
  ############################################################
29
29
  # Processors (rewriters at bottom)
30
30
 
@@ -35,7 +35,7 @@ class RubyToRuby < SexpProcessor
35
35
  def process_and(exp)
36
36
  "(#{process exp.shift} and #{process exp.shift})"
37
37
  end
38
-
38
+
39
39
  def process_args(exp)
40
40
  args = []
41
41
 
@@ -67,7 +67,7 @@ class RubyToRuby < SexpProcessor
67
67
  args << process(names.shift) until names.size == v_size
68
68
  names.zip(vals) do |name, val|
69
69
  args << "#{process name} = #{process val}"
70
- end
70
+ end
71
71
  else
72
72
  raise "unknown arg type #{arg.first.inspect}"
73
73
  end
@@ -78,7 +78,7 @@ class RubyToRuby < SexpProcessor
78
78
 
79
79
  return "(#{args.join ', '})"
80
80
  end
81
-
81
+
82
82
  def process_arglist(exp) # custom made node
83
83
  code = []
84
84
  until exp.empty? do
@@ -86,7 +86,7 @@ class RubyToRuby < SexpProcessor
86
86
  end
87
87
  code.join ', '
88
88
  end
89
-
89
+
90
90
  def process_argscat(exp)
91
91
  args = []
92
92
  ary = exp.shift
@@ -113,7 +113,18 @@ class RubyToRuby < SexpProcessor
113
113
  end
114
114
 
115
115
  def process_attrasgn(exp)
116
- process_call(exp)
116
+ receiver = process exp.shift
117
+ name = exp.shift
118
+ args = exp.shift
119
+
120
+ case name
121
+ when :[]= then
122
+ lhs = process args.delete_at(1)
123
+ args[0] = :arglist
124
+ "#{receiver}[#{lhs}] = #{process(args)}"
125
+ else
126
+ "#{receiver}.#{name.to_s[0..-2]} = #{process(args)[1..-2]}"
127
+ end
117
128
  end
118
129
 
119
130
  def process_back_ref(exp)
@@ -158,7 +169,7 @@ class RubyToRuby < SexpProcessor
158
169
  def process_block_arg(exp)
159
170
  "&#{exp.shift}"
160
171
  end
161
-
172
+
162
173
  def process_block_pass(exp)
163
174
  bname = [:lvar, "&" + process(exp.shift)]
164
175
  call = exp.shift
@@ -168,7 +179,7 @@ class RubyToRuby < SexpProcessor
168
179
 
169
180
  process(call)
170
181
  end
171
-
182
+
172
183
  def process_break(exp)
173
184
  val = process(exp.shift)
174
185
  "break" + (val ? " #{val}" : "")
@@ -177,7 +188,7 @@ class RubyToRuby < SexpProcessor
177
188
  def process_call(exp)
178
189
  receiver = process exp.shift
179
190
  name = exp.shift
180
- args_exp = exp.shift
191
+ args_exp = exp.shift rescue nil
181
192
  if args_exp && args_exp.first == :array
182
193
  args = "#{process(args_exp)[1..-2]}"
183
194
  else
@@ -197,10 +208,15 @@ class RubyToRuby < SexpProcessor
197
208
  end
198
209
  end
199
210
  end
200
-
211
+
201
212
  def process_case(exp)
202
213
  result = []
203
- result << "case #{process exp.shift}"
214
+ expr = process exp.shift
215
+ if expr then
216
+ result << "case #{expr}"
217
+ else
218
+ result << "case"
219
+ end
204
220
  until exp.empty?
205
221
  pt = exp.shift
206
222
  if pt and pt.first == :when
@@ -214,7 +230,7 @@ class RubyToRuby < SexpProcessor
214
230
  result << "end"
215
231
  result.join("\n")
216
232
  end
217
-
233
+
218
234
  def process_cdecl(exp)
219
235
  "#{exp.shift} = #{process(exp.shift)}"
220
236
  end
@@ -238,19 +254,19 @@ class RubyToRuby < SexpProcessor
238
254
  end
239
255
  s + body + "end"
240
256
  end
241
-
257
+
242
258
  def process_colon2(exp)
243
259
  "#{process(exp.shift)}::#{exp.shift}"
244
260
  end
245
-
261
+
246
262
  def process_colon3(exp)
247
263
  "::#{exp.shift}"
248
264
  end
249
-
265
+
250
266
  def process_const(exp)
251
267
  exp.shift.to_s
252
268
  end
253
-
269
+
254
270
  def process_cvar(exp)
255
271
  "#{exp.shift}"
256
272
  end
@@ -264,7 +280,7 @@ class RubyToRuby < SexpProcessor
264
280
  end
265
281
 
266
282
  def process_dasgn_curr(exp)
267
- s = exp.shift.to_s
283
+ s = exp.shift.to_s
268
284
  s += "=" + process(exp.shift) unless exp.empty?
269
285
  s
270
286
  end
@@ -320,14 +336,14 @@ class RubyToRuby < SexpProcessor
320
336
  raise "Unknown defn type: #{t} for #{exp.inspect}"
321
337
  end
322
338
  end
323
-
339
+
324
340
  def process_defx(exp) # custom node type - TODO why in r2r?
325
341
  name = exp.shift
326
342
  args = process(exp.shift)
327
343
  body = indent(process(exp.shift))
328
344
  return "defx #{name}#{args}\n#{body}end".gsub(/\n\s*\n+/, "\n")
329
345
  end
330
-
346
+
331
347
  def process_dot2(exp)
332
348
  "(#{process exp.shift}..#{process exp.shift})"
333
349
  end
@@ -335,7 +351,7 @@ class RubyToRuby < SexpProcessor
335
351
  def process_dot3(exp)
336
352
  "(#{process exp.shift}...#{process exp.shift})"
337
353
  end
338
-
354
+
339
355
  def process_dregx(exp)
340
356
  "/#{process_dstr(exp)[1..-2]}/"
341
357
  end
@@ -387,7 +403,7 @@ class RubyToRuby < SexpProcessor
387
403
  def process_false(exp)
388
404
  "false"
389
405
  end
390
-
406
+
391
407
  def process_fcall(exp)
392
408
  exp_orig = exp.deep_clone
393
409
  name = exp.shift.to_s
@@ -399,7 +415,7 @@ class RubyToRuby < SexpProcessor
399
415
  end
400
416
  return "#{name}(#{code.join(', ')})"
401
417
  end
402
-
418
+
403
419
  def process_flip2(exp)
404
420
  "#{process(exp.shift)}..#{process(exp.shift)}"
405
421
  end
@@ -414,7 +430,7 @@ class RubyToRuby < SexpProcessor
414
430
  body = process exp.shift
415
431
  return "for #{iter} in #{recv}\n#{indent body}\nend\n"
416
432
  end
417
-
433
+
418
434
  def process_gasgn(exp)
419
435
  process_iasgn(exp)
420
436
  end
@@ -434,11 +450,11 @@ class RubyToRuby < SexpProcessor
434
450
  def process_iasgn(exp)
435
451
  "#{exp.shift} = #{process exp.shift}"
436
452
  end
437
-
453
+
438
454
  def cond_indent_process(pt)
439
455
  (pt and pt.first == :block) ? process(pt) : indent(process(pt))
440
456
  end
441
-
457
+
442
458
  def process_if(exp)
443
459
  c = process exp.shift
444
460
  t = process exp.shift
@@ -453,7 +469,7 @@ class RubyToRuby < SexpProcessor
453
469
  "unless #{c} then\n#{indent(f)}\nend"
454
470
  end
455
471
  end
456
-
472
+
457
473
  def process_iter(exp)
458
474
  iter = process exp.shift
459
475
  args = process exp.shift
@@ -480,17 +496,17 @@ class RubyToRuby < SexpProcessor
480
496
  result << e
481
497
  result.join
482
498
  end
483
-
499
+
484
500
  def process_ivar(exp)
485
501
  exp.shift.to_s
486
502
  end
487
-
503
+
488
504
  def process_lasgn(exp)
489
- s = "#{exp.shift}"
505
+ s = "#{exp.shift}"
490
506
  s += " = #{process exp.shift}" unless exp.empty?
491
507
  s
492
508
  end
493
-
509
+
494
510
  def process_lit(exp)
495
511
  obj = exp.shift
496
512
  if obj.is_a? Range # to get around how parsed ranges turn into lits and lose parens
@@ -499,11 +515,11 @@ class RubyToRuby < SexpProcessor
499
515
  obj.inspect
500
516
  end
501
517
  end
502
-
518
+
503
519
  def process_lvar(exp)
504
520
  exp.shift.to_s
505
521
  end
506
-
522
+
507
523
  def process_masgn(exp)
508
524
  lhs = exp.shift
509
525
  rhs = exp.shift
@@ -553,7 +569,7 @@ class RubyToRuby < SexpProcessor
553
569
  end
554
570
  s + body + "end"
555
571
  end
556
-
572
+
557
573
  def process_next(exp)
558
574
  "next"
559
575
  end
@@ -561,11 +577,11 @@ class RubyToRuby < SexpProcessor
561
577
  def process_nil(exp)
562
578
  "nil"
563
579
  end
564
-
580
+
565
581
  def process_not(exp)
566
582
  "(not #{process exp.shift})"
567
583
  end
568
-
584
+
569
585
  def process_nth_ref(exp)
570
586
  "$#{exp.shift}"
571
587
  end
@@ -585,7 +601,7 @@ class RubyToRuby < SexpProcessor
585
601
  lhs = process(exp.shift)
586
602
  index = exp.shift.to_s[0..-2]
587
603
  msg = exp.shift
588
-
604
+
589
605
  rhs = process(exp.shift)
590
606
 
591
607
  "#{lhs}.#{index} #{msg}= #{rhs}"
@@ -608,7 +624,7 @@ class RubyToRuby < SexpProcessor
608
624
  def process_or(exp)
609
625
  "(#{process exp.shift} or #{process exp.shift})"
610
626
  end
611
-
627
+
612
628
  def process_postexe(exp)
613
629
  "END"
614
630
  end
@@ -624,7 +640,7 @@ class RubyToRuby < SexpProcessor
624
640
  until exp.empty? and (sexp.nil? or sexp.empty?)
625
641
  list = sexp.shift
626
642
  body = sexp.shift
627
-
643
+
628
644
  var = if list.last.first == :lasgn then
629
645
  list.pop[1]
630
646
  else
@@ -686,16 +702,16 @@ class RubyToRuby < SexpProcessor
686
702
  resbody.shift # resbody
687
703
  resbody.shift # nil (no types for expression form)
688
704
  resbody = resbody.shift # actual code
689
-
705
+
690
706
  resbody = process resbody
691
707
  "#{body} rescue #{resbody}"
692
708
  end
693
709
  end
694
-
710
+
695
711
  def process_retry(exp)
696
712
  "retry"
697
713
  end
698
-
714
+
699
715
  def process_return(exp)
700
716
  return "return" + (exp.empty? ? "" : " #{process exp.shift}")
701
717
  end
@@ -725,7 +741,7 @@ class RubyToRuby < SexpProcessor
725
741
  args[0] = :arglist
726
742
  "super(#{process(args)})"
727
743
  end
728
-
744
+
729
745
  def process_svalue(exp)
730
746
  process(exp.shift)
731
747
  end
@@ -745,7 +761,7 @@ class RubyToRuby < SexpProcessor
745
761
  def process_until(exp)
746
762
  cond_loop(exp, 'until')
747
763
  end
748
-
764
+
749
765
  def process_valias(exp)
750
766
  "alias #{exp.shift} #{exp.shift}"
751
767
  end
@@ -753,18 +769,23 @@ class RubyToRuby < SexpProcessor
753
769
  def process_vcall(exp)
754
770
  return exp.shift.to_s
755
771
  end
756
-
772
+
757
773
  def process_when(exp)
758
- cond = process(exp.shift).to_s[1..-2]
759
- code = indent(process(exp.shift))
760
- code = indent "# do nothing" if code =~ /\A\s*\Z/
761
- "when #{cond} then\n#{code.chomp}"
774
+ src = []
775
+
776
+ until exp.empty?
777
+ cond = process(exp.shift).to_s[1..-2]
778
+ code = indent(process(exp.shift))
779
+ code = indent "# do nothing" if code =~ /\A\s*\Z/
780
+ src << "when #{cond} then\n#{code.chomp}"
781
+ end
782
+ src.join("\n")
762
783
  end
763
784
 
764
785
  def process_while(exp)
765
786
  cond_loop(exp, 'while')
766
787
  end
767
-
788
+
768
789
  def process_xstr(exp)
769
790
  "`#{process_str(exp)[1..-2]}`"
770
791
  end
@@ -778,7 +799,7 @@ class RubyToRuby < SexpProcessor
778
799
 
779
800
  "yield" + (args ? "(#{args})" : "")
780
801
  end
781
-
802
+
782
803
  def process_zarray(exp)
783
804
  "[]"
784
805
  end
@@ -786,7 +807,7 @@ class RubyToRuby < SexpProcessor
786
807
  def process_zsuper(exp)
787
808
  "super"
788
809
  end
789
-
810
+
790
811
  def cond_loop(exp, name)
791
812
  cond = process(exp.shift)
792
813
  body = process(exp.shift)
@@ -807,7 +828,7 @@ class RubyToRuby < SexpProcessor
807
828
  code.join("\n")
808
829
  end
809
830
 
810
- ############################################################
831
+ ############################################################
811
832
  # Rewriters
812
833
 
813
834
  ##
@@ -875,7 +896,7 @@ class RubyToRuby < SexpProcessor
875
896
  else
876
897
  raise "Unknown :defn format: #{name.inspect} #{args.inspect} #{body.inspect}"
877
898
  end
878
-
899
+
879
900
  return s(:defn, name, args, body)
880
901
  end
881
902
 
@@ -899,7 +920,7 @@ class RubyToRuby < SexpProcessor
899
920
  body = nil
900
921
  when :block then
901
922
  # TODO: check that it is assigning $!
902
- list << body.delete_at(1) if body[1].first == :lasgn
923
+ list << body.delete_at(1) if body[1].first == :lasgn
903
924
  else
904
925
  # do nothing (expression form)
905
926
  end
@@ -49,8 +49,8 @@ class TestRubyToRuby < Test::Unit::TestCase
49
49
 
50
50
  ParseTreeTestCase.testcases.each do |node, data|
51
51
  define_method :"test_#{node}" do
52
- pt = data['ParseTree']
53
- rb = data['Ruby2Ruby'] || data['Ruby']
52
+ pt = data['ParseTree'].deep_clone
53
+ rb = (data['Ruby2Ruby'] || data['Ruby']).deep_clone
54
54
 
55
55
  result = @processor.process(pt)
56
56
 
@@ -60,11 +60,6 @@ class TestRubyToRuby < Test::Unit::TestCase
60
60
  end
61
61
  end
62
62
 
63
-
64
- end
65
-
66
- class R2RTest < Test::Unit::TestCase
67
-
68
63
  def test_self_translation
69
64
  r2r2r = RubyToRuby.translate(RubyToRuby).sub("RubyToRuby","RubyToRubyToRuby")
70
65
 
@@ -80,7 +75,7 @@ class R2RTest < Test::Unit::TestCase
80
75
  assert_equal(r2r2r, r2r2r2, "first generation must equal second generation")
81
76
  assert_equal(r2r2r, r2r2r2r, "first generation must equal third generation")
82
77
  end
83
-
78
+
84
79
  def hairy_method(z,x=10,y=20*z.abs,&blok)
85
80
  n = 1 + 2 * 40.0 / (z - 2)
86
81
  retried = false
@@ -92,7 +87,7 @@ class R2RTest < Test::Unit::TestCase
92
87
  raise n
93
88
  rescue RuntimeError => e
94
89
  raise if n != e.message
95
- n = lambda do |i|
90
+ n = lambda do |i|
96
91
  lambda do |j|
97
92
  "#{i} #{z+2*2} #{j.message.reverse}"
98
93
  end
@@ -102,7 +97,7 @@ class R2RTest < Test::Unit::TestCase
102
97
  retry
103
98
  end
104
99
  rescue ArgumentError => e
105
- e.message
100
+ e.message
106
101
  rescue
107
102
  end
108
103
  ensure
@@ -111,18 +106,18 @@ class R2RTest < Test::Unit::TestCase
111
106
 
112
107
  def foobar a, &block; block.call(a) end
113
108
  def k; foobar [1,2,3].each { |x| x*2 } do |x| x*2 end end
114
-
109
+
115
110
  def test_block_precedence_escape
116
111
  eval RubyToRuby.translate(self.class, :k).sub(" k"," l")
117
112
  assert_equal(k, l)
118
113
  end
119
-
114
+
120
115
  def test_hairy_method
121
116
  src = RubyToRuby.translate(self.class, :hairy_method).sub(" h", " f")
122
117
 
123
118
  eval src
124
-
125
- blk = lambda{|x,y,z,arr|
119
+
120
+ blk = lambda{|x,y,z,arr|
126
121
  unless y
127
122
  x.to_i*2
128
123
  else
@@ -137,3 +132,17 @@ class R2RTest < Test::Unit::TestCase
137
132
  assert_equal("ensure a-working", x1)
138
133
  end
139
134
  end
135
+
136
+ # TODO: pass your tests through yourself and run them again
137
+ # r2r2 = RubyToRuby.translate(RubyToRuby).sub("RubyToRuby","RubyToRuby2")
138
+ # begin
139
+ # Object.class_eval r2r2
140
+ # rescue SyntaxError => e
141
+ # $stderr.puts r2r2
142
+ # flunk "syntax error, see above (#{e.inspect})"
143
+ # end
144
+ # class TestRubyToRubyToRuby < TestRubyToRuby
145
+ # def setup
146
+ # @processor = RubyToRuby2.new
147
+ # end
148
+ # end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: ruby2ruby
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.1
7
- date: 2006-11-13 00:00:00 -05:00
6
+ version: 1.1.2
7
+ date: 2006-12-19 00:00:00 -08:00
8
8
  summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps.
9
9
  require_paths:
10
10
  - lib