Appearance
| 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 |