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.
- data/History.txt +10 -0
- data/lib/ruby2ruby.rb +76 -55
- data/test/test_ruby2ruby.rb +23 -14
- 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.
|
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
|
-
|
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
|
-
|
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
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
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
|
data/test/test_ruby2ruby.rb
CHANGED
@@ -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.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.
|
7
|
-
date: 2006-
|
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
|