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