ruby2ruby 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/lib/ruby2ruby.rb +92 -62
- data/test/test_ruby2ruby.rb +8 -3
- metadata +5 -6
data/History.txt
CHANGED
data/lib/ruby2ruby.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
|
3
|
+
begin require 'rubygems'; rescue LoadError; end
|
2
4
|
require 'parse_tree'
|
3
5
|
require 'sexp_processor'
|
4
6
|
|
5
|
-
class NilClass
|
7
|
+
class NilClass # Objective-C trick
|
6
8
|
def method_missing(msg, *args, &block)
|
7
9
|
nil
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
13
|
class RubyToRuby < SexpProcessor
|
12
|
-
VERSION = '1.1.
|
14
|
+
VERSION = '1.1.1'
|
13
15
|
|
14
16
|
def self.translate(klass_or_str, method=nil)
|
15
17
|
self.new.process(ParseTree.translate(klass_or_str, method))
|
@@ -136,6 +138,7 @@ class RubyToRuby < SexpProcessor
|
|
136
138
|
|
137
139
|
until exp.empty? do
|
138
140
|
found = exp.first.first == :block_arg rescue false
|
141
|
+
|
139
142
|
if found then
|
140
143
|
raise "wtf"
|
141
144
|
result[-1] = result[-1][0..-2] + ", #{process(exp.shift)})"
|
@@ -223,9 +226,17 @@ class RubyToRuby < SexpProcessor
|
|
223
226
|
s << " < #{superk}" if superk
|
224
227
|
s << "\n"
|
225
228
|
|
226
|
-
body =
|
227
|
-
|
228
|
-
|
229
|
+
body = []
|
230
|
+
begin
|
231
|
+
code = process(exp.shift).chomp
|
232
|
+
body << code unless code.nil? or code.empty?
|
233
|
+
end until exp.empty?
|
234
|
+
unless body.empty? then
|
235
|
+
body = indent(body.join("\n\n")) + "\n"
|
236
|
+
else
|
237
|
+
body = ""
|
238
|
+
end
|
239
|
+
s + body + "end"
|
229
240
|
end
|
230
241
|
|
231
242
|
def process_colon2(exp)
|
@@ -273,6 +284,7 @@ class RubyToRuby < SexpProcessor
|
|
273
284
|
def process_defn(exp)
|
274
285
|
t = exp[1].first
|
275
286
|
t2 = exp[2].first rescue nil
|
287
|
+
|
276
288
|
if t == :args and [:ivar, :attrset].include? t2 then
|
277
289
|
name = exp.shift
|
278
290
|
case t2
|
@@ -303,7 +315,6 @@ class RubyToRuby < SexpProcessor
|
|
303
315
|
name = exp.shift
|
304
316
|
exp.shift # :fcall to define_method
|
305
317
|
body = process(exp.shift)
|
306
|
-
p name, body
|
307
318
|
raise "no"
|
308
319
|
else
|
309
320
|
raise "Unknown defn type: #{t} for #{exp.inspect}"
|
@@ -429,33 +440,18 @@ p name, body
|
|
429
440
|
end
|
430
441
|
|
431
442
|
def process_if(exp)
|
432
|
-
|
443
|
+
c = process exp.shift
|
433
444
|
t = process exp.shift
|
445
|
+
f = process exp.shift
|
434
446
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
case code.first
|
443
|
-
when nil
|
444
|
-
# do nothing
|
445
|
-
when :if then
|
446
|
-
s << "els#{process(code).sub(/\nend\Z/, '')}"
|
447
|
-
else
|
448
|
-
s << "else\n#{cond_indent_process(code)}"
|
449
|
-
end
|
450
|
-
|
451
|
-
if t.nil? then
|
452
|
-
s[-1] = s[-1][5..-1] # remove else\n
|
453
|
-
t = true
|
454
|
-
end
|
447
|
+
if t then
|
448
|
+
r = "if #{c} then\n#{indent(t)}\n"
|
449
|
+
r << "else\n#{indent(f)}\n" if f
|
450
|
+
r << "end"
|
451
|
+
r
|
452
|
+
else
|
453
|
+
"unless #{c} then\n#{indent(f)}\nend"
|
455
454
|
end
|
456
|
-
s << "end"
|
457
|
-
|
458
|
-
s.join("\n")
|
459
455
|
end
|
460
456
|
|
461
457
|
def process_iter(exp)
|
@@ -545,9 +541,17 @@ p name, body
|
|
545
541
|
|
546
542
|
def process_module(exp)
|
547
543
|
s = "module #{exp.shift}\n"
|
548
|
-
body =
|
549
|
-
|
550
|
-
|
544
|
+
body = []
|
545
|
+
begin
|
546
|
+
code = process exp.shift
|
547
|
+
body << code unless code.nil? or code.empty?
|
548
|
+
end until exp.empty?
|
549
|
+
unless body.empty? then
|
550
|
+
body = indent(body.join("\n\n")) + "\n"
|
551
|
+
else
|
552
|
+
body = ""
|
553
|
+
end
|
554
|
+
s + body + "end"
|
551
555
|
end
|
552
556
|
|
553
557
|
def process_next(exp)
|
@@ -616,9 +620,10 @@ p name, body
|
|
616
620
|
def process_resbody(exp) # TODO: rewrite this fucker
|
617
621
|
code = []
|
618
622
|
|
619
|
-
|
620
|
-
|
621
|
-
|
623
|
+
sexp = exp
|
624
|
+
until exp.empty? and (sexp.nil? or sexp.empty?)
|
625
|
+
list = sexp.shift
|
626
|
+
body = sexp.shift
|
622
627
|
|
623
628
|
var = if list.last.first == :lasgn then
|
624
629
|
list.pop[1]
|
@@ -636,13 +641,16 @@ p name, body
|
|
636
641
|
code.last << " => #{var}" if var
|
637
642
|
|
638
643
|
if body then
|
639
|
-
code << indent(process(body))
|
644
|
+
code << indent(process(body)).chomp
|
640
645
|
else
|
641
646
|
code << indent("# do nothing")
|
642
647
|
end
|
643
648
|
|
644
|
-
|
645
|
-
|
649
|
+
sexp = exp.shift
|
650
|
+
if sexp then
|
651
|
+
assert_type sexp, :resbody
|
652
|
+
sexp.shift
|
653
|
+
end
|
646
654
|
end
|
647
655
|
|
648
656
|
code.join("\n")
|
@@ -653,20 +661,35 @@ p name, body
|
|
653
661
|
#
|
654
662
|
# a = b rescue c => [lasgn a [rescue b c]]
|
655
663
|
# begin; a = b; rescue c => [begin [rescue [lasgn a b] c]]
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
code
|
665
|
-
code << indent(
|
666
|
-
|
667
|
-
|
664
|
+
stack = caller.map { |s| s[/process_\w+/] }.compact
|
665
|
+
|
666
|
+
case stack.first
|
667
|
+
when "process_begin", "process_ensure", "process_block" then
|
668
|
+
body = process exp.shift
|
669
|
+
resbody = process exp.shift
|
670
|
+
els = process exp.shift
|
671
|
+
|
672
|
+
code = []
|
673
|
+
code << indent(body)
|
674
|
+
code << resbody
|
675
|
+
if els then
|
676
|
+
code << "else"
|
677
|
+
code << indent(els)
|
678
|
+
else
|
679
|
+
code << "end\n"
|
680
|
+
end
|
681
|
+
code.join("\n")
|
682
|
+
else # a rescue b and others
|
683
|
+
body = process exp.shift
|
684
|
+
assert_type exp.first, :resbody
|
685
|
+
resbody = exp.shift
|
686
|
+
resbody.shift # resbody
|
687
|
+
resbody.shift # nil (no types for expression form)
|
688
|
+
resbody = resbody.shift # actual code
|
689
|
+
|
690
|
+
resbody = process resbody
|
691
|
+
"#{body} rescue #{resbody}"
|
668
692
|
end
|
669
|
-
code.join("\n")
|
670
693
|
end
|
671
694
|
|
672
695
|
def process_retry(exp)
|
@@ -674,7 +697,7 @@ p name, body
|
|
674
697
|
end
|
675
698
|
|
676
699
|
def process_return(exp)
|
677
|
-
return "return #{process exp.shift}"
|
700
|
+
return "return" + (exp.empty? ? "" : " #{process exp.shift}")
|
678
701
|
end
|
679
702
|
|
680
703
|
def process_sclass(exp)
|
@@ -682,7 +705,7 @@ p name, body
|
|
682
705
|
end
|
683
706
|
|
684
707
|
def process_scope(exp)
|
685
|
-
return process(exp.shift)
|
708
|
+
return process(exp.shift) || ""
|
686
709
|
end
|
687
710
|
|
688
711
|
def process_self(exp)
|
@@ -766,17 +789,19 @@ p name, body
|
|
766
789
|
|
767
790
|
def cond_loop(exp, name)
|
768
791
|
cond = process(exp.shift)
|
769
|
-
body =
|
770
|
-
head_controlled = exp.
|
792
|
+
body = process(exp.shift)
|
793
|
+
head_controlled = exp.shift
|
794
|
+
|
795
|
+
body = indent(body).chomp if body
|
771
796
|
|
772
797
|
code = []
|
773
798
|
if head_controlled then
|
774
799
|
code << "#{name} #{cond} do"
|
775
|
-
code << body
|
800
|
+
code << body if body
|
776
801
|
code << "end"
|
777
802
|
else
|
778
803
|
code << "begin"
|
779
|
-
code << body
|
804
|
+
code << body if body
|
780
805
|
code << "end #{name} #{cond}"
|
781
806
|
end
|
782
807
|
code.join("\n")
|
@@ -858,7 +883,7 @@ p name, body
|
|
858
883
|
result = []
|
859
884
|
|
860
885
|
code = result
|
861
|
-
while exp.first == :resbody do
|
886
|
+
while exp and exp.first == :resbody do
|
862
887
|
code << exp.shift
|
863
888
|
list = exp.shift
|
864
889
|
body = exp.shift
|
@@ -876,7 +901,7 @@ p name, body
|
|
876
901
|
# TODO: check that it is assigning $!
|
877
902
|
list << body.delete_at(1) if body[1].first == :lasgn
|
878
903
|
else
|
879
|
-
|
904
|
+
# do nothing (expression form)
|
880
905
|
end
|
881
906
|
|
882
907
|
code << list << body
|
@@ -914,6 +939,10 @@ class Method
|
|
914
939
|
ParseTree.new(false).parse_tree_for_method(klass, method)
|
915
940
|
end
|
916
941
|
end
|
942
|
+
|
943
|
+
def to_ruby
|
944
|
+
RubyToRuby.new.process(self.to_sexp)
|
945
|
+
end
|
917
946
|
end
|
918
947
|
|
919
948
|
class ProcStoreTmp
|
@@ -948,7 +977,8 @@ class Proc
|
|
948
977
|
end
|
949
978
|
|
950
979
|
def to_ruby
|
951
|
-
|
980
|
+
name = ProcStoreTmp.name
|
981
|
+
self.to_method.to_ruby.sub(/def [^\(]+\(([^\)]*)\)/,
|
952
982
|
'proc { |\1|').sub(/end\Z/, '}')
|
953
983
|
end
|
954
984
|
end
|
data/test/test_ruby2ruby.rb
CHANGED
@@ -65,10 +65,15 @@ end
|
|
65
65
|
|
66
66
|
class R2RTest < Test::Unit::TestCase
|
67
67
|
|
68
|
-
def
|
68
|
+
def test_self_translation
|
69
69
|
r2r2r = RubyToRuby.translate(RubyToRuby).sub("RubyToRuby","RubyToRubyToRuby")
|
70
70
|
|
71
|
-
|
71
|
+
begin
|
72
|
+
Object.class_eval r2r2r
|
73
|
+
rescue SyntaxError => e
|
74
|
+
$stderr.puts r2r2r
|
75
|
+
flunk "syntax error, see above (#{e.inspect})"
|
76
|
+
end
|
72
77
|
|
73
78
|
r2r2r2 = RubyToRubyToRuby.translate(RubyToRuby).sub("RubyToRuby","RubyToRubyToRuby")
|
74
79
|
r2r2r2r = RubyToRubyToRuby.translate(RubyToRubyToRuby)
|
@@ -112,7 +117,7 @@ class R2RTest < Test::Unit::TestCase
|
|
112
117
|
assert_equal(k, l)
|
113
118
|
end
|
114
119
|
|
115
|
-
def
|
120
|
+
def test_hairy_method
|
116
121
|
src = RubyToRuby.translate(self.class, :hairy_method).sub(" h", " f")
|
117
122
|
|
118
123
|
eval src
|
metadata
CHANGED
@@ -3,12 +3,11 @@ 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.1
|
7
|
+
date: 2006-11-13 00:00:00 -05: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
|
11
|
-
- test
|
12
11
|
email: ryand-ruby@zenspider.com
|
13
12
|
homepage: http://seattlerb.rubyforge.org/
|
14
13
|
rubyforge_project: seattlerb
|
@@ -36,8 +35,8 @@ files:
|
|
36
35
|
- Rakefile
|
37
36
|
- lib/ruby2ruby.rb
|
38
37
|
- test/test_ruby2ruby.rb
|
39
|
-
test_files:
|
40
|
-
|
38
|
+
test_files:
|
39
|
+
- test/test_ruby2ruby.rb
|
41
40
|
rdoc_options: []
|
42
41
|
|
43
42
|
extra_rdoc_files: []
|
@@ -56,7 +55,7 @@ dependencies:
|
|
56
55
|
requirements:
|
57
56
|
- - ">="
|
58
57
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.1.
|
58
|
+
version: 1.1.4
|
60
59
|
version:
|
61
60
|
- !ruby/object:Gem::Dependency
|
62
61
|
name: ParseTree
|