# 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$