Skip to content
← Back

src/semantic/symbols/enum_order_operator.ghul

1
namespace Semantic.Symbols is
2
// Supplies the `<>` operator for an enum type.
3
//
4
// Enums order by their underlying integer, so the comparison is the
5
// same opcode the numeric primitives use. It cannot be declared in
6
// the runtime alongside those: each enum is its own type, so there
7
// is nothing to hang a declaration on, and a declaration generic
8
// enough to cover them all also covers structs, whose values those
9
// opcodes cannot compare.
10
//
11
// Supplied as a member rather than as a global operator. The type is
12
// the one place that belongs to the enum itself, so it needs no
13
// decision about which of the two stores the innate operators occupy
14
// — the namespace when the assembly declaring them is being built,
15
// that assembly's reflected globals carrier otherwise — and it keeps
16
// one operator per enum out of every candidate list in the program.
17
//
18
// A member is also the shape an interface is satisfied by, but this
19
// is not yet enough to satisfy `Ghul.Comparable[E]`: the interface
20
// is absent from an enum's ancestors, because a .NET enum carries
21
// only the non-generic `IComparable`.
22
class ENUM_ORDER_OPERATOR is
23
register(owner: Classy) static is
24
register(owner, IoC.CONTAINER.instance.innate_symbol_lookup.get_int_type())
25
si
26
27
register(owner: Classy, int_type: Types.Type) static is
28
let type = owner.type
29
30
// An enum whose type is not built yet has nothing to compare
31
// against; nothing reaches this today, and the check is here
32
// so a caller that does gets no half-formed operator.
33
if !type? then
34
return
35
fi
36
37
let operator =
38
INNATE_METHOD(owner.location, owner, "<>", owner, "compare.order")
39
40
operator.argument_names = Collections.LIST[string](["other"])
41
operator.arguments = Collections.LIST[Types.Type]([type])
42
operator.return_type = int_type
43
44
// The comparison lowers to an opcode and writes nothing.
45
// Declared here rather than inferred: the store-free
46
// analysis classifies a function by walking its body, and
47
// this one is built as a symbol without one.
48
operator.mark_declared_pure()
49
50
owner.add_member(operator)
51
si
52
si
53
si