Skip to content
← Back

src/semantic/symbols/enum_equality_operator.ghul

1
namespace Semantic.Symbols is
2
// Supplies the `=~` operator for an enum type.
3
//
4
// Enums compare for equality by their underlying integer, the same
5
// opcode the numeric primitives use. It cannot be declared in the
6
// runtime alongside those for the same reason `<>` cannot: each enum
7
// is its own type, so there is nothing to hang a declaration on, and a
8
// declaration generic enough to cover them all also covers structs.
9
//
10
// Mirrors `ENUM_ORDER_OPERATOR`, which supplies `<>` for the same
11
// types via `compare.order`. This supplies `=~` via `compare.value`,
12
// the innate that emits `ceq` and already backs `==` on enums. `!~`
13
// reaches the same innate with `actual_operation` `!~`; the innate
14
// negates it there, as it does for `!=`.
15
class ENUM_EQUALITY_OPERATOR is
16
register(owner: Classy) static is
17
register(owner, IoC.CONTAINER.instance.innate_symbol_lookup.get_bool_type())
18
si
19
20
register(owner: Classy, bool_type: Types.Type) static is
21
let type = owner.type
22
23
// An enum whose type is not built yet has nothing to compare
24
// against; nothing reaches this today, and the check is here
25
// so a caller that does gets no half-formed operator.
26
if !type? then
27
return
28
fi
29
30
let operator =
31
INNATE_METHOD(owner.location, owner, "=~", owner, "compare.value")
32
33
operator.argument_names = Collections.LIST[string](["other"])
34
operator.arguments = Collections.LIST[Types.Type]([type])
35
operator.return_type = bool_type
36
37
// The comparison lowers to an opcode and writes nothing.
38
// Declared here rather than inferred: the store-free
39
// analysis classifies a function by walking its body, and
40
// this one is built as a symbol without one.
41
operator.mark_declared_pure()
42
43
owner.add_member(operator)
44
si
45
si
46
si