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,749 @@
|
|
1
|
+
# -*- encoding: us-ascii -*-
|
2
|
+
|
3
|
+
module Rubinius
|
4
|
+
module AST
|
5
|
+
class Alias < Node
|
6
|
+
attr_accessor :to, :from
|
7
|
+
|
8
|
+
def initialize(line, to, from)
|
9
|
+
@line = line
|
10
|
+
@to = to
|
11
|
+
@from = from
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_sexp
|
15
|
+
[:alias, @to.to_sexp, @from.to_sexp]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class VAlias < Alias
|
20
|
+
def to_sexp
|
21
|
+
[:valias, @to, @from]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Undef < Node
|
26
|
+
attr_accessor :name
|
27
|
+
|
28
|
+
def initialize(line, sym)
|
29
|
+
@line = line
|
30
|
+
@name = sym
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_sexp
|
34
|
+
[:undef, @name.to_sexp]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Is it weird that Block has the :arguments attribute? Yes. Is it weird
|
39
|
+
# that MRI parse tree puts arguments and block_arg in Block? Yes. So we
|
40
|
+
# make do and pull them out here rather than having something else reach
|
41
|
+
# inside of Block.
|
42
|
+
class Block < Node
|
43
|
+
attr_accessor :array, :locals
|
44
|
+
|
45
|
+
def initialize(line, array)
|
46
|
+
@line = line
|
47
|
+
@array = array
|
48
|
+
|
49
|
+
# These are any local variable that are declared as explicit
|
50
|
+
# locals for this scope. This is only used by the |a;b| syntax.
|
51
|
+
@locals = nil
|
52
|
+
end
|
53
|
+
|
54
|
+
def strip_arguments
|
55
|
+
if @array.first.kind_of? FormalArguments
|
56
|
+
node = @array.shift
|
57
|
+
if @array.first.kind_of? BlockArgument
|
58
|
+
node.block_arg = @array.shift
|
59
|
+
end
|
60
|
+
return node
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_sexp
|
65
|
+
@array.inject([:block]) { |s, x| s << x.to_sexp }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class ClosedScope < Node
|
70
|
+
include Compiler::LocalVariables
|
71
|
+
|
72
|
+
attr_accessor :body
|
73
|
+
|
74
|
+
# A nested scope is looking up a local variable. If the variable exists
|
75
|
+
# in our local variables hash, return a nested reference to it.
|
76
|
+
def search_local(name)
|
77
|
+
if variable = variables[name]
|
78
|
+
variable.nested_reference
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def new_local(name)
|
83
|
+
variable = Compiler::LocalVariable.new allocate_slot
|
84
|
+
variables[name] = variable
|
85
|
+
end
|
86
|
+
|
87
|
+
def new_nested_local(name)
|
88
|
+
new_local(name).nested_reference
|
89
|
+
end
|
90
|
+
|
91
|
+
# There is no place above us that may contain a local variable. Set the
|
92
|
+
# local in our local variables hash if not set. Set the local variable
|
93
|
+
# node attribute to a reference to the local variable.
|
94
|
+
def assign_local_reference(var)
|
95
|
+
unless variable = variables[var.name]
|
96
|
+
variable = new_local var.name
|
97
|
+
end
|
98
|
+
|
99
|
+
var.variable = variable.reference
|
100
|
+
end
|
101
|
+
|
102
|
+
def nest_scope(scope)
|
103
|
+
scope.parent = self
|
104
|
+
end
|
105
|
+
|
106
|
+
def module?
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_sexp
|
111
|
+
sexp = [:scope]
|
112
|
+
sexp << @body.to_sexp if @body
|
113
|
+
sexp
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Define < ClosedScope
|
118
|
+
attr_accessor :name, :arguments
|
119
|
+
|
120
|
+
def initialize(line, name, block)
|
121
|
+
@line = line
|
122
|
+
@name = name
|
123
|
+
@arguments = block.strip_arguments
|
124
|
+
block.array << NilLiteral.new(line) if block.array.empty?
|
125
|
+
@body = block
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_sexp
|
129
|
+
[:defn, @name, @arguments.to_sexp, [:scope, @body.to_sexp]]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class DefineSingleton < Node
|
134
|
+
attr_accessor :receiver, :body
|
135
|
+
|
136
|
+
def initialize(line, receiver, name, block)
|
137
|
+
@line = line
|
138
|
+
@receiver = receiver
|
139
|
+
@body = DefineSingletonScope.new line, name, block
|
140
|
+
end
|
141
|
+
|
142
|
+
def to_sexp
|
143
|
+
[:defs, @receiver.to_sexp, @body.name,
|
144
|
+
@body.arguments.to_sexp, [:scope, @body.body.to_sexp]]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class DefineSingletonScope < Define
|
149
|
+
def initialize(line, name, block)
|
150
|
+
super line, name, block
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
class FormalArguments < Node
|
156
|
+
attr_accessor :names, :required, :optional, :defaults, :splat
|
157
|
+
attr_reader :block_arg
|
158
|
+
|
159
|
+
def initialize(line, args, defaults, splat)
|
160
|
+
@line = line
|
161
|
+
@defaults = nil
|
162
|
+
@block_arg = nil
|
163
|
+
|
164
|
+
if defaults
|
165
|
+
defaults = DefaultArguments.new line, defaults
|
166
|
+
@defaults = defaults
|
167
|
+
@optional = defaults.names
|
168
|
+
|
169
|
+
stop = defaults.names.first
|
170
|
+
last = args.each_with_index { |a, i| break i if a == stop }
|
171
|
+
@required = args[0, last]
|
172
|
+
else
|
173
|
+
@required = args.dup
|
174
|
+
@optional = []
|
175
|
+
end
|
176
|
+
|
177
|
+
if splat.kind_of? Symbol
|
178
|
+
args << splat
|
179
|
+
elsif splat
|
180
|
+
splat = :@unnamed_splat
|
181
|
+
args << splat
|
182
|
+
end
|
183
|
+
@names = args
|
184
|
+
@splat = splat
|
185
|
+
end
|
186
|
+
|
187
|
+
def block_arg=(node)
|
188
|
+
@names << node.name
|
189
|
+
@block_arg = node
|
190
|
+
end
|
191
|
+
|
192
|
+
def required_args
|
193
|
+
@required.size
|
194
|
+
end
|
195
|
+
|
196
|
+
alias_method :arity, :required_args
|
197
|
+
|
198
|
+
def post_args
|
199
|
+
0
|
200
|
+
end
|
201
|
+
|
202
|
+
def total_args
|
203
|
+
@required.size + @optional.size
|
204
|
+
end
|
205
|
+
|
206
|
+
def splat_index
|
207
|
+
if @splat
|
208
|
+
index = @names.size
|
209
|
+
index -= 1 if @block_arg
|
210
|
+
index -= 1 if @splat.kind_of? Symbol
|
211
|
+
index
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def map_arguments(scope)
|
216
|
+
@required.each { |arg| scope.new_local arg }
|
217
|
+
@defaults.map_arguments scope if @defaults
|
218
|
+
scope.new_local @splat if @splat.kind_of? Symbol
|
219
|
+
scope.assign_local_reference @block_arg if @block_arg
|
220
|
+
end
|
221
|
+
|
222
|
+
def to_actual(line)
|
223
|
+
arguments = ActualArguments.new line
|
224
|
+
|
225
|
+
last = -1
|
226
|
+
last -= 1 if @block_arg and @block_arg.name == names[last]
|
227
|
+
last -= 1 if @splat == names[last]
|
228
|
+
|
229
|
+
arguments.array = @names[0..last].map { |name| LocalVariableAccess.new line, name }
|
230
|
+
|
231
|
+
if @splat.kind_of? Symbol
|
232
|
+
arguments.splat = SplatValue.new(line, LocalVariableAccess.new(line, @splat))
|
233
|
+
end
|
234
|
+
|
235
|
+
arguments
|
236
|
+
end
|
237
|
+
|
238
|
+
def to_sexp
|
239
|
+
sexp = [:args]
|
240
|
+
|
241
|
+
@required.each { |x| sexp << x }
|
242
|
+
sexp += @defaults.names if @defaults
|
243
|
+
|
244
|
+
if @splat == :@unnamed_splat
|
245
|
+
sexp << :*
|
246
|
+
elsif @splat
|
247
|
+
sexp << :"*#{@splat}"
|
248
|
+
end
|
249
|
+
|
250
|
+
sexp += @post if @post
|
251
|
+
|
252
|
+
sexp << :"&#{@block_arg.name}" if @block_arg
|
253
|
+
|
254
|
+
sexp << [:block] + @defaults.to_sexp if @defaults
|
255
|
+
|
256
|
+
sexp
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
class FormalArguments19 < FormalArguments
|
261
|
+
attr_accessor :post
|
262
|
+
|
263
|
+
def initialize(line, required, optional, splat, post, block)
|
264
|
+
@line = line
|
265
|
+
@defaults = nil
|
266
|
+
@block_arg = nil
|
267
|
+
@splat_index = nil
|
268
|
+
|
269
|
+
@required = []
|
270
|
+
names = []
|
271
|
+
|
272
|
+
if required
|
273
|
+
required.each do |arg|
|
274
|
+
case arg
|
275
|
+
when Symbol
|
276
|
+
names << arg
|
277
|
+
@required << arg
|
278
|
+
when MultipleAssignment
|
279
|
+
@required << PatternArguments.from_masgn(arg)
|
280
|
+
@splat_index = -4 if @required.size == 1
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
if optional
|
286
|
+
@defaults = DefaultArguments.new line, optional
|
287
|
+
@optional = @defaults.names
|
288
|
+
names.concat @optional
|
289
|
+
else
|
290
|
+
@optional = []
|
291
|
+
end
|
292
|
+
|
293
|
+
case splat
|
294
|
+
when Symbol
|
295
|
+
names << splat
|
296
|
+
when true
|
297
|
+
splat = :@unnamed_splat
|
298
|
+
names << splat
|
299
|
+
when false
|
300
|
+
@splat_index = -3
|
301
|
+
splat = nil
|
302
|
+
end
|
303
|
+
|
304
|
+
if post
|
305
|
+
names.concat post
|
306
|
+
@post = post
|
307
|
+
else
|
308
|
+
@post = []
|
309
|
+
end
|
310
|
+
|
311
|
+
if block
|
312
|
+
@block_arg = BlockArgument.new line, block
|
313
|
+
names << block
|
314
|
+
end
|
315
|
+
|
316
|
+
@splat = splat
|
317
|
+
@names = names
|
318
|
+
end
|
319
|
+
|
320
|
+
def required_args
|
321
|
+
@required.size + @post.size
|
322
|
+
end
|
323
|
+
|
324
|
+
def post_args
|
325
|
+
@post.size
|
326
|
+
end
|
327
|
+
|
328
|
+
def total_args
|
329
|
+
@required.size + @optional.size + @post.size
|
330
|
+
end
|
331
|
+
|
332
|
+
def splat_index
|
333
|
+
return @splat_index if @splat_index
|
334
|
+
|
335
|
+
if @splat
|
336
|
+
index = @names.size
|
337
|
+
index -= 1 if @block_arg
|
338
|
+
index -= 1 if @splat.kind_of? Symbol
|
339
|
+
index -= @post.size
|
340
|
+
index
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
def map_arguments(scope)
|
345
|
+
@required.each_with_index do |arg, index|
|
346
|
+
case arg
|
347
|
+
when PatternArguments
|
348
|
+
arg.map_arguments scope
|
349
|
+
when Symbol
|
350
|
+
@required[index] = arg = :"_#{index}" if arg == :_
|
351
|
+
scope.new_local arg
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
@defaults.map_arguments scope if @defaults
|
356
|
+
scope.new_local @splat if @splat.kind_of? Symbol
|
357
|
+
@post.each { |arg| scope.new_local arg }
|
358
|
+
scope.assign_local_reference @block_arg if @block_arg
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|
362
|
+
|
363
|
+
class PatternArguments < Node
|
364
|
+
attr_accessor :arguments, :argument
|
365
|
+
|
366
|
+
def self.from_masgn(node)
|
367
|
+
array = []
|
368
|
+
node.left.body.map do |n|
|
369
|
+
case n
|
370
|
+
when MultipleAssignment
|
371
|
+
array << PatternArguments.from_masgn(n)
|
372
|
+
when LocalVariable
|
373
|
+
array << PatternVariable.new(n.line, n.name)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
PatternArguments.new node.line, ArrayLiteral.new(node.line, array)
|
378
|
+
end
|
379
|
+
|
380
|
+
def initialize(line, arguments)
|
381
|
+
@line = line
|
382
|
+
@arguments = arguments
|
383
|
+
@argument = nil
|
384
|
+
end
|
385
|
+
|
386
|
+
# Assign the left-most, depth-first PatternVariable so that this local
|
387
|
+
# will be assigned the passed argument at that position. The rest of the
|
388
|
+
# pattern will be destructured from the value of this assignment.
|
389
|
+
def map_arguments(scope)
|
390
|
+
arguments = @arguments.body
|
391
|
+
while arguments
|
392
|
+
node = arguments.first
|
393
|
+
if node.kind_of? PatternVariable
|
394
|
+
@argument = node
|
395
|
+
scope.assign_local_reference node
|
396
|
+
return
|
397
|
+
end
|
398
|
+
arguments = node.arguments.body
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
class DefaultArguments < Node
|
405
|
+
attr_accessor :arguments, :names
|
406
|
+
|
407
|
+
def initialize(line, block)
|
408
|
+
@line = line
|
409
|
+
array = block.array
|
410
|
+
@names = array.map { |a| a.name }
|
411
|
+
@arguments = array
|
412
|
+
end
|
413
|
+
|
414
|
+
def map_arguments(scope)
|
415
|
+
@arguments.each { |var| scope.assign_local_reference var }
|
416
|
+
end
|
417
|
+
|
418
|
+
def to_sexp
|
419
|
+
@arguments.map { |x| x.to_sexp }
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
module LocalVariable
|
424
|
+
attr_accessor :variable
|
425
|
+
end
|
426
|
+
|
427
|
+
class BlockArgument < Node
|
428
|
+
include LocalVariable
|
429
|
+
|
430
|
+
attr_accessor :name
|
431
|
+
|
432
|
+
def initialize(line, name)
|
433
|
+
@line = line
|
434
|
+
@name = name
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
class Class < Node
|
439
|
+
attr_accessor :name, :superclass, :body
|
440
|
+
|
441
|
+
def initialize(line, name, superclass, body)
|
442
|
+
@line = line
|
443
|
+
|
444
|
+
@superclass = superclass ? superclass : NilLiteral.new(line)
|
445
|
+
|
446
|
+
case name
|
447
|
+
when Symbol
|
448
|
+
@name = ClassName.new line, name, @superclass
|
449
|
+
when ToplevelConstant
|
450
|
+
@name = ToplevelClassName.new line, name, @superclass
|
451
|
+
else
|
452
|
+
@name = ScopedClassName.new line, name, @superclass
|
453
|
+
end
|
454
|
+
|
455
|
+
if body
|
456
|
+
@body = ClassScope.new line, @name, body
|
457
|
+
else
|
458
|
+
@body = EmptyBody.new line
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
def to_sexp
|
463
|
+
superclass = @superclass.kind_of?(NilLiteral) ? nil : @superclass.to_sexp
|
464
|
+
[:class, @name.to_sexp, superclass, @body.to_sexp]
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
class ClassScope < ClosedScope
|
469
|
+
def initialize(line, name, body)
|
470
|
+
@line = line
|
471
|
+
@name = name.name
|
472
|
+
@body = body
|
473
|
+
end
|
474
|
+
|
475
|
+
def module?
|
476
|
+
true
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
class ClassName < Node
|
481
|
+
attr_accessor :name, :superclass
|
482
|
+
|
483
|
+
def initialize(line, name, superclass)
|
484
|
+
@line = line
|
485
|
+
@name = name
|
486
|
+
@superclass = superclass
|
487
|
+
end
|
488
|
+
|
489
|
+
def to_sexp
|
490
|
+
@name
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
class ToplevelClassName < ClassName
|
495
|
+
def initialize(line, node, superclass)
|
496
|
+
@line = line
|
497
|
+
@name = node.name
|
498
|
+
@superclass = superclass
|
499
|
+
end
|
500
|
+
|
501
|
+
def to_sexp
|
502
|
+
[:colon3, @name]
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
class ScopedClassName < ClassName
|
507
|
+
attr_accessor :parent
|
508
|
+
|
509
|
+
def initialize(line, node, superclass)
|
510
|
+
@line = line
|
511
|
+
@name = node.name
|
512
|
+
@parent = node.parent
|
513
|
+
@superclass = superclass
|
514
|
+
end
|
515
|
+
|
516
|
+
def to_sexp
|
517
|
+
[:colon2, @parent.to_sexp, @name]
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
class Module < Node
|
522
|
+
attr_accessor :name, :body
|
523
|
+
|
524
|
+
def initialize(line, name, body)
|
525
|
+
@line = line
|
526
|
+
|
527
|
+
case name
|
528
|
+
when Symbol
|
529
|
+
@name = ModuleName.new line, name
|
530
|
+
when ToplevelConstant
|
531
|
+
@name = ToplevelModuleName.new line, name
|
532
|
+
else
|
533
|
+
@name = ScopedModuleName.new line, name
|
534
|
+
end
|
535
|
+
|
536
|
+
if body
|
537
|
+
@body = ModuleScope.new line, @name, body
|
538
|
+
else
|
539
|
+
@body = EmptyBody.new line
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
def to_sexp
|
544
|
+
[:module, @name.to_sexp, @body.to_sexp]
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
class EmptyBody < Node
|
549
|
+
def to_sexp
|
550
|
+
[:scope]
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
class ModuleName < Node
|
555
|
+
attr_accessor :name
|
556
|
+
|
557
|
+
def initialize(line, name)
|
558
|
+
@line = line
|
559
|
+
@name = name
|
560
|
+
end
|
561
|
+
|
562
|
+
def to_sexp
|
563
|
+
@name
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
class ToplevelModuleName < ModuleName
|
568
|
+
def initialize(line, node)
|
569
|
+
@line = line
|
570
|
+
@name = node.name
|
571
|
+
end
|
572
|
+
|
573
|
+
def to_sexp
|
574
|
+
[:colon3, @name]
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
class ScopedModuleName < ModuleName
|
579
|
+
attr_accessor :parent
|
580
|
+
|
581
|
+
def initialize(line, node)
|
582
|
+
@line = line
|
583
|
+
@name = node.name
|
584
|
+
@parent = node.parent
|
585
|
+
end
|
586
|
+
|
587
|
+
def to_sexp
|
588
|
+
[:colon2, @parent.to_sexp, @name]
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
class ModuleScope < ClosedScope
|
593
|
+
def initialize(line, name, body)
|
594
|
+
@line = line
|
595
|
+
@name = name.name
|
596
|
+
@body = body
|
597
|
+
end
|
598
|
+
|
599
|
+
def module?
|
600
|
+
true
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
class SClass < Node
|
605
|
+
attr_accessor :receiver
|
606
|
+
|
607
|
+
def initialize(line, receiver, body)
|
608
|
+
@line = line
|
609
|
+
@receiver = receiver
|
610
|
+
@body = SClassScope.new line, body
|
611
|
+
end
|
612
|
+
|
613
|
+
def to_sexp
|
614
|
+
[:sclass, @receiver.to_sexp, @body.to_sexp]
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
class SClassScope < ClosedScope
|
619
|
+
def initialize(line, body)
|
620
|
+
@line = line
|
621
|
+
@body = body
|
622
|
+
@name = nil
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
class Container < ClosedScope
|
627
|
+
attr_accessor :file, :name, :variable_scope, :pre_exe
|
628
|
+
|
629
|
+
def initialize(body)
|
630
|
+
@body = body || NilLiteral.new(1)
|
631
|
+
@pre_exe = []
|
632
|
+
end
|
633
|
+
|
634
|
+
def push_state(g)
|
635
|
+
g.push_state self
|
636
|
+
end
|
637
|
+
|
638
|
+
def pop_state(g)
|
639
|
+
g.pop_state
|
640
|
+
end
|
641
|
+
|
642
|
+
def to_sexp
|
643
|
+
sexp = [sexp_name]
|
644
|
+
@pre_exe.each { |pe| sexp << pe.pre_sexp }
|
645
|
+
sexp << @body.to_sexp
|
646
|
+
sexp
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
class EvalExpression < Container
|
651
|
+
def initialize(body)
|
652
|
+
super body
|
653
|
+
@name = :__eval_script__
|
654
|
+
end
|
655
|
+
|
656
|
+
def should_cache?
|
657
|
+
!@body.kind_of?(AST::ClosedScope)
|
658
|
+
end
|
659
|
+
|
660
|
+
def search_scopes(name)
|
661
|
+
depth = 1
|
662
|
+
scope = @variable_scope
|
663
|
+
while scope
|
664
|
+
if !scope.method.for_eval? and slot = scope.method.local_slot(name)
|
665
|
+
return Compiler::NestedLocalVariable.new(depth, slot)
|
666
|
+
elsif scope.eval_local_defined?(name, false)
|
667
|
+
return Compiler::EvalLocalVariable.new(name)
|
668
|
+
end
|
669
|
+
|
670
|
+
depth += 1
|
671
|
+
scope = scope.parent
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
# Returns a cached reference to a variable or searches all
|
676
|
+
# surrounding scopes for a variable. If no variable is found,
|
677
|
+
# it returns nil and a nested scope will create the variable
|
678
|
+
# in itself.
|
679
|
+
def search_local(name)
|
680
|
+
if variable = variables[name]
|
681
|
+
return variable.nested_reference
|
682
|
+
end
|
683
|
+
|
684
|
+
if variable = search_scopes(name)
|
685
|
+
variables[name] = variable
|
686
|
+
return variable.nested_reference
|
687
|
+
end
|
688
|
+
end
|
689
|
+
|
690
|
+
def new_local(name)
|
691
|
+
variable = Compiler::EvalLocalVariable.new name
|
692
|
+
variables[name] = variable
|
693
|
+
end
|
694
|
+
|
695
|
+
def assign_local_reference(var)
|
696
|
+
unless reference = search_local(var.name)
|
697
|
+
variable = new_local var.name
|
698
|
+
reference = variable.reference
|
699
|
+
end
|
700
|
+
|
701
|
+
var.variable = reference
|
702
|
+
end
|
703
|
+
|
704
|
+
def push_state(g)
|
705
|
+
g.push_state self
|
706
|
+
g.state.push_eval self
|
707
|
+
end
|
708
|
+
|
709
|
+
def sexp_name
|
710
|
+
:eval
|
711
|
+
end
|
712
|
+
end
|
713
|
+
|
714
|
+
class Snippet < Container
|
715
|
+
def initialize(body)
|
716
|
+
super body
|
717
|
+
@name = :__snippet__
|
718
|
+
end
|
719
|
+
|
720
|
+
def sexp_name
|
721
|
+
:snippet
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
class Script < Container
|
726
|
+
def initialize(body)
|
727
|
+
super body
|
728
|
+
@name = :__script__
|
729
|
+
end
|
730
|
+
|
731
|
+
def sexp_name
|
732
|
+
:script
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
class Defined < Node
|
737
|
+
attr_accessor :expression
|
738
|
+
|
739
|
+
def initialize(line, expr)
|
740
|
+
@line = line
|
741
|
+
@expression = expr
|
742
|
+
end
|
743
|
+
|
744
|
+
def to_sexp
|
745
|
+
[:defined, @expression.to_sexp]
|
746
|
+
end
|
747
|
+
end
|
748
|
+
end
|
749
|
+
end
|