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

<div align="center">
<i>enum(Typename) EnumName<sub>opt</sub> = { enumerator-list }</i>
</div> or
, where <i>enumerator-list</i> is a list of <i>identifier</i> or <i>identifier = const-expression</i>.  
<div>

</div>

## CFA Typed Enum vs C Enum vs C++ Enum
In C, an enum variable declaration is isomorphic to an integer declaration. For example,  
<div align="center">
<i>enum EnumType VariableName = EnumValue;</i>
</div>
is equivalent to
<div align="center">
<i>int VariableName = EnumValue;</i>
</div>
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:
<div align="center">
<i>enum E(int) = EnumValue;</i>
</div>
Now <i>E</i> is a proper subset of <i>int</i> type. The compiler will stop you from assignment an integer value of a variable with type E, as in C++.</p>
Since C++11, C++ supports enum definition with an enum base.
<div align="center">
<i>enum EnumName : enum-base = { enumerator-list };</i>
</div>
An enum base is a sequence of basic integral type specifier.
<div align="center">
<i>
enum E: char {A='a'};<br/>
E e = A; <br/>
cout << e << end;
</i>
</div>
Will print a character 'a' to the output instead of 97.</br>
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 :  <i>enum($T$) { enumerator_list comma<sub>opt</sub> }</i>,  
where $T \in IntegralTypes.$  
For $enumerator\_list \rightarrow$<sub>derive</sub> $identifier = constant\_expression$:   
&emsp;$Code(enumerator\_list) = Code(const\ T \ identifier = constant\_expression)$  
For $enumerator\_list \rightarrow$<sub>derive</sub> $identifier_k$ :   
&emsp;$Code(enumerator\_list) = Code(const\ T \ identifier_k = identifier_{k-1}+1)(k>0)$  
&emsp;$Code(enumerator\_list) = Code(const\ T \ identifier_k = 0)(k=0)$  
  
During the code compilation, probably during the <i>static type checking</i> we save all the enum element <b>Names</b>. 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$<sub>derive</sub> $identifier = constant\_expression$


