Skip to content
← Back

src/semantic/symbols/enum_constant.ghul

1
namespace Semantic.Symbols is
2
use IR.Values
3
4
// Builds the constant a value of an enum type is read at, at the
5
// width the enum was declared over: the full bit pattern for an
6
// enum imported with a 64-bit underlying type, and the low 32 bits
7
// for every other enum, which is what a ghūl-declared one always
8
// is.
9
//
10
// One home for the decision, because it is one fact about the enum
11
// - the underlying type only the import path records. Metadata
12
// carries an enum's value as a bit pattern, and a member of an enum
13
// wider than int32 arrives as the text of one, so both readers - a
14
// member load and a stored-value conversion - hold the pattern and
15
// differ in nothing else.
16
class ENUM_CONSTANT is
17
from_pattern(
18
enum_type: Types.Type,
19
pattern: ulong,
20
lookup: Lookups.InnateSymbolLookup
21
) -> IR.Values.Value static is
22
if _wide(enum_type, lookup) then
23
return Literal.NUMBER(Literal.CONSTANT.I8(cast long(pattern)), enum_type)
24
fi
25
26
return Literal.NUMBER(Literal.CONSTANT.I4(cast int(cast uint(pattern))), enum_type)
27
si
28
29
// The already-parsed branch of from_pattern: a member whose
30
// value fits int32 arrives as that number, and a wide enum
31
// reads it at the enum's width rather than the width it
32
// happened to parse at - a small member and a large one of the
33
// same wide enum load at one width.
34
from_number(
35
enum_type: Types.Type,
36
number: int,
37
lookup: Lookups.InnateSymbolLookup
38
) -> IR.Values.Value static is
39
if _wide(enum_type, lookup) then
40
return Literal.NUMBER(Literal.CONSTANT.I8(cast long(number)), enum_type)
41
fi
42
43
return Literal.NUMBER(Literal.CONSTANT.I4(number), enum_type)
44
si
45
46
_wide(enum_type: Types.Type, lookup: Lookups.InnateSymbolLookup) -> bool static is
47
let `enum = cast ENUM_STRUCT?(enum_type.symbol)
48
49
return `enum? /\ `enum.is_wider_than_int32(lookup)
50
si
51
si
52
si