Class: Yadriggy::TypeChecker
- Defined in:
- lib/yadriggy/typecheck.rb
Overview
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".
Direct Known Subclasses
Defined Under Namespace
Classes: FreeVarFinder, TypeDef, TypeEnv
Constant Summary
Constants included from Yadriggy
Instance Method Summary collapse
-
#add_typedef(key) ⇒ TypeDef
Adds a type definition if it does not exist.
- #error_group ⇒ Object
-
#initialize ⇒ TypeChecker
constructor
A new instance of TypeChecker.
-
#make_base_env(klass) ⇒ TypeEnv
Makes a new base type environment with the given context class.
-
#type(an_ast, ast_tenv = nil) ⇒ Type
Applies typing rules to determine the type of the given AST.
-
#type?(an_ast) ⇒ Type|nil
Gets the type of the given AST if its type has been already determined by #type.
-
#type_as(an_ast, a_type) ⇒ Type|DynType
Sets the type of an AST to the given type.
- #type_assert(is_valid, errmsg = '') ⇒ Object
- #type_assert_false(is_invalid, errmsg = '') ⇒ Object
-
#type_assert_later(&proc) ⇒ Object
Later invokes proc, which performs type checking.
-
#type_env ⇒ TypeEnv
Gets the current type environment.
-
#typecheck(an_ast) ⇒ Type
Applies typing rules to the given AST.
-
#typedef(key) ⇒ TypeDef|nil
Obtains the type definition associated with
key
.
Methods inherited from Checker
#ast, #ast_env, #check_all, #check_later, #error!, #error_found!, #error_messages, #errors?, #last_error, #proceed, rule
Methods included from Yadriggy
debug, debug=, define_syntax, reify, reset_pry
Constructor Details
#initialize ⇒ TypeChecker
Returns a new instance of TypeChecker.
156 157 158 159 160 |
# File 'lib/yadriggy/typecheck.rb', line 156 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.
193 194 195 |
# File 'lib/yadriggy/typecheck.rb', line 193 def add_typedef(key) @typedefs[key] || @typedefs[key] = TypeDef.new end |
#error_group ⇒ Object
292 293 294 |
# File 'lib/yadriggy/typecheck.rb', line 292 def error_group 'type' end |
#make_base_env(klass) ⇒ TypeEnv
Makes a new base type environment with the given context class.
219 220 221 |
# File 'lib/yadriggy/typecheck.rb', line 219 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.
240 241 242 243 244 245 246 247 248 249 250 251 |
# 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) ⇒ Type|nil
Gets the type of the given AST if its type has been already determined by #type. Only the memoized types are returned.
272 273 274 |
# File 'lib/yadriggy/typecheck.rb', line 272 def type?(an_ast) @typetable[an_ast] end |
#type_as(an_ast, a_type) ⇒ Type|DynType
Sets the type of an AST to the given type.
258 259 260 261 262 263 264 |
# 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 = '') ⇒ Object
276 277 278 |
# 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 = '') ⇒ Object
280 281 282 |
# 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) ⇒ Object
Later invokes proc, which performs type checking. This is used for avoiding infinite regression when determining the type of ASTs.
288 289 290 |
# File 'lib/yadriggy/typecheck.rb', line 288 def type_assert_later(&proc) check_later(&proc) end |
#type_env ⇒ TypeEnv
Gets the current type environment.
165 166 167 |
# File 'lib/yadriggy/typecheck.rb', line 165 def type_env @current_env end |
#typecheck(an_ast) ⇒ Type
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.
211 212 213 |
# File 'lib/yadriggy/typecheck.rb', line 211 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.
177 178 179 180 181 182 183 |
# File 'lib/yadriggy/typecheck.rb', line 177 def typedef(key) if key.nil? nil else @typedefs[key] end end |