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