class Malady::Scope

Attributes

parent[RW]

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/malady/scope.rb, line 46
def assign_local_reference(var)
  if variable = variables[var.name]
    var.variable = variable.reference
  elsif block_local?(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/malady/scope.rb, line 28
def block_local?(name)
  @locals.include?(name) if @locals
end
nest_scope(scope) click to toggle source
# File lib/malady/scope.rb, line 7
def nest_scope(scope)
  scope.parent = self
end
new_local(name) click to toggle source
# File lib/malady/scope.rb, line 32
def new_local(name)
  variable = RBX::Compiler::LocalVariable.new allocate_slot
  variables[name] = variable
end
new_nested_local(name) click to toggle source
# File lib/malady/scope.rb, line 37
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/malady/scope.rb, line 17
def search_local(name)
  if variable = variables[name]
    variable.nested_reference
  elsif block_local?(name)
    new_local name
  elsif reference = @parent.search_local(name)
    reference.depth += 1
    reference
  end
end