Class: Yadriggy::Checker
- Inherits:
-
Object
- Object
- Yadriggy::Checker
- Includes:
- Yadriggy
- Defined in:
- lib/yadriggy/checker.rb
Overview
AST checker. It visits the AST nodes and does various checks like type checking.
Direct Known Subclasses
Yadriggy::C::CodeGen, PrettyPrinter, Py::CodeGen, TypeChecker
Constant Summary
Constants included from Yadriggy
Class Method Summary collapse
-
.rule(node_type) { ... } ⇒ void
Defines the rule for a node type.
Instance Method Summary collapse
-
#ast ⇒ ASTnode
The current abstract syntax tree.
-
#ast_env ⇒ Object
The current environment.
-
#check(an_ast, ast_env = nil) ⇒ Object
Applies rules to the given AST.
-
#check_all(an_ast) ⇒ Object
Applies rules to the given AST.
-
#check_later { ... } ⇒ void
Later invokes the block, which performs checking.
-
#error!(an_ast, msg = '') ⇒ Object
Records an error message.
-
#error_found!(an_ast, msg = '') ⇒ void
Throws an error.
-
#error_messages ⇒ Array<String>
Gets an array of error messages.
-
#errors? ⇒ Boolean
Tests whether a type error was found.
-
#initialize ⇒ Checker
constructor
Initializes the object.
-
#last_error ⇒ String|nil
The last error message.
-
#make_base_env(klass) ⇒ Object
Makes a new base environment with the given context class.
-
#proceed(an_ast, envi = nil) ⇒ Type
Applies the rule supplied by the superclass.
Methods included from Yadriggy
debug, debug=, define_syntax, reify
Constructor Details
#initialize ⇒ Checker
Initializes the object.
78 79 80 81 82 83 84 85 86 |
# File 'lib/yadriggy/checker.rb', line 78 def initialize self.class.check_init_class @nerrors = 0 = [] @check_list = [] @current_ast = nil @current_env = nil @rule_declarator = nil end |
Class Method Details
.rule(node_type) { ... } ⇒ void
This method returns an undefined value.
Defines the rule for a node type.
21 22 23 24 25 |
# File 'lib/yadriggy/checker.rb', line 21 def self.rule(node_type, &proc) init_class if @rules.nil? @rules[node_type] = proc @rule_declarators[node_type] = self end |
Instance Method Details
#ast ⇒ ASTnode
Returns the current abstract syntax tree.
228 229 230 |
# File 'lib/yadriggy/checker.rb', line 228 def ast @current_ast end |
#ast_env ⇒ Object
Returns the current environment.
233 234 235 |
# File 'lib/yadriggy/checker.rb', line 233 def ast_env @current_env end |
#check(an_ast, ast_env = nil) ⇒ Object
Applies rules to the given AST.
It assumes that ast is processed by Syntax and it has usertype method. An exception is thrown when the checking fails. ast may be nil.
The environment given to this method can be accessed in the rules through ast_env(). It is optional and can be any object. The initial one is made by make_base_env().
181 182 183 184 185 186 187 188 |
# File 'lib/yadriggy/checker.rb', line 181 def check(an_ast, ast_env=nil) if an_ast.nil? nil else rule = self.class.find_rule_entry(an_ast) apply_typing_rule(rule, an_ast, ast_env) end end |
#check_all(an_ast) ⇒ Object
Applies rules to the given AST. It returns the result of the rule-application or throws a CheckError. This is the entry point of the checker. It may also check the other ASTs invoked in the given AST.
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/yadriggy/checker.rb', line 152 def check_all(an_ast) return nil if an_ast.nil? an_ast = an_ast.tree if an_ast.is_a?(ASTree) t = check(an_ast, make_base_env(an_ast.get_context_class)) until (checked = @check_list.pop).nil? @current_ast = checked[0] @current_env = checked[1] checked[2].call end t end |
#check_later { ... } ⇒ void
This method returns an undefined value.
Later invokes the block, which performs checking. The method immediately returns. This is used for avoiding infinite regression during the checking.
242 243 244 245 246 |
# File 'lib/yadriggy/checker.rb', line 242 def check_later(&proc) cur_ast = @current_ast cur_env = @current_env @check_list << [cur_ast, cur_env, proc] end |
#error!(an_ast, msg = '') ⇒ Object
Records an error message.
124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/yadriggy/checker.rb', line 124 def error!(an_ast, msg='') loc = if an_ast.is_a?(ASTnode) an_ast.source_location_string else '' end emsg = "#{loc} DSL #{error_group} error. #{msg}" @nerrors += 1 << emsg binding.pry if Yadriggy.debug > 1 emsg end |
#error_found!(an_ast, msg = '') ⇒ void
This method returns an undefined value.
Throws an error.
114 115 116 117 |
# File 'lib/yadriggy/checker.rb', line 114 def error_found!(an_ast, msg='') emsg = error!(an_ast, msg) raise CheckError.new(emsg) end |
#error_messages ⇒ Array<String>
Gets an array of error messages.
98 99 100 |
# File 'lib/yadriggy/checker.rb', line 98 def end |
#errors? ⇒ Boolean
Tests whether a type error was found.
91 92 93 |
# File 'lib/yadriggy/checker.rb', line 91 def errors? @nerrors > 0 end |
#last_error ⇒ String|nil
The last error message.
105 106 107 |
# File 'lib/yadriggy/checker.rb', line 105 def last_error .last end |
#make_base_env(klass) ⇒ Object
Makes a new base environment with the given context class.
166 167 168 |
# File 'lib/yadriggy/checker.rb', line 166 def make_base_env(klass) klass end |
#proceed(an_ast, envi = nil) ⇒ Type
Applies the rule supplied by the superclass.
214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/yadriggy/checker.rb', line 214 def proceed(an_ast, envi=nil) rule = if @rule_declarator&.superclass == Object nil else @rule_declarator&.superclass.find_rule_entry(an_ast) end if rule.nil? error_found!(an_ast, 'no more rule. we cannot proceed') else apply_typing_rule(rule, an_ast, envi) end end |