sexp2ruby 0.0.1 → 0.0.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.
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6521d5161ee2027c4a9fcfbfa58a6f8800a1032
|
|
4
|
+
data.tar.gz: dd984a8d70a35a285dae0b591e4cc523424c1417
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f87f34c8f9ca2006e15738e8329289ae087bc928b2d0c0eb06e9d813f20f7346796c0935347f0913841ff466cbe5b0f486856264944ee9e87dca4af76f2e77b2
|
|
7
|
+
data.tar.gz: 43e0e32832b2a01b3966770a812c917bc130f3489bb29d4900c5d554d110ee80badd8b50967a245c170aec0e15c510772277b00feb2dc12a2e6b7a6f3c9d2fd0
|
data/.rspec
ADDED
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
sexp2ruby
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
[![Build Status][5]][6] [![Code Climate][7]][8]
|
|
5
|
+
|
|
4
6
|
`sexp2ruby` generates ruby from RubyParser S-expressions.
|
|
5
7
|
It is a fork of [ruby2ruby][1] with slightly different goals.
|
|
6
8
|
|
|
7
9
|
- Generates ruby that follows [ruby-style-guide][3] where possible
|
|
8
10
|
- Prefers OO design over performance
|
|
11
|
+
- Drops support for ruby 1.8.7
|
|
12
|
+
- Depends on [activesupport][4]
|
|
9
13
|
- Uses bundler instead of hoe
|
|
10
14
|
- Uses rspec instead of minitest
|
|
11
15
|
|
|
@@ -30,3 +34,8 @@ so `deep_clone` if you need to preserve it.
|
|
|
30
34
|
[1]: https://github.com/seattlerb/ruby2ruby
|
|
31
35
|
[2]: http://docs.seattlerb.org/ruby2ruby
|
|
32
36
|
[3]: https://github.com/bbatsov/ruby-style-guide
|
|
37
|
+
[4]: https://rubygems.org/gems/activesupport
|
|
38
|
+
[5]: https://travis-ci.org/jaredbeck/sexp2ruby.svg
|
|
39
|
+
[6]: https://travis-ci.org/jaredbeck/sexp2ruby
|
|
40
|
+
[7]: https://codeclimate.com/github/jaredbeck/sexp2ruby/badges/gpa.svg
|
|
41
|
+
[8]: https://codeclimate.com/github/jaredbeck/sexp2ruby
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Arglist < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
code = []
|
|
6
|
+
until exp.empty? do
|
|
7
|
+
arg = exp.shift
|
|
8
|
+
to_wrap = arg.first == :rescue
|
|
9
|
+
arg_code = process arg
|
|
10
|
+
code << (to_wrap ? "(#{arg_code})" : arg_code)
|
|
11
|
+
end
|
|
12
|
+
code.join ', '
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Args < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
args = []
|
|
6
|
+
|
|
7
|
+
until exp.empty? do
|
|
8
|
+
arg = exp.shift
|
|
9
|
+
case arg
|
|
10
|
+
when Symbol then
|
|
11
|
+
args << arg
|
|
12
|
+
when Sexp then
|
|
13
|
+
case arg.first
|
|
14
|
+
when :lasgn then
|
|
15
|
+
args << process(arg)
|
|
16
|
+
when :masgn then
|
|
17
|
+
args << process(arg)
|
|
18
|
+
when :kwarg then
|
|
19
|
+
_, k, v = arg
|
|
20
|
+
args << "#{k}: #{process v}"
|
|
21
|
+
else
|
|
22
|
+
raise "unknown arg type #{arg.first.inspect}"
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
raise "unknown arg type #{arg.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
"(#{args.join ', '})"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Attrasgn < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
receiver = process exp.shift
|
|
6
|
+
name = exp.shift
|
|
7
|
+
rhs = exp.pop
|
|
8
|
+
args = s(:array, *exp)
|
|
9
|
+
exp.clear
|
|
10
|
+
|
|
11
|
+
case name
|
|
12
|
+
when :[]= then
|
|
13
|
+
args = process args
|
|
14
|
+
"#{receiver}#{args} = #{process rhs}"
|
|
15
|
+
else
|
|
16
|
+
raise "dunno what to do: #{args.inspect}" unless args.size == 1 # s(:array)
|
|
17
|
+
name = name.to_s.sub(/=$/, '')
|
|
18
|
+
if rhs && rhs != s(:arglist)
|
|
19
|
+
"#{receiver}.#{name} = #{process(rhs)}"
|
|
20
|
+
else
|
|
21
|
+
raise "dunno what to do: #{rhs.inspect}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
|
|
4
|
+
# A node in the AST.
|
|
5
|
+
class Base
|
|
6
|
+
ASSIGN_NODES = Processor::ASSIGN_NODES
|
|
7
|
+
LF = Processor::LF
|
|
8
|
+
LINE_LENGTH = 78 # cutoff for one-liners
|
|
9
|
+
|
|
10
|
+
attr_reader :processor
|
|
11
|
+
delegate(
|
|
12
|
+
:call_push,
|
|
13
|
+
:call_pop,
|
|
14
|
+
:cond_loop,
|
|
15
|
+
:hash_syntax,
|
|
16
|
+
:in_context,
|
|
17
|
+
:indent,
|
|
18
|
+
:indent_lvl,
|
|
19
|
+
:finish,
|
|
20
|
+
:parenthesize,
|
|
21
|
+
:process,
|
|
22
|
+
:process_arglist,
|
|
23
|
+
:process_dregx,
|
|
24
|
+
:process_iasgn,
|
|
25
|
+
:ruby19_hash_key?,
|
|
26
|
+
:util_dthing,
|
|
27
|
+
:util_module_or_class,
|
|
28
|
+
to: :processor
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def initialize(processor)
|
|
32
|
+
@processor = processor
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
|
|
4
|
+
# TODO: figure out how to do rescue and ensure ENTIRELY w/o begin
|
|
5
|
+
class Begin < Base
|
|
6
|
+
def to_s(exp)
|
|
7
|
+
code = []
|
|
8
|
+
code << "begin"
|
|
9
|
+
until exp.empty?
|
|
10
|
+
src = process(exp.shift)
|
|
11
|
+
src = indent(src) unless src =~ /(^|\n)(rescue|ensure)/ # ensure no level 0 rescues
|
|
12
|
+
code << src
|
|
13
|
+
end
|
|
14
|
+
code << "end"
|
|
15
|
+
code.join(LF)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Block < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
result = []
|
|
6
|
+
|
|
7
|
+
exp << nil if exp.empty?
|
|
8
|
+
until exp.empty? do
|
|
9
|
+
code = exp.shift
|
|
10
|
+
if code.nil? or code.first == :nil
|
|
11
|
+
result << "# do nothing\n"
|
|
12
|
+
else
|
|
13
|
+
result << process(code)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
result = parenthesize result.join LF
|
|
18
|
+
result += LF unless result.start_with? "("
|
|
19
|
+
|
|
20
|
+
result
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Call < Base
|
|
4
|
+
|
|
5
|
+
# binary operation messages
|
|
6
|
+
BINARY = [:<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :**, :'!=']
|
|
7
|
+
|
|
8
|
+
def to_s(exp)
|
|
9
|
+
receiver_node_type = exp.first.nil? ? nil : exp.first.first
|
|
10
|
+
receiver = process exp.shift
|
|
11
|
+
receiver = "(#{receiver})" if ASSIGN_NODES.include? receiver_node_type
|
|
12
|
+
|
|
13
|
+
name = exp.shift
|
|
14
|
+
args = []
|
|
15
|
+
|
|
16
|
+
# this allows us to do both old and new sexp forms:
|
|
17
|
+
exp.push(*exp.pop[1..-1]) if exp.size == 1 && exp.first.first == :arglist
|
|
18
|
+
|
|
19
|
+
call_push(name)
|
|
20
|
+
|
|
21
|
+
in_context :arglist do
|
|
22
|
+
until exp.empty? do
|
|
23
|
+
arg_type = exp.first.sexp_type
|
|
24
|
+
is_empty_hash = (exp.first == s(:hash))
|
|
25
|
+
arg = process exp.shift
|
|
26
|
+
|
|
27
|
+
next if arg.empty?
|
|
28
|
+
|
|
29
|
+
strip_hash = (arg_type == :hash and
|
|
30
|
+
not BINARY.include? name and
|
|
31
|
+
not is_empty_hash and
|
|
32
|
+
(exp.empty? or exp.first.sexp_type == :splat))
|
|
33
|
+
wrap_arg = ASSIGN_NODES.include? arg_type
|
|
34
|
+
|
|
35
|
+
arg = arg[2..-3] if strip_hash
|
|
36
|
+
arg = "(#{arg})" if wrap_arg
|
|
37
|
+
|
|
38
|
+
args << arg
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
case name
|
|
43
|
+
when *BINARY then
|
|
44
|
+
"(#{receiver} #{name} #{args.join(', ')})"
|
|
45
|
+
when :[] then
|
|
46
|
+
receiver ||= "self"
|
|
47
|
+
"#{receiver}[#{args.join(', ')}]"
|
|
48
|
+
when :[]= then
|
|
49
|
+
receiver ||= "self"
|
|
50
|
+
rhs = args.pop
|
|
51
|
+
"#{receiver}[#{args.join(', ')}] = #{rhs}"
|
|
52
|
+
when :"!" then
|
|
53
|
+
"(not #{receiver})"
|
|
54
|
+
when :"-@" then
|
|
55
|
+
"-#{receiver}"
|
|
56
|
+
when :"+@" then
|
|
57
|
+
"+#{receiver}"
|
|
58
|
+
else
|
|
59
|
+
args = nil if args.empty?
|
|
60
|
+
args = "(#{args.join(', ')})" if args
|
|
61
|
+
receiver = "#{receiver}." if receiver
|
|
62
|
+
|
|
63
|
+
"#{receiver}#{name}#{args}"
|
|
64
|
+
end
|
|
65
|
+
ensure
|
|
66
|
+
call_pop
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Case < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
result = []
|
|
6
|
+
expr = process exp.shift
|
|
7
|
+
if expr
|
|
8
|
+
result << "case #{expr}"
|
|
9
|
+
else
|
|
10
|
+
result << "case"
|
|
11
|
+
end
|
|
12
|
+
until exp.empty?
|
|
13
|
+
pt = exp.shift
|
|
14
|
+
if pt and pt.first == :when
|
|
15
|
+
result << "#{process(pt)}"
|
|
16
|
+
else
|
|
17
|
+
code = indent(process(pt))
|
|
18
|
+
code = indent("# do nothing") if code =~ /^\s*$/
|
|
19
|
+
result << "else\n#{code}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
result << "end"
|
|
23
|
+
result.join(LF)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Defn < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
type1 = exp[1].first
|
|
6
|
+
type2 = exp[2].first rescue nil
|
|
7
|
+
expect = [:ivar, :iasgn, :attrset]
|
|
8
|
+
|
|
9
|
+
# s(name, args, ivar|iasgn|attrset)
|
|
10
|
+
if exp.size == 3 and type1 == :args and expect.include? type2
|
|
11
|
+
name = exp.first # don't shift in case we pass through
|
|
12
|
+
case type2
|
|
13
|
+
when :ivar then
|
|
14
|
+
ivar_name = exp.ivar.last
|
|
15
|
+
|
|
16
|
+
meth_name = ivar_name.to_s[1..-1].to_sym
|
|
17
|
+
expected = s(meth_name, s(:args), s(:ivar, ivar_name))
|
|
18
|
+
|
|
19
|
+
if exp == expected
|
|
20
|
+
exp.clear
|
|
21
|
+
return "attr_reader #{name.inspect}"
|
|
22
|
+
end
|
|
23
|
+
when :attrset then
|
|
24
|
+
# TODO: deprecate? this is a PT relic
|
|
25
|
+
exp.clear
|
|
26
|
+
return "attr_writer :#{name.to_s[0..-2]}"
|
|
27
|
+
when :iasgn then
|
|
28
|
+
ivar_name = exp.iasgn[1]
|
|
29
|
+
meth_name = "#{ivar_name.to_s[1..-1]}=".to_sym
|
|
30
|
+
arg_name = exp.args.last
|
|
31
|
+
expected = s(meth_name, s(:args, arg_name),
|
|
32
|
+
s(:iasgn, ivar_name, s(:lvar, arg_name)))
|
|
33
|
+
|
|
34
|
+
if exp == expected
|
|
35
|
+
exp.clear
|
|
36
|
+
return "attr_writer :#{name.to_s[0..-2]}"
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
raise "Unknown defn type: #{exp.inspect}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
comm = exp.comments
|
|
44
|
+
name = exp.shift
|
|
45
|
+
args = process exp.shift
|
|
46
|
+
args = "" if args == "()"
|
|
47
|
+
|
|
48
|
+
exp.shift if exp == s(s(:nil)) # empty it out of a default nil expression
|
|
49
|
+
|
|
50
|
+
# REFACTOR: use process_block but get it happier wrt parenthesize
|
|
51
|
+
body = []
|
|
52
|
+
until exp.empty? do
|
|
53
|
+
body << process(exp.shift)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
body << "# do nothing" if body.empty?
|
|
57
|
+
body = body.join(LF)
|
|
58
|
+
body = body.lines.to_a[1..-2].join(LF) if
|
|
59
|
+
body =~ /^\Abegin/ && body =~ /^end\z/
|
|
60
|
+
body = indent(body) unless body =~ /(^|\n)rescue/
|
|
61
|
+
|
|
62
|
+
"#{comm}def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, LF)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Defs < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
lhs = exp.shift
|
|
6
|
+
var = [:self, :cvar, :dvar, :ivar, :gvar, :lvar].include? lhs.first
|
|
7
|
+
name = exp.shift
|
|
8
|
+
|
|
9
|
+
lhs = process(lhs)
|
|
10
|
+
lhs = "(#{lhs})" unless var
|
|
11
|
+
|
|
12
|
+
exp.unshift "#{lhs}.#{name}"
|
|
13
|
+
process_defn(exp)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Sexp2Ruby
|
|
2
|
+
module Node
|
|
3
|
+
class Dregx < Base
|
|
4
|
+
def to_s(exp)
|
|
5
|
+
options = re_opt exp.pop if Fixnum === exp.last
|
|
6
|
+
"/" << util_dthing(:dregx, exp) << "/#{options}"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Return the appropriate regexp flags for a given numeric code.
|
|
12
|
+
def re_opt options
|
|
13
|
+
bits = (0..8).map { |n| options[n] * 2**n }
|
|
14
|
+
bits.delete 0
|
|
15
|
+
bits.map { |n| Regexp::CODES[n] }.join
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|