class CodeTools::AST::Iter
Attributes
arguments[RW]
body[RW]
parent[RW]
Public Class Methods
new(line, arguments, body)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 572 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
Public Instance Methods
assign_local_reference(var)
click to toggle source
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.
# File lib/rubinius/code/ast/sends.rb, line 630 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)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 584 def block_local?(name) @locals.include?(name) if @locals end
block_parameter?(name)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 588 def block_parameter?(name) @arguments.block_arg.name == name if @arguments.block_arg end
bytecode(g)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 645 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 # Push line info down. 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?()
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 592 def module? false end
nest_scope(scope)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 596 def nest_scope(scope) scope.parent = self end
new_local(name)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 617 def new_local(name) variables[name] ||= Compiler::LocalVariable.new allocate_slot end
new_nested_local(name)
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 621 def new_nested_local(name) new_local(name).nested_reference end
search_local(name)
click to toggle source
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).
# File lib/rubinius/code/ast/sends.rb, line 606 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()
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 688 def sexp_name :iter end
to_sexp()
click to toggle source
# File lib/rubinius/code/ast/sends.rb, line 692 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