Class: Duby::AST::If
- Defined in:
- lib/duby/ast/flow.rb,
lib/duby/compiler.rb,
lib/duby/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) ⇒ Object
-
#initialize(parent, line_number, &block) ⇒ If
constructor
A new instance of If.
Methods inherited from Node
#<<, ===, #[], #_set_parent, child, child_name, #each, #empty?, #initialize_copy, #insert, #inspect, #line_number, #log, #precompile, #resolve_if, #resolved!, #resolved?, #simple_name, #temp, #to_s
Constructor Details
#initialize(parent, line_number, &block) ⇒ If
Returns a new instance of If.
34 35 36 |
# File 'lib/duby/ast/flow.rb', line 34 def initialize(parent, line_number, &block) super(parent, line_number, &block) end |
Instance Method Details
#compile(compiler, expression) ⇒ Object
176 177 178 179 |
# File 'lib/duby/compiler.rb', line 176 def compile(compiler, expression) compiler.line(line_number) compiler.branch(self, expression) end |
#expr?(compiler) ⇒ Boolean
50 51 52 53 54 55 |
# File 'lib/duby/jvm/source_generator/precompile.rb', line 50 def expr?(compiler) return false unless condition.predicate.expr?(compiler) return false unless body.nil? || body.expr?(compiler) return false unless self.else.nil? || self.else.expr?(compiler) true end |
#infer(typer) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/duby/ast/flow.rb', line 38 def infer(typer) unless resolved? condition_type = typer.infer(condition) unless condition_type typer.defer(condition) end # condition type is unrelated to body types, so we proceed with bodies then_type = typer.infer(body) if body if !then_type # attempt to determine else branch if self.else else_type = typer.infer(self.else) if !else_type # we have neither type, defer until later typer.defer(self) else # we have else but not then, defer only then and use else type for now @inferred_type = else_type if body typer.defer(self) else resolved! if condition_type end end else # no then type could be inferred and no else body, defer for now typer.defer(self) end else if self.else else_type = typer.infer(self.else) if !else_type # we determined a then type, so we use that and defer the else body @inferred_type = then_type typer.defer(self) else # both then and else inferred, ensure they're compatible if then_type.compatible?(else_type) # types are compatible...if condition is resolved, we're done @inferred_type = then_type.narrow(else_type) resolved! if condition_type else raise Typer::InferenceError.new("if statement with incompatible result types") end end else # only then and type inferred, we're 100% resolved @inferred_type = then_type resolved! if condition_type end end end @inferred_type end |