Class: Loxxy::BackEnd::SymbolTable
- Inherits:
-
Object
- Object
- Loxxy::BackEnd::SymbolTable
- Defined in:
- lib/loxxy/back_end/symbol_table.rb
Overview
A symbol table is basically a mapping from a name onto an object that holds information associated with that name. It is a data structure that keeps track of variables and their respective environment where they are declared. The key requirements for the symbol are:
- To perform fast lookup operations: given a name, retrieve the corresponding object.
- To allow the efficient insertion of names and related information
- To support the nesting of environments
- To handle the entry environment and exit environment events,
- To cope with variable redefinition in nested environment The terminology 'symbol table' comes from the compiler design community.
Instance Attribute Summary collapse
-
#current_env ⇒ Environment
readonly
The current environment.
-
#name2envs ⇒ Hash{String => Array<Environment>}
readonly
Mapping between a name and the environment(s) where it is defined.
-
#root ⇒ Environment
readonly
The top-level environment (= root of environment tree).
Instance Method Summary collapse
-
#all_variables ⇒ Object
Return all variables defined in the current ..
-
#empty? ⇒ Boolean
Returns iff there is no entry in the symbol table.
-
#enter_environment(anEnv) ⇒ Object
Use this method to signal the interpreter that a given environment to be a child of current environment and to be itself the new current environment.
-
#initialize(anEnv = nil) ⇒ SymbolTable
constructor
Build symbol table with given environment as root.
-
#insert(anEntry) ⇒ String
Add an entry with given name to current environment.
- #leave_environment ⇒ Object
-
#lookup(aName) ⇒ BackEnd::Variable
Search for the object with the given name.
Constructor Details
#initialize(anEnv = nil) ⇒ SymbolTable
Build symbol table with given environment as root.
32 33 34 35 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 32 def initialize(anEnv = nil) @name2envs = {} init_root(anEnv) # Set default (global) environment end |
Instance Attribute Details
#current_env ⇒ Environment (readonly)
Returns The current environment.
28 29 30 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 28 def current_env @current_env end |
#name2envs ⇒ Hash{String => Array<Environment>} (readonly)
Mapping between a name and the environment(s) where it is defined
22 23 24 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 22 def name2envs @name2envs end |
#root ⇒ Environment (readonly)
Returns The top-level environment (= root of environment tree).
25 26 27 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 25 def root @root end |
Instance Method Details
#all_variables ⇒ Object
Return all variables defined in the current .. root chain. Variables are sorted top-down and left-to-right.
104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 104 def all_variables vars = [] skope = current_env while skope vars_of_environment = skope.defns.select { |_, item| item.kind_of?(Variable) } vars = vars_of_environment.values.concat(vars) skope = skope.enclosing end vars end |
#empty? ⇒ Boolean
Returns iff there is no entry in the symbol table
39 40 41 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 39 def empty? name2envs.empty? end |
#enter_environment(anEnv) ⇒ Object
Use this method to signal the interpreter that a given environment to be a child of current environment and to be itself the new current environment.
46 47 48 49 50 51 52 53 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 46 def enter_environment(anEnv) if anEnv.enclosing && (anEnv.enclosing != current_env) anEnv.predecessor = current_env else anEnv.enclosing = current_env end @current_env = anEnv end |
#insert(anEntry) ⇒ String
Add an entry with given name to current environment.
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 79 def insert(anEntry) current_env.insert(anEntry) name = anEntry.name if name2envs.include?(name) name2envs[name] << current_env else name2envs[name] = [current_env] end anEntry.name end |
#leave_environment ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 55 def leave_environment unless current_env. current_env.defns.each_pair do |nm, _item| environments = name2envs[nm] if environments.size == 1 name2envs.delete(nm) else environments.pop name2envs[nm] = environments end end end raise StandardError, 'Cannot remove root environment.' if current_env == root if current_env.predecessor @current_env = current_env.predecessor else @current_env = current_env.enclosing end end |
#lookup(aName) ⇒ BackEnd::Variable
Search for the object with the given name
94 95 96 97 98 99 100 |
# File 'lib/loxxy/back_end/symbol_table.rb', line 94 def lookup(aName) environments = name2envs.fetch(aName, nil) return nil if environments.nil? sc = environments.last sc.defns[aName] end |