mutant-melbourne 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/LICENSE +25 -0
  2. data/README.md +69 -0
  3. data/Rakefile +14 -0
  4. data/ext/melbourne/.gitignore +3 -0
  5. data/ext/melbourne/bstring-license.txt +29 -0
  6. data/ext/melbourne/bstrlib.c +2687 -0
  7. data/ext/melbourne/bstrlib.h +267 -0
  8. data/ext/melbourne/encoding_compat.cpp +188 -0
  9. data/ext/melbourne/encoding_compat.hpp +57 -0
  10. data/ext/melbourne/extconf.rb +87 -0
  11. data/ext/melbourne/grammar18.cpp +11280 -0
  12. data/ext/melbourne/grammar18.hpp +13 -0
  13. data/ext/melbourne/grammar18.y +6088 -0
  14. data/ext/melbourne/grammar19.cpp +12420 -0
  15. data/ext/melbourne/grammar19.hpp +11 -0
  16. data/ext/melbourne/grammar19.y +7113 -0
  17. data/ext/melbourne/lex.c.blt +152 -0
  18. data/ext/melbourne/lex.c.tab +136 -0
  19. data/ext/melbourne/local_state.hpp +43 -0
  20. data/ext/melbourne/melbourne.cpp +88 -0
  21. data/ext/melbourne/melbourne.hpp +19 -0
  22. data/ext/melbourne/node18.hpp +262 -0
  23. data/ext/melbourne/node19.hpp +271 -0
  24. data/ext/melbourne/node_types.rb +304 -0
  25. data/ext/melbourne/node_types18.cpp +255 -0
  26. data/ext/melbourne/node_types18.hpp +129 -0
  27. data/ext/melbourne/node_types19.cpp +249 -0
  28. data/ext/melbourne/node_types19.hpp +126 -0
  29. data/ext/melbourne/parser_state18.hpp +181 -0
  30. data/ext/melbourne/parser_state19.hpp +251 -0
  31. data/ext/melbourne/quark.cpp +42 -0
  32. data/ext/melbourne/quark.hpp +45 -0
  33. data/ext/melbourne/symbols.cpp +224 -0
  34. data/ext/melbourne/symbols.hpp +119 -0
  35. data/ext/melbourne/var_table18.cpp +83 -0
  36. data/ext/melbourne/var_table18.hpp +33 -0
  37. data/ext/melbourne/var_table19.cpp +65 -0
  38. data/ext/melbourne/var_table19.hpp +35 -0
  39. data/ext/melbourne/visitor18.cpp +963 -0
  40. data/ext/melbourne/visitor18.hpp +12 -0
  41. data/ext/melbourne/visitor19.cpp +960 -0
  42. data/ext/melbourne/visitor19.hpp +15 -0
  43. data/lib/compiler/ast/constants.rb +81 -0
  44. data/lib/compiler/ast/control_flow.rb +290 -0
  45. data/lib/compiler/ast/data.rb +14 -0
  46. data/lib/compiler/ast/definitions.rb +749 -0
  47. data/lib/compiler/ast/encoding.rb +18 -0
  48. data/lib/compiler/ast/exceptions.rb +138 -0
  49. data/lib/compiler/ast/file.rb +11 -0
  50. data/lib/compiler/ast/grapher.rb +89 -0
  51. data/lib/compiler/ast/literals.rb +207 -0
  52. data/lib/compiler/ast/node.rb +362 -0
  53. data/lib/compiler/ast/operators.rb +106 -0
  54. data/lib/compiler/ast/self.rb +15 -0
  55. data/lib/compiler/ast/sends.rb +615 -0
  56. data/lib/compiler/ast/transforms.rb +298 -0
  57. data/lib/compiler/ast/values.rb +88 -0
  58. data/lib/compiler/ast/variables.rb +351 -0
  59. data/lib/compiler/ast.rb +20 -0
  60. data/lib/compiler/locals.rb +109 -0
  61. data/lib/melbourne/processor.rb +651 -0
  62. data/lib/melbourne/version.rb +3 -0
  63. data/lib/melbourne.rb +143 -0
  64. metadata +112 -0
@@ -0,0 +1,362 @@
1
+ # -*- encoding: us-ascii -*-
2
+
3
+ module Rubinius
4
+ module AST
5
+ class Node
6
+ attr_accessor :line
7
+
8
+ def self.transform(category, name, comment)
9
+ Transforms.register category, name, self
10
+ @transform_name = name
11
+ @transform_comment = comment
12
+ @transform_kind = :call
13
+ end
14
+
15
+ def self.transform_name
16
+ @transform_name
17
+ end
18
+
19
+ def self.transform_comment
20
+ @transform_comment
21
+ end
22
+
23
+ def self.transform_kind
24
+ @transform_kind
25
+ end
26
+
27
+ def self.transform_kind=(k)
28
+ @transform_kind = k
29
+ end
30
+
31
+ def self.match_send?(node, receiver, method, name)
32
+ node.kind_of? ConstantAccess and
33
+ node.name == receiver and
34
+ method == name
35
+ end
36
+
37
+ def self.match_arguments?(arguments, count)
38
+ case arguments
39
+ when ArrayLiteral
40
+ arguments.body.size == count
41
+ when nil
42
+ count == 0
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def initialize(line)
49
+ @line = line
50
+ end
51
+
52
+ def pos(g)
53
+ g.set_line @line
54
+ end
55
+
56
+ def new_block_generator(g, arguments)
57
+ blk = g.class.new
58
+ blk.name = g.state.name || :__block__
59
+ blk.file = g.file
60
+ blk.for_block = true
61
+
62
+ blk.required_args = arguments.required_args
63
+ blk.post_args = arguments.post_args
64
+ blk.total_args = arguments.total_args
65
+
66
+ blk
67
+ end
68
+
69
+ def new_generator(g, name, arguments=nil)
70
+ meth = g.class.new
71
+ meth.name = name
72
+ meth.file = g.file
73
+
74
+ if arguments
75
+ meth.required_args = arguments.required_args
76
+ meth.post_args = arguments.post_args
77
+ meth.total_args = arguments.total_args
78
+ meth.splat_index = arguments.splat_index
79
+ end
80
+
81
+ meth
82
+ end
83
+
84
+ # This method implements a sort of tree iterator, yielding each Node
85
+ # instance to the provided block with the first argument to #walk. If
86
+ # the block returns a non-true value, the walk is terminated.
87
+ #
88
+ # This method is really an iterator, not a Visitor pattern.
89
+ def walk(arg=true, &block)
90
+ children do |child|
91
+ if ch_arg = block.call(arg, child)
92
+ child.walk(ch_arg, &block)
93
+ end
94
+ end
95
+ end
96
+
97
+ def ascii_graph
98
+ AsciiGrapher.new(self).print
99
+ end
100
+
101
+ def to_sexp
102
+ [:node, self.class.name]
103
+ end
104
+
105
+ # Yields each child of this Node to the block. Additionally, for any
106
+ # attribute that is an Array, yields each element that is a Node.
107
+ def children
108
+ instance_variables.each do |var|
109
+ child = instance_variable_get var
110
+ if child.kind_of? Node
111
+ yield child
112
+ elsif child.kind_of? Array
113
+ child.each { |x| yield x if x.kind_of? Node }
114
+ end
115
+ end
116
+ end
117
+
118
+ # The equivalent of Some::Module.demodulize.underscore in ActiveSupport.
119
+ # The code is shamelessly borrowed as well.
120
+ def self.node_name
121
+ @node_name ||=
122
+ begin
123
+ name = self.name.gsub(/^.*::/, '')
124
+ name.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
125
+ name.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
126
+ name.downcase!
127
+ name
128
+ end
129
+ end
130
+
131
+ def node_name
132
+ self.class.node_name
133
+ end
134
+
135
+ # Supports the Visitor pattern on a tree of Nodes. The +visitor+ should
136
+ # be an object that responds to methods named after the Node subclasses.
137
+ # The method called is determined by the #node_name method. Passes both
138
+ # the node and its parent so that the visitor can maintain nesting
139
+ # information if desired.
140
+ #
141
+ # The #visit implements a read-only traversal of the tree. To modify the
142
+ # tree, see the #transform methed.
143
+ def visit(visitor, parent=nil)
144
+ visitor.__send__ self.node_name, self, parent
145
+ children { |c| c.visit visitor, self }
146
+ end
147
+
148
+ # Called by #transform to update the child of a Node instance. The
149
+ # default just calls the attr_accessor for the child. However, Node
150
+ # subclasses that must synchronize other internal state can override
151
+ # this method.
152
+ def set_child(name, node)
153
+ send :"#{name}=", node
154
+ end
155
+
156
+ # Yields each attribute and its name to the block.
157
+ def attributes
158
+ instance_variables.each do |var|
159
+ child = instance_variable_get var
160
+ name = var.to_s[1..-1]
161
+ yield child, name
162
+ end
163
+ end
164
+
165
+ # A fixed-point algorithm for transforming an AST with a visitor. The
166
+ # traversal is top-down. The visitor object's method corresponding to
167
+ # each node (see #node_name) is called for each node, passing the node
168
+ # and its parent.
169
+ #
170
+ # To replace the node in the tree, the visitor method should return a
171
+ # new node; otherwise, return the existing node. The visitor is free to
172
+ # change values in the node, but substituting a node causes the entire
173
+ # tree to be walked repeatedly until no modifications are made.
174
+ def transform(visitor, parent=nil, state=nil)
175
+ state ||= TransformState.new
176
+
177
+ node = visitor.send :"node_#{node_name}", self, parent
178
+ state.modify unless equal? node
179
+
180
+ node.attributes do |attr, name|
181
+ if attr.kind_of? Node
182
+ child = attr.transform visitor, node, state
183
+ unless attr.equal? child
184
+ state.modify
185
+ node.set_child name, child
186
+ end
187
+ elsif attr.kind_of? Array
188
+ attr.each_with_index do |x, i|
189
+ if x.kind_of? Node
190
+ child = x.transform visitor, node, state
191
+ unless x.equal? child
192
+ state.modify
193
+ attr[i] = child
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ # Repeat the walk until the tree is not modified.
201
+ if parent.nil? and state.modified?
202
+ state.unmodify
203
+ node = transform visitor, nil, state
204
+ end
205
+
206
+ node
207
+ end
208
+
209
+ # Manage the state of the #transform method.
210
+ class TransformState
211
+ def initialized
212
+ @modified = false
213
+ end
214
+
215
+ def modified?
216
+ @modified
217
+ end
218
+
219
+ def modify
220
+ @modified = true
221
+ end
222
+
223
+ def unmodify
224
+ @modified = false
225
+ end
226
+ end
227
+ end
228
+
229
+ # In a perfect world, each AST node would fully encapsulate its state. But
230
+ # in the real world, some state exists across the AST rather than just in
231
+ # a node. For example, some nodes need to emit different bytecode when in
232
+ # a rescue.
233
+ #
234
+ # This class maintains state needed as the AST is walked to generate
235
+ # bytecode. An instance of State is pushed onto a stack in the Generator
236
+ # instance as each ClosedScope or Iter is entered, and popped when left.
237
+ class State
238
+ attr_reader :scope, :super, :eval
239
+
240
+ class << self
241
+ attr_accessor :flip_flops
242
+ end
243
+
244
+ self.flip_flops ||= 0
245
+
246
+ def initialize(scope)
247
+ @scope = scope
248
+ @ensure = 0
249
+ @block = 0
250
+ @masgn = 0
251
+ @loop = 0
252
+ @op_asgn = 0
253
+ @rescue = []
254
+ @name = []
255
+ end
256
+
257
+ def push_name(name)
258
+ @name.push name
259
+ end
260
+
261
+ def pop_name
262
+ @name.pop
263
+ end
264
+
265
+ def name
266
+ @name.last
267
+ end
268
+
269
+ def push_rescue(val)
270
+ @rescue.push(val)
271
+ end
272
+
273
+ def pop_rescue
274
+ @rescue.pop if rescue?
275
+ end
276
+
277
+ def rescue?
278
+ @rescue.last
279
+ end
280
+
281
+ def push_ensure
282
+ @ensure += 1
283
+ end
284
+
285
+ def pop_ensure
286
+ @ensure -= 1 if ensure?
287
+ end
288
+
289
+ def ensure?
290
+ @ensure > 0
291
+ end
292
+
293
+ def push_block
294
+ @block += 1
295
+ end
296
+
297
+ def pop_block
298
+ @block -= 1 if block?
299
+ end
300
+
301
+ def block?
302
+ @block > 0
303
+ end
304
+
305
+ def flip_flops
306
+ State.flip_flops
307
+ end
308
+
309
+ def push_flip_flop
310
+ State.flip_flops += 1
311
+ end
312
+
313
+ def push_masgn
314
+ @masgn += 1
315
+ end
316
+
317
+ def pop_masgn
318
+ @masgn -= 1 if masgn?
319
+ end
320
+
321
+ def masgn?
322
+ @masgn > 0
323
+ end
324
+
325
+ def push_op_asgn
326
+ @op_asgn += 1
327
+ end
328
+
329
+ def pop_op_asgn
330
+ @op_asgn -= 1 if op_asgn?
331
+ end
332
+
333
+ def op_asgn?
334
+ @op_asgn > 0
335
+ end
336
+
337
+ def push_super(scope)
338
+ @super = scope
339
+ end
340
+
341
+ alias_method :super?, :super
342
+
343
+ def push_eval(scope)
344
+ @eval = scope
345
+ end
346
+
347
+ alias_method :eval?, :eval
348
+
349
+ def push_loop
350
+ @loop += 1
351
+ end
352
+
353
+ def pop_loop
354
+ @loop -= 1 if loop?
355
+ end
356
+
357
+ def loop?
358
+ @loop > 0
359
+ end
360
+ end
361
+ end
362
+ end
@@ -0,0 +1,106 @@
1
+ # -*- encoding: us-ascii -*-
2
+
3
+ module Rubinius
4
+ module AST
5
+ class And < Node
6
+ attr_accessor :left, :right
7
+
8
+ def initialize(line, left, right)
9
+ @line = line
10
+ @left = left
11
+ @right = right
12
+ end
13
+
14
+ def sexp_name
15
+ :and
16
+ end
17
+
18
+ def to_sexp
19
+ [sexp_name, @left.to_sexp, @right.to_sexp]
20
+ end
21
+ end
22
+
23
+ class Or < And
24
+ def sexp_name
25
+ :or
26
+ end
27
+ end
28
+
29
+ class Not < Node
30
+ attr_accessor :value
31
+
32
+ def initialize(line, value)
33
+ @line = line
34
+ @value = value
35
+ end
36
+
37
+ def to_sexp
38
+ [:not, @value.to_sexp]
39
+ end
40
+ end
41
+
42
+ class OpAssign1 < Node
43
+ attr_accessor :receiver, :op, :arguments, :value
44
+
45
+ def initialize(line, receiver, arguments, op, value)
46
+ @line = line
47
+ @receiver = receiver
48
+ @op = op
49
+ arguments = nil if arguments.is_a?(EmptyArray)
50
+ @arguments = ActualArguments.new line, arguments
51
+ @value = value
52
+ end
53
+
54
+ def to_sexp
55
+ arguments = [:arglist] + @arguments.to_sexp
56
+ op = @op == :or ? :"||" : :"&&"
57
+ [:op_asgn1, @receiver.to_sexp, arguments, op, @value.to_sexp]
58
+ end
59
+ end
60
+
61
+ class OpAssign2 < Node
62
+ attr_accessor :receiver, :name, :assign, :op, :value
63
+
64
+ def initialize(line, receiver, name, op, value)
65
+ @line = line
66
+ @receiver = receiver
67
+ @name = name
68
+ @op = op
69
+ @value = value
70
+ @assign = name.to_s[-1] == ?= ? name : :"#{name}="
71
+ end
72
+
73
+ def to_sexp
74
+ op = @op == :or ? :"||" : :"&&"
75
+ [:op_asgn2, @receiver.to_sexp, :"#{@name}=", op, @value.to_sexp]
76
+ end
77
+ end
78
+
79
+ class OpAssignAnd < Node
80
+ attr_accessor :left, :right
81
+
82
+ def initialize(line, left, right)
83
+ @line = line
84
+ @left = left
85
+ @right = right
86
+ end
87
+
88
+ def sexp_name
89
+ :op_asgn_and
90
+ end
91
+
92
+ def to_sexp
93
+ [sexp_name, @left.to_sexp, @right.to_sexp]
94
+ end
95
+ end
96
+
97
+ class OpAssignOr < OpAssignAnd
98
+ def sexp_name
99
+ :op_asgn_or
100
+ end
101
+ end
102
+
103
+ class OpAssignOr19 < OpAssignOr
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,15 @@
1
+ # -*- encoding: us-ascii -*-
2
+
3
+ module Rubinius
4
+ module AST
5
+ class Self < Node
6
+ def value_defined(g, f)
7
+ g.push :self
8
+ end
9
+
10
+ def to_sexp
11
+ [:self]
12
+ end
13
+ end
14
+ end
15
+ end