Class: Idl::FunctionBodyAst
- Includes:
- Executable, Returns
- Defined in:
- lib/idl/ast.rb
Instance Method Summary collapse
-
#execute_unknown(symtab) ⇒ void
included
from Executable
“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.
-
#initialize(input, interval, stmts) ⇒ FunctionBodyAst
constructor
A new instance of FunctionBodyAst.
- #return_value(symtab) ⇒ Object (also: #execute)
- #return_values(symtab) ⇒ Object
- #statements ⇒ Object
- #stmts ⇒ Object
- #to_idl ⇒ Object
-
#type_check(symtab) ⇒ void
type check this node and all children.
Constructor Details
#initialize(input, interval, stmts) ⇒ FunctionBodyAst
Returns a new instance of FunctionBodyAst.
4729 4730 4731 |
# File 'lib/idl/ast.rb', line 4729 def initialize(input, interval, stmts) super(input, interval, stmts) end |
Instance Method Details
#execute_unknown(symtab) ⇒ void Originally defined in module Executable
This method returns an undefined value.
“execute” the statement, forcing any variable assignments to an unknown state This is used down unknown conditional paths.
#return_value(symtab) ⇒ Object Also known as: execute
Note:
arguments and template arguments must be put on the symtab before calling
4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 |
# File 'lib/idl/ast.rb', line 4764 def return_value(symtab) internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2 # go through the statements, and return the first one that has a return value stmts.each do |s| if s.is_a?(Returns) v = s.return_value(symtab) return v unless v.nil? else s.execute(symtab) end end value_error "No function body statement returned a value" end |
#return_values(symtab) ⇒ Object
4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 |
# File 'lib/idl/ast.rb', line 4782 def return_values(symtab) internal_error "Function bodies should be at global + 1 scope" unless symtab.levels == 2 values = [] value_result = value_try do # if there is a definate return value, then just return that return [return_value(symtab)] end value_else(value_result) do # go through the statements, and collect return values # we can stop if we encounter a statement with a known return value stmts.each do |s| if s.is_a?(Returns) value_result = value_try do v = s.return_value(symtab) return values.push(v).uniq unless v.nil? end value_else(value_result) do values += s.return_values(symtab) end else s.execute(symtab) end end end values.uniq end |
#statements ⇒ Object
4733 |
# File 'lib/idl/ast.rb', line 4733 def statements = @children |
#stmts ⇒ Object
4735 |
# File 'lib/idl/ast.rb', line 4735 def stmts = @children |
#to_idl ⇒ Object
4811 4812 4813 4814 4815 4816 4817 4818 |
# File 'lib/idl/ast.rb', line 4811 def to_idl result = "" # go through the statements, and return the first one that has a return value stmts.each do |s| result << s.to_idl end result end |
#type_check(symtab) ⇒ 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
4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 |
# File 'lib/idl/ast.rb', line 4738 def type_check(symtab) internal_error "Function bodies should be at global + 1 scope (at #{symtab.levels})" unless symtab.levels == 2 return_value_might_be_known = true stmts.each do |s| s.type_check(symtab) # next unless return_value_might_be_known # begin # if s.is_a?(Returns) # s.return_value(symtab) # # if we reach here, the return value is known, so we don't have to go futher # break # else # s.execute(symtab) # end # rescue ValueError # return_value_might_be_known = false # end end end |