sexp2ruby 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/.travis.yml +1 -2
- data/README.md +9 -0
- data/lib/{sexp2ruby/core_extensions → core_extensions}/regexp.rb +0 -0
- data/lib/sexp2ruby/node/alias.rb +9 -0
- data/lib/sexp2ruby/node/and.rb +9 -0
- data/lib/sexp2ruby/node/arglist.rb +16 -0
- data/lib/sexp2ruby/node/args.rb +33 -0
- data/lib/sexp2ruby/node/array.rb +9 -0
- data/lib/sexp2ruby/node/attrasgn.rb +27 -0
- data/lib/sexp2ruby/node/back_ref.rb +9 -0
- data/lib/sexp2ruby/node/base.rb +36 -0
- data/lib/sexp2ruby/node/begin.rb +19 -0
- data/lib/sexp2ruby/node/block.rb +24 -0
- data/lib/sexp2ruby/node/block_pass.rb +10 -0
- data/lib/sexp2ruby/node/break.rb +14 -0
- data/lib/sexp2ruby/node/call.rb +70 -0
- data/lib/sexp2ruby/node/case.rb +27 -0
- data/lib/sexp2ruby/node/cdecl.rb +17 -0
- data/lib/sexp2ruby/node/class.rb +9 -0
- data/lib/sexp2ruby/node/colon2.rb +9 -0
- data/lib/sexp2ruby/node/colon3.rb +9 -0
- data/lib/sexp2ruby/node/const.rb +9 -0
- data/lib/sexp2ruby/node/cvar.rb +9 -0
- data/lib/sexp2ruby/node/cvasgn.rb +9 -0
- data/lib/sexp2ruby/node/cvdecl.rb +9 -0
- data/lib/sexp2ruby/node/defined.rb +9 -0
- data/lib/sexp2ruby/node/defn.rb +66 -0
- data/lib/sexp2ruby/node/defs.rb +17 -0
- data/lib/sexp2ruby/node/dot2.rb +9 -0
- data/lib/sexp2ruby/node/dot3.rb +9 -0
- data/lib/sexp2ruby/node/dregx.rb +19 -0
- data/lib/sexp2ruby/node/dregx_once.rb +9 -0
- data/lib/sexp2ruby/node/dstr.rb +9 -0
- data/lib/sexp2ruby/node/dsym.rb +9 -0
- data/lib/sexp2ruby/node/dxstr.rb +9 -0
- data/lib/sexp2ruby/node/ensure.rb +18 -0
- data/lib/sexp2ruby/node/evstr.rb +9 -0
- data/lib/sexp2ruby/node/false.rb +9 -0
- data/lib/sexp2ruby/node/flip2.rb +9 -0
- data/lib/sexp2ruby/node/flip3.rb +9 -0
- data/lib/sexp2ruby/node/for.rb +17 -0
- data/lib/sexp2ruby/node/gasgn.rb +9 -0
- data/lib/sexp2ruby/node/gvar.rb +9 -0
- data/lib/sexp2ruby/node/hash.rb +53 -0
- data/lib/sexp2ruby/node/iasgn.rb +14 -0
- data/lib/sexp2ruby/node/if.rb +41 -0
- data/lib/sexp2ruby/node/iter.rb +50 -0
- data/lib/sexp2ruby/node/ivar.rb +9 -0
- data/lib/sexp2ruby/node/kwsplat.rb +9 -0
- data/lib/sexp2ruby/node/lasgn.rb +11 -0
- data/lib/sexp2ruby/node/lit.rb +15 -0
- data/lib/sexp2ruby/node/lvar.rb +9 -0
- data/lib/sexp2ruby/node/masgn.rb +46 -0
- data/lib/sexp2ruby/node/match.rb +9 -0
- data/lib/sexp2ruby/node/match2.rb +11 -0
- data/lib/sexp2ruby/node/match3.rb +17 -0
- data/lib/sexp2ruby/node/module.rb +9 -0
- data/lib/sexp2ruby/node/next.rb +14 -0
- data/lib/sexp2ruby/node/nil.rb +9 -0
- data/lib/sexp2ruby/node/not.rb +9 -0
- data/lib/sexp2ruby/node/nth_ref.rb +9 -0
- data/lib/sexp2ruby/node/op_asgn1.rb +16 -0
- data/lib/sexp2ruby/node/op_asgn2.rb +17 -0
- data/lib/sexp2ruby/node/op_asgn_and.rb +13 -0
- data/lib/sexp2ruby/node/op_asgn_or.rb +13 -0
- data/lib/sexp2ruby/node/or.rb +9 -0
- data/lib/sexp2ruby/node/postexe.rb +9 -0
- data/lib/sexp2ruby/node/redo.rb +9 -0
- data/lib/sexp2ruby/node/resbody.rb +19 -0
- data/lib/sexp2ruby/node/rescue.rb +32 -0
- data/lib/sexp2ruby/node/retry.rb +9 -0
- data/lib/sexp2ruby/node/return.rb +13 -0
- data/lib/sexp2ruby/node/sclass.rb +9 -0
- data/lib/sexp2ruby/node/self.rb +9 -0
- data/lib/sexp2ruby/node/splat.rb +13 -0
- data/lib/sexp2ruby/node/str.rb +9 -0
- data/lib/sexp2ruby/node/super.rb +10 -0
- data/lib/sexp2ruby/node/svalue.rb +13 -0
- data/lib/sexp2ruby/node/to_ary.rb +9 -0
- data/lib/sexp2ruby/node/true.rb +9 -0
- data/lib/sexp2ruby/node/undef.rb +9 -0
- data/lib/sexp2ruby/node/until.rb +9 -0
- data/lib/sexp2ruby/node/valias.rb +9 -0
- data/lib/sexp2ruby/node/when.rb +24 -0
- data/lib/sexp2ruby/node/while.rb +9 -0
- data/lib/sexp2ruby/node/xstr.rb +9 -0
- data/lib/sexp2ruby/node/yield.rb +18 -0
- data/lib/sexp2ruby/node/zsuper.rb +9 -0
- data/lib/sexp2ruby/processor.rb +121 -912
- data/lib/sexp2ruby/version.rb +1 -1
- data/lib/sexp2ruby.rb +88 -1
- data/sexp2ruby.gemspec +1 -0
- data/spec/lib/processor_spec.rb +478 -1
- metadata +104 -8
- data/Rakefile +0 -92
- data/test/test_ruby2ruby.rb +0 -496
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Ensure < Base
|
4
|
+
def to_s(exp)
|
5
|
+
body = process exp.shift
|
6
|
+
ens = exp.shift
|
7
|
+
ens = nil if ens == s(:nil)
|
8
|
+
ens = process(ens) || "# do nothing"
|
9
|
+
ens = "begin\n#{ens}\nend\n" if ens =~ /(^|\n)rescue/
|
10
|
+
|
11
|
+
body.sub!(/\n\s*end\z/, '')
|
12
|
+
body = indent(body) unless body =~ /(^|\n)rescue/
|
13
|
+
|
14
|
+
"#{body}\nensure\n#{indent ens}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class For < Base
|
4
|
+
def to_s(exp)
|
5
|
+
recv = process exp.shift
|
6
|
+
iter = process exp.shift
|
7
|
+
body = exp.empty? ? nil : process(exp.shift)
|
8
|
+
|
9
|
+
result = ["for #{iter} in #{recv} do"]
|
10
|
+
result << indent(body ? body : "# do nothing")
|
11
|
+
result << "end"
|
12
|
+
|
13
|
+
result.join(LF)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Hash < Base
|
4
|
+
|
5
|
+
# Some sexp types are OK without parens when appearing as hash values.
|
6
|
+
# This list can include `:call`s because they're always printed with parens
|
7
|
+
# around their arguments. For example:
|
8
|
+
#
|
9
|
+
# { :foo => (bar("baz")) } # The outer parens are unnecessary
|
10
|
+
# { :foo => bar("baz") } # This is the normal code style
|
11
|
+
#
|
12
|
+
HASH_VAL_NO_PAREN = [
|
13
|
+
:call,
|
14
|
+
:false,
|
15
|
+
:lit,
|
16
|
+
:lvar,
|
17
|
+
:nil,
|
18
|
+
:str,
|
19
|
+
:true
|
20
|
+
]
|
21
|
+
|
22
|
+
def to_s(exp)
|
23
|
+
result = []
|
24
|
+
|
25
|
+
until exp.empty?
|
26
|
+
s = exp.shift
|
27
|
+
t = s.sexp_type
|
28
|
+
ruby19_key = ruby19_hash_key?(s)
|
29
|
+
lhs = process s
|
30
|
+
|
31
|
+
case t
|
32
|
+
when :kwsplat then
|
33
|
+
result << lhs
|
34
|
+
else
|
35
|
+
rhs = exp.shift
|
36
|
+
t = rhs.first
|
37
|
+
rhs = process rhs
|
38
|
+
rhs = "(#{rhs})" unless HASH_VAL_NO_PAREN.include? t
|
39
|
+
|
40
|
+
if hash_syntax == :ruby19 && ruby19_key
|
41
|
+
lhs.gsub!(/\A:/, "")
|
42
|
+
result << "#{lhs}: #{rhs}"
|
43
|
+
else
|
44
|
+
result << "#{lhs} => #{rhs}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
result.empty? ? "{}" : "{ #{result.join(', ')} }"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class If < Base
|
4
|
+
def to_s(exp)
|
5
|
+
expand = ASSIGN_NODES.include? exp.first.first
|
6
|
+
c = process exp.shift
|
7
|
+
t = process exp.shift
|
8
|
+
f = process exp.shift
|
9
|
+
|
10
|
+
c = "(#{c.chomp})" if c =~ /\n/
|
11
|
+
|
12
|
+
if t
|
13
|
+
unless expand
|
14
|
+
if f
|
15
|
+
r = "#{c} ? (#{t}) : (#{f})"
|
16
|
+
r = nil if r =~ /return/ # HACK - need contextual awareness or something
|
17
|
+
else
|
18
|
+
r = "#{t} if #{c}"
|
19
|
+
end
|
20
|
+
return r if r and (indent_lvl + r).size < LINE_LENGTH and r !~ /\n/
|
21
|
+
end
|
22
|
+
|
23
|
+
r = "if #{c} then\n#{indent(t)}\n"
|
24
|
+
r << "else\n#{indent(f)}\n" if f
|
25
|
+
r << "end"
|
26
|
+
|
27
|
+
r
|
28
|
+
elsif f
|
29
|
+
unless expand
|
30
|
+
r = "#{f} unless #{c}"
|
31
|
+
return r if (indent_lvl + r).size < LINE_LENGTH and r !~ /\n/
|
32
|
+
end
|
33
|
+
"unless #{c} then\n#{indent(f)}\nend"
|
34
|
+
else
|
35
|
+
# empty if statement, just do it in case of side effects from condition
|
36
|
+
"if #{c} then\n#{indent '# do nothing'}\nend"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Iter < Base
|
4
|
+
def to_s(exp)
|
5
|
+
iter = process exp.shift
|
6
|
+
args = exp.shift
|
7
|
+
body = exp.empty? ? nil : process(exp.shift)
|
8
|
+
|
9
|
+
args = case args
|
10
|
+
when 0 then
|
11
|
+
""
|
12
|
+
else
|
13
|
+
" |#{process(args)[1..-2]}|"
|
14
|
+
end
|
15
|
+
|
16
|
+
b, e = if iter == "END"
|
17
|
+
[ "{", "}" ]
|
18
|
+
else
|
19
|
+
[ "do", "end" ]
|
20
|
+
end
|
21
|
+
|
22
|
+
iter.sub!(/\(\)$/, '')
|
23
|
+
|
24
|
+
# REFACTOR: ugh
|
25
|
+
result = []
|
26
|
+
result << "#{iter} {"
|
27
|
+
result << args
|
28
|
+
if body
|
29
|
+
result << " #{body.strip} "
|
30
|
+
else
|
31
|
+
result << ' '
|
32
|
+
end
|
33
|
+
result << "}"
|
34
|
+
result = result.join
|
35
|
+
return result if result !~ /\n/ and result.size < LINE_LENGTH
|
36
|
+
|
37
|
+
result = []
|
38
|
+
result << "#{iter} #{b}"
|
39
|
+
result << args
|
40
|
+
result << LF
|
41
|
+
if body
|
42
|
+
result << indent(body.strip)
|
43
|
+
result << LF
|
44
|
+
end
|
45
|
+
result << e
|
46
|
+
result.join
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Masgn < Base
|
4
|
+
|
5
|
+
# s(:masgn, s(:array, s(:lasgn, :var), ...), s(:to_ary, <val>, ...))
|
6
|
+
# s(:iter, <call>, s(:args, s(:masgn, :a, :b)), <body>)
|
7
|
+
def to_s(exp)
|
8
|
+
case exp.first
|
9
|
+
when Sexp then
|
10
|
+
lhs = exp.shift
|
11
|
+
rhs = exp.empty? ? nil : exp.shift
|
12
|
+
|
13
|
+
case lhs.first
|
14
|
+
when :array then
|
15
|
+
lhs.shift # node type
|
16
|
+
lhs = lhs.map do |l|
|
17
|
+
case l.first
|
18
|
+
when :masgn then
|
19
|
+
"(#{process(l)})"
|
20
|
+
else
|
21
|
+
process(l)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
raise "no clue: #{lhs.inspect}"
|
26
|
+
end
|
27
|
+
|
28
|
+
if rhs.nil?
|
29
|
+
return lhs.join(", ")
|
30
|
+
else
|
31
|
+
t = rhs.first
|
32
|
+
rhs = process rhs
|
33
|
+
rhs = rhs[1..-2] if t == :array # FIX: bad? I dunno
|
34
|
+
return "#{lhs.join(", ")} = #{rhs}"
|
35
|
+
end
|
36
|
+
when Symbol then # block arg list w/ masgn
|
37
|
+
result = exp.join ", "
|
38
|
+
exp.clear
|
39
|
+
"(#{result})"
|
40
|
+
else
|
41
|
+
raise "unknown masgn: #{exp.inspect}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Match3 < Base
|
4
|
+
def to_s(exp)
|
5
|
+
rhs = process(exp.shift)
|
6
|
+
left_type = exp.first.sexp_type
|
7
|
+
lhs = process(exp.shift)
|
8
|
+
|
9
|
+
if ASSIGN_NODES.include? left_type
|
10
|
+
"(#{lhs}) =~ #{rhs}"
|
11
|
+
else
|
12
|
+
"#{lhs} =~ #{rhs}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class OpAsgn1 < Base
|
4
|
+
|
5
|
+
# [[:lvar, :b], [:arglist, [:lit, 1]], :"||", [:lit, 10]]
|
6
|
+
def to_s(exp)
|
7
|
+
lhs = process(exp.shift)
|
8
|
+
index = process(exp.shift)
|
9
|
+
msg = exp.shift
|
10
|
+
rhs = process(exp.shift)
|
11
|
+
|
12
|
+
"#{lhs}[#{index}] #{msg}= #{rhs}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class OpAsgn2 < Base
|
4
|
+
|
5
|
+
# [[:lvar, :c], :var=, :"||", [:lit, 20]]
|
6
|
+
def to_s(exp)
|
7
|
+
lhs = process(exp.shift)
|
8
|
+
index = exp.shift.to_s[0..-2]
|
9
|
+
msg = exp.shift
|
10
|
+
|
11
|
+
rhs = process(exp.shift)
|
12
|
+
|
13
|
+
"#{lhs}.#{index} #{msg}= #{rhs}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Resbody < Base
|
4
|
+
def to_s(exp)
|
5
|
+
args = exp.shift
|
6
|
+
body = finish(exp)
|
7
|
+
body << "# do nothing" if body.empty?
|
8
|
+
|
9
|
+
name = args.lasgn true
|
10
|
+
name ||= args.iasgn true
|
11
|
+
args = process(args)[1..-2]
|
12
|
+
args = " #{args}" unless args.empty?
|
13
|
+
args += " => #{name[1]}" if name
|
14
|
+
|
15
|
+
"rescue#{args}\n#{indent body.join(LF)}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Sexp2Ruby
|
2
|
+
module Node
|
3
|
+
class Rescue < Base
|
4
|
+
def to_s(exp)
|
5
|
+
body = process(exp.shift) unless exp.first.first == :resbody
|
6
|
+
els = process(exp.pop) unless exp.last.first == :resbody
|
7
|
+
|
8
|
+
body ||= "# do nothing"
|
9
|
+
simple = exp.size == 1 && exp.resbody.size <= 3 &&
|
10
|
+
!exp.resbody.block &&
|
11
|
+
!exp.resbody.return
|
12
|
+
|
13
|
+
resbodies = []
|
14
|
+
until exp.empty? do
|
15
|
+
resbody = exp.shift
|
16
|
+
simple &&= resbody[1] == s(:array)
|
17
|
+
simple &&= resbody[2] != nil && resbody[2].node_type != :block
|
18
|
+
resbodies << process(resbody)
|
19
|
+
end
|
20
|
+
|
21
|
+
if els
|
22
|
+
"#{indent body}\n#{resbodies.join(LF)}\nelse\n#{indent els}"
|
23
|
+
elsif simple
|
24
|
+
resbody = resbodies.first.sub(/\n\s*/, ' ')
|
25
|
+
"#{body} #{resbody}"
|
26
|
+
else
|
27
|
+
"#{indent body}\n#{resbodies.join(LF)}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|