ripper_ruby_parser 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +8 -25
  4. data/lib/ripper_ruby_parser.rb +2 -2
  5. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +54 -23
  6. data/lib/ripper_ruby_parser/parser.rb +3 -3
  7. data/lib/ripper_ruby_parser/sexp_handlers.rb +11 -9
  8. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +10 -11
  9. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +48 -63
  10. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  11. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  12. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  13. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +4 -2
  14. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +1 -1
  15. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +24 -24
  16. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +266 -0
  17. data/lib/ripper_ruby_parser/sexp_processor.rb +47 -78
  18. data/lib/ripper_ruby_parser/unescape.rb +79 -50
  19. data/lib/ripper_ruby_parser/version.rb +1 -1
  20. metadata +115 -78
  21. data/Rakefile +0 -33
  22. data/test/end_to_end/comments_test.rb +0 -59
  23. data/test/end_to_end/comparison_test.rb +0 -104
  24. data/test/end_to_end/lib_comparison_test.rb +0 -29
  25. data/test/end_to_end/line_numbering_test.rb +0 -64
  26. data/test/end_to_end/samples_comparison_test.rb +0 -13
  27. data/test/end_to_end/test_comparison_test.rb +0 -32
  28. data/test/pt_testcase/pt_test.rb +0 -44
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -190
  30. data/test/ripper_ruby_parser/parser_test.rb +0 -469
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -649
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -661
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1117
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -427
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  40. data/test/ripper_ruby_parser/version_test.rb +0 -7
  41. data/test/samples/assignment.rb +0 -17
  42. data/test/samples/comments.rb +0 -13
  43. data/test/samples/conditionals.rb +0 -23
  44. data/test/samples/loops.rb +0 -36
  45. data/test/samples/misc.rb +0 -278
  46. data/test/samples/number.rb +0 -7
  47. data/test/samples/operators.rb +0 -18
  48. data/test/samples/strings.rb +0 -140
  49. data/test/test_helper.rb +0 -79
@@ -1,303 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
-
5
- class TestProcessor < RipperRubyParser::SexpProcessor
6
- def process_foo(exp)
7
- exp.shift
8
- s(:foo_p)
9
- end
10
-
11
- def process_bar(exp)
12
- exp.shift
13
- s(:bar_p)
14
- end
15
-
16
- def process_baz(exp)
17
- exp.shift
18
- s(:baz_p)
19
- end
20
- end
21
-
22
- describe RipperRubyParser::SexpProcessor do
23
- let :processor do
24
- TestProcessor.new
25
- end
26
-
27
- describe '#process' do
28
- describe 'for a :program sexp' do
29
- it 'strips off the outer :program node' do
30
- sexp = s(:program, s(:stmts, s(:foo)))
31
- result = processor.process sexp
32
- result.must_equal s(:foo_p)
33
- end
34
-
35
- it 'transforms a multi-statement :program into a :block sexp' do
36
- sexp = s(:program, s(:stmts, s(:foo), s(:bar)))
37
- result = processor.process sexp
38
- result.must_equal s(:block, s(:foo_p), s(:bar_p))
39
- end
40
- end
41
-
42
- describe 'for a :string_literal sexp' do
43
- it 'transforms a simple sexp to :str' do
44
- sexp = s(:string_literal,
45
- s(:string_content,
46
- s(:@tstring_content, 'foo', s(1, 1), '"')))
47
- result = processor.process sexp
48
- result.must_equal s(:str, 'foo')
49
- end
50
- end
51
-
52
- describe 'for a :command sexp' do
53
- it 'transforms a sexp to a :call' do
54
- sexp = s(:command, s(:@ident, 'foo', s(1, 0)), s(:arglist, s(:foo)))
55
- result = processor.process sexp
56
- result.must_equal s(:call, nil, :foo, s(:foo_p))
57
- end
58
- end
59
-
60
- describe 'for a :var_ref sexp' do
61
- it 'transforms the sexp to a :lvar sexp' do
62
- sexp = s(:var_ref, s(:@ident, 'bar', s(1, 4)))
63
- result = processor.process sexp
64
- result.must_equal s(:lvar, :bar)
65
- end
66
- end
67
-
68
- describe 'for a :vcall sexp' do
69
- it 'transforms the sexp to a :call sexp' do
70
- sexp = s(:vcall, s(:@ident, 'bar', s(1, 4)))
71
- result = processor.process sexp
72
- result.must_equal s(:call, nil, :bar)
73
- end
74
- end
75
-
76
- describe 'for a :module sexp' do
77
- it 'does not create body eleents for an empty definition' do
78
- sexp = s(:module,
79
- s(:const_ref, s(:@const, 'Foo', s(1, 13))),
80
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil))
81
- result = processor.process sexp
82
- result.must_equal s(:module, :Foo)
83
- end
84
-
85
- it 'creates a single body element for a definition with one statement' do
86
- sexp = s(:module,
87
- s(:const_ref, s(:@const, 'Foo', s(1, 13))),
88
- s(:bodystmt, s(:stmts, s(:foo)), nil, nil, nil))
89
- result = processor.process sexp
90
- result.must_equal s(:module, :Foo, s(:foo_p))
91
- end
92
-
93
- it 'creates multiple body elements for a definition with more than one statement' do
94
- sexp = s(:module,
95
- s(:const_ref, s(:@const, 'Foo', s(1, 13))),
96
- s(:bodystmt, s(:stmts, s(:foo), s(:bar)), nil, nil, nil))
97
- result = processor.process sexp
98
- result.must_equal s(:module, :Foo, s(:foo_p), s(:bar_p))
99
- end
100
- end
101
-
102
- describe 'for a :class sexp' do
103
- it 'does not create body eleents for an empty definition' do
104
- sexp = s(:class,
105
- s(:const_ref, s(:@const, 'Foo', s(1, 13))), nil,
106
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil))
107
- result = processor.process sexp
108
- result.must_equal s(:class, :Foo, nil)
109
- end
110
-
111
- it 'creates a single body element for a definition with one statement' do
112
- sexp = s(:class,
113
- s(:const_ref, s(:@const, 'Foo', s(1, 13))), nil,
114
- s(:bodystmt, s(:stmts, s(:foo)), nil, nil, nil))
115
- result = processor.process sexp
116
- result.must_equal s(:class, :Foo, nil, s(:foo_p))
117
- end
118
-
119
- it 'creates multiple body elements for a definition with more than one statement' do
120
- sexp = s(:class,
121
- s(:const_ref, s(:@const, 'Foo', s(1, 13))), nil,
122
- s(:bodystmt, s(:stmts, s(:foo), s(:bar)), nil, nil, nil))
123
- result = processor.process sexp
124
- result.must_equal s(:class, :Foo, nil, s(:foo_p), s(:bar_p))
125
- end
126
-
127
- it 'passes on the given ancestor' do
128
- sexp = s(:class,
129
- s(:const_ref, s(:@const, 'Foo', s(1, 13))),
130
- s(:var_ref, s(:@const, 'Bar', s(1, 12))),
131
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil))
132
- result = processor.process sexp
133
- result.must_equal s(:class, :Foo, s(:const, :Bar))
134
- end
135
- end
136
-
137
- describe 'for a :bodystmt sexp' do
138
- it 'creates a :block sexp when multiple statements are present' do
139
- sexp = s(:bodystmt, s(:stmts, s(:foo), s(:bar)), nil, nil, nil)
140
- result = processor.process sexp
141
- result.must_equal s(:block, s(:foo_p), s(:bar_p))
142
- end
143
-
144
- it 'removes nested :void_stmt sexps' do
145
- sexp = s(:bodystmt, s(:stmts, s(:void_stmt), s(:foo)), nil, nil, nil)
146
- result = processor.process sexp
147
- result.must_equal s(:foo_p)
148
- end
149
- end
150
-
151
- describe 'for a :def sexp' do
152
- it 'transforms the sexp for a basic function definition' do
153
- sexp = s(:def,
154
- s(:@ident, 'foo', s(1, 4)),
155
- s(:params, nil, nil, nil, nil, nil),
156
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil))
157
- result = processor.process sexp
158
- result.must_equal s(:defn, :foo, s(:args), s(:nil))
159
- end
160
- end
161
-
162
- describe 'for a :params sexp' do
163
- describe 'with a normal arguments' do
164
- it 'creates :lvar sexps' do
165
- sexp = s(:params, s(s(:@ident, 'bar', s(1, 8))), nil, nil, nil, nil)
166
- result = processor.process sexp
167
- result.must_equal s(:args, s(:lvar, :bar))
168
- end
169
- end
170
-
171
- describe 'with a ruby 2.4-style doublesplat argument' do
172
- it 'creates :lvar sexps' do
173
- sexp = s(:params,
174
- nil, nil, nil, nil, nil,
175
- s(:@ident, 'bar', s(1, 8)),
176
- nil)
177
- result = processor.process sexp
178
- result.must_equal s(:args, s(:dsplat, s(:lvar, :bar)))
179
- end
180
- end
181
- describe 'with a ruby 2.5-style kwrest argument' do
182
- it 'creates :lvar sexps' do
183
- sexp = s(:params,
184
- nil, nil, nil, nil, nil,
185
- s(:kwrest_param, s(:@ident, 'bar', s(1, 8))),
186
- nil)
187
- result = processor.process sexp
188
- result.must_equal s(:args, s(:dsplat, s(:lvar, :bar)))
189
- end
190
- end
191
- end
192
-
193
- describe 'for an :assign sexp' do
194
- it 'creates a :lasgn sexp' do
195
- sexp = s(:assign,
196
- s(:var_field, s(:@ident, 'a', s(1, 0))),
197
- s(:@int, '1', s(1, 4)))
198
- result = processor.process sexp
199
- result.must_equal s(:lasgn, :a, s(:lit, 1))
200
- end
201
- end
202
-
203
- describe 'for a :binary sexp' do
204
- it 'creates a :call sexp' do
205
- sexp = s(:binary, s(:bar), :==, s(:foo))
206
- result = processor.process sexp
207
- result.must_equal s(:call, s(:bar_p), :==, s(:foo_p))
208
- end
209
- end
210
-
211
- describe 'for a :method_add_block sexp' do
212
- it 'creates an :iter sexp' do
213
- sexp = s(:method_add_block,
214
- s(:call, s(:foo), :".", s(:@ident, 'baz', s(1, 2))),
215
- s(:brace_block, nil, s(:stmts, s(:bar))))
216
- result = processor.process sexp
217
- result.must_equal s(:iter,
218
- s(:call, s(:foo_p), :baz), 0,
219
- s(:bar_p))
220
- end
221
-
222
- describe 'with a block parameter' do
223
- it 'creates an :iter sexp with an :args sexp for the block parameter' do
224
- sexp = s(:method_add_block,
225
- s(:call, s(:foo), :".", s(:@ident, 'baz', s(1, 2))),
226
- s(:brace_block,
227
- s(:block_var,
228
- s(:params, s(s(:@ident, 'i', s(1, 6))), nil, nil, nil, nil),
229
- nil),
230
- s(:stmts, s(:bar))))
231
- result = processor.process sexp
232
- result.must_equal s(:iter,
233
- s(:call, s(:foo_p), :baz),
234
- s(:args, :i),
235
- s(:bar_p))
236
- end
237
- end
238
- end
239
-
240
- describe 'for an :if sexp' do
241
- describe 'with a single statement in the if body' do
242
- it 'uses the statement sexp as the body' do
243
- sexp = s(:if, s(:foo), s(:stmts, s(:bar)), nil)
244
- result = processor.process sexp
245
- result.must_equal s(:if, s(:foo_p), s(:bar_p), nil)
246
- end
247
- end
248
-
249
- describe 'with multiple statements in the if body' do
250
- it 'uses a block containing the statement sexps as the body' do
251
- sexp = s(:if, s(:foo), s(:stmts, s(:bar), s(:baz)), nil)
252
- result = processor.process sexp
253
- result.must_equal s(:if, s(:foo_p), s(:block, s(:bar_p), s(:baz_p)), nil)
254
- end
255
- end
256
- end
257
-
258
- describe 'for an :array sexp' do
259
- it 'pulls up the element sexps' do
260
- sexp = s(:array, s(:words, s(:foo), s(:bar), s(:baz)))
261
- result = processor.process sexp
262
- result.must_equal s(:array, s(:foo_p), s(:bar_p), s(:baz_p))
263
- end
264
- end
265
-
266
- describe 'for a :const_path_ref sexp' do
267
- it 'returns a :colon2 sexp' do
268
- sexp = s(:const_path_ref,
269
- s(:var_ref, s(:@const, 'Foo', s(1, 0))),
270
- s(:@const, 'Bar', s(1, 5)))
271
- result = processor.process sexp
272
- result.must_equal s(:colon2, s(:const, :Foo), :Bar)
273
- end
274
- end
275
-
276
- describe 'for a :when sexp' do
277
- it 'turns nested :when clauses into a list' do
278
- sexp = s(:when, s(:args, s(:foo)), s(:stmts, s(:bar)),
279
- s(:when, s(:args, s(:foo)), s(:stmts, s(:bar)),
280
- s(:when, s(:args, s(:foo)), s(:stmts, s(:bar)), nil)))
281
- result = processor.process sexp
282
- result.must_equal s(s(:when, s(:array, s(:foo_p)), s(:bar_p)),
283
- s(:when, s(:array, s(:foo_p)), s(:bar_p)),
284
- s(:when, s(:array, s(:foo_p)), s(:bar_p)),
285
- nil)
286
- end
287
- end
288
- end
289
-
290
- describe '#extract_node_symbol' do
291
- it 'processes an lvar sexp to a bare symbol' do
292
- sexp = s(:lvar, 'foo')
293
- result = processor.send :extract_node_symbol, sexp
294
- result.must_equal :foo
295
- end
296
-
297
- it 'processes a const sexp to a bare symbol' do
298
- sexp = s(:const, 'Foo')
299
- result = processor.send :extract_node_symbol, sexp
300
- result.must_equal :Foo
301
- end
302
- end
303
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe RipperRubyParser do
4
- it 'knows its own version' do
5
- RipperRubyParser::VERSION.wont_be_nil
6
- end
7
- end
@@ -1,17 +0,0 @@
1
- # Samples of assignment
2
- foo[bar] = baz
3
- foo[bar] += baz
4
- foo[bar] ||= foo bar
5
- foo[bar] ||= foo(bar)
6
- foo[bar] ||= baz.qux quuz
7
- foo[bar] ||= baz.qux(quuz)
8
-
9
- # Destructuring assignments
10
- foo, bar = baz
11
- (foo, bar) = baz
12
- ((foo, bar)) = baz
13
- (((foo, bar))) = baz
14
- foo, (bar, baz) = qux
15
- foo, ((bar, baz)) = qux
16
- foo, (((bar, baz))) = qux
17
- foo, (bar, (baz, qux)) = quuz
@@ -1,13 +0,0 @@
1
- =begin
2
- This is an unusual type of comment that needs to be handled correctly
3
- =end
4
-
5
- class Foo
6
-
7
- end
8
-
9
- # This is a more common type of comment
10
-
11
- class Bar
12
-
13
- end
@@ -1,23 +0,0 @@
1
- # Conditionals
2
-
3
- if begin foo end
4
- bar
5
- end
6
-
7
- if begin foo..bar end
8
- baz
9
- end
10
-
11
- if foo
12
- elsif begin bar end
13
- end
14
-
15
- if foo
16
- elsif begin bar..baz end
17
- end
18
-
19
- if 1
20
- bar
21
- else
22
- baz
23
- end
@@ -1,36 +0,0 @@
1
- # Loop samples
2
-
3
- def for_samples
4
- for foo in bar
5
- end
6
-
7
- for foo, bar in baz
8
- end
9
-
10
- for foo, in bar
11
- end
12
- end
13
-
14
- # begin..end in conditions
15
- #
16
- def while_until_samples
17
- while begin foo end
18
- bar
19
- end
20
-
21
- until begin foo end
22
- bar
23
- end
24
-
25
- while begin foo end do
26
- bar
27
- end
28
-
29
- until begin foo end do
30
- bar
31
- end
32
-
33
- foo while begin bar end
34
-
35
- foo until begin bar end
36
- end
data/test/samples/misc.rb DELETED
@@ -1,278 +0,0 @@
1
- # Miscellaneous samples
2
-
3
- BEGIN {
4
- begin
5
- foo
6
- end
7
- }
8
-
9
- BEGIN {}
10
-
11
- END {
12
- begin
13
- bar
14
- end
15
- }
16
-
17
- END {}
18
-
19
- # regular expressions with different encoding flags
20
- regular = /foo/
21
- noenc = /foo/n
22
- utf8 = /foo/u
23
- euc = /foo/e
24
- sjis = /foo/s
25
-
26
- bar = 'bar'
27
- regular = /foo#{bar}/
28
- noenc = /foo#{bar}/n
29
- utf8 = /foo#{bar}/u
30
- euc = /foo#{bar}/e
31
- sjis = /foo#{bar}/s
32
-
33
- # Use of __ENCODING__
34
- enc = __ENCODING__
35
-
36
- class Foo
37
- # calling #[] on self
38
- # https://github.com/seattlerb/ruby_parser/issues/250
39
- def bar
40
- self[:foo]
41
- end
42
-
43
- # required keyword arguments and no parentheses
44
- # https://github.com/seattlerb/ruby_parser/pull/254
45
- def foo a:, b:
46
- puts "A: #{a}, B: #{b}"
47
- end
48
-
49
- # Combinations of begin..end and diverse operators
50
- def qux
51
- begin end
52
- begin; foo; end
53
- begin; foo; bar; end
54
- - begin; foo; end
55
- begin; bar; end + foo
56
- foo + begin; bar; end
57
- begin; foo; end ? bar : baz
58
- foo ? begin; bar; end : baz
59
- foo ? bar : begin; baz; end
60
- begin; bar; end and foo
61
- foo and begin; bar; end
62
- begin; foo; end if bar
63
- begin; foo; end unless bar
64
- begin; foo; end.bar
65
- foo ||= begin; bar; end
66
- foo += begin; bar; end
67
- foo[qux] ||= begin; bar; end
68
- foo = begin; bar; end
69
- foo = begin; if bar; baz; end; end
70
- baz = begin; foo; ensure; bar; end
71
- foo = *begin; bar; end
72
- foo = bar, *begin; baz; end
73
- foo, bar = *begin; baz; end
74
- foo if begin bar end
75
- end
76
-
77
- # Nested do and begin blocks
78
- def quuz
79
- foo do
80
- bar
81
-
82
- begin
83
- baz
84
- rescue
85
- qux
86
- end
87
-
88
- quuz
89
- end
90
- end
91
-
92
- # Nested begin/rescue blocks
93
- def quuz
94
- begin
95
- bar
96
- rescue
97
- begin
98
- baz
99
- end
100
- end
101
-
102
- begin
103
- bar
104
- rescue
105
- begin
106
- baz
107
- rescue
108
- qux
109
- end
110
- end
111
-
112
- begin
113
- bar
114
- rescue
115
- begin
116
- baz
117
- end
118
- begin
119
- qux
120
- end
121
- end
122
- end
123
-
124
- # Begin/end blocks and case statements
125
- def quuz
126
- case foo
127
- when bar
128
- begin
129
- baz
130
- end
131
- end
132
-
133
- case foo
134
- when bar
135
- begin
136
- baz
137
- qux
138
- end
139
- end
140
-
141
- case foo
142
- when bar
143
- begin
144
- baz
145
- qux
146
- end
147
- quuz
148
- end
149
-
150
- case foo
151
- when bar
152
- else
153
- begin
154
- baz
155
- qux
156
- end
157
- end
158
-
159
- case foo
160
- when bar
161
- else
162
- begin
163
- baz
164
- qux
165
- end
166
- quuz
167
- end
168
- end
169
-
170
- # Using splat and double-splat args
171
- def barbaz(*foo, **bar)
172
- puts [foo, bar]
173
- foo.each do |baz, **qux|
174
- puts [foo, bar, baz, qux]
175
- end
176
- puts [foo, bar]
177
- end
178
-
179
- def barbaz_block(*foo, **bar, &block)
180
- puts [foo, bar]
181
- end
182
-
183
- def self.barbaz(*foo, **bar)
184
- puts [foo, bar]
185
- foo.each do |baz, **qux|
186
- puts [foo, bar, baz, qux]
187
- end
188
- puts [foo, bar]
189
- end
190
-
191
- # rescue
192
- def barfoo
193
- foo
194
- rescue *bar
195
- baz
196
- rescue *quuz, Bar
197
- zyxxy
198
- rescue *qux => err
199
- puts err
200
- end
201
-
202
- # begin/rescue with multiple assignment
203
- foo, bar = begin
204
- baz
205
- rescue qux
206
- quuz
207
- end
208
-
209
- # alias
210
- alias foo bar
211
- alias :foo bar
212
- alias :foo :bar
213
- alias foo :bar
214
- alias :+ -
215
- alias next bar
216
-
217
- # rescue with assignment
218
- foo = bar rescue baz
219
- foo = bar baz rescue qux
220
- foo = bar(baz) rescue qux
221
- foo, bar = baz qux rescue quuz
222
- @foo = bar baz rescue qux
223
- @@foo = bar baz rescue qux
224
- FOO = bar baz rescue qux
225
- $foo = bar baz rescue qux
226
- foo = Foo.bar(baz) rescue qux
227
- foo = Foo.bar baz rescue qux
228
-
229
- # Assignment to class variables inside method argument
230
- # definitions.
231
- def foo(bar = (@@baz = qux))
232
- end
233
-
234
- def self.foo(bar = (@@baz = qux))
235
- end
236
-
237
- def (bar = (@@baz = qux)).foo
238
- end
239
-
240
- # Assignment to global variables inside method argument
241
- # definitions.
242
- def foo(bar = ($baz = qux))
243
- end
244
-
245
- # Argument destructuring
246
- def foo((bar, baz))
247
- end
248
-
249
- def foo((bar, baz), (qux, quuz))
250
- end
251
-
252
- def foo((bar, *qux))
253
- end
254
-
255
- def foo((bar, (baz, qux)))
256
- end
257
-
258
- def foo((bar, (baz, *qux)))
259
- end
260
-
261
- def self.foo((bar, baz))
262
- end
263
-
264
- def self.foo((bar, baz), (qux, quuz))
265
- end
266
-
267
- def self.foo((bar, *qux))
268
- end
269
-
270
- def self.foo((bar, (baz, qux)))
271
- end
272
-
273
- def self.foo((bar, (baz, *qux)))
274
- end
275
- end
276
-
277
- # Special symbols
278
- [:`, :|, :*, :&, :%, :'^', :-@, :+@, :'~@']