Class: Scope
- Inherits:
-
Object
- Object
- Scope
- Defined in:
- lib/nodes.rb
Overview
Class to handle scopes when evaluating AST.
Instance Attribute Summary collapse
-
#identifiers ⇒ Object
readonly
Returns the value of attribute identifiers.
-
#non_local_variables ⇒ Object
readonly
Returns the value of attribute non_local_variables.
-
#parent_scope ⇒ Object
readonly
Returns the value of attribute parent_scope.
Instance Method Summary collapse
-
#get_identifier(name) ⇒ Object
Get value of identifier in current or parent scope(s) if defined.
-
#get_scope(name) ⇒ Object
Get first scope where identifier is defined.
-
#initialize(parent_scope = nil) ⇒ Scope
constructor
A new instance of Scope.
-
#is_function?(name) ⇒ Boolean
Checks if a identifier is a function.
-
#set_function(name, block, parameters) ⇒ Object
Set a function in current scope.
-
#set_non_local_variable(name) ⇒ Object
Add non local variable used in scope.
-
#set_variable(name, op, expression) ⇒ Object
Set variable in current scope.
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
#identifiers ⇒ Object (readonly)
Returns the value of attribute identifiers.
7 8 9 |
# File 'lib/nodes.rb', line 7 def identifiers @identifiers end |
#non_local_variables ⇒ Object (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_scope ⇒ Object (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.
51 52 53 54 55 56 57 58 |
# File 'lib/nodes.rb', line 51 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.
61 62 63 64 65 66 67 |
# File 'lib/nodes.rb', line 61 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.
70 71 72 73 74 75 76 |
# File 'lib/nodes.rb', line 70 def is_function?(name) scope = get_scope(name) return false unless scope id_value = scope.get_identifier(name) return id_value.is_a?(Hash) end |
#set_function(name, block, parameters) ⇒ Object
Set a function in current scope.
79 80 81 |
# File 'lib/nodes.rb', line 79 def set_function(name, block, parameters) @identifiers[name] = {:parameters => parameters, :block => block} end |
#set_non_local_variable(name) ⇒ Object
Add non local variable used in scope
44 45 46 47 48 |
# File 'lib/nodes.rb', line 44 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 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/nodes.rb', line 15 def set_variable(name, op, expression) # Checks if the variable has been used as a non-local variable, if true: raise NameError if @non_local_variables.include?(name) raise NameError, "Local identifier #{name} referenced before assignment" end if op == '=' @identifiers[name] = expression else # Checks if the variable is local, raise NameError if otherwise unless @identifiers.has_key?(name) raise NameError, "Local identifier #{name} referenced before assignment" end if op == '+=' @identifiers[name] += expression else if @identifiers[name].is_a?(String) || expression.is_a?(String) raise TypeError, "Operation #{op} is not allowed for identifier #{name} or the expression as they must not be strings" else @identifiers[name] -= expression end end end end |