to_source 0.2.9 → 0.2.11

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.
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