Class: Idl::ReturnExpressionAst

Inherits:
AstNode
  • Object
show all
Defined in:
lib/idl/ast.rb

Instance Method Summary collapse

Constructor Details

#initialize(input, interval, return_nodes) ⇒ ReturnExpressionAst

Returns a new instance of ReturnExpressionAst.



3960
3961
3962
3963
# File 'lib/idl/ast.rb', line 3960

def initialize(input, interval, return_nodes)
  super(input, interval, return_nodes)
  @func_type_cache = {}
end

Instance Method Details

#enclosing_functionObject



4036
4037
4038
# File 'lib/idl/ast.rb', line 4036

def enclosing_function
  find_ancestor(FunctionDefAst)
end

#expected_return_type(symtab) ⇒ Type

Returns The expected return type (as defined by the encolsing function).

Returns:

  • (Type)

    The expected return type (as defined by the encolsing function)



3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
# File 'lib/idl/ast.rb', line 3985

def expected_return_type(symtab)
  func_def = find_ancestor(FunctionDefAst)
  if func_def.nil?
    if symtab.get("__expected_return_type").nil?
      internal_error "Forgot to set __expected_return_type in the symbol table"
    end

    symtab.get("__expected_return_type")
  else
    # need to find the type to get the right symbol table
    func_type = @func_type_cache[symtab.archdef]
    return func_type.return_type(EMPTY_ARRAY, self) unless func_type.nil?

    func_type = symtab.get_global(func_def.name)
    internal_error "Couldn't find function type for '#{func_def.name}' #{symtab.keys} " if func_type.nil?

    # to get the return type, we need to find the template values in case this is
    # a templated function definition
    #
    # that information should be up the stack in the symbol table
    if func_type.templated?
      template_values = symtab.find_all(single_scope: true) do |o|
        o.is_a?(Var) && o.template_value_for?(func_def.name)
      end
      unless template_values.size == func_type.template_names.size
        internal_error "Did not find correct number of template arguments (found #{template_values.size}, need #{func_type.template_names.size}) #{symtab.keys_pretty}"
      end
      func_type.return_type(template_values.sort { |a, b| a.template_index <=> b.template_index }.map(&:value), self)
    else
      @func_type_cache[symtab.archdef]= func_type
      func_type.return_type(EMPTY_ARRAY, self)
    end
  end
end

#return_type(symtab) ⇒ Object



3975
3976
3977
3978
3979
3980
3981
3982
# File 'lib/idl/ast.rb', line 3975

def return_type(symtab)
  types = return_types(symtab)
  if types.size > 1
    Type.new(:tuple, tuple_types: types)
  else
    types[0]
  end
end

#return_types(symtab) ⇒ Array<Type>

Returns List of actual return types.

Returns:

  • (Array<Type>)

    List of actual return types



3966
3967
3968
3969
3970
3971
3972
# File 'lib/idl/ast.rb', line 3966

def return_types(symtab)
  if return_value_nodes[0].type(symtab).kind == :tuple
    return_value_nodes[0].type(symtab).tuple_types
  else
    return_value_nodes.map{ |v| v.type(symtab) }
  end
end

#return_value(symtab) ⇒ Object



4041
4042
4043
4044
4045
4046
4047
# File 'lib/idl/ast.rb', line 4041

def return_value(symtab)
  if return_value_nodes.size == 1
    return_value_nodes[0].value(symtab)
  else
    return_value_nodes.map { |v| v.value(symtab) }
  end
end

#return_value_nodesObject



3958
# File 'lib/idl/ast.rb', line 3958

def return_value_nodes = @children

#return_values(symtab) ⇒ Object



4050
4051
4052
4053
4054
4055
4056
# File 'lib/idl/ast.rb', line 4050

def return_values(symtab)
  if return_value_nodes.size == 1
    return_value_nodes[0].values(symtab)
  else
    return_value_nodes.map { |v| v.values(symtab) }
  end
end

#to_idlObject



4058
# File 'lib/idl/ast.rb', line 4058

def to_idl = "return #{return_value_nodes.map(&:to_idl).join(',')}"

#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

Parameters:

Raises:



4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
# File 'lib/idl/ast.rb', line 4021

def type_check(symtab)
  return_value_nodes.each do |v|
    v.type_check(symtab)
    type_error "Unknown type for #{v.text_value}" if v.type(symtab).nil?
  end

  if return_value_nodes[0].type(symtab).kind == :tuple
    type_error("Can't combine tuple types in return") unless return_value_nodes.size == 1
  end

  unless return_type(symtab).convertable_to?(expected_return_type(symtab))
    type_error "Return type (#{return_type(symtab)}) not convertable to expected return type (#{expected_return_type(symtab)})"
  end
end