Class: Rubinius::ToolSet.current::TS::AST::MultipleAssignment
- Inherits:
-
Node
- Object
- Node
- Rubinius::ToolSet.current::TS::AST::MultipleAssignment
show all
- Defined in:
- lib/rubinius/ast/variables.rb
Instance Attribute Summary collapse
Attributes inherited from Node
#line
Instance Method Summary
collapse
Methods inherited from Node
#ascii_graph, #attributes, #children, match_arguments?, match_send?, #new_block_generator, #new_generator, #node_name, #or_bytecode, #pos, #set_child, transform, #transform, transform_comment, transform_kind, transform_kind=, transform_name, #value_defined, #visit, #walk
Constructor Details
#initialize(line, left, right, splat) ⇒ MultipleAssignment
Returns a new instance of MultipleAssignment.
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
|
# File 'lib/rubinius/ast/variables.rb', line 546
def initialize(line, left, right, splat)
@line = line
@left = left
@right = right
@splat = nil
@block = nil @post = nil
if splat.kind_of?(PostArg)
@fixed = false
@post = splat.rest
splat = splat.into
elsif right.kind_of?(ArrayLiteral)
@fixed = right.body.size > 1
else
@fixed = false
end
if splat.kind_of? Node
if @left
if right
@splat = SplatAssignment.new line, splat
else
@splat = SplatWrapped.new line, splat
end
elsif @fixed
@splat = SplatArray.new line, splat, right.body.size
elsif right.kind_of? SplatValue
@splat = splat
else
@splat = SplatWrapped.new line, splat
end
elsif splat
size = @fixed ? right.body.size : 0
@splat = EmptySplat.new line, size
end
end
|
Instance Attribute Details
#block ⇒ Object
Returns the value of attribute block.
544
545
546
|
# File 'lib/rubinius/ast/variables.rb', line 544
def block
@block
end
|
#left ⇒ Object
Returns the value of attribute left.
544
545
546
|
# File 'lib/rubinius/ast/variables.rb', line 544
def left
@left
end
|
#post ⇒ Object
Returns the value of attribute post.
544
545
546
|
# File 'lib/rubinius/ast/variables.rb', line 544
def post
@post
end
|
#right ⇒ Object
Returns the value of attribute right.
544
545
546
|
# File 'lib/rubinius/ast/variables.rb', line 544
def right
@right
end
|
#splat ⇒ Object
Returns the value of attribute splat.
544
545
546
|
# File 'lib/rubinius/ast/variables.rb', line 544
def splat
@splat
end
|
Instance Method Details
#bytecode(g, array_on_stack = false) ⇒ Object
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
|
# File 'lib/rubinius/ast/variables.rb', line 650
def bytecode(g, array_on_stack=false)
unless array_on_stack
g.cast_array unless @right or (@splat and not @left)
end
declare_local_scope(g.state.scope)
if @fixed
pad_short(g) if @left and !@splat
@right.body.each { |x| x.bytecode(g) }
if @left
make_retval(g)
if @splat
pad_short(g)
make_array(g)
end
rotate(g)
g.state.push_masgn
@left.body.each do |x|
x.bytecode(g)
g.pop
end
g.state.pop_masgn
pop_excess(g) unless @splat
end
else
if @right
if @right.kind_of? ArrayLiteral and @right.body.size == 1
@right.body.first.bytecode(g)
g.cast_multi_value
else
@right.bytecode(g)
end
g.cast_array unless @right.kind_of? ToArray
g.dup end
if @left
g.state.push_masgn
@left.body.each do |x|
g.shift_array
g.cast_array if x.kind_of? MultipleAssignment and x.left
x.bytecode(g)
g.pop
end
g.state.pop_masgn
end
if @post
g.state.push_masgn
@post.body.each do |x|
g.dup
g.send :pop, 0
g.cast_array if x.kind_of? MultipleAssignment and x.left
x.bytecode(g)
g.pop
end
g.state.pop_masgn
end
end
if @splat
g.state.push_masgn
@splat.bytecode(g)
g.dup if @fixed and !@left
g.state.pop_masgn
end
g.pop if @right and (!@fixed or @splat)
end
|
#declare_local_scope(scope) ⇒ Object
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
|
# File 'lib/rubinius/ast/variables.rb', line 627
def declare_local_scope(scope)
if @left
@left.body.each do |var|
case var
when LocalVariable
scope.assign_local_reference var
when MultipleAssignment
var.declare_local_scope(scope)
end
end
end
if @splat and @splat.kind_of?(SplatAssignment)
if @splat.value.kind_of?(LocalVariable)
scope.assign_local_reference @splat.value
end
end
end
|
#defined(g) ⇒ Object
730
731
732
|
# File 'lib/rubinius/ast/variables.rb', line 730
def defined(g)
g.push_literal "assignment"
end
|
#iter_arguments ⇒ Object
623
624
625
|
# File 'lib/rubinius/ast/variables.rb', line 623
def iter_arguments
@iter_arguments = true
end
|
#make_array(g) ⇒ Object
598
599
600
601
|
# File 'lib/rubinius/ast/variables.rb', line 598
def make_array(g)
size = @right.body.size - @left.body.size
g.make_array size if size >= 0
end
|
#make_retval(g) ⇒ Object
603
604
605
606
607
608
609
610
611
612
|
# File 'lib/rubinius/ast/variables.rb', line 603
def make_retval(g)
size = @right.body.size
if @left and !@splat
lhs = @left.body.size
size = lhs if lhs > size
end
g.dup_many @right.body.size
g.make_array @right.body.size
g.move_down size
end
|
#pad_short(g) ⇒ Object
585
586
587
588
589
590
591
|
# File 'lib/rubinius/ast/variables.rb', line 585
def pad_short(g)
short = @left.body.size - @right.body.size
if short > 0
short.times { g.push :nil }
g.make_array 0 if @splat
end
end
|
#pop_excess(g) ⇒ Object
593
594
595
596
|
# File 'lib/rubinius/ast/variables.rb', line 593
def pop_excess(g)
excess = @right.body.size - @left.body.size
excess.times { g.pop } if excess > 0
end
|
#rotate(g) ⇒ Object
614
615
616
617
618
619
620
621
|
# File 'lib/rubinius/ast/variables.rb', line 614
def rotate(g)
if @splat
size = @left.body.size + 1
else
size = @right.body.size
end
g.rotate size
end
|
#to_sexp ⇒ Object
734
735
736
737
738
739
740
741
742
|
# File 'lib/rubinius/ast/variables.rb', line 734
def to_sexp
left = @left ? @left.to_sexp : [:array]
left << [:splat, @splat.to_sexp] if @splat
left << @block.to_sexp if @block
sexp = [:masgn, left]
sexp << @right.to_sexp if @right
sexp
end
|