rubinius-ast 2.1.3 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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