rubinius-ast 1.3.0 → 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.
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
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 CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class Send < Node
6
6
  attr_accessor :receiver, :name, :privately, :block, :variable, :vcall_style
@@ -65,11 +65,6 @@ module CodeTools
65
65
  end
66
66
 
67
67
  def defined(g)
68
- if @block.kind_of? For
69
- @block.defined(g)
70
- return
71
- end
72
-
73
68
  if @vcall_style and check_local_reference(g)
74
69
  g.push_literal "local-variable"
75
70
  return
@@ -264,8 +259,7 @@ module CodeTools
264
259
  g.push_state ClosedScope.new(@line)
265
260
  g.state.push_name :BEGIN
266
261
 
267
- g.push_rubinius
268
- g.find_const :Runtime
262
+ g.push_literal Compiler::Runtime
269
263
  @block.bytecode(g)
270
264
  g.send_with_block :pre_exe, 0, false
271
265
 
@@ -342,8 +336,7 @@ module CodeTools
342
336
  end
343
337
 
344
338
  def assignment_bytecode(g)
345
- g.push_block_arg
346
- convert(g)
339
+ g.push_proc
347
340
  @body.bytecode(g)
348
341
  end
349
342
 
@@ -810,10 +803,6 @@ module CodeTools
810
803
  var.variable = reference
811
804
  end
812
805
 
813
- def defined(g)
814
- g.push_literal "expression"
815
- end
816
-
817
806
  def sexp_name
818
807
  :for
819
808
  end
@@ -837,8 +826,7 @@ module CodeTools
837
826
 
838
827
  def bytecode(g)
839
828
  if @splat
840
- g.push_rubinius
841
- g.find_const :Runtime
829
+ g.push_literal Compiler::Runtime
842
830
  g.push_local 0
843
831
  g.send :unwrap_block_arg, 1
844
832
  else
@@ -1011,14 +999,7 @@ module CodeTools
1011
999
  end
1012
1000
 
1013
1001
  def to_sexp
1014
- args = @arguments.to_sexp
1015
- args << @block.to_sexp if @block
1016
- if @argument_count == 1 and !@yield_splat and @arguments.splat.nil? and
1017
- @arguments.array.first.kind_of? SplatValue
1018
- [:yield, [:array] + args]
1019
- else
1020
- [:yield] + args
1021
- end
1002
+ arguments_sexp :yield
1022
1003
  end
1023
1004
  end
1024
1005
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  module Transforms
6
6
  def self.register(category, name, klass)
@@ -249,6 +249,9 @@ module CodeTools
249
249
  class SendFastNew < SendWithArguments
250
250
  transform :default, :fast_new, "Fast SomeClass.new path"
251
251
 
252
+ # FIXME duplicated from kernel/common/compiled_code.rb
253
+ KernelMethodSerial = 47
254
+
252
255
  def self.match?(line, receiver, name, arguments, privately)
253
256
  # ignore vcall style
254
257
  return false if !arguments and privately
@@ -267,9 +270,9 @@ module CodeTools
267
270
  g.dup
268
271
 
269
272
  if @privately
270
- g.check_serial_private :new, Rubinius::CompiledCode::KernelMethodSerial
273
+ g.check_serial_private :new, KernelMethodSerial
271
274
  else
272
- g.check_serial :new, Rubinius::CompiledCode::KernelMethodSerial
275
+ g.check_serial :new, KernelMethodSerial
273
276
  end
274
277
  g.gif slow
275
278
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class SplatValue < Node
6
6
  attr_accessor :value
@@ -12,83 +12,7 @@ module CodeTools
12
12
 
13
13
  def bytecode(g)
14
14
  @value.bytecode(g)
15
- return if @value.kind_of? ArrayLiteral
16
-
17
- convert_to_ary(g)
18
- end
19
-
20
- def convert_to_ary(g)
21
- done = g.new_label
22
- coerce = g.new_label
23
- coerce_method = :to_ary
24
-
25
- kind_of_array(g, done)
26
-
27
- check_respond_to = g.new_label
28
-
29
- g.dup
30
- g.push :nil
31
- g.swap
32
- g.send :equal?, 1, true
33
- g.gif check_respond_to
34
-
35
- g.make_array 1
36
- g.goto done
37
-
38
- check_respond_to.set!
39
- g.dup
40
- g.push_literal :to_ary
41
- g.send :respond_to?, 1, true
42
- g.git coerce
43
-
44
- discard = g.new_label
45
- check_array = g.new_label
46
-
47
- make_array = g.new_label
48
- make_array.set!
49
- g.dup
50
- g.send :to_a, 0, true
51
- coerce_method = :to_a
52
- g.goto check_array
53
-
54
- coerce.set!
55
- g.dup
56
- g.send :to_ary, 0, true
57
-
58
- g.dup
59
- g.push :nil
60
- g.send :equal?, 1, true
61
- coerce_method = :to_ary
62
- g.gif check_array
63
-
64
- g.pop
65
- g.goto make_array
66
-
67
- check_array.set!
68
- kind_of_array(g, discard)
69
-
70
- g.push_type
71
- g.move_down 2
72
- g.push_literal coerce_method
73
- g.push_cpath_top
74
- g.find_const :Array
75
- g.send :coerce_to_type_error, 4, true
76
- g.goto done
77
-
78
- discard.set!
79
- g.swap
80
- g.pop
81
-
82
- done.set!
83
- end
84
-
85
- def kind_of_array(g, label)
86
- g.dup
87
- g.push_cpath_top
88
- g.find_const :Array
89
- g.swap
90
- g.kind_of
91
- g.git label
15
+ g.cast_array unless @value.kind_of? ArrayLiteral
92
16
  end
93
17
 
94
18
  def to_sexp
@@ -113,7 +37,7 @@ module CodeTools
113
37
  if @array
114
38
  @array.bytecode(g)
115
39
  @rest.bytecode(g)
116
- convert_to_ary(g)
40
+ g.cast_array
117
41
  g.send :+, 1
118
42
  else
119
43
  @rest.bytecode(g)
@@ -121,69 +45,6 @@ module CodeTools
121
45
  end
122
46
  end
123
47
 
124
- # TODO: de-dup
125
- def convert_to_ary(g)
126
- done = g.new_label
127
- coerce = g.new_label
128
- make_array = g.new_label
129
- coerce_method = :to_ary
130
-
131
- kind_of_array(g, done)
132
-
133
- g.dup
134
- g.push_literal :to_ary
135
- g.send :respond_to?, 1, true
136
- g.git coerce
137
-
138
- discard = g.new_label
139
- check_array = g.new_label
140
-
141
- make_array.set!
142
- g.dup
143
- g.send :to_a, 0, true
144
- coerce_method = :to_a
145
- g.goto check_array
146
-
147
- coerce.set!
148
- g.dup
149
- g.send :to_ary, 0, true
150
-
151
- g.dup
152
- g.push :nil
153
- g.send :equal?, 1, true
154
- coerce_method = :to_ary
155
- g.gif check_array
156
-
157
- g.pop
158
- g.goto make_array
159
-
160
- check_array.set!
161
- kind_of_array(g, discard)
162
-
163
- g.push_type
164
- g.move_down 2
165
- g.push_literal :to_ary
166
- g.push_cpath_top
167
- g.find_const :Array
168
- g.send :coerce_to_type_error, 4, true
169
- g.goto done
170
-
171
- discard.set!
172
- g.swap
173
- g.pop
174
-
175
- done.set!
176
- end
177
-
178
- def kind_of_array(g, label)
179
- g.dup
180
- g.push_cpath_top
181
- g.find_const :Array
182
- g.swap
183
- g.kind_of
184
- g.git label
185
- end
186
-
187
48
  # Dive down and try to find an array of regular values
188
49
  # that could construct the left side of a concatination.
189
50
  # This is used to minimize the splat doing a send.
@@ -281,49 +142,8 @@ module CodeTools
281
142
  def bytecode(g)
282
143
  pos(g)
283
144
 
284
- done = g.new_label
285
- coerce = g.new_label
286
-
287
145
  @value.bytecode(g)
288
- kind_of_array(g, done)
289
-
290
- g.dup
291
- g.push_literal :to_ary
292
- g.send :respond_to?, 1, true
293
- g.git coerce
294
-
295
- g.make_array 1
296
- g.goto done
297
-
298
- coerce.set!
299
- g.dup
300
- g.send :to_ary, 0, true
301
-
302
- discard = g.new_label
303
- kind_of_array(g, discard)
304
-
305
- g.push_type
306
- g.move_down 2
307
- g.push_literal :to_a
308
- g.push_cpath_top
309
- g.find_const :Array
310
- g.send :coerce_to_type_error, 4, true
311
- g.goto done
312
-
313
- discard.set!
314
- g.swap
315
- g.pop
316
-
317
- done.set!
318
- end
319
-
320
- def kind_of_array(g, label)
321
- g.dup
322
- g.push_cpath_top
323
- g.find_const :Array
324
- g.swap
325
- g.kind_of
326
- g.git label
146
+ g.cast_multi_value
327
147
  end
328
148
 
329
149
  def to_sexp
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class BackRef < Node
6
6
  attr_accessor :kind
@@ -45,7 +45,7 @@ module CodeTools
45
45
  g.is_nil
46
46
  g.git f
47
47
 
48
- g.push_literal "$#{@kind}"
48
+ g.push_literal "global-variable"
49
49
  g.string_dup
50
50
 
51
51
  g.goto done
@@ -87,7 +87,7 @@ module CodeTools
87
87
  g.is_nil
88
88
  g.git f
89
89
 
90
- g.push_literal "$#{@which}"
90
+ g.push_literal "global-variable"
91
91
  g.string_dup
92
92
 
93
93
  g.goto done
@@ -541,7 +541,7 @@ module CodeTools
541
541
  end
542
542
 
543
543
  class MultipleAssignment < Node
544
- attr_accessor :left, :right, :splat, :block
544
+ attr_accessor :left, :right, :splat, :block, :post
545
545
 
546
546
  def initialize(line, left, right, splat)
547
547
  @line = line
@@ -549,8 +549,17 @@ module CodeTools
549
549
  @right = right
550
550
  @splat = nil
551
551
  @block = nil # support for |&b|
552
-
553
- @fixed = right.kind_of?(ArrayLiteral) ? true : false
552
+ @post = nil # in `a,*b,c`, c is in post.
553
+
554
+ if splat.kind_of?(PostArg)
555
+ @fixed = false
556
+ @post = splat.rest
557
+ splat = splat.into
558
+ elsif right.kind_of?(ArrayLiteral)
559
+ @fixed = right.body.size > 1
560
+ else
561
+ @fixed = false
562
+ end
554
563
 
555
564
  if splat.kind_of? Node
556
565
  if @left
@@ -573,6 +582,44 @@ module CodeTools
573
582
  end
574
583
  end
575
584
 
585
+ def pad_short(g)
586
+ short = @left.body.size - @right.body.size
587
+ if short > 0
588
+ short.times { g.push :nil }
589
+ g.make_array 0 if @splat
590
+ end
591
+ end
592
+
593
+ def pop_excess(g)
594
+ excess = @right.body.size - @left.body.size
595
+ excess.times { g.pop } if excess > 0
596
+ end
597
+
598
+ def make_array(g)
599
+ size = @right.body.size - @left.body.size
600
+ g.make_array size if size >= 0
601
+ end
602
+
603
+ def make_retval(g)
604
+ size = @right.body.size
605
+ if @left and !@splat
606
+ lhs = @left.body.size
607
+ size = lhs if lhs > size
608
+ end
609
+ g.dup_many @right.body.size
610
+ g.make_array @right.body.size
611
+ g.move_down size
612
+ end
613
+
614
+ def rotate(g)
615
+ if @splat
616
+ size = @left.body.size + 1
617
+ else
618
+ size = @right.body.size
619
+ end
620
+ g.rotate size
621
+ end
622
+
576
623
  def iter_arguments
577
624
  @iter_arguments = true
578
625
  end
@@ -601,233 +648,83 @@ module CodeTools
601
648
  end
602
649
 
603
650
  def bytecode(g, array_on_stack=false)
604
- declare_local_scope(g.state.scope)
605
-
606
- case @right
607
- when ArrayLiteral, ConcatArgs
608
- @right.bytecode(g)
609
- when SplatValue
610
- @right.bytecode(g)
611
- convert_to_ary(g)
612
- when ToArray
613
- @right.bytecode(g)
614
- when nil
615
- convert_to_ary(g)
616
- else
617
- @right.bytecode(g)
618
- convert_to_a(g)
651
+ unless array_on_stack
652
+ g.cast_array unless @right or (@splat and not @left)
619
653
  end
620
654
 
621
- size = g.new_stack_local
622
- g.dup
623
- g.send :size, 0, true
624
- g.set_stack_local size
625
- g.pop
626
-
627
- index = g.new_stack_local
628
- g.push 0
629
- g.set_stack_local index
630
- g.pop
631
-
632
- g.state.push_masgn
633
-
634
- if @left
635
- @left.body.each do |x|
636
- convert_to_ary(g) if x.kind_of? MultipleAssignment
637
-
638
- get_element(g, index)
639
-
640
- x.bytecode(g)
641
- g.pop
642
- end
643
- end
644
-
645
- if @splat
646
- g.dup
647
-
648
- convert_to_ary(g) if @splat.kind_of? SplatValue
649
-
650
- g.push_stack_local index
651
-
652
- check_count = g.new_label
653
-
654
- g.push_stack_local size
655
- g.push_stack_local index
656
- g.send :-, 1, true
655
+ declare_local_scope(g.state.scope)
657
656
 
658
- g.goto check_count
657
+ if @fixed
658
+ pad_short(g) if @left and !@splat
659
+ @right.body.each { |x| x.bytecode(g) }
659
660
 
660
- underflow = g.new_label
661
- assign_splat = g.new_label
661
+ if @left
662
+ make_retval(g)
662
663
 
663
- underflow.set!
664
- g.pop_many 3
665
- g.make_array 0
664
+ if @splat
665
+ pad_short(g)
666
+ make_array(g)
667
+ end
666
668
 
667
- g.goto assign_splat
669
+ rotate(g)
668
670
 
669
- check_count.set!
670
- g.dup
671
- g.push 0
672
- g.send :<, 1, true
673
- g.git underflow
671
+ g.state.push_masgn
672
+ @left.body.each do |x|
673
+ x.bytecode(g)
674
+ g.pop
675
+ end
676
+ g.state.pop_masgn
674
677
 
675
- g.dup
676
- g.push_stack_local index
677
- g.send :+, 1, true
678
- g.set_stack_local index
679
- g.pop
678
+ pop_excess(g) unless @splat
679
+ end
680
+ else
681
+ if @right
682
+ if @right.kind_of? ArrayLiteral and @right.body.size == 1
683
+ @right.body.first.bytecode(g)
684
+ g.cast_multi_value
685
+ else
686
+ @right.bytecode(g)
687
+ end
680
688
 
681
- g.send :[], 2, true
689
+ g.cast_array unless @right.kind_of? ToArray
690
+ g.dup # Use the array as the return value
691
+ end
682
692
 
683
- assign_splat.set!
693
+ if @left
694
+ g.state.push_masgn
695
+ @left.body.each do |x|
696
+ g.shift_array
697
+ g.cast_array if x.kind_of? MultipleAssignment and x.left
698
+ x.bytecode(g)
699
+ g.pop
700
+ end
701
+ g.state.pop_masgn
702
+ end
684
703
 
685
- # TODO: Fix nodes to work correctly.
686
- case @splat
687
- when EmptySplat
688
- # nothing
689
- when SplatArray, SplatWrapped
690
- @splat.value.bytecode(g)
691
- else
692
- @splat.bytecode(g)
704
+ if @post
705
+ g.state.push_masgn
706
+ @post.body.each do |x|
707
+ g.dup
708
+ g.send :pop, 0
709
+ g.cast_array if x.kind_of? MultipleAssignment and x.left
710
+ x.bytecode(g)
711
+ g.pop
712
+ end
713
+ g.state.pop_masgn
693
714
  end
694
- g.pop
695
715
  end
696
716
 
697
- g.state.pop_masgn
698
- end
699
-
700
- def convert_to_a(g)
701
- done = g.new_label
702
- check_array = g.new_label
703
-
704
- kind_of_array(g, done)
705
-
706
- wrap_tuple = g.new_label
707
- kind_of_tuple(g, wrap_tuple)
708
-
709
- g.dup
710
- g.send :to_a, 0, true
711
- g.goto check_array
712
-
713
- wrap_tuple.set!
714
- g.dup
715
- g.make_array 0
716
- g.dup
717
- g.move_down 2
718
- g.swap
719
- g.push_literal :@tuple
720
- g.swap
721
- g.invoke_primitive :object_set_ivar, 3
722
- g.send :size, 0, true
723
- g.push_literal :@total
724
- g.swap
725
- g.invoke_primitive :object_set_ivar, 3
726
- g.pop
727
- g.goto done
728
-
729
- discard = g.new_label
730
-
731
- check_array.set!
732
- kind_of_array(g, discard)
733
-
734
- g.push_type
735
- g.move_down 2
736
- g.push_literal :to_a
737
- g.push_cpath_top
738
- g.find_const :Array
739
- g.send :coerce_to_type_error, 4, true
740
- g.goto done
741
-
742
- discard.set!
743
- g.swap
744
- g.pop
745
-
746
- done.set!
747
- end
748
-
749
- def convert_to_ary(g)
750
- done = g.new_label
751
- coerce = g.new_label
752
- make_array = g.new_label
753
- coerce_method = :to_ary
754
-
755
- kind_of_array(g, done)
756
-
757
- g.dup
758
- g.push_literal :to_ary
759
- g.send :respond_to?, 1, true
760
- g.git coerce
761
-
762
- discard = g.new_label
763
- check_array = g.new_label
764
-
765
- make_array.set!
766
- g.dup
767
- g.send :to_a, 0, true
768
- coerce_method = :to_a
769
- g.goto check_array
770
-
771
- coerce.set!
772
- g.dup
773
- g.send :to_ary, 0, true
774
-
775
- g.dup
776
- g.push :nil
777
- g.send :equal?, 1, true
778
- coerce_method = :to_ary
779
- g.gif check_array
780
-
781
- g.pop
782
- g.goto make_array
783
-
784
- check_array.set!
785
- kind_of_array(g, discard)
786
-
787
- g.push_type
788
- g.move_down 2
789
- g.push_literal coerce_method
790
- g.push_cpath_top
791
- g.find_const :Array
792
- g.send :coerce_to_type_error, 4, true
793
- g.goto done
794
-
795
- discard.set!
796
- g.swap
797
- g.pop
798
-
799
- done.set!
800
- end
801
-
802
- def kind_of_array(g, label)
803
- g.dup
804
- g.push_cpath_top
805
- g.find_const :Array
806
- g.swap
807
- g.kind_of
808
- g.git label
809
- end
810
-
811
- def kind_of_tuple(g, label)
812
- g.dup
813
- g.push_rubinius
814
- g.find_const :Tuple
815
- g.swap
816
- g.kind_of
817
- g.git label
818
- end
717
+ if @splat
718
+ g.state.push_masgn
719
+ @splat.bytecode(g)
819
720
 
820
- def get_element(g, index)
821
- g.dup
822
- g.push_stack_local index
721
+ # Use the array as the return value
722
+ g.dup if @fixed and !@left
823
723
 
824
- g.dup
825
- g.push 1
826
- g.send :+, 1, true
827
- g.set_stack_local index
828
- g.pop
724
+ g.state.pop_masgn
725
+ end
829
726
 
830
- g.send :[], 1, true
727
+ g.pop if @right and (!@fixed or @splat)
831
728
  end
832
729
 
833
730
  def defined(g)