mutant-melbourne 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +25 -0
- data/README.md +69 -0
- data/Rakefile +14 -0
- data/ext/melbourne/.gitignore +3 -0
- data/ext/melbourne/bstring-license.txt +29 -0
- data/ext/melbourne/bstrlib.c +2687 -0
- data/ext/melbourne/bstrlib.h +267 -0
- data/ext/melbourne/encoding_compat.cpp +188 -0
- data/ext/melbourne/encoding_compat.hpp +57 -0
- data/ext/melbourne/extconf.rb +87 -0
- data/ext/melbourne/grammar18.cpp +11280 -0
- data/ext/melbourne/grammar18.hpp +13 -0
- data/ext/melbourne/grammar18.y +6088 -0
- data/ext/melbourne/grammar19.cpp +12420 -0
- data/ext/melbourne/grammar19.hpp +11 -0
- data/ext/melbourne/grammar19.y +7113 -0
- data/ext/melbourne/lex.c.blt +152 -0
- data/ext/melbourne/lex.c.tab +136 -0
- data/ext/melbourne/local_state.hpp +43 -0
- data/ext/melbourne/melbourne.cpp +88 -0
- data/ext/melbourne/melbourne.hpp +19 -0
- data/ext/melbourne/node18.hpp +262 -0
- data/ext/melbourne/node19.hpp +271 -0
- data/ext/melbourne/node_types.rb +304 -0
- data/ext/melbourne/node_types18.cpp +255 -0
- data/ext/melbourne/node_types18.hpp +129 -0
- data/ext/melbourne/node_types19.cpp +249 -0
- data/ext/melbourne/node_types19.hpp +126 -0
- data/ext/melbourne/parser_state18.hpp +181 -0
- data/ext/melbourne/parser_state19.hpp +251 -0
- data/ext/melbourne/quark.cpp +42 -0
- data/ext/melbourne/quark.hpp +45 -0
- data/ext/melbourne/symbols.cpp +224 -0
- data/ext/melbourne/symbols.hpp +119 -0
- data/ext/melbourne/var_table18.cpp +83 -0
- data/ext/melbourne/var_table18.hpp +33 -0
- data/ext/melbourne/var_table19.cpp +65 -0
- data/ext/melbourne/var_table19.hpp +35 -0
- data/ext/melbourne/visitor18.cpp +963 -0
- data/ext/melbourne/visitor18.hpp +12 -0
- data/ext/melbourne/visitor19.cpp +960 -0
- data/ext/melbourne/visitor19.hpp +15 -0
- data/lib/compiler/ast/constants.rb +81 -0
- data/lib/compiler/ast/control_flow.rb +290 -0
- data/lib/compiler/ast/data.rb +14 -0
- data/lib/compiler/ast/definitions.rb +749 -0
- data/lib/compiler/ast/encoding.rb +18 -0
- data/lib/compiler/ast/exceptions.rb +138 -0
- data/lib/compiler/ast/file.rb +11 -0
- data/lib/compiler/ast/grapher.rb +89 -0
- data/lib/compiler/ast/literals.rb +207 -0
- data/lib/compiler/ast/node.rb +362 -0
- data/lib/compiler/ast/operators.rb +106 -0
- data/lib/compiler/ast/self.rb +15 -0
- data/lib/compiler/ast/sends.rb +615 -0
- data/lib/compiler/ast/transforms.rb +298 -0
- data/lib/compiler/ast/values.rb +88 -0
- data/lib/compiler/ast/variables.rb +351 -0
- data/lib/compiler/ast.rb +20 -0
- data/lib/compiler/locals.rb +109 -0
- data/lib/melbourne/processor.rb +651 -0
- data/lib/melbourne/version.rb +3 -0
- data/lib/melbourne.rb +143 -0
- metadata +112 -0
@@ -0,0 +1,615 @@
|
|
1
|
+
# -*- encoding: us-ascii -*-
|
2
|
+
|
3
|
+
module Rubinius
|
4
|
+
module AST
|
5
|
+
class Send < Node
|
6
|
+
attr_accessor :receiver, :name, :privately, :block, :variable
|
7
|
+
attr_accessor :check_for_local
|
8
|
+
|
9
|
+
def initialize(line, receiver, name, privately=false, vcall_style=false)
|
10
|
+
@line = line
|
11
|
+
@receiver = receiver
|
12
|
+
@name = name
|
13
|
+
@privately = privately
|
14
|
+
@block = nil
|
15
|
+
@check_for_local = false
|
16
|
+
@vcall_style = vcall_style
|
17
|
+
end
|
18
|
+
|
19
|
+
def check_local_reference(g)
|
20
|
+
if @receiver.kind_of? Self and (@check_for_local or g.state.eval?)
|
21
|
+
g.state.scope.search_local(@name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def sexp_name
|
26
|
+
:call
|
27
|
+
end
|
28
|
+
|
29
|
+
def receiver_sexp
|
30
|
+
@privately ? nil : @receiver.to_sexp
|
31
|
+
end
|
32
|
+
|
33
|
+
def arguments_sexp
|
34
|
+
return nil if @vcall_style
|
35
|
+
|
36
|
+
sexp = [:arglist]
|
37
|
+
sexp << @block.to_sexp if @block.kind_of? BlockPass
|
38
|
+
sexp
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_sexp
|
42
|
+
sexp = [sexp_name, receiver_sexp, @name, arguments_sexp]
|
43
|
+
case @block
|
44
|
+
when For
|
45
|
+
@block.to_sexp.insert 1, @receiver.to_sexp
|
46
|
+
when Iter
|
47
|
+
@block.to_sexp.insert 1, sexp
|
48
|
+
else
|
49
|
+
sexp
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class SendWithArguments < Send
|
55
|
+
attr_accessor :arguments
|
56
|
+
|
57
|
+
def initialize(line, receiver, name, arguments, privately=false)
|
58
|
+
super line, receiver, name, privately
|
59
|
+
@block = nil
|
60
|
+
@arguments = ActualArguments.new line, arguments
|
61
|
+
end
|
62
|
+
|
63
|
+
def arguments_sexp(name=:arglist)
|
64
|
+
sexp = [name] + @arguments.to_sexp
|
65
|
+
sexp << @block.to_sexp if @block
|
66
|
+
sexp
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class AttributeAssignment < SendWithArguments
|
71
|
+
def initialize(line, receiver, name, arguments)
|
72
|
+
@line = line
|
73
|
+
|
74
|
+
@receiver = receiver
|
75
|
+
@privately = receiver.kind_of?(Self) ? true : false
|
76
|
+
|
77
|
+
@name = :"#{name}="
|
78
|
+
|
79
|
+
@arguments = ActualArguments.new line, arguments
|
80
|
+
end
|
81
|
+
|
82
|
+
def sexp_name
|
83
|
+
:attrasgn
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class ElementAssignment < SendWithArguments
|
88
|
+
def initialize(line, receiver, arguments)
|
89
|
+
@line = line
|
90
|
+
|
91
|
+
@receiver = receiver
|
92
|
+
@privately = receiver.kind_of?(Self) ? true : false
|
93
|
+
|
94
|
+
@name = :[]=
|
95
|
+
|
96
|
+
case arguments
|
97
|
+
when PushArgs
|
98
|
+
@arguments = PushActualArguments.new arguments
|
99
|
+
else
|
100
|
+
@arguments = ActualArguments.new line, arguments
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def sexp_name
|
105
|
+
:attrasgn
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class PreExe < Node
|
110
|
+
attr_accessor :block
|
111
|
+
|
112
|
+
def initialize(line)
|
113
|
+
@line = line
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_sexp
|
117
|
+
end
|
118
|
+
|
119
|
+
def pre_sexp
|
120
|
+
@block.to_sexp.insert 1, :pre_exe
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class PreExe19 < PreExe
|
125
|
+
end
|
126
|
+
|
127
|
+
class PushActualArguments
|
128
|
+
def initialize(pa)
|
129
|
+
@arguments = pa.arguments
|
130
|
+
@value = pa.value
|
131
|
+
end
|
132
|
+
|
133
|
+
def size
|
134
|
+
splat? ? 1 : @arguments.size + 1
|
135
|
+
end
|
136
|
+
|
137
|
+
def splat?
|
138
|
+
@arguments.kind_of? SplatValue or @arguments.kind_of? ConcatArgs
|
139
|
+
end
|
140
|
+
|
141
|
+
def to_sexp
|
142
|
+
[@arguments.to_sexp, @value.to_sexp]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
class BlockPass < Node
|
147
|
+
attr_accessor :body
|
148
|
+
|
149
|
+
def initialize(line, body)
|
150
|
+
@line = line
|
151
|
+
@body = body
|
152
|
+
end
|
153
|
+
|
154
|
+
def convert(g)
|
155
|
+
nil_block = g.new_label
|
156
|
+
g.dup
|
157
|
+
g.is_nil
|
158
|
+
g.git nil_block
|
159
|
+
|
160
|
+
g.push_cpath_top
|
161
|
+
g.find_const :Proc
|
162
|
+
|
163
|
+
g.swap
|
164
|
+
g.send :__from_block__, 1
|
165
|
+
|
166
|
+
nil_block.set!
|
167
|
+
end
|
168
|
+
|
169
|
+
def to_sexp
|
170
|
+
[:block_pass, @body.to_sexp]
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class BlockPass19 < BlockPass
|
175
|
+
attr_accessor :arguments
|
176
|
+
|
177
|
+
def initialize(line, arguments, body)
|
178
|
+
super(line, body)
|
179
|
+
@arguments = arguments
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
class CollectSplat < Node
|
184
|
+
def initialize(line, *parts)
|
185
|
+
@line = line
|
186
|
+
@splat = parts.shift
|
187
|
+
@last = parts.pop
|
188
|
+
@array = parts
|
189
|
+
end
|
190
|
+
|
191
|
+
def to_sexp
|
192
|
+
[:collect_splat] + @parts.map { |x| x.to_sexp }
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class ActualArguments < Node
|
197
|
+
attr_accessor :array, :splat
|
198
|
+
|
199
|
+
def initialize(line, arguments=nil)
|
200
|
+
@line = line
|
201
|
+
@splat = nil
|
202
|
+
|
203
|
+
case arguments
|
204
|
+
when SplatValue
|
205
|
+
@splat = arguments
|
206
|
+
@array = []
|
207
|
+
when ConcatArgs
|
208
|
+
case arguments.array
|
209
|
+
when ArrayLiteral
|
210
|
+
@array = arguments.array.body
|
211
|
+
@splat = SplatValue.new line, arguments.rest
|
212
|
+
when PushArgs
|
213
|
+
@array = []
|
214
|
+
node = SplatValue.new line, arguments.rest
|
215
|
+
@splat = CollectSplat.new line, arguments.array, node
|
216
|
+
else
|
217
|
+
@array = []
|
218
|
+
@splat = CollectSplat.new line, arguments.array, arguments.rest
|
219
|
+
end
|
220
|
+
when PushArgs
|
221
|
+
if arguments.arguments.kind_of? ConcatArgs
|
222
|
+
if ary = arguments.arguments.peel_lhs
|
223
|
+
@array = ary
|
224
|
+
else
|
225
|
+
@array = []
|
226
|
+
end
|
227
|
+
else
|
228
|
+
@array = []
|
229
|
+
end
|
230
|
+
|
231
|
+
@splat = CollectSplat.new line, arguments.arguments, arguments.value
|
232
|
+
when ArrayLiteral
|
233
|
+
@array = arguments.body
|
234
|
+
when nil
|
235
|
+
@array = []
|
236
|
+
else
|
237
|
+
@array = [arguments]
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def size
|
242
|
+
@array.size
|
243
|
+
end
|
244
|
+
|
245
|
+
def stack_size
|
246
|
+
size = @array.size
|
247
|
+
size += 1 if splat?
|
248
|
+
size
|
249
|
+
end
|
250
|
+
|
251
|
+
def splat?
|
252
|
+
not @splat.nil?
|
253
|
+
end
|
254
|
+
|
255
|
+
def to_sexp
|
256
|
+
sexp = @array.map { |x| x.to_sexp }
|
257
|
+
sexp << @splat.to_sexp if @splat
|
258
|
+
sexp
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
class Iter < Node
|
263
|
+
include Compiler::LocalVariables
|
264
|
+
|
265
|
+
attr_accessor :parent, :arguments, :body
|
266
|
+
|
267
|
+
def initialize(line, arguments, body)
|
268
|
+
@line = line
|
269
|
+
@arguments = IterArguments.new line, arguments
|
270
|
+
@body = body || NilLiteral.new(line)
|
271
|
+
end
|
272
|
+
|
273
|
+
# 1.8 doesn't support declared Iter locals
|
274
|
+
def block_local?(name)
|
275
|
+
false
|
276
|
+
end
|
277
|
+
|
278
|
+
def module?
|
279
|
+
false
|
280
|
+
end
|
281
|
+
|
282
|
+
def nest_scope(scope)
|
283
|
+
scope.parent = self
|
284
|
+
end
|
285
|
+
|
286
|
+
# A nested scope is looking up a local variable. If the variable exists
|
287
|
+
# in our local variables hash, return a nested reference to it. If it
|
288
|
+
# exists in an enclosing scope, increment the depth of the reference
|
289
|
+
# when it passes through this nested scope (i.e. the depth of a
|
290
|
+
# reference is a function of the nested scopes it passes through from
|
291
|
+
# the scope it is defined in to the scope it is used in).
|
292
|
+
def search_local(name)
|
293
|
+
if variable = variables[name]
|
294
|
+
variable.nested_reference
|
295
|
+
elsif block_local?(name)
|
296
|
+
new_local name
|
297
|
+
elsif reference = @parent.search_local(name)
|
298
|
+
reference.depth += 1
|
299
|
+
reference
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
def new_local(name)
|
304
|
+
variable = Compiler::LocalVariable.new allocate_slot
|
305
|
+
variables[name] = variable
|
306
|
+
end
|
307
|
+
|
308
|
+
def new_nested_local(name)
|
309
|
+
new_local(name).nested_reference
|
310
|
+
end
|
311
|
+
|
312
|
+
# If the local variable exists in this scope, set the local variable
|
313
|
+
# node attribute to a reference to the local variable. If the variable
|
314
|
+
# exists in an enclosing scope, set the local variable node attribute to
|
315
|
+
# a nested reference to the local variable. Otherwise, create a local
|
316
|
+
# variable in this scope and set the local variable node attribute.
|
317
|
+
def assign_local_reference(var)
|
318
|
+
if variable = variables[var.name]
|
319
|
+
var.variable = variable.reference
|
320
|
+
elsif block_local?(var.name)
|
321
|
+
variable = new_local var.name
|
322
|
+
var.variable = variable.reference
|
323
|
+
elsif reference = @parent.search_local(var.name)
|
324
|
+
reference.depth += 1
|
325
|
+
var.variable = reference
|
326
|
+
else
|
327
|
+
variable = new_local var.name
|
328
|
+
var.variable = variable.reference
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def sexp_name
|
333
|
+
:iter
|
334
|
+
end
|
335
|
+
|
336
|
+
def to_sexp
|
337
|
+
[sexp_name, @arguments.to_sexp, @body.to_sexp]
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
class Iter19 < Iter
|
342
|
+
def initialize(line, arguments, body)
|
343
|
+
@line = line
|
344
|
+
@arguments = arguments || IterArguments.new(line, nil)
|
345
|
+
@body = body || NilLiteral.new(line)
|
346
|
+
|
347
|
+
if @body.kind_of?(Block) and @body.locals
|
348
|
+
@locals = @body.locals.body.map { |x| x.value }
|
349
|
+
else
|
350
|
+
@locals = nil
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def block_local?(name)
|
355
|
+
@locals.include?(name) if @locals
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
class IterArguments < Node
|
360
|
+
attr_accessor :prelude, :arity, :optional, :arguments, :splat_index
|
361
|
+
attr_accessor :required_args
|
362
|
+
|
363
|
+
def initialize(line, arguments)
|
364
|
+
@line = line
|
365
|
+
@optional = 0
|
366
|
+
@arguments = nil
|
367
|
+
|
368
|
+
@splat_index = -1
|
369
|
+
@required_args = 0
|
370
|
+
@splat = nil
|
371
|
+
@block = nil
|
372
|
+
@prelude = nil
|
373
|
+
|
374
|
+
case arguments
|
375
|
+
when Fixnum
|
376
|
+
@splat_index = nil
|
377
|
+
@arity = 0
|
378
|
+
@prelude = nil
|
379
|
+
when MultipleAssignment
|
380
|
+
arguments.iter_arguments
|
381
|
+
|
382
|
+
if arguments.splat
|
383
|
+
case arguments.splat
|
384
|
+
when EmptySplat
|
385
|
+
@splat_index = -2
|
386
|
+
arguments.splat = nil
|
387
|
+
@prelude = :empty
|
388
|
+
else
|
389
|
+
@splat = arguments.splat = arguments.splat.value
|
390
|
+
end
|
391
|
+
|
392
|
+
@optional = 1
|
393
|
+
if arguments.left
|
394
|
+
@prelude = :multi
|
395
|
+
size = arguments.left.body.size
|
396
|
+
@arity = -(size + 1)
|
397
|
+
@required_args = size
|
398
|
+
else
|
399
|
+
@prelude = :splat unless @prelude
|
400
|
+
@arity = -1
|
401
|
+
end
|
402
|
+
elsif arguments.left
|
403
|
+
size = arguments.left.body.size
|
404
|
+
@prelude = :multi
|
405
|
+
@arity = size
|
406
|
+
@required_args = size
|
407
|
+
|
408
|
+
# distinguish { |a, | ... } from { |a| ... }
|
409
|
+
@splat_index = nil unless size == 1
|
410
|
+
else
|
411
|
+
@splat_index = 0
|
412
|
+
@prelude = :multi
|
413
|
+
@arity = -1
|
414
|
+
end
|
415
|
+
|
416
|
+
@block = arguments.block
|
417
|
+
|
418
|
+
@arguments = arguments
|
419
|
+
when nil
|
420
|
+
@arity = -1
|
421
|
+
@splat_index = -2 # -2 means accept the splat, but don't store it anywhere
|
422
|
+
@prelude = nil
|
423
|
+
when BlockPass
|
424
|
+
@arity = -1
|
425
|
+
@splat_index = -2
|
426
|
+
@prelude = nil
|
427
|
+
@block = arguments
|
428
|
+
else # Assignment
|
429
|
+
@splat_index = nil
|
430
|
+
@arguments = arguments
|
431
|
+
@arity = 1
|
432
|
+
@required_args = 1
|
433
|
+
@prelude = :single
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
alias_method :total_args, :required_args
|
438
|
+
|
439
|
+
def post_args
|
440
|
+
0
|
441
|
+
end
|
442
|
+
|
443
|
+
def names
|
444
|
+
case @arguments
|
445
|
+
when MultipleAssignment
|
446
|
+
if arguments = @arguments.left.body
|
447
|
+
array = arguments.map { |x| x.name }
|
448
|
+
else
|
449
|
+
array = []
|
450
|
+
end
|
451
|
+
|
452
|
+
if @arguments.splat.kind_of? SplatAssignment
|
453
|
+
array << @arguments.splat.name
|
454
|
+
end
|
455
|
+
|
456
|
+
array
|
457
|
+
when nil
|
458
|
+
[]
|
459
|
+
else
|
460
|
+
[@arguments.name]
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
def to_sexp
|
465
|
+
if @arguments
|
466
|
+
@arguments.to_sexp
|
467
|
+
elsif @arity == 0
|
468
|
+
0
|
469
|
+
else
|
470
|
+
nil
|
471
|
+
end
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
class For < Iter
|
476
|
+
def nest_scope(scope)
|
477
|
+
scope.parent = self
|
478
|
+
end
|
479
|
+
|
480
|
+
def search_local(name)
|
481
|
+
if reference = @parent.search_local(name)
|
482
|
+
reference.depth += 1
|
483
|
+
reference
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
def new_nested_local(name)
|
488
|
+
reference = @parent.new_nested_local name
|
489
|
+
reference.depth += 1
|
490
|
+
reference
|
491
|
+
end
|
492
|
+
|
493
|
+
def assign_local_reference(var)
|
494
|
+
unless reference = search_local(var.name)
|
495
|
+
reference = new_nested_local var.name
|
496
|
+
end
|
497
|
+
|
498
|
+
var.variable = reference
|
499
|
+
end
|
500
|
+
|
501
|
+
def sexp_name
|
502
|
+
:for
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
class For19Arguments < Node
|
507
|
+
def initialize(line, arguments)
|
508
|
+
@line = line
|
509
|
+
@arguments = arguments
|
510
|
+
|
511
|
+
if @arguments.kind_of? MultipleAssignment
|
512
|
+
@args = 0
|
513
|
+
@splat = 0
|
514
|
+
else
|
515
|
+
@args = 1
|
516
|
+
@splat = nil
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
def required_args
|
521
|
+
@args
|
522
|
+
end
|
523
|
+
|
524
|
+
def total_args
|
525
|
+
@args
|
526
|
+
end
|
527
|
+
|
528
|
+
def post_args
|
529
|
+
0
|
530
|
+
end
|
531
|
+
|
532
|
+
def splat_index
|
533
|
+
@splat
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
class For19 < For
|
538
|
+
def initialize(line, arguments, body)
|
539
|
+
@line = line
|
540
|
+
@arguments = For19Arguments.new line, arguments
|
541
|
+
@body = body || NilLiteral.new(line)
|
542
|
+
|
543
|
+
new_local :"$for_args"
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
class Negate < Node
|
548
|
+
attr_accessor :value
|
549
|
+
|
550
|
+
def initialize(line, value)
|
551
|
+
@line = line
|
552
|
+
@value = value
|
553
|
+
end
|
554
|
+
|
555
|
+
def to_sexp
|
556
|
+
[:negate, @value.to_sexp]
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
class Super < SendWithArguments
|
561
|
+
attr_accessor :name, :block
|
562
|
+
|
563
|
+
def initialize(line, arguments)
|
564
|
+
@line = line
|
565
|
+
@block = nil
|
566
|
+
@name = nil
|
567
|
+
@arguments = ActualArguments.new line, arguments
|
568
|
+
end
|
569
|
+
|
570
|
+
def to_sexp
|
571
|
+
arguments_sexp :super
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
class Yield < SendWithArguments
|
576
|
+
attr_accessor :flags
|
577
|
+
|
578
|
+
def initialize(line, arguments, unwrap)
|
579
|
+
@line = line
|
580
|
+
|
581
|
+
if arguments.kind_of? ArrayLiteral and not unwrap
|
582
|
+
arguments = ArrayLiteral.new line, [arguments]
|
583
|
+
end
|
584
|
+
|
585
|
+
@arguments = ActualArguments.new line, arguments
|
586
|
+
@argument_count = @arguments.size
|
587
|
+
@yield_splat = false
|
588
|
+
|
589
|
+
if @arguments.splat?
|
590
|
+
splat = @arguments.splat.value
|
591
|
+
if (splat.kind_of? ArrayLiteral or splat.kind_of? EmptyArray) and not unwrap
|
592
|
+
@argument_count += 1
|
593
|
+
else
|
594
|
+
@yield_splat = true
|
595
|
+
end
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
def to_sexp
|
600
|
+
arguments_sexp :yield
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
class ZSuper < Super
|
605
|
+
def initialize(line)
|
606
|
+
@line = line
|
607
|
+
@block = nil
|
608
|
+
end
|
609
|
+
|
610
|
+
def to_sexp
|
611
|
+
[:zsuper]
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
end
|