unparser 0.0.1
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 +7 -0
- data/.circle.yml +4 -0
- data/.gitignore +2 -0
- data/.rspec +3 -0
- data/.travis.yml +16 -0
- data/Changelog.md +3 -0
- data/Gemfile +6 -0
- data/Gemfile.devtools +60 -0
- data/Guardfile +18 -0
- data/README.md +41 -0
- data/Rakefile +24 -0
- data/TODO +1 -0
- data/config/devtools.yml +2 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +3 -0
- data/config/reek.yml +107 -0
- data/config/yardstick.yml +2 -0
- data/lib/unparser/buffer.rb +93 -0
- data/lib/unparser/constants.rb +87 -0
- data/lib/unparser/emitter/alias.rb +27 -0
- data/lib/unparser/emitter/argument.rb +154 -0
- data/lib/unparser/emitter/assignment.rb +140 -0
- data/lib/unparser/emitter/begin.rb +179 -0
- data/lib/unparser/emitter/binary.rb +52 -0
- data/lib/unparser/emitter/block.rb +53 -0
- data/lib/unparser/emitter/break.rb +28 -0
- data/lib/unparser/emitter/case.rb +97 -0
- data/lib/unparser/emitter/cbase.rb +22 -0
- data/lib/unparser/emitter/class.rb +72 -0
- data/lib/unparser/emitter/def.rb +107 -0
- data/lib/unparser/emitter/defined.rb +27 -0
- data/lib/unparser/emitter/for.rb +50 -0
- data/lib/unparser/emitter/hookexe.rb +42 -0
- data/lib/unparser/emitter/if.rb +85 -0
- data/lib/unparser/emitter/literal/composed.rb +64 -0
- data/lib/unparser/emitter/literal/dynamic.rb +54 -0
- data/lib/unparser/emitter/literal/dynamic_body.rb +109 -0
- data/lib/unparser/emitter/literal/execute_string.rb +38 -0
- data/lib/unparser/emitter/literal/primitive.rb +49 -0
- data/lib/unparser/emitter/literal/range.rb +33 -0
- data/lib/unparser/emitter/literal/regexp.rb +96 -0
- data/lib/unparser/emitter/literal/singleton.rb +24 -0
- data/lib/unparser/emitter/literal.rb +7 -0
- data/lib/unparser/emitter/module.rb +37 -0
- data/lib/unparser/emitter/next.rb +22 -0
- data/lib/unparser/emitter/not.rb +25 -0
- data/lib/unparser/emitter/op_assign.rb +63 -0
- data/lib/unparser/emitter/redo.rb +22 -0
- data/lib/unparser/emitter/repetition.rb +33 -0
- data/lib/unparser/emitter/retry.rb +22 -0
- data/lib/unparser/emitter/return.rb +38 -0
- data/lib/unparser/emitter/root.rb +7 -0
- data/lib/unparser/emitter/send/binary.rb +100 -0
- data/lib/unparser/emitter/send/index.rb +82 -0
- data/lib/unparser/emitter/send/unary.rb +29 -0
- data/lib/unparser/emitter/send.rb +273 -0
- data/lib/unparser/emitter/splat.rb +24 -0
- data/lib/unparser/emitter/super.rb +46 -0
- data/lib/unparser/emitter/undef.rb +25 -0
- data/lib/unparser/emitter/variable.rb +83 -0
- data/lib/unparser/emitter/yield.rb +28 -0
- data/lib/unparser/emitter.rb +308 -0
- data/lib/unparser.rb +87 -0
- data/spec/integration/unparser/spike_spec.rb +914 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit/unparser/buffer/append_spec.rb +23 -0
- data/spec/unit/unparser/buffer/content_spec.rb +38 -0
- data/spec/unit/unparser/buffer/indent_spec.rb +18 -0
- data/spec/unit/unparser/buffer/nl_spec.rb +16 -0
- data/spec/unit/unparser/buffer/unindent_spec.rb +18 -0
- data/spec/unit/unparser/class_methods/unparse_spec.rb +16 -0
- data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +17 -0
- data/spec/unit/unparser/emitter/class_methods/visit_spec.rb +37 -0
- data/spec/unit/unparser/emitter/source_map/class_methods/emit_spec.rb +20 -0
- data/unparser.gemspec +24 -0
- metadata +201 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Emitter for def node
|
4
|
+
class Def < self
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# Emit name
|
9
|
+
#
|
10
|
+
# @return [undefined]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
#
|
14
|
+
abstract_method :emit_name
|
15
|
+
private :emit_name
|
16
|
+
|
17
|
+
# Return body node
|
18
|
+
#
|
19
|
+
# @return [Parser::AST::Node]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
abstract_method :body
|
24
|
+
private :body
|
25
|
+
|
26
|
+
# Perform dispatch
|
27
|
+
#
|
28
|
+
# @return [undefined]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
#
|
32
|
+
def dispatch
|
33
|
+
write(K_DEF, WS)
|
34
|
+
emit_name
|
35
|
+
emit_arguments
|
36
|
+
emit_body
|
37
|
+
k_end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Emit body
|
41
|
+
#
|
42
|
+
# @return [undefined]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
def emit_body
|
47
|
+
indented { visit(body) }
|
48
|
+
end
|
49
|
+
|
50
|
+
# Emit arguments
|
51
|
+
#
|
52
|
+
# @return [undefined]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
def emit_arguments
|
57
|
+
return if arguments.children.empty?
|
58
|
+
parentheses do
|
59
|
+
visit(arguments)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Instance def emitter
|
64
|
+
class Instance < self
|
65
|
+
|
66
|
+
handle :def
|
67
|
+
|
68
|
+
children :name, :arguments, :body
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
# Emit name
|
73
|
+
#
|
74
|
+
# @return [undefined]
|
75
|
+
#
|
76
|
+
# @api private
|
77
|
+
#
|
78
|
+
def emit_name
|
79
|
+
write(name.to_s)
|
80
|
+
end
|
81
|
+
|
82
|
+
end # Instance
|
83
|
+
|
84
|
+
# Emitter for defines on singleton
|
85
|
+
class Singleton < self
|
86
|
+
|
87
|
+
handle :defs
|
88
|
+
|
89
|
+
children :subject, :name, :arguments, :body
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
# Return mame
|
94
|
+
#
|
95
|
+
# @return [String]
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
#
|
99
|
+
def emit_name
|
100
|
+
visit(subject)
|
101
|
+
write(O_DOT, name.to_s)
|
102
|
+
end
|
103
|
+
|
104
|
+
end # Singleton
|
105
|
+
end # Def
|
106
|
+
end # Emitter
|
107
|
+
end # Unparser
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Emitter for defined? nodes
|
4
|
+
class Defined < self
|
5
|
+
|
6
|
+
handle :defined?
|
7
|
+
|
8
|
+
children :subject
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Perform dispatch
|
13
|
+
#
|
14
|
+
# @return [undefined]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def dispatch
|
19
|
+
write(K_DEFINED)
|
20
|
+
parentheses do
|
21
|
+
visit(subject)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end # Defined
|
26
|
+
end # Emitter
|
27
|
+
end # Unparser
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Emitter for for nodes
|
4
|
+
class For < self
|
5
|
+
|
6
|
+
handle :for
|
7
|
+
|
8
|
+
children :condition, :assignment, :body
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Perform dispatch
|
13
|
+
#
|
14
|
+
# @return [undefined]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def dispatch
|
19
|
+
write(K_FOR, WS)
|
20
|
+
emit_condition
|
21
|
+
emit_body
|
22
|
+
k_end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Emit assignment
|
26
|
+
#
|
27
|
+
# @return [undefined]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
def emit_condition
|
32
|
+
visit(condition)
|
33
|
+
write(WS, K_IN, WS)
|
34
|
+
visit(assignment)
|
35
|
+
write(WS, K_DO)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Emit body
|
39
|
+
#
|
40
|
+
# @return [undefined]
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
#
|
44
|
+
def emit_body
|
45
|
+
indented { visit(body) }
|
46
|
+
end
|
47
|
+
|
48
|
+
end # For
|
49
|
+
end # Emitter
|
50
|
+
end # Unparser
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Base class for pre and postexe emitters
|
4
|
+
class Hookexe < self
|
5
|
+
|
6
|
+
MAP = {
|
7
|
+
:preexe => K_PREEXE,
|
8
|
+
:postexe => K_POSTEXE
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
handle *MAP.keys
|
12
|
+
|
13
|
+
children :body
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Perfrom dispatch
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
def dispatch
|
24
|
+
write(MAP.fetch(node.type), WS)
|
25
|
+
parentheses(*CURLY_BRACKETS) do
|
26
|
+
emit_body
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Emit body
|
31
|
+
#
|
32
|
+
# @return [undefined]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
def emit_body
|
37
|
+
indented { visit(body) }
|
38
|
+
end
|
39
|
+
|
40
|
+
end # Hookexe
|
41
|
+
end # Emitter
|
42
|
+
end # Unparser
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
# Emitter if nodes
|
4
|
+
class If < self
|
5
|
+
|
6
|
+
handle :if
|
7
|
+
|
8
|
+
children :condition, :if_branch, :else_branch
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Perform dispatch
|
13
|
+
#
|
14
|
+
# @return [undefined]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def dispatch
|
19
|
+
write(keyword, WS)
|
20
|
+
emit_condition
|
21
|
+
emit_if_branch
|
22
|
+
emit_else_branch
|
23
|
+
k_end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Test for unless
|
27
|
+
#
|
28
|
+
# @return [true]
|
29
|
+
# if to emit as unless
|
30
|
+
#
|
31
|
+
# @return [false]
|
32
|
+
# otherwise
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
def unless?
|
37
|
+
!if_branch
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return keyword
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
#
|
46
|
+
def keyword
|
47
|
+
unless? ? K_UNLESS : K_IF
|
48
|
+
end
|
49
|
+
|
50
|
+
# Emit condition
|
51
|
+
#
|
52
|
+
# @return [undefined]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
#
|
56
|
+
def emit_condition
|
57
|
+
visit(condition)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Emit if branch
|
61
|
+
#
|
62
|
+
# @return [undefined]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
#
|
66
|
+
def emit_if_branch
|
67
|
+
return unless if_branch
|
68
|
+
indented { visit(if_branch) }
|
69
|
+
end
|
70
|
+
|
71
|
+
# Emit else branch
|
72
|
+
#
|
73
|
+
# @return [undefined]
|
74
|
+
#
|
75
|
+
# @api private
|
76
|
+
#
|
77
|
+
def emit_else_branch
|
78
|
+
return unless else_branch
|
79
|
+
write(K_ELSE) unless unless?
|
80
|
+
indented { visit(else_branch) }
|
81
|
+
end
|
82
|
+
|
83
|
+
end # If
|
84
|
+
end # Emitter
|
85
|
+
end # Unparser
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
|
5
|
+
# Emitter for hash keyvalue pair
|
6
|
+
class HashPair < self
|
7
|
+
HASHROCKET = ' => '.freeze
|
8
|
+
|
9
|
+
handle :pair
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Perform dispatch
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
def dispatch
|
20
|
+
delimited(children, HASHROCKET)
|
21
|
+
end
|
22
|
+
|
23
|
+
end # HashPair
|
24
|
+
|
25
|
+
# Base class for compound literal emitters
|
26
|
+
class Compound < self
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Perform dispatch
|
31
|
+
#
|
32
|
+
# @return [undefined]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
#
|
36
|
+
def dispatch
|
37
|
+
util = self.class
|
38
|
+
parentheses(util::OPEN, util::CLOSE) do
|
39
|
+
delimited(children, util::DELIMITER)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Hash literal emitter
|
44
|
+
class Hash < self
|
45
|
+
OPEN = '{'.freeze
|
46
|
+
CLOSE = '}'.freeze
|
47
|
+
DELIMITER = ', '.freeze
|
48
|
+
|
49
|
+
handle :hash
|
50
|
+
end # Hash
|
51
|
+
|
52
|
+
# Array literal emitter
|
53
|
+
class Array < self
|
54
|
+
OPEN = '['.freeze
|
55
|
+
CLOSE = ']'.freeze
|
56
|
+
DELIMITER = ', '.freeze
|
57
|
+
|
58
|
+
handle :array
|
59
|
+
end # Array
|
60
|
+
|
61
|
+
end # Compound
|
62
|
+
end # Literal
|
63
|
+
end # Emitter
|
64
|
+
end # Unparser
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
|
5
|
+
# Base class for dynamic literal emitters
|
6
|
+
class Dynamic < self
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Perform dispatch
|
11
|
+
#
|
12
|
+
# @return [undefined]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
#
|
16
|
+
def dispatch
|
17
|
+
util = self.class
|
18
|
+
parentheses(util::OPEN, util::CLOSE) do
|
19
|
+
visit(dynamic_body)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return dynamic body
|
24
|
+
#
|
25
|
+
# @return [Parser::AST::Node]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
def dynamic_body
|
30
|
+
Parser::AST::Node.new(:dyn_str_body, children)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Dynamic string literal emitter
|
34
|
+
class String < self
|
35
|
+
|
36
|
+
OPEN = CLOSE = '"'.freeze
|
37
|
+
handle :dstr
|
38
|
+
|
39
|
+
end # String
|
40
|
+
|
41
|
+
# Dynamic symbol literal emitter
|
42
|
+
class Symbol < self
|
43
|
+
|
44
|
+
OPEN = ':"'.freeze
|
45
|
+
CLOSE = '"'.freeze
|
46
|
+
|
47
|
+
handle :dsym
|
48
|
+
|
49
|
+
end # Symbol
|
50
|
+
|
51
|
+
end
|
52
|
+
end # Literal
|
53
|
+
end # Emitter
|
54
|
+
end # Unparser
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
|
5
|
+
# Emitter for dynamic bodies
|
6
|
+
class DynamicBody < self
|
7
|
+
|
8
|
+
OPEN = '#{'.freeze
|
9
|
+
CLOSE = '}'.freeze
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Perform dispatch
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
def dispatch
|
20
|
+
children.each do |node|
|
21
|
+
emit_segment(node)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Emit segment
|
26
|
+
#
|
27
|
+
# @param [Parser::Node] node
|
28
|
+
#
|
29
|
+
# @return [undefined]
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
#
|
33
|
+
def emit_segment(node)
|
34
|
+
if node.type == :str
|
35
|
+
emit_str_segment(node)
|
36
|
+
return
|
37
|
+
end
|
38
|
+
emit_interpolated_segment(node)
|
39
|
+
end
|
40
|
+
|
41
|
+
ESCAPES = IceNine.deep_freeze(
|
42
|
+
"\n" => '\n'
|
43
|
+
)
|
44
|
+
|
45
|
+
REPLACEMENTS = ::Regexp.union(ESCAPES.keys)
|
46
|
+
|
47
|
+
# Emit str segment
|
48
|
+
#
|
49
|
+
# @param [Parser::Node] node
|
50
|
+
#
|
51
|
+
# @return [undefined]
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
#
|
55
|
+
def emit_str_segment(node)
|
56
|
+
util = self.class
|
57
|
+
str = node.children.first
|
58
|
+
str = str.
|
59
|
+
gsub(util::DELIMITER, util::REPLACEMENT).
|
60
|
+
gsub(REPLACEMENTS, ESCAPES)
|
61
|
+
write(str)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Emit interpolated segment
|
65
|
+
#
|
66
|
+
# @param [Parser::Node] node
|
67
|
+
#
|
68
|
+
# @return [undefined]
|
69
|
+
#
|
70
|
+
# @api private
|
71
|
+
#
|
72
|
+
def emit_interpolated_segment(node)
|
73
|
+
parentheses(OPEN, CLOSE) { visit(node) }
|
74
|
+
end
|
75
|
+
|
76
|
+
# Dynamic string body
|
77
|
+
class String < self
|
78
|
+
|
79
|
+
handle :dyn_str_body
|
80
|
+
|
81
|
+
DELIMITER = '"'.freeze
|
82
|
+
REPLACEMENT = '\"'.freeze
|
83
|
+
|
84
|
+
end # String
|
85
|
+
|
86
|
+
# Dynamic regexp body
|
87
|
+
class Regexp < self
|
88
|
+
|
89
|
+
handle :dyn_regexp_body
|
90
|
+
|
91
|
+
DELIMITER = '/'.freeze
|
92
|
+
REPLACEMENT = '/'.freeze
|
93
|
+
|
94
|
+
end # Regexp
|
95
|
+
|
96
|
+
# Dynamic regexp body
|
97
|
+
class ExecuteString < self
|
98
|
+
|
99
|
+
handle :dyn_xstr_body
|
100
|
+
|
101
|
+
DELIMITER = '`'.freeze
|
102
|
+
REPLACEMENT = '\`'.freeze
|
103
|
+
|
104
|
+
end # ExecuteString
|
105
|
+
|
106
|
+
end # DynamicBody
|
107
|
+
end # Literal
|
108
|
+
end # Emitter
|
109
|
+
end # Unparser
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
# Emitter for execute strings (xstr) nodes
|
5
|
+
class ExecuteString < self
|
6
|
+
|
7
|
+
OPEN = CLOSE = '`'.freeze
|
8
|
+
|
9
|
+
handle :xstr
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# Perform dispatch
|
14
|
+
#
|
15
|
+
# @return [undefined]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
#
|
19
|
+
def dispatch
|
20
|
+
parentheses(OPEN, CLOSE) do
|
21
|
+
visit(dynamic_body)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return dynamic body
|
26
|
+
#
|
27
|
+
# @return [Parser::AST::Node]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
def dynamic_body
|
32
|
+
Parser::AST::Node.new(:dyn_xstr_body, children)
|
33
|
+
end
|
34
|
+
|
35
|
+
end # ExecuteString
|
36
|
+
end # Literal
|
37
|
+
end # Emitter
|
38
|
+
end # Unparser
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
|
5
|
+
# Base class for primitive emitters
|
6
|
+
class Primitive < self
|
7
|
+
|
8
|
+
children :value
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Dispatch node
|
13
|
+
#
|
14
|
+
# @return [undefined]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
def dispatch
|
19
|
+
if node.location
|
20
|
+
emit_source_map
|
21
|
+
else
|
22
|
+
dispatch_value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
abstract_method :disaptch_value
|
27
|
+
|
28
|
+
# Emitter for primitives based on Object#inspect
|
29
|
+
class Inspect < self
|
30
|
+
|
31
|
+
handle :int, :str, :float, :sym
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Dispatch value
|
36
|
+
#
|
37
|
+
# @return [undefined]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
#
|
41
|
+
def dispatch_value
|
42
|
+
buffer.append(value.inspect)
|
43
|
+
end
|
44
|
+
|
45
|
+
end # Inspect
|
46
|
+
end # Primitive
|
47
|
+
end # Literal
|
48
|
+
end # Emitter
|
49
|
+
end # Unparser
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Literal
|
4
|
+
# Abstract base class for literal range emitter
|
5
|
+
class Range < self
|
6
|
+
|
7
|
+
TOKENS = IceNine.deep_freeze(
|
8
|
+
:irange => '..',
|
9
|
+
:erange => '...'
|
10
|
+
)
|
11
|
+
|
12
|
+
handle *TOKENS.keys
|
13
|
+
|
14
|
+
children :begin_node, :end_node
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Perform dispatch
|
19
|
+
#
|
20
|
+
# @return [undefined]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
#
|
24
|
+
def dispatch
|
25
|
+
visit(begin_node)
|
26
|
+
write(TOKENS.fetch(node.type))
|
27
|
+
visit(end_node)
|
28
|
+
end
|
29
|
+
|
30
|
+
end # Range
|
31
|
+
end # Literal
|
32
|
+
end # Emitter
|
33
|
+
end # Unparser
|