to_source 0.2.9 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Changelog.md +13 -0
  2. data/LICENSE +21 -0
  3. data/README.md +6 -22
  4. data/TODO +3 -3
  5. data/lib/to_source.rb +68 -3
  6. data/lib/to_source/buffer.rb +40 -0
  7. data/lib/to_source/command.rb +44 -0
  8. data/lib/to_source/emitter.rb +76 -0
  9. data/lib/to_source/emitter/access.rb +20 -0
  10. data/lib/to_source/emitter/actual_arguments.rb +46 -0
  11. data/lib/to_source/emitter/alias.rb +18 -0
  12. data/lib/to_source/emitter/assignment.rb +77 -0
  13. data/lib/to_source/emitter/attribute_assignment.rb +19 -0
  14. data/lib/to_source/emitter/begin.rb +51 -0
  15. data/lib/to_source/emitter/binary_operator.rb +36 -0
  16. data/lib/to_source/emitter/binary_operator_method.rb +29 -0
  17. data/lib/to_source/emitter/block.rb +22 -0
  18. data/lib/to_source/emitter/block_argument.rb +16 -0
  19. data/lib/to_source/emitter/block_pass.rb +16 -0
  20. data/lib/to_source/emitter/class.rb +29 -0
  21. data/lib/to_source/emitter/concat_arguments.rb +20 -0
  22. data/lib/to_source/emitter/default_arguments.rb +15 -0
  23. data/lib/to_source/emitter/define.rb +61 -0
  24. data/lib/to_source/emitter/defined.rb +17 -0
  25. data/lib/to_source/emitter/element_assignment.rb +20 -0
  26. data/lib/to_source/emitter/element_reference.rb +16 -0
  27. data/lib/to_source/emitter/empty_body.rb +12 -0
  28. data/lib/to_source/emitter/ensure.rb +23 -0
  29. data/lib/to_source/emitter/ensure_body.rb +18 -0
  30. data/lib/to_source/emitter/execute_string.rb +13 -0
  31. data/lib/to_source/emitter/formal_arguments.rb +120 -0
  32. data/lib/to_source/emitter/if.rb +51 -0
  33. data/lib/to_source/emitter/iter.rb +20 -0
  34. data/lib/to_source/emitter/keyword_value.rb +43 -0
  35. data/lib/to_source/emitter/literal.rb +239 -0
  36. data/lib/to_source/emitter/match3.rb +17 -0
  37. data/lib/to_source/emitter/module.rb +21 -0
  38. data/lib/to_source/emitter/multiple_assignment.rb +23 -0
  39. data/lib/to_source/emitter/nth_ref.rb +15 -0
  40. data/lib/to_source/emitter/op_assign1.rb +19 -0
  41. data/lib/to_source/emitter/op_assign2.rb +19 -0
  42. data/lib/to_source/emitter/pattern_arguments.rb +17 -0
  43. data/lib/to_source/emitter/receiver_case.rb +35 -0
  44. data/lib/to_source/emitter/rescue.rb +21 -0
  45. data/lib/to_source/emitter/rescue_condition.rb +56 -0
  46. data/lib/to_source/emitter/scope.rb +17 -0
  47. data/lib/to_source/emitter/scope_name.rb +16 -0
  48. data/lib/to_source/emitter/scoped_name.rb +17 -0
  49. data/lib/to_source/emitter/send.rb +47 -0
  50. data/lib/to_source/emitter/send_with_arguments.rb +62 -0
  51. data/lib/to_source/emitter/singleton_class.rb +23 -0
  52. data/lib/to_source/emitter/splat.rb +17 -0
  53. data/lib/to_source/emitter/splat_when.rb +16 -0
  54. data/lib/to_source/emitter/static.rb +33 -0
  55. data/lib/to_source/emitter/super.rb +47 -0
  56. data/lib/to_source/emitter/to_array.rb +15 -0
  57. data/lib/to_source/emitter/to_string.rb +17 -0
  58. data/lib/to_source/emitter/toplevel.rb +15 -0
  59. data/lib/to_source/emitter/unary_operator_method.rb +20 -0
  60. data/lib/to_source/emitter/unless.rb +16 -0
  61. data/lib/to_source/emitter/until.rb +20 -0
  62. data/lib/to_source/emitter/util.rb +19 -0
  63. data/lib/to_source/emitter/when.rb +38 -0
  64. data/lib/to_source/emitter/while.rb +20 -0
  65. data/lib/to_source/emitter/yield.rb +19 -0
  66. data/lib/to_source/emitter/z_super.rb +17 -0
  67. data/lib/to_source/state.rb +60 -0
  68. data/spec/unit/to_source/{visitor/class_methods → class_methods}/run_spec.rb +84 -33
  69. data/to_source.gemspec +14 -12
  70. metadata +106 -11
  71. data/lib/to_source/visitor.rb +0 -1890
data/to_source.gemspec CHANGED
@@ -1,18 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
- s.name = 'to_source'
4
- s.version = '0.2.9'
5
- s.authors = ['Josep M. Bach', 'Markus Schirp']
6
- s.email = ['josep.m.bach@gmail.com', 'mbj@seonic.net']
7
- s.homepage = 'http://github.com/txus/to_source'
8
- s.summary = %q{Transform your Rubinius AST nodes back to source code. Reverse parsing!}
9
- s.description = %q{Transform your Rubinius AST nodes back to source code. Reverse parsing!}
10
-
11
- s.files = `git ls-files`.split("\n")
12
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
- s.require_paths = ['lib']
3
+ s.name = 'to_source'
4
+ s.version = '0.2.11'
5
+ s.authors = ['Markus Schirp']
6
+ s.email = ['mbj@seonic.net']
7
+ s.homepage = 'http://github.com/mbj/to_source'
8
+ s.summary = %q{Transform Rubinius 1.9 AST back to equvalent source code.}
9
+ s.description = s.summary
10
+ s.files = `git ls-files`.split("\n")
11
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
12
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ s.extra_rdoc_files = %w[LICENSE README.md TODO]
14
+ s.require_paths = ['lib']
15
15
 
16
16
  s.add_dependency('adamantium', '~> 0.0.3')
17
+ s.add_dependency('equalizer', '~> 0.0.2')
18
+ s.add_dependency('abstract_type', '~> 0.0.1')
17
19
  s.add_dependency('mutant-melbourne', '~> 2.0.3')
18
20
  end
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: to_source
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.2.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
- - Josep M. Bach
9
8
  - Markus Schirp
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-01-03 00:00:00.000000000 Z
12
+ date: 2013-01-09 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: adamantium
@@ -28,6 +27,38 @@ dependencies:
28
27
  - - ~>
29
28
  - !ruby/object:Gem::Version
30
29
  version: 0.0.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: equalizer
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.0.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.0.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: abstract_type
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.0.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.1
31
62
  - !ruby/object:Gem::Dependency
32
63
  name: mutant-melbourne
33
64
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +75,16 @@ dependencies:
44
75
  - - ~>
45
76
  - !ruby/object:Gem::Version
46
77
  version: 2.0.3
47
- description: Transform your Rubinius AST nodes back to source code. Reverse parsing!
78
+ description: Transform Rubinius 1.9 AST back to equvalent source code.
48
79
  email:
49
- - josep.m.bach@gmail.com
50
80
  - mbj@seonic.net
51
81
  executables:
52
82
  - to_source
53
83
  extensions: []
54
- extra_rdoc_files: []
84
+ extra_rdoc_files:
85
+ - LICENSE
86
+ - README.md
87
+ - TODO
55
88
  files:
56
89
  - .gitignore
57
90
  - .rspec
@@ -60,6 +93,7 @@ files:
60
93
  - Gemfile
61
94
  - Gemfile.devtools
62
95
  - Guardfile
96
+ - LICENSE
63
97
  - README.md
64
98
  - Rakefile
65
99
  - TODO
@@ -70,11 +104,72 @@ files:
70
104
  - config/site.reek
71
105
  - config/yardstick.yml
72
106
  - lib/to_source.rb
73
- - lib/to_source/visitor.rb
107
+ - lib/to_source/buffer.rb
108
+ - lib/to_source/command.rb
109
+ - lib/to_source/emitter.rb
110
+ - lib/to_source/emitter/access.rb
111
+ - lib/to_source/emitter/actual_arguments.rb
112
+ - lib/to_source/emitter/alias.rb
113
+ - lib/to_source/emitter/assignment.rb
114
+ - lib/to_source/emitter/attribute_assignment.rb
115
+ - lib/to_source/emitter/begin.rb
116
+ - lib/to_source/emitter/binary_operator.rb
117
+ - lib/to_source/emitter/binary_operator_method.rb
118
+ - lib/to_source/emitter/block.rb
119
+ - lib/to_source/emitter/block_argument.rb
120
+ - lib/to_source/emitter/block_pass.rb
121
+ - lib/to_source/emitter/class.rb
122
+ - lib/to_source/emitter/concat_arguments.rb
123
+ - lib/to_source/emitter/default_arguments.rb
124
+ - lib/to_source/emitter/define.rb
125
+ - lib/to_source/emitter/defined.rb
126
+ - lib/to_source/emitter/element_assignment.rb
127
+ - lib/to_source/emitter/element_reference.rb
128
+ - lib/to_source/emitter/empty_body.rb
129
+ - lib/to_source/emitter/ensure.rb
130
+ - lib/to_source/emitter/ensure_body.rb
131
+ - lib/to_source/emitter/execute_string.rb
132
+ - lib/to_source/emitter/formal_arguments.rb
133
+ - lib/to_source/emitter/if.rb
134
+ - lib/to_source/emitter/iter.rb
135
+ - lib/to_source/emitter/keyword_value.rb
136
+ - lib/to_source/emitter/literal.rb
137
+ - lib/to_source/emitter/match3.rb
138
+ - lib/to_source/emitter/module.rb
139
+ - lib/to_source/emitter/multiple_assignment.rb
140
+ - lib/to_source/emitter/nth_ref.rb
141
+ - lib/to_source/emitter/op_assign1.rb
142
+ - lib/to_source/emitter/op_assign2.rb
143
+ - lib/to_source/emitter/pattern_arguments.rb
144
+ - lib/to_source/emitter/receiver_case.rb
145
+ - lib/to_source/emitter/rescue.rb
146
+ - lib/to_source/emitter/rescue_condition.rb
147
+ - lib/to_source/emitter/scope.rb
148
+ - lib/to_source/emitter/scope_name.rb
149
+ - lib/to_source/emitter/scoped_name.rb
150
+ - lib/to_source/emitter/send.rb
151
+ - lib/to_source/emitter/send_with_arguments.rb
152
+ - lib/to_source/emitter/singleton_class.rb
153
+ - lib/to_source/emitter/splat.rb
154
+ - lib/to_source/emitter/splat_when.rb
155
+ - lib/to_source/emitter/static.rb
156
+ - lib/to_source/emitter/super.rb
157
+ - lib/to_source/emitter/to_array.rb
158
+ - lib/to_source/emitter/to_string.rb
159
+ - lib/to_source/emitter/toplevel.rb
160
+ - lib/to_source/emitter/unary_operator_method.rb
161
+ - lib/to_source/emitter/unless.rb
162
+ - lib/to_source/emitter/until.rb
163
+ - lib/to_source/emitter/util.rb
164
+ - lib/to_source/emitter/when.rb
165
+ - lib/to_source/emitter/while.rb
166
+ - lib/to_source/emitter/yield.rb
167
+ - lib/to_source/emitter/z_super.rb
168
+ - lib/to_source/state.rb
74
169
  - spec/spec_helper.rb
75
- - spec/unit/to_source/visitor/class_methods/run_spec.rb
170
+ - spec/unit/to_source/class_methods/run_spec.rb
76
171
  - to_source.gemspec
77
- homepage: http://github.com/txus/to_source
172
+ homepage: http://github.com/mbj/to_source
78
173
  licenses: []
79
174
  post_install_message:
80
175
  rdoc_options: []
@@ -97,8 +192,8 @@ rubyforge_project:
97
192
  rubygems_version: 1.8.23
98
193
  signing_key:
99
194
  specification_version: 3
100
- summary: Transform your Rubinius AST nodes back to source code. Reverse parsing!
195
+ summary: Transform Rubinius 1.9 AST back to equvalent source code.
101
196
  test_files:
102
197
  - spec/spec_helper.rb
103
- - spec/unit/to_source/visitor/class_methods/run_spec.rb
198
+ - spec/unit/to_source/class_methods/run_spec.rb
104
199
  has_rdoc:
@@ -1,1890 +0,0 @@
1
- module ToSource
2
- # Converter from AST to source
3
- class Visitor
4
-
5
- # Create source code from AST node
6
- #
7
- # @param [Rubinius::AST::Node] node
8
- # the node to convert to source code
9
- #
10
- # @return [String]
11
- # returns the source code for ast node
12
- #
13
- # @api private
14
- #
15
- def self.run(node)
16
- new(node).output
17
- end
18
-
19
- # Return handler registry
20
- #
21
- # @return [Hash]
22
- #
23
- # @api private
24
- #
25
- def self.registry
26
- @registry ||= {}
27
- end
28
-
29
- # Register handler class
30
- #
31
- # @param [Class:Rubinius::AST::Node] node_klass
32
- #
33
- # @return [undefined]
34
- #
35
- # @api private
36
- #
37
- def self.register(node_klass)
38
- registry[node_klass]=self
39
- end
40
-
41
- # Return the source code of AST
42
- #
43
- # @return [String]
44
- #
45
- # @api private
46
- #
47
- def output
48
- @output.join
49
- end
50
-
51
- private
52
-
53
- # Initialize visitor
54
- #
55
- # @param [Rubinius::AST::Node] node
56
- #
57
- # @return [undefined]
58
- #
59
- # @api private
60
- #
61
- def initialize(node)
62
- @output = []
63
- @indentation = 0
64
- dispatch(node)
65
- end
66
-
67
- # Dispatch node
68
- #
69
- # @param [Rubinius::AST::Node] node
70
- #
71
- # @return [undefined]
72
- #
73
- # @api private
74
- #
75
- def dispatch(node)
76
- handler = self.class.registry.fetch(node.class) do
77
- name = node.node_name
78
- name = "#{name}_def" if %w(class module).include?(name)
79
- __send__(name, node)
80
- nil
81
- end
82
-
83
- handler.run(self, node) if handler
84
- end
85
-
86
- # Emit file
87
- #
88
- # @param [Rubinius::AST::Node] node
89
- #
90
- # @return [undefined]
91
- #
92
- # @api private
93
- #
94
- def file(node)
95
- emit('__FILE__')
96
- end
97
-
98
- # Emit element assignment
99
- #
100
- # @param [Rubinius::AST::Node] node
101
- #
102
- # @return [undefined]
103
- #
104
- # @api private
105
- #
106
- def element_assignment(node)
107
- index, value = node.arguments.array
108
- dispatch(node.receiver)
109
- emit('[')
110
- dispatch(index)
111
- emit('] = ')
112
- dispatch(value)
113
- end
114
-
115
- # Emit alias
116
- #
117
- # @param [Rubinius::AST::Node] node
118
- #
119
- # @return [undefined]
120
- #
121
- # @api private
122
- #
123
- def alias(node)
124
- emit("alias #{node.to.value} #{node.from.value}")
125
- end
126
-
127
- # Emit match operator
128
- #
129
- # @param [Rubinius::AST::Node] node
130
- #
131
- # @return [undefined]
132
- #
133
- # @api private
134
- #
135
- def match3(node)
136
- dispatch(node.value)
137
- emit(' =~ ')
138
- dispatch(node.pattern)
139
- end
140
-
141
- # Emit break
142
- #
143
- # @param [Rubinius::AST::Node] node
144
- #
145
- # @return [undefined]
146
- #
147
- # @api private
148
- #
149
- def break(node)
150
- emit('break')
151
- if node.value.class != Rubinius::AST::NilLiteral
152
- emit('(')
153
- dispatch(node.value)
154
- emit(')')
155
- end
156
- end
157
-
158
- # Emit next
159
- #
160
- # @param [Rubinius::AST::Node] node
161
- #
162
- # @return [undefined]
163
- #
164
- # @api private
165
- #
166
- def next(node)
167
- emit('next')
168
- end
169
-
170
- # Emit conditional element assignment
171
- #
172
- # @param [Rubinius::AST::Node] node
173
- #
174
- # @return [undefined]
175
- #
176
- # @api private
177
- #
178
- def op_assign1(node)
179
- receiver(node)
180
- emit('[')
181
- dispatch(node.arguments.array.first)
182
- emit('] ||= ')
183
- dispatch(node.value)
184
- end
185
-
186
- # Emit attribute assignment after merge
187
- #
188
- # @param [Rubinius::AST::Node] node
189
- #
190
- # @return [undefined]
191
- #
192
- # @api private
193
- #
194
- def op_assign2(node)
195
- dispatch(node.receiver)
196
- emit('.')
197
- emit(node.name)
198
- emit(' |= ')
199
- dispatch(node.value)
200
- end
201
-
202
- # Emit rescue
203
- #
204
- # @param [Rubinius::AST::Node] node
205
- #
206
- # @return [undefined]
207
- #
208
- # @api private
209
- #
210
- def rescue(node)
211
- body(node.body)
212
- rescue_condition(node.rescue)
213
- end
214
-
215
- # Emit rescue condition
216
- #
217
- # @param [Rubinius::AST::Node] node
218
- #
219
- # @return [undefined]
220
- #
221
- # @api private
222
- #
223
- def rescue_condition(node)
224
- emit('rescue')
225
- if node.conditions
226
- body = node.conditions.body
227
- first = body.first
228
- unless body.one? and first.kind_of?(Rubinius::AST::ConstantAccess) and first.name == :StandardError
229
- emit(' ')
230
- array_body(body)
231
- end
232
- end
233
-
234
- if node.splat
235
- emit(',') if node.conditions
236
- emit(' ')
237
- dispatch(node.splat)
238
- end
239
-
240
- if node.assignment
241
- emit(' => ')
242
- emit(node.assignment.name)
243
- end
244
- nl
245
- body(node.body)
246
-
247
- if node.next
248
- dispatch(node.next)
249
- end
250
- end
251
-
252
- # Emit rescue splat
253
- #
254
- # @param [Rubinius::AST::Node] node
255
- #
256
- # @return [undefined]
257
- #
258
- # @api private
259
- #
260
- def rescue_splat(node)
261
- emit('*')
262
- dispatch(node.value)
263
- end
264
-
265
- # Emit ensure
266
- #
267
- # @param [Rubinius::AST::Node] node
268
- #
269
- # @return [undefined]
270
- #
271
- # @api private
272
- #
273
- def ensure(node)
274
- body(node.body)
275
- emit('ensure')
276
- nl
277
- body(node.ensure)
278
- end
279
-
280
- # Emit attribute assignment
281
- #
282
- # @param [Rubinius::AST::Node] node
283
- #
284
- # @return [undefined]
285
- #
286
- # @api private
287
- #
288
- def attribute_assignment(node)
289
- dispatch(node.receiver)
290
- emit('.')
291
- emit(node.name)
292
- emit(' ')
293
- actual_arguments(node.arguments)
294
- end
295
-
296
- # Emit body with taking care on indentation
297
- #
298
- # @param [Rubinius::AST::Node] node
299
- #
300
- # @return [undefined]
301
- #
302
- # @api private
303
- #
304
- def body(node)
305
- @indentation+=1
306
- node =
307
- case node
308
- when Rubinius::AST::EmptyBody
309
- node
310
- when Rubinius::AST::Block
311
- # Hack to correctly indent ensure or rescue
312
- noindent = [Rubinius::AST::Ensure, Rubinius::AST::Rescue]
313
- if node.array.one? && noindent.include?(node.array.first.class)
314
- @indentation-=1
315
- dispatch(node)
316
- return
317
- end
318
- node
319
- else
320
- Rubinius::AST::Block.new(node.line, [node])
321
- end
322
-
323
- dispatch(node)
324
- nl
325
- @indentation-=1
326
- end
327
-
328
- # Emit end keyword
329
- #
330
- # @return [undefined]
331
- #
332
- # @api private
333
- #
334
- def kend
335
- emit(current_indentation)
336
- emit('end')
337
- end
338
-
339
- # Emit newline
340
- #
341
- # @return [undefined]
342
- #
343
- # @api private
344
- #
345
- def nl
346
- emit("\n")
347
- end
348
-
349
- # Emit pice of code
350
- #
351
- # @param [String] code
352
- #
353
- # @return [undefined]
354
- #
355
- # @api private
356
- #
357
- def emit(code)
358
- @output << code
359
- end
360
-
361
- # Return current indentation
362
- #
363
- # @return [String]
364
- #
365
- # @api private
366
- #
367
- def current_indentation
368
- ' ' * @indentation
369
- end
370
-
371
- # Emit dynamic regexp
372
- #
373
- # @param [Rubinius::AST::Node] node
374
- #
375
- # @return [undefined]
376
- #
377
- # @api private
378
- #
379
- def dynamic_regex(node)
380
- emit('/')
381
- emit(node.string)
382
- node.array.each do |member|
383
- case member
384
- when Rubinius::AST::ToString
385
- emit('#{')
386
- dispatch(member.value)
387
- emit('}')
388
- when Rubinius::AST::StringLiteral
389
- emit(member.string)
390
- end
391
- end
392
- emit('/')
393
- end
394
-
395
- # Emit dynamic string body
396
- #
397
- # @param [Rubinius::AST::Node] node
398
- #
399
- # @return [undefined]
400
- #
401
- # @api private
402
- #
403
- def dynamic_string_body(node)
404
- emit(node.string.inspect[1..-2])
405
- node.array.each do |member|
406
- case member
407
- when Rubinius::AST::ToString
408
- emit('#{')
409
- dispatch(member.value)
410
- emit('}')
411
- when Rubinius::AST::StringLiteral
412
- emit(member.string.inspect[1..-2])
413
- end
414
- end
415
- end
416
-
417
- # Emit dynamic execute string
418
- #
419
- # @param [Rubinius::AST::Node] node
420
- #
421
- # @return [undefined]
422
- #
423
- # @api private
424
- #
425
- def dynamic_execute_string(node)
426
- emit('`')
427
- dynamic_string_body(node)
428
- emit('`')
429
- end
430
-
431
- # Emit dynamic string
432
- #
433
- # @param [Rubinius::AST::Node] node
434
- #
435
- # @return [undefined]
436
- #
437
- # @api private
438
- #
439
- def dynamic_string(node)
440
- emit('"')
441
- dynamic_string_body(node)
442
- emit('"')
443
- end
444
-
445
- # Emit dynamic symbol
446
- #
447
- # @param [Rubinius::AST::Node] node
448
- #
449
- # @return [undefined]
450
- #
451
- # @api private
452
- #
453
- def dynamic_symbol(node)
454
- emit(':')
455
- dynamic_string(node)
456
- end
457
-
458
- # Emit singleton class inheritance
459
- #
460
- # @param [Rubinius::AST::Node] node
461
- #
462
- # @return [undefined]
463
- #
464
- # @api private
465
- #
466
- def s_class(node)
467
- emit('class << ')
468
- dispatch(node.receiver)
469
- nl
470
- # FIXME: attr_reader missing on Rubinius::AST::SClass
471
- scope = node.instance_variable_get(:@body)
472
- body = scope.body
473
- if body
474
- body(body)
475
- end
476
- kend
477
- end
478
-
479
- # Emit to array
480
- #
481
- # @param [Rubinius::AST::Node] node
482
- #
483
- # @return [undefined]
484
- #
485
- # @api private
486
- #
487
- def to_array(node)
488
- dispatch(node.value)
489
- end
490
-
491
- # Emit multiple assignment
492
- #
493
- # @param [Rubinius::AST::Node] node
494
- #
495
- # @return [undefined]
496
- #
497
- # @api private
498
- #
499
- def multiple_assignment(node)
500
- body = node.left.body
501
-
502
- array_body(node.left.body)
503
-
504
- emit(' = ')
505
-
506
- right = node.right
507
-
508
- if node.right.kind_of?(Rubinius::AST::ArrayLiteral)
509
- array_body(right.body)
510
- else
511
- dispatch(right)
512
- end
513
- end
514
-
515
- # Emit constant assignment
516
- #
517
- # @param [Rubinius::AST::Node] node
518
- #
519
- # @return [undefined]
520
- #
521
- # @api private
522
- #
523
- def constant_assignment(node)
524
- dispatch(node.constant)
525
- emit(' = ')
526
- dispatch(node.value)
527
- end
528
-
529
- # Emit negation
530
- #
531
- # @param [Rubinius::AST::Node] node
532
- #
533
- # @return [undefined]
534
- #
535
- # @api private
536
- #
537
- def negate(node)
538
- emit('-')
539
- dispatch(node.value)
540
- end
541
-
542
- # Emit class definition
543
- #
544
- # @param [Rubinius::AST::Node] node
545
- #
546
- # @return [undefined]
547
- #
548
- # @api private
549
- #
550
- def class_def(node)
551
- emit('class ')
552
-
553
- dispatch(node.name)
554
-
555
- superclass = node.superclass
556
- unless superclass.is_a?(Rubinius::AST::NilLiteral)
557
- emit ' < '
558
- dispatch(superclass)
559
- end
560
- nl
561
-
562
- dispatch(node.body)
563
-
564
- kend
565
- end
566
-
567
- # Emit class name
568
- #
569
- # @param [Rubinius::AST::Node] node
570
- #
571
- # @return [undefined]
572
- #
573
- # @api private
574
- #
575
- def class_name(node)
576
- emit(node.name)
577
- end
578
-
579
- # Emit module name
580
- #
581
- # @param [Rubinius::AST::Node] node
582
- #
583
- # @return [undefined]
584
- #
585
- # @api private
586
- #
587
- def module_name(node)
588
- emit(node.name)
589
- end
590
-
591
- # Emit module definition
592
- #
593
- # @param [Rubinius::AST::Node] node
594
- #
595
- # @return [undefined]
596
- #
597
- # @api private
598
- #
599
- def module_def(node)
600
- emit "module "
601
- dispatch(node.name)
602
- nl
603
-
604
- dispatch(node.body)
605
-
606
- kend
607
- end
608
-
609
- # Emit empty body
610
- #
611
- # @param [Rubinius::AST::Node] node
612
- #
613
- # @return [undefined]
614
- #
615
- # @api private
616
- #
617
- def empty_body(node)
618
- # do nothing
619
- end
620
-
621
- # Emit class scope
622
- #
623
- # @param [Rubinius::AST::Node] node
624
- #
625
- # @return [undefined]
626
- #
627
- # @api private
628
- #
629
- def class_scope(node)
630
- body(node.body)
631
- end
632
-
633
- # Emit module scope
634
- #
635
- # @param [Rubinius::AST::Node] node
636
- #
637
- # @return [undefined]
638
- #
639
- # @api private
640
- #
641
- def module_scope(node)
642
- body(node.body)
643
- end
644
-
645
- # Emit class variable assignment
646
- #
647
- # @param [Rubinius::AST::Node] node
648
- #
649
- # @return [undefined]
650
- #
651
- # @api private
652
- #
653
- def class_variable_assignment(node)
654
- if node.value
655
- emit("#{node.name} = ")
656
- dispatch(node.value)
657
- else
658
- emit(node.name)
659
- end
660
- end
661
-
662
- # Emit local variable assignment
663
- #
664
- # @param [Rubinius::AST::Node] node
665
- #
666
- # @return [undefined]
667
- #
668
- # @api private
669
- #
670
- def local_variable_assignment(node)
671
- if node.value
672
- emit("#{node.name} = ")
673
- dispatch(node.value)
674
- else
675
- emit(node.name)
676
- end
677
- end
678
-
679
- # Emit class variable
680
- #
681
- # @param [Rubinius::AST::Node] node
682
- #
683
- # @return [undefined]
684
- #
685
- # @api private
686
- #
687
- def class_variable_access(node)
688
- emit(node.name)
689
- end
690
-
691
- # Emit local variable access
692
- #
693
- # @param [Rubinius::AST::Node] node
694
- #
695
- # @return [undefined]
696
- #
697
- # @api private
698
- #
699
- def local_variable_access(node)
700
- emit(node.name)
701
- end
702
-
703
- # Emit global variable access
704
- #
705
- # @param [Rubinius::AST::Node] node
706
- #
707
- # @return [undefined]
708
- #
709
- # @api private
710
- #
711
- def global_variable_access(node)
712
- emit(node.name)
713
- end
714
-
715
- # Emit global variable assignment
716
- #
717
- # @param [Rubinius::AST::Node] node
718
- #
719
- # @return [undefined]
720
- #
721
- # @api private
722
- #
723
- def global_variable_assignment(node)
724
- if(node.value)
725
- emit("%s = " % node.name)
726
- dispatch(node.value)
727
- else
728
- emit(node.name)
729
- end
730
- end
731
-
732
- # Emit nref global variable access
733
- #
734
- # @param [Rubinius::AST::Node] node
735
- #
736
- # @return [undefined]
737
- #
738
- # @api private
739
- #
740
- def nth_ref(node)
741
- emit("$#{node.which}")
742
- end
743
-
744
- # Emit instance variable assignment
745
- #
746
- # @param [Rubinius::AST::Node] node
747
- #
748
- # @return [undefined]
749
- #
750
- # @api private
751
- #
752
- def instance_variable_assignment(node)
753
- if(node.value)
754
- emit("%s = " % node.name)
755
- dispatch(node.value)
756
- else
757
- emit(node.name)
758
- end
759
- end
760
-
761
- # Emit instance variable access
762
- #
763
- # @param [Rubinius::AST::Node] node
764
- #
765
- # @return [undefined]
766
- #
767
- # @api private
768
- #
769
- def instance_variable_access(node)
770
- emit(node.name)
771
- end
772
-
773
- # Emit defined check
774
- #
775
- # @param [Rubinius::AST::Node] node
776
- #
777
- # @return [undefined]
778
- #
779
- # @api private
780
- #
781
- def defined(node)
782
- emit('defined?(')
783
- dispatch(node.expression)
784
- emit(')')
785
- end
786
-
787
- # Emit fixnum literal
788
- #
789
- # @param [Rubinius::AST::Node] node
790
- #
791
- # @return [undefined]
792
- #
793
- # @api private
794
- #
795
- def fixnum_literal(node)
796
- emit(node.value.to_s)
797
- end
798
-
799
- # Emit float literal
800
- #
801
- # @param [Rubinius::AST::Node] node
802
- #
803
- # @return [undefined]
804
- #
805
- # @api private
806
- #
807
- def float_literal(node)
808
- emit(node.value.to_s)
809
- end
810
-
811
- # Emit string literal
812
- #
813
- # @param [Rubinius::AST::Node] node
814
- #
815
- # @return [undefined]
816
- #
817
- # @api private
818
- #
819
- def string_literal(node)
820
- emit(node.string.inspect)
821
- end
822
-
823
- # Emit execute string
824
- #
825
- # @param [Rubinius::AST::Node] node
826
- #
827
- # @return [undefined]
828
- #
829
- # @api private
830
- #
831
- def execute_string(node)
832
- emit("`#{node.string.inspect[1..-2]}`")
833
- end
834
-
835
- # Emit symbol literal
836
- #
837
- # @param [Rubinius::AST::Node] node
838
- #
839
- # @return [undefined]
840
- #
841
- # @api private
842
- #
843
- def symbol_literal(node)
844
- emit ":#{node.value.to_s}"
845
- end
846
-
847
- # Emit true literal
848
- #
849
- # @param [Rubinius::AST::Node] node
850
- #
851
- # @return [undefined]
852
- #
853
- # @api private
854
- #
855
- def true_literal(node)
856
- emit 'true'
857
- end
858
-
859
- # Emit false literal
860
- #
861
- # @param [Rubinius::AST::Node] node
862
- #
863
- # @return [undefined]
864
- #
865
- # @api private
866
- #
867
- def false_literal(node)
868
- emit 'false'
869
- end
870
-
871
- # Emit nil literal
872
- #
873
- # @param [Rubinius::AST::Node] node
874
- #
875
- # @return [undefined]
876
- #
877
- # @api private
878
- #
879
- def nil_literal(node)
880
- emit 'nil'
881
- end
882
-
883
- # Emit argumentless super
884
- #
885
- # @param [Rubinius::AST::Node] node
886
- #
887
- # @return [undefined]
888
- #
889
- # @api private
890
- #
891
- def z_super(node)
892
- emit('super')
893
- if node.block
894
- dispatch(node.block)
895
- end
896
- end
897
-
898
- # Emit super
899
- #
900
- # @param [Rubinius::AST::Node] node
901
- #
902
- # @return [undefined]
903
- #
904
- # @api private
905
- #
906
- def super(node)
907
- emit('super')
908
- # Stupid hack to ensure super() is emitted, this lib needs a redesign!
909
- arguments = node.arguments
910
- empty = arguments.array.empty? && !arguments.splat && !node.block
911
- emit('()') if empty
912
- arguments(node)
913
- end
914
-
915
- # Emit concat args
916
- #
917
- # @param [Rubinius::AST::Node] node
918
- #
919
- # @return [undefined]
920
- #
921
- # @api private
922
- #
923
- def concat_args(node)
924
- emit('[')
925
- array_body(node.array.body)
926
- emit(', ')
927
- emit('*')
928
- dispatch(node.rest)
929
- emit(']')
930
- end
931
-
932
- # Emit array body
933
- #
934
- # @param [Array] body
935
- #
936
- # @return [undefined]
937
- #
938
- # @api private
939
- #
940
- def array_body(body)
941
- body.each_with_index do |node, index|
942
- dispatch(node)
943
- emit ', ' unless body.length == index + 1 # last element
944
- end
945
- end
946
-
947
- # Emit array literal
948
- #
949
- # @param [Rubinius::AST::Node] node
950
- #
951
- # @return [undefined]
952
- #
953
- # @api private
954
- #
955
- def array_literal(node)
956
- emit('[')
957
- array_body(node.body)
958
- emit(']')
959
- end
960
-
961
-
962
- # Emit emtpy array literal
963
- #
964
- # @param [Rubinius::AST::Node] node
965
- #
966
- # @return [undefined]
967
- #
968
- # @api private
969
- #
970
- def empty_array(node)
971
- emit('[]')
972
- end
973
-
974
- # Emit hash literal
975
- #
976
- # @param [Rubinius::AST::Node] node
977
- #
978
- # @return [undefined]
979
- #
980
- # @api private
981
- #
982
- def hash_literal(node)
983
- body = node.array.each_slice(2)
984
-
985
- emit '{'
986
- body.each_with_index do |slice, index|
987
- key, value = slice
988
-
989
- dispatch(key)
990
- emit " => "
991
- dispatch(value)
992
-
993
- emit ', ' unless body.to_a.length == index + 1 # last element
994
- end
995
- emit '}'
996
- end
997
-
998
- # Emit inclusive range literal
999
- #
1000
- # @param [Rubinius::AST::Node] node
1001
- #
1002
- # @return [undefined]
1003
- #
1004
- # @api private
1005
- #
1006
- def range(node)
1007
- dispatch(node.start)
1008
- emit '..'
1009
- dispatch(node.finish)
1010
- end
1011
-
1012
- # Emit exlusive range literal
1013
- #
1014
- # @param [Rubinius::AST::Node] node
1015
- #
1016
- # @return [undefined]
1017
- #
1018
- # @api private
1019
- #
1020
- def range_exclude(node)
1021
- dispatch(node.start)
1022
- emit '...'
1023
- dispatch(node.finish)
1024
- end
1025
-
1026
- # Emit range literal
1027
- #
1028
- # @param [Rubinius::AST::Node] node
1029
- #
1030
- # @return [undefined]
1031
- #
1032
- # @api private
1033
- #
1034
- def regex_literal(node)
1035
- emit(Regexp.new(node.source).inspect)
1036
- end
1037
-
1038
-
1039
- # Emit receiver
1040
- #
1041
- # @param [Rubinius::AST::Node] node
1042
- #
1043
- # @return [true]
1044
- # returns true if there is an explicit receiver
1045
- #
1046
- # @return [false]
1047
- # returns false otherwise
1048
- #
1049
- # @api private
1050
- #
1051
- def receiver(node)
1052
- unless node.receiver.is_a?(Rubinius::AST::Self) and node.privately
1053
- dispatch(node.receiver)
1054
- true
1055
- else
1056
- false
1057
- end
1058
- end
1059
-
1060
- UNARY_OPERATORS = %w(
1061
- ! ~ -@ +@
1062
- ).map(&:to_sym).to_set.freeze
1063
-
1064
- UNARY_MAPPING = {
1065
- :-@ => :-,
1066
- :+@ => :+,
1067
- }.freeze
1068
-
1069
- # Emit unary operator
1070
- #
1071
- # @param [Rubinius::AST::Node] node
1072
- #
1073
- # @return [true]
1074
- # if node was emitted
1075
- #
1076
- # @return [false]
1077
- # otherwise
1078
- #
1079
- # @api private
1080
- #
1081
- def unary_operator(node)
1082
- name = node.name
1083
-
1084
- if UNARY_OPERATORS.include?(name)
1085
- emit(UNARY_MAPPING.fetch(name, name))
1086
- dispatch(node.receiver)
1087
- return true
1088
- end
1089
-
1090
- false
1091
- end
1092
-
1093
- # Emit send node
1094
- #
1095
- # @param [Rubinius::AST::Node] node
1096
- #
1097
- # @return [undefined]
1098
- #
1099
- # @api private
1100
- #
1101
- def send(node)
1102
- return if unary_operator(node)
1103
-
1104
- if receiver(node)
1105
- emit('.')
1106
- end
1107
-
1108
- emit(node.name)
1109
-
1110
- block = node.block
1111
-
1112
- if(block)
1113
- if block.kind_of?(Rubinius::AST::BlockPass)
1114
- emit('(')
1115
- block_pass(block)
1116
- emit(')')
1117
- else
1118
- dispatch(block)
1119
- end
1120
- end
1121
- end
1122
-
1123
- # Emit arguments
1124
- #
1125
- # @param [Rubinius::AST::Node] node
1126
- #
1127
- # @return [undefined]
1128
- #
1129
- # @api private
1130
- #
1131
- def arguments(node, open='(', close=')')
1132
- arguments = node.arguments
1133
- array, block = arguments.array, node.block
1134
-
1135
- return if array.empty? and block.nil? and arguments.splat.nil?
1136
-
1137
- emit(open)
1138
-
1139
- array_body(array)
1140
- is_block_pass = block.kind_of?(Rubinius::AST::BlockPass)
1141
-
1142
- empty = array.empty?
1143
-
1144
- if arguments.splat
1145
- emit(', ') unless empty
1146
- dispatch(arguments.splat)
1147
- empty = false
1148
- end
1149
-
1150
- if is_block_pass
1151
- emit(', ') unless empty
1152
- block_pass(block)
1153
- end
1154
-
1155
- emit(close)
1156
-
1157
- if block and !is_block_pass
1158
- dispatch(node.block)
1159
- end
1160
- end
1161
-
1162
- # Emit self
1163
- #
1164
- # @param [Rubinius::AST::Node] node
1165
- #
1166
- # @return [undefined]
1167
- #
1168
- # @api private
1169
- #
1170
- def self(node)
1171
- emit('self')
1172
- end
1173
-
1174
- # Emit element reference
1175
- #
1176
- # @param [Rubinius::AST::Node] node
1177
- #
1178
- # @return [undefined]
1179
- #
1180
- # @api private
1181
- #
1182
- def element_reference(node)
1183
- dispatch(node.receiver)
1184
- arguments(node, '[', ']')
1185
- end
1186
-
1187
- # Emit send with arguments
1188
- #
1189
- # @param [Rubinius::AST::Node] node
1190
- #
1191
- # @return [undefined]
1192
- #
1193
- # @api private
1194
- #
1195
- def send_with_arguments(node)
1196
- if node.name == :[]
1197
- return element_reference(node)
1198
- end
1199
-
1200
- return if process_binary_operator(node)
1201
-
1202
- if receiver(node)
1203
- emit('.')
1204
- end
1205
-
1206
- emit(node.name)
1207
-
1208
- arguments(node)
1209
- end
1210
-
1211
- # Emit yield
1212
- #
1213
- # @param [Rubinius::AST::Node] node
1214
- #
1215
- # @return [undefined]
1216
- #
1217
- # @api private
1218
- #
1219
- def yield(node)
1220
- emit('yield')
1221
- arguments(node)
1222
- end
1223
-
1224
- # Emit receiver case statment
1225
- #
1226
- # @param [Rubinius::AST::Node] node
1227
- #
1228
- # @return [undefined]
1229
- #
1230
- # @api private
1231
- #
1232
- def receiver_case(node)
1233
- emit('case ')
1234
- dispatch(node.receiver)
1235
- nl
1236
- node.whens.each do |branch|
1237
- dispatch(branch)
1238
- end
1239
- else_body = node.else
1240
- unless else_body.kind_of?(Rubinius::AST::NilLiteral)
1241
- emit('else')
1242
- nl
1243
- body(else_body)
1244
- end
1245
- kend
1246
- end
1247
-
1248
- # Emit when
1249
- #
1250
- # @param [Rubinius::AST::Node] node
1251
- #
1252
- # @return [undefined]
1253
- #
1254
- # @api private
1255
- #
1256
- def when(node)
1257
- emit('when ')
1258
- if node.single
1259
- dispatch(node.single)
1260
- end
1261
- if node.conditions
1262
- array_body(node.conditions.body)
1263
- end
1264
- if node.splat
1265
- dispatch(node.splat)
1266
- end
1267
- nl
1268
- body(node.body)
1269
- end
1270
-
1271
- # Emit splat when
1272
- #
1273
- # @param [Rubinius::AST::Node] node
1274
- #
1275
- # @return [undefined]
1276
- #
1277
- # @api private
1278
- #
1279
- def splat_when(node)
1280
- emit('*')
1281
- dispatch(node.condition)
1282
- end
1283
-
1284
- # Emit splat value
1285
- #
1286
- # @param [Rubinius::AST::Node] node
1287
- #
1288
- # @return [undefined]
1289
- #
1290
- # @api private
1291
- #
1292
- def splat_value(node)
1293
- emit('*')
1294
- dispatch(node.value)
1295
- end
1296
-
1297
- # Emit acutal arguments
1298
- #
1299
- # @param [Rubinius::AST::Node] node
1300
- #
1301
- # @return [undefined]
1302
- #
1303
- # @api private
1304
- #
1305
- def actual_arguments(node)
1306
- array_body(node.array)
1307
- end
1308
-
1309
- # Emit iteration
1310
- #
1311
- # @param [Rubinius::AST::Node] node
1312
- #
1313
- # @return [undefined]
1314
- #
1315
- # @api private
1316
- #
1317
- def iter(node)
1318
- emit(' do')
1319
-
1320
- arguments = node.arguments
1321
- unless arguments.names.empty?
1322
- emit(' ')
1323
- iter_arguments(node.arguments)
1324
- end
1325
-
1326
- nl
1327
- body(node.body)
1328
-
1329
- kend
1330
- end
1331
-
1332
- # Emit iteration arguments for ruby18 mode
1333
- #
1334
- # @param [Rubinius::AST::Node] node
1335
- #
1336
- # @return [undefined]
1337
- #
1338
- # @api private
1339
- #
1340
- def iter_arguments(node)
1341
- body = if node.prelude == :single
1342
- Array(node.arguments.name)
1343
- else
1344
- node.arguments.left.body.map(&:name)
1345
- end
1346
-
1347
- emit '|'
1348
- body.each_with_index do |argument, index|
1349
- emit argument.to_s
1350
- emit ', ' unless body.length == index + 1 # last element
1351
- end
1352
- emit '|'
1353
- end
1354
-
1355
- # Emit iteration arguments for ruby19 mode
1356
- #
1357
- # @param [Rubinius::AST::Node] node
1358
- #
1359
- # @return [undefined]
1360
- #
1361
- # @api private
1362
- #
1363
- def iter19(node)
1364
- emit(' do')
1365
-
1366
- arguments = node.arguments
1367
- unless arguments.required.empty?
1368
- emit(' ')
1369
- formal_arguments_generic(node.arguments,'|','|')
1370
- end
1371
-
1372
- nl
1373
- body(node.body)
1374
-
1375
- kend
1376
- end
1377
-
1378
- # Emit block
1379
- #
1380
- # @param [Rubinius::AST::Node] node
1381
- #
1382
- # @return [undefined]
1383
- #
1384
- # @api private
1385
- #
1386
- def block(node)
1387
- body = node.array
1388
- body.each_with_index do |expression,index|
1389
- emit(current_indentation)
1390
- dispatch(expression)
1391
- nl unless body.length == index+1
1392
- end
1393
- end
1394
-
1395
- # Emit not
1396
- #
1397
- # @param [Rubinius::AST::Node] node
1398
- #
1399
- # @return [undefined]
1400
- #
1401
- # @api private
1402
- #
1403
- def not(node)
1404
- emit('!')
1405
- dispatch(node.value)
1406
- end
1407
-
1408
- # Emit and
1409
- #
1410
- # @param [Rubinius::AST::Node] node
1411
- #
1412
- # @return [undefined]
1413
- #
1414
- # @api private
1415
- #
1416
- def and(node)
1417
- binary(node, '&&')
1418
- end
1419
-
1420
- # Call block while emitting parantheses
1421
- #
1422
- # @return [undefined]
1423
- #
1424
- # @api private
1425
- #
1426
- def parantheses
1427
- emit('(')
1428
- yield
1429
- emit(')')
1430
- end
1431
-
1432
- # Emit binary operation
1433
- #
1434
- # @param [Rubnius::AST::Node] node
1435
- #
1436
- # @param [Symbol] symbol
1437
- # the operation symbol
1438
- #
1439
- # @api private
1440
- #
1441
- def binary(node, symbol)
1442
- parantheses do
1443
- parantheses { dispatch(node.left) }
1444
- emit(" #{symbol} ")
1445
- parantheses { dispatch(node.right) }
1446
- end
1447
- end
1448
-
1449
- # Emit binary shortcut
1450
- #
1451
- # @param [Rubinius::AST::Node] node
1452
- #
1453
- # @param [Symbol] symbol
1454
- #
1455
- # @api private
1456
- #
1457
- def binary_shortcut(node, symbol)
1458
- parantheses do
1459
- dispatch(node.left)
1460
- emit(" #{symbol} ")
1461
- parantheses { dispatch(node.right.value) }
1462
- end
1463
- end
1464
-
1465
- # Emit or
1466
- #
1467
- # @param [Rubinius::AST::Node] node
1468
- #
1469
- # @return [undefined]
1470
- #
1471
- # @api private
1472
- #
1473
- def or(node)
1474
- binary(node, '||')
1475
- end
1476
-
1477
- # Emit and operation with assignment
1478
- #
1479
- # @param [Rubinius::AST::Node] node
1480
- #
1481
- # @return [undefined]
1482
- #
1483
- # @api private
1484
- #
1485
- def op_assign_and(node)
1486
- binary_shortcut(node, :'&&=')
1487
- end
1488
-
1489
- # Emit or operation with assignment
1490
- #
1491
- # @param [Rubinius::AST::Node] node
1492
- #
1493
- # @return [undefined]
1494
- #
1495
- # @api private
1496
- #
1497
- def op_assign_or(node)
1498
- binary_shortcut(node, :'||=')
1499
- end
1500
- alias_method :op_assign_or19, :op_assign_or
1501
-
1502
- # Emit toplevel constant
1503
- #
1504
- # @param [Rubinius::AST::Node] node
1505
- #
1506
- # @return [undefined]
1507
- #
1508
- # @api private
1509
- #
1510
- def toplevel_constant(node)
1511
- emit('::')
1512
- emit(node.name)
1513
- end
1514
-
1515
- # Emit constant accesws
1516
- #
1517
- # @param [Rubinius::AST::Node] node
1518
- #
1519
- # @return [undefined]
1520
- #
1521
- # @api private
1522
- #
1523
- def constant_access(node)
1524
- emit(node.name)
1525
- end
1526
-
1527
- # Emit scoped constant
1528
- #
1529
- # @param [Rubinius::AST::Node] node
1530
- #
1531
- # @return [undefined]
1532
- #
1533
- # @api private
1534
- #
1535
- def scoped_constant(node)
1536
- dispatch(node.parent)
1537
- emit('::')
1538
- emit(node.name)
1539
- end
1540
- alias_method :scoped_class_name, :scoped_constant
1541
- alias_method :scoped_module_name, :scoped_constant
1542
-
1543
- # Emit toplevel class name
1544
- #
1545
- # @param [Rubinius::AST::Node] node
1546
- #
1547
- # @return [undefined]
1548
- #
1549
- # @api private
1550
- #
1551
- def toplevel_class_name(node)
1552
- emit("::#{node.name}")
1553
- end
1554
-
1555
- # Emit if expression
1556
- #
1557
- # @param [Rubinius::AST::Node] node
1558
- #
1559
- # @return [undefined]
1560
- #
1561
- # @api private
1562
- #
1563
- def if(node)
1564
- body, else_body = node.body, node.else
1565
-
1566
- keyword = 'if'
1567
-
1568
- if node.body.is_a?(Rubinius::AST::NilLiteral) && !node.else.is_a?(Rubinius::AST::NilLiteral)
1569
- body, else_body = else_body, body
1570
- keyword = 'unless'
1571
- end
1572
-
1573
- emit(keyword)
1574
- emit(' ')
1575
- dispatch(node.condition)
1576
- nl
1577
-
1578
- body(body)
1579
-
1580
- if else_body.is_a?(Rubinius::AST::NilLiteral)
1581
- kend
1582
- return
1583
- end
1584
-
1585
- emit('else')
1586
- nl
1587
-
1588
- body(else_body)
1589
-
1590
- kend
1591
- end
1592
-
1593
- # Dispatch node
1594
- #
1595
- # @param [Rubinius::AST::Node] node
1596
- #
1597
- # @return [undefined]
1598
- #
1599
- # @api private
1600
- #
1601
- def while(node)
1602
- emit 'while '
1603
- dispatch(node.condition)
1604
- nl
1605
-
1606
- body(node.body)
1607
-
1608
- kend
1609
- end
1610
-
1611
- # Emit until
1612
- #
1613
- # @param [Rubinius::AST::Node] node
1614
- #
1615
- # @return [undefined]
1616
- #
1617
- # @api private
1618
- #
1619
- def until(node)
1620
- emit 'until '
1621
- dispatch(node.condition)
1622
- nl
1623
-
1624
- body(node.body)
1625
-
1626
- kend
1627
- end
1628
-
1629
- # Emit pattern variable
1630
- #
1631
- # @param [Rubinius::AST::PatternVariable] node
1632
- #
1633
- # @return [undefined]
1634
- #
1635
- # @api private
1636
- #
1637
- def pattern_variable(node)
1638
- emit(node.name)
1639
- end
1640
-
1641
- # Emit pattern arguments
1642
- #
1643
- # @param [Rubinius::AST::PatternArguments] node
1644
- #
1645
- # @return [undefined]
1646
- #
1647
- # @api private
1648
- #
1649
- def pattern_arguments(node)
1650
- emit('(')
1651
- arguments = node.arguments.body
1652
- arguments.each_with_index do |argument, index|
1653
- dispatch(argument)
1654
- emit(', ') unless index == arguments.size - 1
1655
- end
1656
- emit(')')
1657
- end
1658
-
1659
- # Emit formal arguments as shared between ruby18 and ruby19 mode
1660
- #
1661
- # @param [Rubinius::AST::Node] node
1662
- #
1663
- # @return [undefined]
1664
- #
1665
- # @api private
1666
- #
1667
- def formal_arguments_generic(node, open, close)
1668
- required, defaults, splat, block_arg = node.required, node.defaults, node.splat, node.block_arg
1669
- return unless required.any? or defaults or splat or block_arg
1670
-
1671
- emit(open)
1672
-
1673
- required.each_with_index do |node, index|
1674
- if node.kind_of?(Rubinius::AST::Node)
1675
- dispatch(node)
1676
- else
1677
- emit(node)
1678
- end
1679
- emit(', ') unless index == required.size-1
1680
- end
1681
-
1682
- empty = required.empty?
1683
-
1684
- if defaults
1685
- emit(', ') unless empty
1686
- dispatch(node.defaults)
1687
- empty = false
1688
- end
1689
-
1690
- if splat
1691
- emit(', ') unless empty
1692
- emit('*')
1693
- empty = false
1694
- unless splat == :@unnamed_splat
1695
- emit(splat)
1696
- end
1697
- end
1698
-
1699
- if block_arg
1700
- emit(', ') unless empty
1701
-
1702
- dispatch(block_arg)
1703
- end
1704
-
1705
- emit(close)
1706
- end
1707
-
1708
- # Emit formal arguments for ruby19 and ruby18
1709
- #
1710
- # @param [Rubinius::AST::Node] node
1711
- #
1712
- # @return [undefined]
1713
- #
1714
- # @api private
1715
- #
1716
- def formal_arguments(node)
1717
- formal_arguments_generic(node,'(',')')
1718
- end
1719
- alias_method :formal_arguments19, :formal_arguments
1720
-
1721
- # Emit block argument
1722
- #
1723
- # @param [Rubinius::AST::Node] node
1724
- #
1725
- # @return [undefined]
1726
- #
1727
- # @api private
1728
- #
1729
- def block_argument(node)
1730
- emit('&')
1731
- emit(node.name)
1732
- end
1733
-
1734
- # Emit default arguments
1735
- #
1736
- # @param [Rubinius::AST::Node] node
1737
- #
1738
- # @return [undefined]
1739
- #
1740
- # @api private
1741
- #
1742
- def default_arguments(node)
1743
- last = node.arguments.length - 1
1744
- node.arguments.each_with_index do |argument, index|
1745
- dispatch(argument)
1746
- emit(',') unless index == last
1747
- end
1748
- end
1749
-
1750
- # Emit begin
1751
- #
1752
- # @param [Rubinius::AST::Node] node
1753
- #
1754
- # @return [undefined]
1755
- #
1756
- # @api private
1757
- #
1758
- def begin(node)
1759
- emit('begin')
1760
- nl
1761
-
1762
- body = node.rescue
1763
- case body
1764
- when Rubinius::AST::Rescue
1765
- # Rescue is reserved keyword
1766
- __send__(:rescue,body)
1767
- when Rubinius::AST::Ensure
1768
- # Ensure is reserved keyword
1769
- __send__(:ensure,body)
1770
- else
1771
- body(node.rescue)
1772
- end
1773
-
1774
- kend
1775
- end
1776
-
1777
- # Emit define on instances
1778
- #
1779
- # @param [Rubinius::AST::Node] node
1780
- #
1781
- # @return [undefined]
1782
- #
1783
- # @api private
1784
- #
1785
- def define(node)
1786
- emit('def ')
1787
-
1788
- emit(node.name)
1789
- dispatch(node.arguments)
1790
- nl
1791
-
1792
- body(node.body)
1793
- kend
1794
- end
1795
-
1796
- # Emit define on singletons
1797
- #
1798
- # @param [Rubinius::AST::Node] node
1799
- #
1800
- # @return [undefined]
1801
- #
1802
- # @api private
1803
- #
1804
- def define_singleton(node)
1805
- emit('def ')
1806
- dispatch(node.receiver)
1807
- emit('.')
1808
- dispatch(node.body)
1809
- end
1810
-
1811
- # Emit singleton scope
1812
- #
1813
- # @param [Rubinius::AST::Node] node
1814
- #
1815
- # @return [undefined]
1816
- #
1817
- # @api private
1818
- #
1819
- def define_singleton_scope(node)
1820
- emit(node.name)
1821
- dispatch(node.arguments)
1822
- nl
1823
-
1824
- body(node.body)
1825
-
1826
- kend
1827
- end
1828
-
1829
- # Emit block pass
1830
- #
1831
- # @param [Rubinius::AST::Node] node
1832
- #
1833
- # @return [undefined]
1834
- #
1835
- # @api private
1836
- #
1837
- def block_pass(node)
1838
- emit('&')
1839
- dispatch(node.body)
1840
- end
1841
- alias_method :block_pass19, :block_pass
1842
-
1843
- # Emit return statement
1844
- #
1845
- # @param [Rubinius::AST::Node] node
1846
- #
1847
- # @return [undefined]
1848
- #
1849
- # @api private
1850
- #
1851
- def return(node)
1852
- emit('return')
1853
- if node.value
1854
- emit(' ')
1855
- dispatch(node.value)
1856
- end
1857
- end
1858
-
1859
- OPERATORS = %w(
1860
- + - * / & | && || << >> ==
1861
- === != <= < <=> > >= =~ !~ ^
1862
- **
1863
- ).map(&:to_sym).to_set
1864
-
1865
- # Process binary operator
1866
- #
1867
- # @param [Rubinius::AST::Node] node
1868
- #
1869
- # @return [self]
1870
- # if node was handled
1871
- #
1872
- # @return [nil]
1873
- # otherwise
1874
- #
1875
- # @api private
1876
- #
1877
- def process_binary_operator(node)
1878
- name = node.name
1879
- return unless OPERATORS.include?(name)
1880
-
1881
- operand = node.arguments.array[0]
1882
-
1883
- parantheses do
1884
- parantheses { dispatch(node.receiver) }
1885
- emit(" #{name.to_s} ")
1886
- parantheses { dispatch(operand) }
1887
- end
1888
- end
1889
- end
1890
- end