While implementing enums in Tyr, I just realized that enum constants are the only form of literal-like entity that is not represented like a literal in the intermediate representation.
The enum concept is pretty much that of C++. I doubt that it really matters for the question. The question is, are there any benefits from having enum members as literals in the IR?
My current approach is essentially treating them like global constants that are somewhat equal to the literal values they correspond to. There are some places in the compiler with special rules projecting the enum types away.
At the moment, I'd expect that the answer doesn't even depend on the representation of the enum concept or if instances are flat values or String
literals or arbitrary Objects
.
EDIT: The question is if a literal type distinct from the literal type of the enum's base type should be introduced. In contrast to projecting the instances to the base type which wasn't the intention, but is apparently a sane interpretation of the original question.
EDIT2: The IR is used to build libraries that can be linked, compiled against and executed like JAR files in Java. The question is if a dedicated EnumLiteral expression subclass akin to an IntLiteral has any obvious advantage or disadvantage over a combination of StaticUse Expression with an EnumInstance Declaration target. Both options would bear an access path to the enum type and the underlying IntLiteral.
int32
) $\endgroup$Colour.RED
and0
, for example, but an IR used for x86 code generation does not. Likewise, if your enum members might have other underlying values depending on context, then at some compilation stages this context might not be fully known yet and hence replacing them would be impossible; consider e.g.Result<Colour, ErrorCode>
which might be implemented by renumbering one enum to prevent overlap. $\endgroup$