ruby2ruby 1.1.8 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +19 -0
- data/README.txt +4 -3
- data/Rakefile +12 -9
- data/bin/r2r_show +16 -31
- data/lib/ruby2ruby.rb +34 -20
- data/test/test_ruby2ruby.rb +48 -23
- metadata +7 -6
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
=== 1.1.9 / 2008-06-09
|
2
|
+
|
3
|
+
* 5 minor enhancements:
|
4
|
+
|
5
|
+
* Added more defensive programming in the tests to make it work with 1.9 and rubinius better.
|
6
|
+
* Converted r2r_show to more plain parse style, no more discover_new_classes.
|
7
|
+
* Made Proc#to_sexp and #to_ruby more resiliant.
|
8
|
+
* Started to work on fallback to ruby_parser code. Should prolly do flog first.
|
9
|
+
* Updated rakefile and readme format for hoe. Much cleaner!
|
10
|
+
|
11
|
+
* 6 bug fixes:
|
12
|
+
|
13
|
+
* Added 1.9 fixes.
|
14
|
+
* Added code to tests to isolate rubyinline builds.
|
15
|
+
* Fixed miniunit-deprecated assertions
|
16
|
+
* Fixes for const2/3, esp in class names
|
17
|
+
* Renamed ProcStoreTmp#name to #new_name. dur.
|
18
|
+
* Skip proc tests in 1.9 since they require ParseTree.
|
19
|
+
|
1
20
|
=== 1.1.8 / 2007-08-21
|
2
21
|
|
3
22
|
* 6 minor enhancements:
|
data/README.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
dirs = %w(
|
3
|
+
dirs = (%w(lib ../../ParseTree/dev/test) +
|
4
|
+
%w(ParseTree RubyInline ruby_parser).map { |p| "../../#{p}/dev/lib" })
|
4
5
|
$:.push(*dirs)
|
5
6
|
ENV['RUBY_FLAGS'] = "-I" + dirs.join(":")
|
6
7
|
|
@@ -8,14 +9,16 @@ require 'rubygems'
|
|
8
9
|
require 'hoe'
|
9
10
|
require './lib/ruby2ruby.rb'
|
10
11
|
|
11
|
-
Hoe.new('ruby2ruby', RubyToRuby::VERSION) do |
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
Hoe.new('ruby2ruby', RubyToRuby::VERSION) do |r2r|
|
13
|
+
r2r.rubyforge_name = 'seattlerb'
|
14
|
+
r2r.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
|
15
|
+
|
16
|
+
r2r.clean_globs << File.expand_path("~/.ruby_inline")
|
17
|
+
r2r.extra_deps << "ParseTree"
|
18
|
+
|
19
|
+
r2r.multiruby_skip << "rubinius"
|
19
20
|
end
|
20
21
|
|
22
|
+
task :test => :clean
|
23
|
+
|
21
24
|
# vim: syntax=Ruby
|
data/bin/r2r_show
CHANGED
@@ -2,43 +2,28 @@
|
|
2
2
|
|
3
3
|
begin require 'rubygems' rescue LoadError end
|
4
4
|
require 'ruby2ruby'
|
5
|
+
require 'parse_tree'
|
5
6
|
|
6
|
-
|
7
|
-
old_classes = []
|
8
|
-
ObjectSpace.each_object(Module) do |klass|
|
9
|
-
old_classes << klass
|
10
|
-
end
|
7
|
+
$h ||= false
|
11
8
|
|
12
|
-
|
9
|
+
if $h then
|
10
|
+
puts "usage: #{File.basename $0} [options] [file...]"
|
11
|
+
puts "options:"
|
12
|
+
puts "-h : display usage"
|
13
13
|
|
14
|
-
|
15
|
-
ObjectSpace.each_object(Module) do |klass|
|
16
|
-
new_classes << klass
|
17
|
-
end
|
18
|
-
|
19
|
-
new_classes -= old_classes
|
20
|
-
new_classes = [ eval($c) ] if defined? $c
|
21
|
-
new_classes
|
14
|
+
exit 1
|
22
15
|
end
|
23
16
|
|
24
|
-
|
25
|
-
|
26
|
-
new_classes = discover_new_classes_from do
|
27
|
-
ARGV.unshift "-" if ARGV.empty?
|
28
|
-
ARGV.each do |name|
|
29
|
-
if name == "-" then
|
30
|
-
code = $stdin.read
|
31
|
-
code = "class Example; def example; #{code}; end; end" if $f
|
32
|
-
eval code unless code.nil?
|
33
|
-
else
|
34
|
-
require name
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
17
|
+
ARGV.push "-" if ARGV.empty?
|
38
18
|
|
39
|
-
|
19
|
+
parse_tree = ParseTree.new
|
20
|
+
ruby2ruby = Ruby2Ruby.new
|
40
21
|
|
41
|
-
|
22
|
+
ARGV.each do |file|
|
23
|
+
ruby = file == "-" ? $stdin.read : File.read(file)
|
42
24
|
|
43
|
-
|
25
|
+
sexp = parse_tree.parse_tree_for_string(ruby, file).first
|
26
|
+
|
27
|
+
puts ruby2ruby.process(sexp)
|
28
|
+
end
|
44
29
|
|
data/lib/ruby2ruby.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
2
|
|
3
3
|
begin require 'rubygems'; rescue LoadError; end
|
4
|
-
require 'parse_tree'
|
5
4
|
require 'sexp_processor'
|
6
5
|
require 'unified_ruby'
|
7
6
|
|
8
7
|
class Ruby2Ruby < SexpProcessor
|
9
8
|
include UnifiedRuby
|
10
9
|
|
11
|
-
VERSION = '1.1.
|
10
|
+
VERSION = '1.1.9'
|
12
11
|
LINE_LENGTH = 78
|
13
12
|
|
14
13
|
##
|
@@ -28,6 +27,7 @@ class Ruby2Ruby < SexpProcessor
|
|
28
27
|
]
|
29
28
|
|
30
29
|
def self.translate(klass_or_str, method = nil)
|
30
|
+
require 'parse_tree'
|
31
31
|
self.new.process(ParseTree.translate(klass_or_str, method))
|
32
32
|
end
|
33
33
|
|
@@ -274,7 +274,10 @@ class Ruby2Ruby < SexpProcessor
|
|
274
274
|
end
|
275
275
|
|
276
276
|
def process_cdecl(exp)
|
277
|
-
|
277
|
+
lhs = exp.shift
|
278
|
+
lhs = process lhs if Sexp === lhs
|
279
|
+
rhs = process exp.shift
|
280
|
+
"#{lhs} = #{rhs}"
|
278
281
|
end
|
279
282
|
|
280
283
|
def process_class(exp)
|
@@ -1000,30 +1003,39 @@ class Ruby2Ruby < SexpProcessor
|
|
1000
1003
|
end
|
1001
1004
|
|
1002
1005
|
def util_module_or_class(exp, is_class=false)
|
1003
|
-
|
1006
|
+
result = []
|
1007
|
+
|
1008
|
+
name = exp.shift
|
1009
|
+
name = process name if Sexp === name
|
1010
|
+
|
1011
|
+
result << name
|
1004
1012
|
|
1005
1013
|
if is_class then
|
1006
1014
|
superk = process(exp.shift)
|
1007
|
-
|
1015
|
+
result << " < #{superk}" if superk
|
1008
1016
|
end
|
1009
1017
|
|
1010
|
-
|
1018
|
+
result << "\n"
|
1011
1019
|
|
1012
1020
|
body = []
|
1013
1021
|
begin
|
1014
1022
|
code = process(exp.shift).chomp
|
1015
1023
|
body << code unless code.nil? or code.empty?
|
1016
1024
|
end until exp.empty?
|
1025
|
+
|
1017
1026
|
unless body.empty? then
|
1018
1027
|
body = indent(body.join("\n\n")) + "\n"
|
1019
1028
|
else
|
1020
1029
|
body = ""
|
1021
1030
|
end
|
1022
|
-
|
1031
|
+
result << body
|
1032
|
+
result << "end"
|
1033
|
+
|
1034
|
+
result.join
|
1023
1035
|
end
|
1024
1036
|
|
1025
1037
|
def indent(s)
|
1026
|
-
s.to_s.map{|line| @indent + line}.join
|
1038
|
+
s.to_s.split(/\n/).map{|line| @indent + line}.join("\n")
|
1027
1039
|
end
|
1028
1040
|
end
|
1029
1041
|
|
@@ -1042,8 +1054,10 @@ class Method
|
|
1042
1054
|
end
|
1043
1055
|
|
1044
1056
|
def to_sexp
|
1057
|
+
require 'parse_tree'
|
1058
|
+
parser = ParseTree.new(false)
|
1045
1059
|
with_class_and_method_name do |klass, method|
|
1046
|
-
|
1060
|
+
parser.parse_tree_for_method(klass, method)
|
1047
1061
|
end
|
1048
1062
|
end
|
1049
1063
|
|
@@ -1054,7 +1068,7 @@ end
|
|
1054
1068
|
|
1055
1069
|
class ProcStoreTmp
|
1056
1070
|
@@n = 0
|
1057
|
-
def self.
|
1071
|
+
def self.new_name
|
1058
1072
|
@@n += 1
|
1059
1073
|
return :"myproc#{@@n}"
|
1060
1074
|
end
|
@@ -1062,7 +1076,7 @@ end
|
|
1062
1076
|
|
1063
1077
|
class UnboundMethod
|
1064
1078
|
def to_ruby
|
1065
|
-
name = ProcStoreTmp.
|
1079
|
+
name = ProcStoreTmp.new_name
|
1066
1080
|
ProcStoreTmp.send(:define_method, name, self)
|
1067
1081
|
m = ProcStoreTmp.new.method(name)
|
1068
1082
|
result = m.to_ruby.sub(/def #{name}(?:\(([^\)]*)\))?/,
|
@@ -1073,22 +1087,22 @@ end
|
|
1073
1087
|
|
1074
1088
|
class Proc
|
1075
1089
|
def to_method
|
1076
|
-
name = ProcStoreTmp.
|
1090
|
+
name = ProcStoreTmp.new_name
|
1077
1091
|
ProcStoreTmp.send(:define_method, name, self)
|
1078
1092
|
ProcStoreTmp.new.method(name)
|
1079
1093
|
end
|
1080
1094
|
|
1081
1095
|
def to_sexp
|
1082
|
-
|
1083
|
-
[
|
1096
|
+
sexp = self.to_method.to_sexp
|
1097
|
+
body = sexp[2]
|
1098
|
+
body[0] = :block
|
1099
|
+
args = body.delete_at 1
|
1100
|
+
body = body[1] if body.size == 2
|
1101
|
+
|
1102
|
+
[:iter, [:fcall, :proc], args, body]
|
1084
1103
|
end
|
1085
1104
|
|
1086
1105
|
def to_ruby
|
1087
|
-
|
1088
|
-
ruby.sub!(/\A(def \S+)\(([^\)]*)\)/, '\1 |\2|') # move args
|
1089
|
-
ruby.sub!(/\Adef[^\n\|]+/, 'proc { ') # strip def name
|
1090
|
-
ruby.sub!(/end\Z/, '}') # strip end
|
1091
|
-
ruby.gsub!(/\s+$/, '') # trailing WS bugs me
|
1092
|
-
ruby
|
1106
|
+
Ruby2Ruby.new.process(self.to_sexp).sub(/^\Aproc do/, 'proc {').sub(/end\Z/, '}')
|
1093
1107
|
end
|
1094
1108
|
end
|
data/test/test_ruby2ruby.rb
CHANGED
@@ -4,19 +4,43 @@ $TESTING = true
|
|
4
4
|
|
5
5
|
$: << 'lib'
|
6
6
|
|
7
|
+
SKIP_PROCS = RUBY_VERSION >= "1.9" or defined? RUBY_ENGINE
|
8
|
+
|
7
9
|
require 'test/unit'
|
8
10
|
require 'ruby2ruby'
|
9
11
|
require 'pt_testcase'
|
12
|
+
require 'fileutils'
|
13
|
+
require 'tmpdir'
|
14
|
+
|
15
|
+
FileUtils.rm_rf File.expand_path("~/.ruby_inline") # for self-translation
|
10
16
|
|
11
17
|
class TestRuby2Ruby < Test::Unit::TestCase
|
18
|
+
|
19
|
+
alias :refute_nil :assert_not_nil unless defined? Mini
|
20
|
+
|
12
21
|
def setup
|
22
|
+
super
|
13
23
|
@processor = Ruby2Ruby.new
|
14
24
|
end
|
15
25
|
|
26
|
+
def teardown
|
27
|
+
unless $DEBUG then
|
28
|
+
FileUtils.rm_rf @rootdir
|
29
|
+
ENV.delete 'INLINEDIR'
|
30
|
+
end if defined?(@rootdir) && @rootdir
|
31
|
+
end
|
32
|
+
|
33
|
+
def util_setup_inline
|
34
|
+
@rootdir = File.join(Dir.tmpdir, "test_ruby_to_ruby.#{$$}")
|
35
|
+
Dir.mkdir @rootdir, 0700 unless test ?d, @rootdir
|
36
|
+
ENV['INLINEDIR'] = @rootdir
|
37
|
+
end
|
38
|
+
|
16
39
|
def test_proc_to_ruby
|
40
|
+
util_setup_inline
|
17
41
|
block = proc { puts "something" }
|
18
|
-
assert_equal
|
19
|
-
end
|
42
|
+
assert_equal 'proc { puts("something") }', block.to_ruby
|
43
|
+
end unless SKIP_PROCS
|
20
44
|
|
21
45
|
def test_lit_regexp_slash
|
22
46
|
inn = s(:lit, /blah\/blah/)
|
@@ -66,17 +90,19 @@ class TestRuby2Ruby < Test::Unit::TestCase
|
|
66
90
|
end
|
67
91
|
|
68
92
|
def test_proc_to_sexp
|
93
|
+
util_setup_inline
|
69
94
|
p = proc { 1 + 1 }
|
70
|
-
s = [:proc, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
|
95
|
+
s = [:iter, [:fcall, :proc], nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
|
71
96
|
assert_equal s, p.to_sexp
|
72
|
-
end
|
97
|
+
end unless SKIP_PROCS
|
73
98
|
|
74
99
|
def test_unbound_method_to_ruby
|
75
|
-
|
100
|
+
util_setup_inline
|
101
|
+
r = "proc { ||\n util_setup_inline\n p = proc { (1 + 1) }\n s = [:iter, [:fcall, :proc], nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]\n assert_equal(s, p.to_sexp)\n}"
|
76
102
|
m = self.class.instance_method(:test_proc_to_sexp)
|
77
103
|
|
78
104
|
assert_equal r, m.to_ruby
|
79
|
-
end
|
105
|
+
end unless SKIP_PROCS
|
80
106
|
|
81
107
|
eval ParseTreeTestCase.testcases.map { |node, data|
|
82
108
|
next if node == "vcall" # HACK
|
@@ -85,8 +111,8 @@ class TestRuby2Ruby < Test::Unit::TestCase
|
|
85
111
|
pt = #{data['ParseTree'].inspect}
|
86
112
|
rb = #{(data['Ruby2Ruby'] || data['Ruby']).inspect}
|
87
113
|
|
88
|
-
|
89
|
-
|
114
|
+
refute_nil pt, \"ParseTree for #{node} undefined\"
|
115
|
+
refute_nil rb, \"Ruby for #{node} undefined\"
|
90
116
|
|
91
117
|
assert_equal rb, @processor.process(pt)
|
92
118
|
end"
|
@@ -99,21 +125,17 @@ end
|
|
99
125
|
|
100
126
|
def morph_and_eval(processor, target, gen, n)
|
101
127
|
begin
|
102
|
-
|
103
|
-
|
128
|
+
processor = Object.const_get processor if Symbol === processor
|
129
|
+
target = Object.const_get target if Symbol === target
|
130
|
+
old_name = target.name
|
131
|
+
new_name = target.name.sub(/\d*$/, gen.to_s)
|
104
132
|
ruby = processor.translate(target).sub(old_name, new_name)
|
105
133
|
|
106
134
|
eval ruby
|
107
135
|
target.constants.each do |constant|
|
108
136
|
eval "#{new_name}::#{constant} = #{old_name}::#{constant}"
|
109
137
|
end
|
110
|
-
rescue
|
111
|
-
warn "Self-Translation Generation #{n} failed:"
|
112
|
-
warn "#{e.class}: #{e.message}"
|
113
|
-
warn ""
|
114
|
-
warn ruby
|
115
|
-
warn ""
|
116
|
-
rescue => e
|
138
|
+
rescue Exception => e
|
117
139
|
warn "Self-Translation Generation #{n} failed:"
|
118
140
|
warn "#{e.class}: #{e.message}"
|
119
141
|
warn ""
|
@@ -138,29 +160,32 @@ end
|
|
138
160
|
# t new 2 3
|
139
161
|
|
140
162
|
# Self-Translation: 1st Generation - morph Ruby2Ruby using Ruby2Ruby
|
141
|
-
morph_and_eval Ruby2Ruby, Ruby2Ruby, 2, 1 do
|
163
|
+
morph_and_eval :Ruby2Ruby, :Ruby2Ruby, 2, 1 do
|
142
164
|
class TestRuby2Ruby1 < TestRuby2Ruby
|
143
165
|
def setup
|
166
|
+
super
|
144
167
|
@processor = Ruby2Ruby2.new
|
145
168
|
end
|
146
169
|
end
|
147
|
-
end
|
170
|
+
end unless SKIP_PROCS
|
148
171
|
|
149
172
|
# Self-Translation: 2nd Generation - morph TestRuby2Ruby using Ruby2Ruby
|
150
|
-
morph_and_eval Ruby2Ruby, TestRuby2Ruby, 2, 2 do
|
173
|
+
morph_and_eval :Ruby2Ruby, :TestRuby2Ruby, 2, 2 do
|
151
174
|
# Self-Translation: 3rd Generation - test Ruby2Ruby2 with TestRuby2Ruby1
|
152
175
|
class TestRuby2Ruby3 < TestRuby2Ruby2
|
153
176
|
def setup
|
177
|
+
super
|
154
178
|
@processor = Ruby2Ruby2.new
|
155
179
|
end
|
156
180
|
end
|
157
|
-
end
|
181
|
+
end unless SKIP_PROCS
|
158
182
|
|
159
183
|
# Self-Translation: 4th (and final) Generation - fully circular
|
160
|
-
morph_and_eval(Ruby2Ruby2, Ruby2Ruby2, 3, 4) do
|
184
|
+
morph_and_eval(:Ruby2Ruby2, :Ruby2Ruby2, 3, 4) do
|
161
185
|
class TestRuby2Ruby4 < TestRuby2Ruby3
|
162
186
|
def setup
|
187
|
+
super
|
163
188
|
@processor = Ruby2Ruby3.new
|
164
189
|
end
|
165
190
|
end
|
166
|
-
end
|
191
|
+
end unless SKIP_PROCS
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2008-06-09 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -28,10 +28,11 @@ dependencies:
|
|
28
28
|
requirements:
|
29
29
|
- - ">="
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: 1.
|
31
|
+
version: 1.5.3
|
32
32
|
version:
|
33
33
|
description: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps. This makes making dynamic language processors much easier in ruby than ever before.
|
34
|
-
email:
|
34
|
+
email:
|
35
|
+
- ryand-ruby@zenspider.com
|
35
36
|
executables:
|
36
37
|
- r2r_show
|
37
38
|
extensions: []
|
@@ -72,9 +73,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
73
|
requirements: []
|
73
74
|
|
74
75
|
rubyforge_project: seattlerb
|
75
|
-
rubygems_version: 1.
|
76
|
+
rubygems_version: 1.1.1
|
76
77
|
signing_key:
|
77
78
|
specification_version: 2
|
78
|
-
summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps
|
79
|
+
summary: ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps
|
79
80
|
test_files:
|
80
81
|
- test/test_ruby2ruby.rb
|