Class: CodeTools::AST::Iter
- Inherits:
-
Node
- Object
- Node
- CodeTools::AST::Iter
show all
- Includes:
- Compiler::LocalVariables
- Defined in:
- lib/rubinius/code/ast/sends.rb
Direct Known Subclasses
For
Instance Attribute Summary collapse
Attributes inherited from Node
#line
Instance Method Summary
collapse
Methods inherited from Node
#ascii_graph, #attributes, #children, #defined, 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, arguments, body) ⇒ Iter
Returns a new instance of Iter.
573
574
575
576
577
578
579
580
581
582
583
|
# File 'lib/rubinius/code/ast/sends.rb', line 573
def initialize(line, arguments, body)
@line = line
@arguments = arguments || Parameters.new(line)
@body = body || NilLiteral.new(line)
if @body.kind_of?(Block) and @body.locals
@locals = @body.locals.body.map { |x| x.value }
else
@locals = nil
end
end
|
Instance Attribute Details
#arguments ⇒ Object
Returns the value of attribute arguments.
571
572
573
|
# File 'lib/rubinius/code/ast/sends.rb', line 571
def arguments
@arguments
end
|
#body ⇒ Object
Returns the value of attribute body.
571
572
573
|
# File 'lib/rubinius/code/ast/sends.rb', line 571
def body
@body
end
|
#parent ⇒ Object
Returns the value of attribute parent.
571
572
573
|
# File 'lib/rubinius/code/ast/sends.rb', line 571
def parent
@parent
end
|
Instance Method Details
#assign_local_reference(var) ⇒ Object
If the local variable exists in this scope, set the local variable node attribute to a reference to the local variable. If the variable exists in an enclosing scope, set the local variable node attribute to a nested reference to the local variable. Otherwise, create a local variable in this scope and set the local variable node attribute.
631
632
633
634
635
636
637
638
639
640
641
642
643
644
|
# File 'lib/rubinius/code/ast/sends.rb', line 631
def assign_local_reference(var)
if variable = variables[var.name]
var.variable = variable.reference
elsif block_local?(var.name) || var.placeholder? || block_parameter?(var.name)
variable = new_local var.name
var.variable = variable.reference
elsif reference = @parent.search_local(var.name)
reference.depth += 1
var.variable = reference
else
variable = new_local var.name
var.variable = variable.reference
end
end
|
#block_local?(name) ⇒ Boolean
585
586
587
|
# File 'lib/rubinius/code/ast/sends.rb', line 585
def block_local?(name)
@locals.include?(name) if @locals
end
|
#block_parameter?(name) ⇒ Boolean
589
590
591
|
# File 'lib/rubinius/code/ast/sends.rb', line 589
def block_parameter?(name)
@arguments.block_arg.name == name if @arguments.block_arg
end
|
#bytecode(g) ⇒ Object
646
647
648
649
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
|
# File 'lib/rubinius/code/ast/sends.rb', line 646
def bytecode(g)
pos(g)
state = g.state
state.scope.nest_scope self
blk = new_block_generator g, @arguments
blk.push_state self
blk.definition_line @line
blk.state.push_super state.super
blk.state.push_eval state.eval
blk.state.push_name blk.name
pos(blk)
@arguments.bytecode(blk)
blk.state.push_block
blk.push_modifiers
blk.break = nil
blk.next = nil
blk.redo = blk.new_label
blk.redo.set!
@body.bytecode(blk)
blk.pop_modifiers
blk.state.pop_block
blk.ret
blk.close
blk.pop_state
blk.splat_index = @arguments.splat_index
blk.kwrest_index = @arguments.kwrest_index
blk.local_count = local_count
blk.local_names = local_names
g.create_block blk
end
|
#module? ⇒ Boolean
593
594
595
|
# File 'lib/rubinius/code/ast/sends.rb', line 593
def module?
false
end
|
#nest_scope(scope) ⇒ Object
597
598
599
|
# File 'lib/rubinius/code/ast/sends.rb', line 597
def nest_scope(scope)
scope.parent = self
end
|
#new_local(name) ⇒ Object
618
619
620
|
# File 'lib/rubinius/code/ast/sends.rb', line 618
def new_local(name)
variables[name] ||= Compiler::LocalVariable.new allocate_slot
end
|
#new_nested_local(name) ⇒ Object
622
623
624
|
# File 'lib/rubinius/code/ast/sends.rb', line 622
def new_nested_local(name)
new_local(name).nested_reference
end
|
#search_local(name) ⇒ Object
A nested scope is looking up a local variable. If the variable exists in our local variables hash, return a nested reference to it. If it exists in an enclosing scope, increment the depth of the reference when it passes through this nested scope (i.e. the depth of a reference is a function of the nested scopes it passes through from the scope it is defined in to the scope it is used in).
607
608
609
610
611
612
613
614
615
616
|
# File 'lib/rubinius/code/ast/sends.rb', line 607
def search_local(name)
if variable = variables[name]
variable.nested_reference
elsif block_local?(name)
new_nested_local name
elsif reference = @parent.search_local(name)
reference.depth += 1
reference
end
end
|
#sexp_name ⇒ Object
689
690
691
|
# File 'lib/rubinius/code/ast/sends.rb', line 689
def sexp_name
:iter
end
|
#to_sexp ⇒ Object
693
694
695
696
697
698
699
|
# File 'lib/rubinius/code/ast/sends.rb', line 693
def to_sexp
body_sexp = @body.to_sexp
if @locals
body_sexp[1] = @locals.map { |x| [:lvar, x] }
end
[sexp_name, @arguments.to_sexp, body_sexp]
end
|