Class: Mirah::AST::Rescue
- Defined in:
- lib/mirah/ast/flow.rb,
lib/mirah/compiler/flow.rb,
lib/mirah/jvm/source_generator/precompile.rb
Instance Attribute Summary
Attributes inherited from Node
#children, #inferred_type, #newline, #parent, #position
Instance Method Summary collapse
- #compile(compiler, expression) ⇒ Object
- #expr?(compiler) ⇒ Boolean
- #infer(typer, expression) ⇒ Object
-
#initialize(parent, position, &block) ⇒ Rescue
constructor
A new instance of Rescue.
Methods inherited from Node
#<<, ===, #[], #[]=, #_dump, _load, #_set_parent, child, child_name, #child_nodes, #each, #empty?, #inferred_type!, #initialize_copy, #insert, #inspect, #inspect_children, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #string_value, #temp, #to_s, #top_level?, #validate_child, #validate_children
Constructor Details
#initialize(parent, position, &block) ⇒ Rescue
Returns a new instance of Rescue.
321 322 323 |
# File 'lib/mirah/ast/flow.rb', line 321 def initialize(parent, position, &block) super(parent, position, &block) end |
Instance Method Details
#compile(compiler, expression) ⇒ Object
92 93 94 95 96 97 |
# File 'lib/mirah/compiler/flow.rb', line 92 def compile(compiler, expression) compiler.line(line_number) compiler.rescue(self, expression) rescue Exception => ex raise Mirah::InternalCompilerError.wrap(ex, self) end |
#expr?(compiler) ⇒ Boolean
188 189 190 |
# File 'lib/mirah/jvm/source_generator/precompile.rb', line 188 def expr?(compiler) false end |
#infer(typer, expression) ⇒ Object
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
# File 'lib/mirah/ast/flow.rb', line 325 def infer(typer, expression) unless resolved? # TODO: generalize this s.t. # the problem with deferred inference # assuming expression == true is dealt with @expression = expression if @expression == nil expression = @expression primary_type = if else_node typer.infer(body, false) if body typer.infer(else_node, expression) elsif body typer.infer(body, expression) end clause_types = clauses.map {|c| typer.infer(c, expression)} types = [] types << primary_type if primary_type types += clause_types if types.any? {|t| t.nil?} typer.defer(self) else if !expression || clause_types.all?{ |t| primary_type.compatible? t} resolved! types.each do |type| @inferred_type ||= type unless type.unreachable? end @inferred_type ||= primary_type else clause, clause_type = clauses.zip(clause_types).find{ |clause, t| !primary_type.compatible? t } raise Mirah::Typer::InferenceError.new("rescue statement with incompatible result types #{primary_type} and #{clause_type}", clause) end end end @inferred_type end |