class Ikra::Types::ZipStructType
This type represents the type of an array that is the result of zipping two arrays. [ZipStructType] is similar to [StructType] but can be accessed via indices.
Public Class Methods
new(*types)
click to toggle source
Calls superclass method
Ikra::Types::StructType::new
# File lib/types/types/struct_type.rb, line 76 def new(*types) identifiers = Array.new(types.size) do |index| :"field_#{index}" end super(Hash[identifiers.zip(types)]) end
Public Instance Methods
[](index)
click to toggle source
Returns the type of the element at [index].
# File lib/types/types/struct_type.rb, line 121 def [](index) return @fields[:"field_#{index}"] end
generate_definition()
click to toggle source
# File lib/translator/struct_type.rb, line 17 def generate_definition fields_def = @fields.map do |field_name, type| "#{type.to_c_type} #{field_name};" end all_fields = fields_def.join("\n") return Translator.read_file(file_name: "struct_definition.cpp", replacements: { "name" => to_c_type, "fields" => all_fields}) end
generate_inline_initialization(*input)
click to toggle source
Generates a source code expression that creates and initializes an instance of this struct.
# File lib/translator/struct_type.rb, line 12 def generate_inline_initialization(*input) field_init = input.join(", ") return "((#{to_c_type}) {#{field_init}})" end
generate_non_constant_read(receiver, selector, index_expression_identifier)
click to toggle source
# File lib/translator/struct_type.rb, line 37 def generate_non_constant_read(receiver, selector, index_expression_identifier) expression = "" for index in 0...@fields.size expression = expression + "(#{index_expression_identifier} == #{index} ? #{receiver}.field_#{index} : " end # Out of bounds case should throw and exception expression = expression + "NULL" for index in 0...@fields.size expression = expression + ")" end return expression end
generate_read(receiver, selector, index)
click to toggle source
Generates a source code expression that reads a fields of this struct by index.
# File lib/translator/struct_type.rb, line 30 def generate_read(receiver, selector, index) # Type inference already ensured that there is exactly one parameter which is # an IntLiteral. return "#{receiver}.field_#{index}" end
get_return_type(selector, *arg_nodes)
click to toggle source
Performs type inference for the result of accessing this Zip “Array” by index.
# File lib/types/types/struct_type.rb, line 86 def get_return_type(selector, *arg_nodes) # TODO: Can only handle single cases at the moment. This should eventually forward # to Array integration code. if selector != :"[]" raise AssertionError.new( "Selector not supported for ZipStructType: #{selector}") end if arg_nodes.size != 1 raise AssertionError.new("Expected exactly one argument") end if arg_nodes.first.class == AST::IntLiteralNode if arg_nodes.first.value >= @fields.size raise AssertionError.new( "ZipStruct index out of bounds: #{arg_nodes.first.value}") end return self[arg_nodes.first.value] else return get_return_type_non_constant(selector) end end
get_return_type_non_constant(selector)
click to toggle source
Performs type inference for the result of accessing this Zip “Array” by index.
# File lib/types/types/struct_type.rb, line 112 def get_return_type_non_constant(selector) # TODO: Can only handle single cases at the moment. This should eventually forward # to Array integration code. # TODO: This code assumes that the all struct elements have the same type return self[0] end
to_ruby_type()
click to toggle source
# File lib/types/types/struct_type.rb, line 155 def to_ruby_type # Cache struct types if @struct_type == nil # Create class @struct_type = Class.new(FFI::Struct) @struct_type.include(ZipStruct) # Define layout of struct var_names = Array.new(@fields.size) do |index| :"field_#{index}" end var_types = var_names.map do |name| @fields[name].to_ffi_type end layout = var_names.zip(var_types).flatten @struct_type.layout(*layout) end return @struct_type end