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) ⇒ Object
Applies the rule supplied by the superclass.
Methods included from Yadriggy
debug, debug=, define_syntax, reify, reset_pry
Constructor Details
#initialize ⇒ Checker
Initializes the object.
80 81 82 83 84 85 86 87 88 |
# File 'lib/yadriggy/checker.rb', line 80 def initialize self.class.check_init_class @nerrors = 0 @messages = [] @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.
233 234 235 |
# File 'lib/yadriggy/checker.rb', line 233 def ast @current_ast end |
#ast_env ⇒ Object
Returns the current environment.
238 239 240 |
# File 'lib/yadriggy/checker.rb', line 238 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().
186 187 188 189 190 191 192 193 |
# File 'lib/yadriggy/checker.rb', line 186 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.
154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/yadriggy/checker.rb', line 154 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.
247 248 249 250 251 |
# File 'lib/yadriggy/checker.rb', line 247 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.
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/yadriggy/checker.rb', line 126 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 @messages << emsg binding.pry if Yadriggy.debug > 1 emsg end |
#error_found!(an_ast, msg = '') ⇒ void
This method returns an undefined value.
Throws an error.
116 117 118 119 |
# File 'lib/yadriggy/checker.rb', line 116 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.
100 101 102 |
# File 'lib/yadriggy/checker.rb', line 100 def @messages end |
#errors? ⇒ Boolean
Tests whether a type error was found.
93 94 95 |
# File 'lib/yadriggy/checker.rb', line 93 def errors? @nerrors > 0 end |
#last_error ⇒ String|nil
The last error message.
107 108 109 |
# File 'lib/yadriggy/checker.rb', line 107 def last_error @messages.last end |
#make_base_env(klass) ⇒ Object
Makes a new base environment with the given context class.
It is called by check_all
. Override this method to customize
check_all
.
171 172 173 |
# File 'lib/yadriggy/checker.rb', line 171 def make_base_env(klass) klass end |
#proceed(an_ast, envi = nil) ⇒ Object
Applies the rule supplied by the superclass.
219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/yadriggy/checker.rb', line 219 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 |