class Yadriggy::TypeChecker

Type checker for ASTree. This provides several basic methods and utility classes for type checking. It does not specify any specific typing rules. Define a subclass of {TypeChecker} and write typing rules there.

A type object used by TypeChecker can be an instance of any subclass of Type. It does not have to necessarily be an object representing a “type”.

Public Class Methods

new() click to toggle source
Calls superclass method Yadriggy::Checker::new
# File lib/yadriggy/typecheck.rb, line 156
def initialize
  super
  @typetable = {}
  @typedefs = {}
end

Public Instance Methods

add_typedef(key) click to toggle source

Adds a type definition if it does not exist. Here, a type definition is a mapping from instance variables or methods to their types. It is defined per class or individual instance object.

@param [Module|Object] key a class or an instance. @return [TypeDef] the type definition for the class

or instance given by `key`.
# File lib/yadriggy/typecheck.rb, line 193
def add_typedef(key)
  @typedefs[key] || @typedefs[key] = TypeDef.new
end
check(an_ast, ast_tenv=nil) click to toggle source

@api private Internal-use only. Don't use this method. Use type().

# File lib/yadriggy/typecheck.rb, line 226
def check(an_ast, ast_tenv=nil)
  type(an_ast, ast_tenv)
end
error_group() click to toggle source
# File lib/yadriggy/typecheck.rb, line 292
def error_group
  'type'
end
make_base_env(klass) click to toggle source

Makes a new base type environment with the given context class.

@return [TypeEnv] the type enviornment.

# File lib/yadriggy/typecheck.rb, line 219
def make_base_env(klass)
  TypeEnv::BaseTypeEnv.new(klass)
end
type(an_ast, ast_tenv=nil) click to toggle source

Applies typing rules to determine the type of the given AST. This method is effective in {.rule}.

It assumes that the AST is processed by Syntax and it has usertype method. An exception is thrown when type checking fails.

@param [ASTnode|nil] an_ast an AST or nil. @param [TypeEnv|nil] ast_tenv a type environment or nil. @return [Type] the type of the given AST. It memoizes the results.

# File lib/yadriggy/typecheck.rb, line 240
def type(an_ast, ast_tenv=nil)
  if an_ast.nil?
    DynType
  else
    ast_type = @typetable[an_ast]
    return ast_type unless ast_type.nil?

    rule = self.class.find_rule_entry(an_ast)
    t = apply_typing_rule(rule, an_ast, ast_tenv)
    @typetable[an_ast] = t
  end
end
type?(an_ast) click to toggle source

Gets the type of the given AST if its type has been already determined by {.type}. Only the memoized types are returned.

@param [ASTnode] an_ast an AST. @return [Type|nil] the type or `nil` if not found.

# File lib/yadriggy/typecheck.rb, line 272
def type?(an_ast)
  @typetable[an_ast]
end
type_as(an_ast, a_type) click to toggle source

Sets the type of an AST to the given type.

@param [ASTnode|nil] an_ast an AST. @param [Type] a_type a type. @return [Type|DynType] the given type `a_type`.

# File lib/yadriggy/typecheck.rb, line 258
def type_as(an_ast, a_type)
  if an_ast.nil?
    DynType
  else
    @typetable[an_ast] = a_type
  end
end
type_assert(is_valid, errmsg='') click to toggle source
# File lib/yadriggy/typecheck.rb, line 276
def type_assert(is_valid, errmsg='')
  error_found!(@current_ast, errmsg) unless is_valid
end
type_assert_false(is_invalid, errmsg='') click to toggle source
# File lib/yadriggy/typecheck.rb, line 280
def type_assert_false(is_invalid, errmsg='')
  error_found!(@current_ast, errmsg) if is_invalid
end
type_assert_later(&proc) click to toggle source

Later invokes proc, which performs type checking. This is used for avoiding infinite regression when determining the type of ASTs.

# File lib/yadriggy/typecheck.rb, line 288
def type_assert_later(&proc)
  check_later(&proc)
end
type_env() click to toggle source

Gets the current type environment. @return [TypeEnv] the type enviornment.

# File lib/yadriggy/typecheck.rb, line 165
def type_env
  @current_env
end
typecheck(an_ast) click to toggle source

Applies typing rules to the given AST. It returns the type of the AST or throws a {CheckError}. This is the entry point of the type checker. It may also type the other ASTs invoked in the given AST.

It assumes that the AST is processed by Syntax and it has usertype method.

This is an alias of check_all() but it memoizes the results.

@param [ASTnode|ASTree|nil] an_ast an AST or nil. @return [Type] the type of the given AST. It memoizes the results.

# File lib/yadriggy/typecheck.rb, line 211
def typecheck(an_ast)
  check_all(an_ast)
end
typedef(key) click to toggle source

Obtains the type definition associated with `key`. Here, a type definition is a mapping from instance variables or methods to their types. It is defined per class or individual instance object. If `key` is `nil`, `nil` is returned.

@param [Module|Object|nil] key a class or an instance. @return [TypeDef|nil] the type definition.

# File lib/yadriggy/typecheck.rb, line 177
def typedef(key)
  if key.nil?
    nil
  else
    @typedefs[key]
  end
end