rubinius-ast 2.1.3 → 2.2.0

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.
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class Encoding < Node
6
6
  attr_accessor :name
@@ -13,7 +13,8 @@ module Rubinius::ToolSets.current::ToolSet
13
13
  def bytecode(g)
14
14
  pos(g)
15
15
 
16
- g.push_literal Compiler::Runtime
16
+ g.push_rubinius
17
+ g.find_const :Runtime
17
18
  g.push_literal @name
18
19
  g.send :get_encoding, 1
19
20
  end
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class Begin < Node
6
6
  attr_accessor :rescue
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class File < Node
6
6
  def bytecode(g)
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class AsciiGrapher
6
6
  def initialize(ast, node_kind=Node)
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class ArrayLiteral < Node
6
6
  attr_accessor :body
@@ -132,14 +132,58 @@ module Rubinius::ToolSets.current::ToolSet
132
132
  g.send :new_from_literal, 1
133
133
 
134
134
  while i < count
135
- k = @array[i]
136
- v = @array[i + 1]
135
+ key = @array[i]
136
+ value = @array[i + 1]
137
+
138
+ if key
139
+ g.dup
140
+ key.bytecode(g)
141
+ value.bytecode(g)
142
+ g.send :[]=, 2
143
+ g.pop
144
+ else
145
+ case value
146
+ when HashLiteral
147
+ value.merge_entries_bytecode(g)
148
+ else
149
+ g.push_rubinius
150
+ g.find_const :Runtime
151
+ g.swap
152
+ value.bytecode(g)
153
+ g.send :splat_hash_value, 2
154
+ end
155
+ end
156
+
157
+ i += 2
158
+ end
159
+ end
137
160
 
138
- g.dup
139
- k.bytecode(g)
140
- v.bytecode(g)
141
- g.send :[]=, 2
142
- g.pop
161
+ def merge_entries_bytecode(g)
162
+ count = @array.size
163
+ i = 0
164
+
165
+ while i < count
166
+ key = @array[i]
167
+ value = @array[i + 1]
168
+ if key
169
+ g.push_rubinius
170
+ g.find_const :Runtime
171
+ g.swap
172
+ key.bytecode(g)
173
+ value.bytecode(g)
174
+ g.send :splat_hash_entry, 3
175
+ else
176
+ case value
177
+ when HashLiteral
178
+ value.merge_entries_bytecode(g)
179
+ else
180
+ g.push_rubinius
181
+ g.find_const :Runtime
182
+ g.swap
183
+ value.bytecode(g)
184
+ g.send :splat_hash_value, 2
185
+ end
186
+ end
143
187
 
144
188
  i += 2
145
189
  end
@@ -150,7 +194,7 @@ module Rubinius::ToolSets.current::ToolSet
150
194
  end
151
195
 
152
196
  def to_sexp
153
- @array.inject([:hash]) { |s, x| s << x.to_sexp }
197
+ @array.inject([:hash]) { |s, x| s << (x ? x.to_sexp : [:hash_splat]) }
154
198
  end
155
199
  end
156
200
 
@@ -233,6 +277,22 @@ module Rubinius::ToolSets.current::ToolSet
233
277
  end
234
278
  end
235
279
 
280
+ class RationalLiteral < NumberLiteral
281
+ def bytecode(g)
282
+ pos(g)
283
+
284
+ g.push_literal @value
285
+ end
286
+ end
287
+
288
+ class ImaginaryLiteral < NumberLiteral
289
+ def bytecode(g)
290
+ pos(g)
291
+
292
+ g.push_literal @value
293
+ end
294
+ end
295
+
236
296
  class Range < Node
237
297
  attr_accessor :start, :finish
238
298
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class Node
6
6
  attr_accessor :line
@@ -64,6 +64,8 @@ module Rubinius::ToolSets.current::ToolSet
64
64
  blk.total_args = arguments.total_args
65
65
  blk.splat_index = arguments.splat_index
66
66
  blk.block_index = arguments.block_index
67
+ blk.arity = arguments.arity
68
+ blk.keywords = arguments.keywords.entries if arguments.keywords
67
69
 
68
70
  blk
69
71
  end
@@ -79,6 +81,8 @@ module Rubinius::ToolSets.current::ToolSet
79
81
  meth.total_args = arguments.total_args
80
82
  meth.splat_index = arguments.splat_index
81
83
  meth.block_index = arguments.block_index
84
+ meth.arity = arguments.arity
85
+ meth.keywords = arguments.keywords.entries if arguments.keywords
82
86
  end
83
87
 
84
88
  meth
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class And < Node
6
6
  attr_accessor :left, :right
@@ -102,7 +102,7 @@ module Rubinius::ToolSets.current::ToolSet
102
102
  end
103
103
  end
104
104
 
105
- class OpAssign1 < Node
105
+ class OpAssignElement < Node
106
106
  attr_accessor :receiver, :op, :arguments, :value
107
107
 
108
108
  def initialize(line, receiver, arguments, op, value)
@@ -110,7 +110,7 @@ module Rubinius::ToolSets.current::ToolSet
110
110
  @receiver = receiver
111
111
  @op = op
112
112
  arguments = nil if arguments.is_a?(EmptyArray)
113
- @arguments = ActualArguments.new line, arguments
113
+ @arguments = Arguments.new line, arguments
114
114
  @value = value
115
115
  end
116
116
 
@@ -146,6 +146,7 @@ module Rubinius::ToolSets.current::ToolSet
146
146
  if @op == :or or @op == :and
147
147
  fnd = g.new_label
148
148
  fin = g.new_label
149
+ assign = g.new_label
149
150
 
150
151
  # We dup the value from [] to leave it as the value of the
151
152
  # expression
@@ -162,8 +163,25 @@ module Rubinius::ToolSets.current::ToolSet
162
163
 
163
164
  # The receiver and arguments are still on the stack
164
165
 
166
+ old_break = g.break
167
+ new_break = g.new_label
168
+ g.break = new_break
169
+
165
170
  @value.bytecode(g)
166
171
 
172
+ g.goto assign
173
+
174
+ new_break.set!
175
+ if old_break
176
+ g.pop_many recv_stack + 1
177
+ g.push :nil
178
+ g.goto old_break
179
+ end
180
+
181
+ g.break = old_break
182
+
183
+ assign.set!
184
+
167
185
  # retain the rhs as the expression value
168
186
  g.dup
169
187
  g.move_down recv_stack + 1
@@ -188,11 +206,30 @@ module Rubinius::ToolSets.current::ToolSet
188
206
 
189
207
  fin.set!
190
208
  else
209
+ assign = g.new_label
210
+
211
+ old_break = g.break
212
+ new_break = g.new_label
213
+ g.break = new_break
214
+
191
215
  # @op is something like + or -
192
216
  # We pull in @value to the stack
193
217
  @value.bytecode(g)
194
218
  # X: 3 TOS
195
219
 
220
+ g.goto assign
221
+
222
+ new_break.set!
223
+ if old_break
224
+ g.pop_many recv_stack + 2
225
+ g.push :nil
226
+ g.goto old_break
227
+ end
228
+
229
+ g.break = old_break
230
+
231
+ assign.set!
232
+
196
233
  # ... then call it as an argument to @or, called on the return
197
234
  # from [].
198
235
  # X: 2 + 3
@@ -233,7 +270,7 @@ module Rubinius::ToolSets.current::ToolSet
233
270
  end
234
271
  end
235
272
 
236
- class OpAssign2 < Node
273
+ class OpAssignAttribute < Node
237
274
  attr_accessor :receiver, :name, :assign, :op, :value
238
275
 
239
276
  def initialize(line, receiver, name, op, value)
@@ -248,7 +285,7 @@ module Rubinius::ToolSets.current::ToolSet
248
285
  def bytecode(g)
249
286
  pos(g)
250
287
 
251
- # X: h[:a] += 3, given h.a == 2
288
+ # X: h.a += 3, given h.a == 2
252
289
  @receiver.bytecode(g)
253
290
  # X: TOS = h
254
291
  g.dup
@@ -258,6 +295,7 @@ module Rubinius::ToolSets.current::ToolSet
258
295
  if @op == :or or @op == :and
259
296
  fnd = g.new_label
260
297
  fin = g.new_label
298
+ assign = g.new_label
261
299
 
262
300
  g.dup
263
301
  if @op == :or
@@ -268,8 +306,26 @@ module Rubinius::ToolSets.current::ToolSet
268
306
 
269
307
  # Remove the copy of 2 and push @value on the stack
270
308
  g.pop
309
+
310
+ old_break = g.break
311
+ new_break = g.new_label
312
+ g.break = new_break
313
+
271
314
  @value.bytecode(g)
272
315
 
316
+ g.goto assign
317
+
318
+ new_break.set!
319
+ if old_break
320
+ g.pop_many 2
321
+ g.push :nil
322
+ g.goto old_break
323
+ end
324
+
325
+ g.break = old_break
326
+
327
+ assign.set!
328
+
273
329
  # Retain the this value to use as the expression value
274
330
  g.dup
275
331
  g.move_down 2
@@ -288,7 +344,27 @@ module Rubinius::ToolSets.current::ToolSet
288
344
 
289
345
  fin.set!
290
346
  else
347
+ assign = g.new_label
348
+
349
+ old_break = g.break
350
+ new_break = g.new_label
351
+ g.break = new_break
352
+
291
353
  @value.bytecode(g)
354
+
355
+ g.goto assign
356
+
357
+ new_break.set!
358
+ if old_break
359
+ g.pop_many 3
360
+ g.push :nil
361
+ g.goto old_break
362
+ end
363
+
364
+ g.break = old_break
365
+
366
+ assign.set!
367
+
292
368
  # X: TOS = 3
293
369
  # X: 2 + 3
294
370
  g.send @op, 1
@@ -356,7 +432,9 @@ module Rubinius::ToolSets.current::ToolSet
356
432
  def bytecode(g)
357
433
  pos(g)
358
434
 
435
+ g.state.push_op_asgn
359
436
  @left.or_bytecode(g) do
437
+ g.state.pop_op_asgn
360
438
  @right.bytecode(g)
361
439
  end
362
440
  end
@@ -365,17 +443,5 @@ module Rubinius::ToolSets.current::ToolSet
365
443
  :op_asgn_or
366
444
  end
367
445
  end
368
-
369
- class OpAssignOr19 < OpAssignOr
370
- def bytecode(g)
371
- pos(g)
372
-
373
- g.state.push_op_asgn
374
- @left.or_bytecode(g) do
375
- g.state.pop_op_asgn
376
- @right.bytecode(g)
377
- end
378
- end
379
- end
380
446
  end
381
447
  end
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class Self < Node
6
6
  def bytecode(g)
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module Rubinius::ToolSets.current::ToolSet
3
+ module CodeTools
4
4
  module AST
5
5
  class Send < Node
6
6
  attr_accessor :receiver, :name, :privately, :block, :variable, :vcall_style
@@ -131,7 +131,7 @@ module Rubinius::ToolSets.current::ToolSet
131
131
  def initialize(line, receiver, name, arguments, privately=false)
132
132
  super line, receiver, name, privately
133
133
  @block = nil
134
- @arguments = ActualArguments.new line, arguments
134
+ @arguments = Arguments.new line, arguments
135
135
  end
136
136
 
137
137
  def bytecode(g)
@@ -167,7 +167,7 @@ module Rubinius::ToolSets.current::ToolSet
167
167
 
168
168
  @name = :"#{name}="
169
169
 
170
- @arguments = ActualArguments.new line, arguments
170
+ @arguments = Arguments.new line, arguments
171
171
  end
172
172
 
173
173
  def bytecode(g)
@@ -209,9 +209,9 @@ module Rubinius::ToolSets.current::ToolSet
209
209
 
210
210
  case arguments
211
211
  when PushArgs
212
- @arguments = PushActualArguments.new arguments
212
+ @arguments = PushArguments.new line, arguments
213
213
  else
214
- @arguments = ActualArguments.new line, arguments
214
+ @arguments = Arguments.new line, arguments
215
215
  end
216
216
  end
217
217
 
@@ -228,13 +228,24 @@ module Rubinius::ToolSets.current::ToolSet
228
228
 
229
229
  @receiver.bytecode(g)
230
230
  @arguments.bytecode(g)
231
+
231
232
  g.dup
232
233
 
233
234
  if @arguments.splat?
234
- g.move_down @arguments.size + 2
235
- g.swap
235
+ case @arguments
236
+ when PushArguments
237
+ g.move_down @arguments.size + 2
238
+ g.swap
239
+ flag = true
240
+ when Arguments
241
+ # TODO: Optimize bytecode for x[a, *b, c, d] = e
242
+ g.send :last, 0, true
243
+ g.move_down @arguments.size + 2
244
+ flag = false
245
+ end
246
+
236
247
  g.push :nil
237
- g.send_with_splat @name, @arguments.size, @privately, true
248
+ g.send_with_splat @name, @arguments.size, @privately, flag
238
249
  else
239
250
  g.move_down @arguments.size + 1
240
251
  g.send @name, @arguments.size, @privately
@@ -261,7 +272,8 @@ module Rubinius::ToolSets.current::ToolSet
261
272
  g.push_state ClosedScope.new(@line)
262
273
  g.state.push_name :BEGIN
263
274
 
264
- g.push_literal Compiler::Runtime
275
+ g.push_rubinius
276
+ g.find_const :Runtime
265
277
  @block.bytecode(g)
266
278
  g.send_with_block :pre_exe, 0, false
267
279
 
@@ -285,10 +297,13 @@ module Rubinius::ToolSets.current::ToolSet
285
297
  end
286
298
  end
287
299
 
288
- class PushActualArguments
289
- def initialize(pa)
290
- @arguments = pa.arguments
291
- @value = pa.value
300
+ class PushArguments < Node
301
+ attr_accessor :arguments
302
+
303
+ def initialize(line, node)
304
+ @line = line
305
+ @arguments = node.arguments
306
+ @value = node.value
292
307
  end
293
308
 
294
309
  def size
@@ -305,7 +320,7 @@ module Rubinius::ToolSets.current::ToolSet
305
320
  end
306
321
 
307
322
  def to_sexp
308
- [@arguments.to_sexp, @value.to_sexp]
323
+ [:argspush, @arguments.to_sexp, @value.to_sexp]
309
324
  end
310
325
  end
311
326
 
@@ -357,6 +372,8 @@ module Rubinius::ToolSets.current::ToolSet
357
372
  end
358
373
 
359
374
  class CollectSplat < Node
375
+ attr_accessor :splat, :array, :last
376
+
360
377
  def initialize(line, *parts)
361
378
  @line = line
362
379
  @splat = parts.shift
@@ -366,7 +383,6 @@ module Rubinius::ToolSets.current::ToolSet
366
383
 
367
384
  def bytecode(g)
368
385
  @splat.bytecode(g)
369
- g.cast_array
370
386
 
371
387
  @array.each do |x|
372
388
  x.bytecode(g)
@@ -380,13 +396,12 @@ module Rubinius::ToolSets.current::ToolSet
380
396
  done = g.new_label
381
397
 
382
398
  @last.bytecode(g)
383
- g.dup
384
399
 
385
- g.push_const :Hash
386
-
387
- g.push_type
388
- g.move_down 2
389
- g.send :object_kind_of?, 2
400
+ g.dup
401
+ g.push_cpath_top
402
+ g.find_const :Hash
403
+ g.swap
404
+ g.kind_of
390
405
  g.gif not_hash
391
406
 
392
407
  g.make_array 1
@@ -404,7 +419,7 @@ module Rubinius::ToolSets.current::ToolSet
404
419
  end
405
420
  end
406
421
 
407
- class ActualArguments < Node
422
+ class Arguments < Node
408
423
  attr_accessor :array, :splat
409
424
 
410
425
  def initialize(line, arguments=nil)
@@ -491,13 +506,18 @@ module Rubinius::ToolSets.current::ToolSet
491
506
 
492
507
  def initialize(line, arguments, body)
493
508
  @line = line
494
- @arguments = IterArguments.new line, arguments
509
+ @arguments = arguments || Parameters.new(line)
495
510
  @body = body || NilLiteral.new(line)
511
+
512
+ if @body.kind_of?(Block) and @body.locals
513
+ @locals = @body.locals.body.map { |x| x.value }
514
+ else
515
+ @locals = nil
516
+ end
496
517
  end
497
518
 
498
- # 1.8 doesn't support declared Iter locals
499
519
  def block_local?(name)
500
- false
520
+ @locals.include?(name) if @locals
501
521
  end
502
522
 
503
523
  def module?
@@ -600,31 +620,17 @@ module Rubinius::ToolSets.current::ToolSet
600
620
  end
601
621
 
602
622
  def to_sexp
603
- [sexp_name, @arguments.to_sexp, @body.to_sexp]
604
- end
605
- end
606
-
607
- class Iter19 < Iter
608
- def initialize(line, arguments, body)
609
- @line = line
610
- @arguments = arguments || IterArguments.new(line, nil)
611
- @body = body || NilLiteral.new(line)
612
-
613
- if @body.kind_of?(Block) and @body.locals
614
- @locals = @body.locals.body.map { |x| x.value }
615
- else
616
- @locals = nil
623
+ body_sexp = @body.to_sexp
624
+ if @locals
625
+ body_sexp[1] = @locals.map { |x| [:lvar, x] }
617
626
  end
618
- end
619
-
620
- def block_local?(name)
621
- @locals.include?(name) if @locals
627
+ [sexp_name, @arguments.to_sexp, body_sexp]
622
628
  end
623
629
  end
624
630
 
625
631
  class IterArguments < Node
626
632
  attr_accessor :prelude, :arity, :optional, :arguments, :splat_index, :block_index
627
- attr_accessor :required_args
633
+ attr_accessor :required_args, :keywords
628
634
 
629
635
  def initialize(line, arguments)
630
636
  @line = line
@@ -780,6 +786,14 @@ module Rubinius::ToolSets.current::ToolSet
780
786
  end
781
787
 
782
788
  class For < Iter
789
+ def initialize(line, arguments, body)
790
+ @line = line
791
+ @arguments = ForParameters.new line, arguments
792
+ @body = body || NilLiteral.new(line)
793
+
794
+ new_local :"$for_args"
795
+ end
796
+
783
797
  def nest_scope(scope)
784
798
  scope.parent = self
785
799
  end
@@ -814,25 +828,36 @@ module Rubinius::ToolSets.current::ToolSet
814
828
  end
815
829
  end
816
830
 
817
- class For19Arguments < Node
818
- attr_reader :block_index
831
+ class ForParameters < Node
832
+ attr_accessor :assignments, :required_args, :splat_index,
833
+ :post_args, :keywords, :block_index
819
834
 
820
- def initialize(line, arguments)
835
+ def initialize(line, assignments)
821
836
  @line = line
822
- @arguments = arguments
837
+ @assignments = assignments
838
+ @splat_index = assignments.kind_of?(MultipleAssignment) ? 0 : nil
839
+ @required_args = @splat_index ? 0 : 1
840
+ @post_args = 0
841
+ @keywords = nil
842
+ @block_index = nil
843
+ end
823
844
 
824
- if @arguments.kind_of? MultipleAssignment
825
- @args = 0
826
- @splat = 0
827
- else
828
- @args = 1
829
- @splat = nil
845
+ alias_method :total_args, :required_args
846
+ alias_method :arity, :required_args
847
+
848
+ def map_arguments(scope)
849
+ case @assignments
850
+ when LocalVariable
851
+ scope.assign_local_reference @assignments
830
852
  end
831
853
  end
832
854
 
833
855
  def bytecode(g)
834
- if @splat
835
- g.push_literal Compiler::Runtime
856
+ map_arguments(g.state.scope)
857
+
858
+ if @splat_index
859
+ g.push_rubinius
860
+ g.find_const :Runtime
836
861
  g.push_local 0
837
862
  g.send :unwrap_block_arg, 1
838
863
  else
@@ -840,39 +865,8 @@ module Rubinius::ToolSets.current::ToolSet
840
865
  end
841
866
 
842
867
  g.state.push_masgn
843
- @arguments.bytecode(g)
868
+ @assignments.bytecode(g)
844
869
  g.state.pop_masgn
845
- g.pop
846
- end
847
-
848
- def required_args
849
- @args
850
- end
851
-
852
- def total_args
853
- @args
854
- end
855
-
856
- def post_args
857
- 0
858
- end
859
-
860
- def splat_index
861
- @splat
862
- end
863
-
864
- def to_sexp
865
- @arguments.to_sexp
866
- end
867
- end
868
-
869
- class For19 < For
870
- def initialize(line, arguments, body)
871
- @line = line
872
- @arguments = For19Arguments.new line, arguments
873
- @body = body || NilLiteral.new(line)
874
-
875
- new_local :"$for_args"
876
870
  end
877
871
  end
878
872
 
@@ -907,7 +901,7 @@ module Rubinius::ToolSets.current::ToolSet
907
901
  @line = line
908
902
  @block = nil
909
903
  @name = nil
910
- @arguments = ActualArguments.new line, arguments
904
+ @arguments = Arguments.new line, arguments
911
905
  end
912
906
 
913
907
  def block_bytecode(g)
@@ -967,7 +961,7 @@ module Rubinius::ToolSets.current::ToolSet
967
961
  arguments = ArrayLiteral.new line, [arguments]
968
962
  end
969
963
 
970
- @arguments = ActualArguments.new line, arguments
964
+ @arguments = Arguments.new line, arguments
971
965
  @argument_count = @arguments.size
972
966
  @yield_splat = false
973
967