Class: Ikra::Types::UnionType

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable, RubyType
Defined in:
lib/types/types/union_type.rb

Overview

Represents a possibly polymorphic type consisting of 0..* instances of RubyType. Only primitive types or class types are allowed for these inner types, but not union types.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from RubyType

#class_id, #eql?, #hash, #inspect, #should_generate_self_arg?, #to_array_type, #to_str

Constructor Details

#initialize(*types) ⇒ UnionType

Returns a new instance of UnionType.



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/types/types/union_type.rb', line 31

def initialize(*types)
    # Check arguments
    types.each do |type|
        if type.is_union_type?
            raise AssertionError.new(
                "Union type not allowed as inner type of union type")
        end
    end

    @types = Set.new(types)
end

Instance Attribute Details

#typesSet<RubyType>

Returns Inner types.

Returns:



19
20
21
# File 'lib/types/types/union_type.rb', line 19

def types
  @types
end

Class Method Details

.create_boolObject



215
216
217
# File 'lib/types/types/union_type.rb', line 215

def create_bool
    return new(PrimitiveType::Bool)
end

.create_floatObject



211
212
213
# File 'lib/types/types/union_type.rb', line 211

def create_float
    return new(PrimitiveType::Float)
end

.create_intObject



207
208
209
# File 'lib/types/types/union_type.rb', line 207

def create_int
    return new(PrimitiveType::Int)
end

.create_nilObject



223
224
225
# File 'lib/types/types/union_type.rb', line 223

def create_nil
    return new(PrimitiveType::Nil)
end

.create_unknownObject



227
228
229
# File 'lib/types/types/union_type.rb', line 227

def create_unknown
    return new(UnknownType::Instance)
end

.create_voidObject



219
220
221
# File 'lib/types/types/union_type.rb', line 219

def create_void
    return new(PrimitiveType::Void)
end

.parameter_hash_to_s(hash) ⇒ Object



231
232
233
234
235
# File 'lib/types/types/union_type.rb', line 231

def parameter_hash_to_s(hash)
    return hash.map do |name, type|
        name.to_s + ": " + type.to_s
    end.join(", ")
end

Instance Method Details

#<=(union_type) ⇒ Object

Alias for #include_all?



198
199
200
# File 'lib/types/types/union_type.rb', line 198

def <=(union_type)
    return union_type.include_all?(self)
end

#==(other) ⇒ Object



21
22
23
# File 'lib/types/types/union_type.rb', line 21

def ==(other)
    return other.class == self.class && other.types == self.types
end

#add(singleton_type) ⇒ Object

Adds a singleton type to this union type.

Returns:

  • True if the type was extended



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/types/types/union_type.rb', line 158

def add(singleton_type)
    if singleton_type.is_union_type?
        raise AssertionError.new("Singleton type expected")
    end

    if singleton_type == PrimitiveType::Int && include?(PrimitiveType::Float)
        # Special rule: Coerce int to float
        return false
    elsif singleton_type == PrimitiveType::Float && include?(PrimitiveType::Int)
        # Special rule: Coerce int to float
        @types.delete(PrimitiveType::Int)
        @types.add(singleton_type)
        return true
    else
        is_expanded = !@types.include?(singleton_type)
        @types.add(singleton_type)
        return is_expanded
    end
end

#c_sizeObject



75
76
77
78
79
80
81
# File 'lib/types/types/union_type.rb', line 75

def c_size
    if is_singleton?
        return @types.first.c_size
    else
        return "sizeof(union_t)"
    end
end

#clear!Object

Removes all type information.



48
49
50
# File 'lib/types/types/union_type.rb', line 48

def clear!
    @types.clear
end

#dupObject



25
26
27
28
29
# File 'lib/types/types/union_type.rb', line 25

def dup
    result = super
    result.types = @types.dup
    return result
end

#empty?Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/types/types/union_type.rb', line 43

def empty?
    return @types.empty?
end

#expand(union_type) ⇒ Bool

Merges all inner types of the argument into this union type.

Parameters:

  • union_type (UnionType)

    The other union type

Returns:

  • (Bool)

    true if the argument added new inner types to this union type



133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/types/types/union_type.rb', line 133

def expand(union_type)
    if not union_type.is_union_type?
        raise AssertionError.new(
            "Cannot expand with non-union type: #{union_type}")
    end

    is_expanded = false

    for type in union_type
        is_expanded = is_expanded | add(type)
    end

    return is_expanded
end

#expand_return_type(union_type) ⇒ UnionType

Merges all inner types of the argument into this union type.

Parameters:

  • union_type (UnionType)

    The other union type

Returns:



151
152
153
154
# File 'lib/types/types/union_type.rb', line 151

def expand_return_type(union_type)
    expand(union_type)
    return self
end

#include?(singleton_type) ⇒ Bool

Determines if this union type contains a specific singleton type.

Parameters:

  • singleton_type (RubyType)

    The other type

Returns:

  • (Bool)

    true if the type is included



181
182
183
184
185
186
187
# File 'lib/types/types/union_type.rb', line 181

def include?(singleton_type)
    if singleton_type.is_union_type?
        raise AssertionError.new("Union type can never be included in union type")
    end

    @types.include?(singleton_type)
end

#include_all?(union_type) ⇒ Boolean

Returns:

  • (Boolean)


189
190
191
192
193
194
195
# File 'lib/types/types/union_type.rb', line 189

def include_all?(union_type)
    if not union_type.is_union_type?
        raise AssertionError.new("Union type expected")
    end

    return (union_type.types - @types).size == 0
end

#is_primitive?Boolean

Returns:

  • (Boolean)


99
100
101
102
103
104
105
# File 'lib/types/types/union_type.rb', line 99

def is_primitive?
    if is_singleton?
        return @types.first.is_primitive?
    else
        return false
    end
end

#is_singleton?Boolean

Returns:

  • (Boolean)


115
116
117
# File 'lib/types/types/union_type.rb', line 115

def is_singleton?
    return @types.size == 1
end

#is_union_type?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/types/types/union_type.rb', line 107

def is_union_type?
    return true
end

#remove!(union_type) ⇒ Object

Removes all singleton types contained in ‘union_type` from this type.



53
54
55
56
57
58
59
60
61
# File 'lib/types/types/union_type.rb', line 53

def remove!(union_type)
    if union_type.is_singleton?
        raise AssertionError.new("Union type expected")
    else
        @types.delete_if do |type|
            union_type.include?(type)
        end
    end
end

#singleton_typeRubyType

Returns the single inner type or raises an error if this union type contains more than one inner type.

Returns:



121
122
123
124
125
126
127
128
# File 'lib/types/types/union_type.rb', line 121

def singleton_type
    if !is_singleton?
        raise AssertionError.new(
            "Union type is not singleton (found #{@types.size} types)")
    end

    return @types.first
end

#sizeObject



63
64
65
# File 'lib/types/types/union_type.rb', line 63

def size
    return @types.size
end

#to_c_typeObject



67
68
69
70
71
72
73
# File 'lib/types/types/union_type.rb', line 67

def to_c_type
    if is_singleton?
        return @types.first.to_c_type
    else
        return "union_t"
    end
end

#to_ffi_typeObject



91
92
93
94
95
96
97
# File 'lib/types/types/union_type.rb', line 91

def to_ffi_type
    if is_singleton?
        return @types.first.to_ffi_type
    else
        raise NotImplementedError.new
    end
end

#to_ruby_typeObject



83
84
85
86
87
88
89
# File 'lib/types/types/union_type.rb', line 83

def to_ruby_type
    if is_singleton?
        return @types.first.to_ruby_type
    else
        raise NotImplementedError.new
    end
end

#to_sObject



202
203
204
# File 'lib/types/types/union_type.rb', line 202

def to_s
    return "U{#{@types.to_a.join(", ")}}"
end

#to_union_typeObject



111
112
113
# File 'lib/types/types/union_type.rb', line 111

def to_union_type
    return self
end