Class: Yadriggy::TypeChecker

Inherits:
Checker
  • Object
show all
Defined in:
lib/yadriggy/typecheck.rb

Overview

Type checker for ASTree

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”.

Direct Known Subclasses

RubyTypeChecker

Defined Under Namespace

Classes: FreeVarFinder, TypeDef, TypeEnv

Constant Summary

Constants included from Yadriggy

DynType, Undef, VERSION, Void

Instance Method Summary collapse

Methods inherited from Checker

all_rules, #apply_typing_rule, #ast, #ast_env, #check_all, check_init_class, #check_later, #error, #error_found!, find_rule_entry, #proceed, rule

Methods included from Yadriggy

debug, debug=, define_syntax, reify

Constructor Details

#initializeTypeChecker

Returns a new instance of TypeChecker.



153
154
155
156
157
# File 'lib/yadriggy/typecheck.rb', line 153

def initialize
  super
  @typetable = {}
  @typedefs = {}
end

Instance Method Details

#add_typedef(key) ⇒ TypeDef

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.

Parameters:

  • key (Module|Object)

    a class or an instance.

Returns:

  • (TypeDef)

    the type definition for the class or instance given by ‘key`.



189
190
191
# File 'lib/yadriggy/typecheck.rb', line 189

def add_typedef(key)
  @typedefs[key] || @typedefs[key] = TypeDef.new
end

#check(an_ast, ast_tenv = nil) ⇒ Object

Internal-use only. Don’t use this method. Use type().



217
218
219
# File 'lib/yadriggy/typecheck.rb', line 217

def check(an_ast, ast_tenv=nil)
  type(an_ast, ast_tenv)
end

#error_groupObject



273
274
275
# File 'lib/yadriggy/typecheck.rb', line 273

def error_group
  'type'
end

#make_base_env(klass) ⇒ Object

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



210
211
212
# File 'lib/yadriggy/typecheck.rb', line 210

def make_base_env(klass)
  TypeEnv::BaseTypeEnv.new(klass)
end

#type(an_ast, ast_tenv = nil) ⇒ Type

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

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

Parameters:

  • an_ast (ASTnode|nil)

    an AST or nil.

  • ast_tenv (TypeEnv|nil) (defaults to: nil)

    a type environment or nil.

Returns:

  • (Type)

    the type of the given AST. It memoizes the results.



231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/yadriggy/typecheck.rb', line 231

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_as(an_ast, a_type) ⇒ Object

Sets the type of an AST to the given type.

Parameters:

  • an_ast (ASTnode|nil)

    an AST.

  • a_type (Type)

    a type.

  • the (Type|nil)

    given type ‘a_type`.



249
250
251
252
253
254
255
# File 'lib/yadriggy/typecheck.rb', line 249

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 = '') ⇒ Object



257
258
259
# File 'lib/yadriggy/typecheck.rb', line 257

def type_assert(is_valid, errmsg='')
  error_found!(@current_ast, errmsg) unless is_valid
end

#type_assert_false(is_invalid, errmsg = '') ⇒ Object



261
262
263
# File 'lib/yadriggy/typecheck.rb', line 261

def type_assert_false(is_invalid, errmsg='')
  error_found!(@current_ast, errmsg) if is_invalid
end

#type_assert_later(&proc) ⇒ Object

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



269
270
271
# File 'lib/yadriggy/typecheck.rb', line 269

def type_assert_later(&proc)
  check_later(&proc)
end

#type_envObject

Gets the current type environment.



161
162
163
# File 'lib/yadriggy/typecheck.rb', line 161

def type_env
  @current_env
end

#typecheck(an_ast) ⇒ Object

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.



204
205
206
# File 'lib/yadriggy/typecheck.rb', line 204

def typecheck(an_ast)
  check_all(an_ast)
end

#typedef(key) ⇒ TypeDef|nil

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.

Parameters:

  • key (Module|Object|nil)

    a class or an instance.

Returns:

  • (TypeDef|nil)

    the type definition.



173
174
175
176
177
178
179
# File 'lib/yadriggy/typecheck.rb', line 173

def typedef(key)
  if key.nil?
    nil
  else
    @typedefs[key]
  end
end