Class: Idl::ConditionalReturnStatementAst
- Includes:
- Returns
- Defined in:
- lib/idlc/ast.rb,
lib/idlc/passes/prune.rb,
lib/idlc/passes/gen_adoc.rb,
lib/idlc/passes/reachable_functions.rb,
lib/idlc/passes/reachable_exceptions.rb
Constant Summary
Constants inherited from AstNode
AstNode::Bits1Type, AstNode::Bits32Type, AstNode::Bits64Type, AstNode::BoolType, AstNode::ConstBoolType, AstNode::PossiblyUnknownBits1Type, AstNode::PossiblyUnknownBits32Type, AstNode::PossiblyUnknownBits64Type, AstNode::ReachableFunctionCacheType, AstNode::StringType, AstNode::VoidType
Instance Attribute Summary
Attributes inherited from AstNode
#children, #input, #interval, #parent
Class Method Summary collapse
Instance Method Summary collapse
- #condition ⇒ Object
- #const_eval?(symtab) ⇒ Boolean
- #gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
-
#initialize(input, interval, return_expression, condition) ⇒ ConditionalReturnStatementAst
constructor
A new instance of ConditionalReturnStatementAst.
- #prune(symtab, forced_type: nil) ⇒ Object
- #reachable_exceptions(symtab, cache = {}) ⇒ Object
- #reachable_functions(symtab, cache = T.let({}, ReachableFunctionCacheType)) ⇒ Object
- #return_expression ⇒ Object
-
#return_type(symtab) ⇒ Type
The actual return type.
-
#return_types(symtab) ⇒ Array<Type>
List of actual return types.
-
#return_value(symtab) ⇒ Integer, ...
Evaluate the compile-time return value of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on the taken path), execute the node and update the symtab.
-
#return_values(symtab) ⇒ Array<Integer>, Array<Boolean>
Evaluate all possible compile-time return values of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on a possible path), execute the node and update the symtab.
- #to_h ⇒ Object
- #to_idl ⇒ Object
-
#type_check(symtab, strict:) ⇒ void
type check this node and all children.
Methods included from Returns
Methods inherited from AstNode
#always_terminates?, #declaration?, #executable?, extract_base_var_name, #find_ancestor, #find_dst_registers, #find_referenced_csrs, #find_src_registers, #freeze_tree, #gen_option_adoc, #input_file, input_from_source_yaml, #inspect, #internal_error, interval_from_source_yaml, #lineno, #lines_around, #nullify_assignments, #pass_find_return_values, #path, #print_ast, #set_input_file, #set_input_file_unless_already_set, #source_line_file_offsets, #source_starting_offset, #source_yaml, #starting_line, #text_value, #truncation_warn, #type_error, #unindent, value_else, #value_else, value_error, #value_error, value_try, #value_try, write_back_nested
Constructor Details
#initialize(input, interval, return_expression, condition) ⇒ ConditionalReturnStatementAst
Returns a new instance of ConditionalReturnStatementAst.
7039 7040 7041 |
# File 'lib/idlc/ast.rb', line 7039 def initialize(input, interval, return_expression, condition) super(input, interval, [return_expression, condition]) end |
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 |
# File 'lib/idlc/ast.rb', line 7096 def self.from_h(yaml, source_mapper) raise "Bad YAML" unless yaml.key?("kind") && yaml.fetch("kind") == "conditional_stmt" input = input_from_source_yaml(yaml.fetch("source"), source_mapper) interval = interval_from_source_yaml(yaml.fetch("source")) ConditionalReturnStatementAst.new( input, interval, AstNode.from_h(yaml.fetch("expr"), source_mapper), AstNode.from_h(yaml.fetch("condition"), source_mapper) ) end |
Instance Method Details
#condition ⇒ Object
7037 |
# File 'lib/idlc/ast.rb', line 7037 def condition = @children[1] |
#const_eval?(symtab) ⇒ Boolean
7034 |
# File 'lib/idlc/ast.rb', line 7034 def const_eval?(symtab) = condition.const_eval?(symtab) && return_expression.const_eval?(symtab) |
#gen_adoc(indent = 0, indent_spaces: 2) ⇒ Object
30 31 32 |
# File 'lib/idlc/passes/gen_adoc.rb', line 30 def gen_adoc(indent = 0, indent_spaces: 2) "#{' ' * indent}#{return_expression.gen_adoc(indent, indent_spaces:)} if (#{condition.gen_adoc(0, indent_spaces:)});" end |
#prune(symtab, forced_type: nil) ⇒ Object
596 597 598 599 600 601 602 603 604 605 606 607 |
# File 'lib/idlc/passes/prune.rb', line 596 def prune(symtab, forced_type: nil) value_result = value_try do if condition.value(symtab) return return_expression.prune(symtab) else return NoopAst.new end end value_else(value_result) do ConditionalReturnStatementAst.new(input, interval, return_expression.prune(symtab), condition.prune(symtab)) end end |
#reachable_exceptions(symtab, cache = {}) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/idlc/passes/reachable_exceptions.rb', line 143 def reachable_exceptions(symtab, cache = {}) mask = condition.is_a?(FunctionCallExpressionAst) ? condition.reachable_exceptions(symtab, cache) : 0 value_result = value_try do if condition.value(symtab) mask |= return_expression.is_a?(FunctionCallExpressionAst) ? return_expression.reachable_exceptions(symtab, cache) : 0 # ok end end value_else(value_result) do mask |= return_expression.is_a?(FunctionCallExpressionAst) ? return_expression.reachable_exceptions(symtab, cache) : 0 end mask end |
#reachable_functions(symtab, cache = T.let({}, ReachableFunctionCacheType)) ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/idlc/passes/reachable_functions.rb', line 160 def reachable_functions(symtab, cache = T.let({}, ReachableFunctionCacheType)) fns = condition.is_a?(FunctionCallExpressionAst) ? condition.reachable_functions(symtab, cache) : [] value_result = value_try do cv = condition.value(symtab) if cv fns.concat return_expression.reachable_functions(symtab, cache) end end value_else(value_result) do fns.concat return_expression.reachable_functions(symtab, cache) end fns end |
#return_expression ⇒ Object
7036 |
# File 'lib/idlc/ast.rb', line 7036 def return_expression = @children[0] |
#return_type(symtab) ⇒ Type
Returns The actual return type.
7051 7052 7053 |
# File 'lib/idlc/ast.rb', line 7051 def return_type(symtab) return_expression.return_type(symtab) end |
#return_types(symtab) ⇒ Array<Type>
Returns List of actual return types.
7056 7057 7058 |
# File 'lib/idlc/ast.rb', line 7056 def return_types(symtab) return_expression.return_types(symtab) end |
#return_value(symtab) ⇒ Integer, ...
Evaluate the compile-time return value of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on the taken path), execute the node and update the symtab
7062 7063 7064 7065 7066 7067 7068 |
# File 'lib/idlc/ast.rb', line 7062 def return_value(symtab) cond = condition.value(symtab) if cond return_expression.return_value(symtab) end end |
#return_values(symtab) ⇒ Array<Integer>, Array<Boolean>
Evaluate all possible compile-time return values of this node, or, if the node does not return (e.g., because it is an IfAst but there is no return on a possible path), execute the node and update the symtab
7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 |
# File 'lib/idlc/ast.rb', line 7071 def return_values(symtab) value_result = value_try do cond = condition.value(symtab) return cond ? return_expression.return_values(symtab) : EMPTY_ARRAY end value_else(value_result) do # condition isn't known, so the return value is always possible return_expression.return_values(symtab) end end |
#to_h ⇒ Object
7088 7089 7090 7091 7092 7093 |
# File 'lib/idlc/ast.rb', line 7088 def to_h = { "kind" => "conditional_stmt", "condition" => condition.to_h, "expr" => return_expression.to_h, "source" => source_yaml } |
#to_idl ⇒ Object
7085 |
# File 'lib/idlc/ast.rb', line 7085 def to_idl = "#{return_expression.to_idl} if (#{condition.to_idl});" |
#type_check(symtab, strict:) ⇒ void
This method returns an undefined value.
type check this node and all children
Calls to #type and/or #value may depend on type_check being called first with the same symtab. If not, those functions may raise an AstNode::InternalError
7044 7045 7046 7047 7048 |
# File 'lib/idlc/ast.rb', line 7044 def type_check(symtab, strict:) condition.type_check(symtab, strict:) type_error "Condition must be boolean" unless condition.type(symtab).kind == :boolean return_expression.type_check(symtab, strict:) end |