# Plan: CFA Typed Enum
## Introduction
CFA allows users to define enum with any type, and an enum's value is a subset of its supertype. The basic syntax of defining a typed enum is the follows:
enum(Typename) EnumNameopt = { enumerator-list }
or
, where enumerator-list is a list of identifier or identifier = const-expression.
## CFA Typed Enum vs C Enum vs C++ Enum
In C, an enum variable declaration is isomorphic to an integer declaration. For example,
enum EnumType VariableName = EnumValue;
is equivalent to
int VariableName = EnumValue;
For backward capatability, we perserve this behaviour in CFA. This is different from an C++ interpretation. C++ disallow an assignment to an enum variable with a value from the base type without an explicit cast. However, if a user defines an enum E using the typed syntax:
enum E(int) = EnumValue;
Now E is a proper subset of int type. The compiler will stop you from assignment an integer value of a variable with type E, as in C++.
Since C++11, C++ supports enum definition with an enum base.
enum EnumName : enum-base = { enumerator-list };
An enum base is a sequence of basic integral type specifier.
enum E: char {A='a'};
E e = A;
cout << e << end;
Will print a character 'a' to the output instead of 97.
CFA extends this idea to allows a typed enum to have an non-intergral or non-basic type. You can create an enum with a base type floating number, pointer, tuple, structure, function pointer, another enum, and more.
## Implementation / Todo
### 0. Grammar
Enumerator_value_opt:
// empty
// | '=' constant_expression
// { $$ = $2; }
| simple_assignment_operator initializer // FIX ME: enum only deals with constant_expression
;
Discussion: FIX ME item.
### 1. Integral Type:
$\forall$ enum_expression : enum($T$) { enumerator_list commaopt },
where $T \in IntegralTypes.$
For $enumerator\_list \rightarrow$derive $identifier = constant\_expression$:
$Code(enumerator\_list) = Code(const\ T \ identifier = constant\_expression)$
For $enumerator\_list \rightarrow$derive $identifier_k$ :
$Code(enumerator\_list) = Code(const\ T \ identifier_k = identifier_{k-1}+1)(k>0)$
$Code(enumerator\_list) = Code(const\ T \ identifier_k = 0)(k=0)$
During the code compilation, probably during the static type checking we save all the enum element Names. A compiler throws error if an assignment to an enum variable with a expression that is not an enum name.
$enum\ T(int) \{A =\ 'a'\}$
$T\ Name =\ 'a' $// Error: Cannot assign a variable of type 'T' with a value of type 'char'.
It behaves the same as C++ and many other languages.
### 2. Non-Integral Type
Syntax:
$enumerator\_list \rightarrow$derive $identifier = constant\_expression$