Class: Ikra::TypeInference::SymbolTable
- Defined in:
- lib/types/inference/symbol_table.rb
Overview
This is a symbol table that stores type information about variables. Ruby has a “flat” variable scope in method, i.e., variables defined in loop bodies, if statement bodies, or begin nodes are also visible outside of them.
Every method/block has its own symbol table.
Defined Under Namespace
Classes: Variable
Instance Attribute Summary collapse
-
#return_type ⇒ Object
readonly
Returns the value of attribute return_type.
-
#symbols ⇒ Object
readonly
For debug purposes.
Instance Method Summary collapse
- #[](variable_name) ⇒ Object
- #clear! ⇒ Object
-
#declare_variable(variable_name, type: Types::UnionType.new, kind: :local) ⇒ Object
Declares a local variable and overwrites (shadows) existing variables (lexical variables).
-
#ensure_variable_declared(variable_name, type: Types::UnionType.new, kind: :local) ⇒ Object
Declares a local variable.
- #expand_return_type(type) ⇒ Object
- #expand_type(variable_name, type) ⇒ Object
-
#initialize ⇒ SymbolTable
constructor
A new instance of SymbolTable.
- #read!(variable_name) ⇒ Object
- #read_and_written_variables ⇒ Object
- #read_variables ⇒ Object
- #written!(variable_name) ⇒ Object
- #written_variables ⇒ Object
Constructor Details
#initialize ⇒ SymbolTable
Returns a new instance of SymbolTable.
36 37 38 39 40 |
# File 'lib/types/inference/symbol_table.rb', line 36 def initialize # This is a mapping from variable names to Variable instances. @symbols = {} @return_type = Types::UnionType.new end |
Instance Attribute Details
#return_type ⇒ Object (readonly)
Returns the value of attribute return_type.
31 32 33 |
# File 'lib/types/inference/symbol_table.rb', line 31 def return_type @return_type end |
#symbols ⇒ Object (readonly)
For debug purposes
34 35 36 |
# File 'lib/types/inference/symbol_table.rb', line 34 def symbols @symbols end |
Instance Method Details
#[](variable_name) ⇒ Object
46 47 48 49 50 51 52 |
# File 'lib/types/inference/symbol_table.rb', line 46 def [](variable_name) if !has_variable?(variable_name) raise AssertionError.new("Variable #{variable_name} not defined") end return @symbols[variable_name].type end |
#clear! ⇒ Object
42 43 44 |
# File 'lib/types/inference/symbol_table.rb', line 42 def clear! @symbols = {} end |
#declare_variable(variable_name, type: Types::UnionType.new, kind: :local) ⇒ Object
Declares a local variable and overwrites (shadows) existing variables (lexical variables). Use this method for method/block parameters.
119 120 121 122 |
# File 'lib/types/inference/symbol_table.rb', line 119 def declare_variable(variable_name, type: Types::UnionType.new, kind: :local) @symbols[variable_name] = Variable.new(type: Types::UnionType.new, kind: kind) (variable_name, type) end |
#ensure_variable_declared(variable_name, type: Types::UnionType.new, kind: :local) ⇒ Object
Declares a local variable. This method should be used only for regular local variables (not parameters). Does not shadow lexical variables.
108 109 110 111 112 113 114 115 |
# File 'lib/types/inference/symbol_table.rb', line 108 def ensure_variable_declared(variable_name, type: Types::UnionType.new, kind: :local) if !has_variable?(variable_name) declare_variable(variable_name, type: type, kind: kind) else # Extend type of variable (variable_name, type) end end |
#expand_return_type(type) ⇒ Object
98 99 100 |
# File 'lib/types/inference/symbol_table.rb', line 98 def (type) @return_type.(type) end |
#expand_type(variable_name, type) ⇒ Object
88 89 90 91 92 93 94 95 96 |
# File 'lib/types/inference/symbol_table.rb', line 88 def (variable_name, type) if !has_variable?(variable_name) raise AssertionError.new( "Attempt to expand type of variable #{variable_name} but not found in " + " symbol table") end @symbols[variable_name].type.(type) end |
#read!(variable_name) ⇒ Object
54 55 56 57 58 59 60 61 |
# File 'lib/types/inference/symbol_table.rb', line 54 def read!(variable_name) if !has_variable?(variable_name) raise AssertionError.new( "Variable #{variable_name} read but not found in symbol table") end @symbols[variable_name].read = true end |
#read_and_written_variables ⇒ Object
84 85 86 |
# File 'lib/types/inference/symbol_table.rb', line 84 def read_and_written_variables return read_variables + written_variables end |
#read_variables ⇒ Object
72 73 74 75 76 |
# File 'lib/types/inference/symbol_table.rb', line 72 def read_variables return @symbols.select do |k, v| v.read end.keys end |
#written!(variable_name) ⇒ Object
63 64 65 66 67 68 69 70 |
# File 'lib/types/inference/symbol_table.rb', line 63 def written!(variable_name) if !has_variable?(variable_name) raise AssertionError.new( "Variable #{variable_name} written but not found in symbol table") end @symbols[variable_name].written = true end |
#written_variables ⇒ Object
78 79 80 81 82 |
# File 'lib/types/inference/symbol_table.rb', line 78 def written_variables return @symbols.select do |k, v| v.written end.keys end |