Class: Scope

Inherits:
Object
  • Object
show all
Defined in:
lib/nodes.rb

Overview

Class to handle scopes when evaluating AST.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent_scope = nil) ⇒ Scope

Returns a new instance of Scope.



8
9
10
11
12
# File 'lib/nodes.rb', line 8

def initialize(parent_scope = nil)
  @identifiers = {}
  @non_local_variables = []
  @parent_scope = parent_scope
end

Instance Attribute Details

#identifiersObject (readonly)

Returns the value of attribute identifiers.



7
8
9
# File 'lib/nodes.rb', line 7

def identifiers
  @identifiers
end

#non_local_variablesObject (readonly)

Returns the value of attribute non_local_variables.



7
8
9
# File 'lib/nodes.rb', line 7

def non_local_variables
  @non_local_variables
end

#parent_scopeObject (readonly)

Returns the value of attribute parent_scope.



7
8
9
# File 'lib/nodes.rb', line 7

def parent_scope
  @parent_scope
end

Instance Method Details

#get_identifier(name) ⇒ Object

Get value of identifier in current or parent scope(s) if defined.



40
41
42
43
44
45
46
47
# File 'lib/nodes.rb', line 40

def get_identifier(name)
  scope = get_scope(name)
  if scope
    return scope.identifiers[name]
  else
    raise NameError,"Identifier #{name} not defined in scope."
  end
end

#get_scope(name) ⇒ Object

Get first scope where identifier is defined.



50
51
52
53
54
55
56
# File 'lib/nodes.rb', line 50

def get_scope(name)
  if @identifiers.has_key?(name)
    return self
  elsif @parent_scope
    return @parent_scope.get_scope(name)
  end
end

#is_function?(name) ⇒ Boolean

Checks if a identifier is a function.

Returns:

  • (Boolean)


59
60
61
62
63
# File 'lib/nodes.rb', line 59

def is_function?(name)
  scope = get_scope(name)
  id_value = scope.get_identifier(name) if scope
  return id_value.is_a?(Hash) 
end

#set_function(name, block, parameters) ⇒ Object

Set a function in current scope.



66
67
68
# File 'lib/nodes.rb', line 66

def set_function(name, block, parameters)
  @identifiers[name] = {:parameters => parameters, :block => block}
end

#set_non_local_variable(name) ⇒ Object



33
34
35
36
37
# File 'lib/nodes.rb', line 33

def set_non_local_variable(name)
  unless @non_local_variables.include?(name) && is_function(name)
    @non_local_variables.append(name)
  end
end

#set_variable(name, op, expression) ⇒ Object

Set variable in current scope



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/nodes.rb', line 15

def set_variable(name, op, expression)
  if @non_local_variables.include?(name)
    raise NameError, "local identifier #{name} referenced before assignment"
  end
  if op == '='
    @identifiers[name] = expression
  else
    unless @identifiers.has_key?(name)
      raise NameError, "local identifier #{name} referenced before assignment"
    end
    if op == '+='
      @identifiers[name] += expression
    else
      @identifiers[name] -= expression
    end
  end
end