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.
7024 7025 7026 |
# File 'lib/idlc/ast.rb', line 7024 def initialize(input, interval, return_expression, condition) super(input, interval, [return_expression, condition]) end |
Class Method Details
.from_h(yaml, source_mapper) ⇒ Object
7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 |
# File 'lib/idlc/ast.rb', line 7081 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
7022 |
# File 'lib/idlc/ast.rb', line 7022 def condition = @children[1] |
#const_eval?(symtab) ⇒ Boolean
7019 |
# File 'lib/idlc/ast.rb', line 7019 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
7021 |
# File 'lib/idlc/ast.rb', line 7021 def return_expression = @children[0] |
#return_type(symtab) ⇒ Type
Returns The actual return type.
7036 7037 7038 |
# File 'lib/idlc/ast.rb', line 7036 def return_type(symtab) return_expression.return_type(symtab) end |
#return_types(symtab) ⇒ Array<Type>
Returns List of actual return types.
7041 7042 7043 |
# File 'lib/idlc/ast.rb', line 7041 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
7047 7048 7049 7050 7051 7052 7053 |
# File 'lib/idlc/ast.rb', line 7047 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
7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 |
# File 'lib/idlc/ast.rb', line 7056 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
7073 7074 7075 7076 7077 7078 |
# File 'lib/idlc/ast.rb', line 7073 def to_h = { "kind" => "conditional_stmt", "condition" => condition.to_h, "expr" => return_expression.to_h, "source" => source_yaml } |
#to_idl ⇒ Object
7070 |
# File 'lib/idlc/ast.rb', line 7070 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
7029 7030 7031 7032 7033 |
# File 'lib/idlc/ast.rb', line 7029 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 |