class Ikra::TypeInference::SymbolTable

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.

Attributes

return_type[R]
symbols[R]

For debug purposes

Public Class Methods

new() click to toggle source
# 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

Public Instance Methods

[](variable_name) click to toggle source
# 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!() click to toggle source
# File lib/types/inference/symbol_table.rb, line 42
def clear!
    @symbols = {}
end
declare_variable(variable_name, type: Types::UnionType.new, kind: :local) click to toggle source

Declares a local variable and overwrites (shadows) existing variables (lexical variables). Use this method for method/block parameters.

# 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)
    expand_type(variable_name, type)
end
ensure_variable_declared(variable_name, type: Types::UnionType.new, kind: :local) click to toggle source

Declares a local variable. This method should be used only for regular local variables (not parameters). Does not shadow lexical variables.

# 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
        expand_type(variable_name, type)
    end
end
expand_return_type(type) click to toggle source
# File lib/types/inference/symbol_table.rb, line 98
def expand_return_type(type)
    @return_type.expand(type)
end
expand_type(variable_name, type) click to toggle source
# File lib/types/inference/symbol_table.rb, line 88
def expand_type(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.expand(type)
end
read!(variable_name) click to toggle source
# 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() click to toggle source
# File lib/types/inference/symbol_table.rb, line 84
def read_and_written_variables
    return read_variables + written_variables
end
read_variables() click to toggle source
# 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) click to toggle source
# 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() click to toggle source
# File lib/types/inference/symbol_table.rb, line 78
def written_variables
    return @symbols.select do |k, v|
        v.written
    end.keys
end

Private Instance Methods

has_variable?(variable_name) click to toggle source
# File lib/types/inference/symbol_table.rb, line 126
def has_variable?(variable_name)
    return @symbols.include?(variable_name)
end