ruby2ruby 1.1.1 → 1.1.2

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