[NAME]
ALL.dao.type.enum

[TITLE]
Enum or Symbol Type

[DESCRIPTION]

enum is a type hybriding C++ enum and Ruby symbol types to offer the advantages of both
types. It can be used as enumerated constant in C++ or as symbol in Ruby.

 0.1  Definition 
     
   1  EnumEntry ::= Identifier [ = ConstExpr ]
   2  
   3  Enum1 ::= 'enum' Identifier '{' EnumEntry { ',' EnumEntry } '}'
   4  Enum2 ::= 'enum' Identifier '{' EnumEntry { ';' EnumEntry } '}'
   5  
   6  Enum ::= Enum1 | Enum2
   7  
   8  EnumType1 ::= 'enum' '<' EnumEntry { ',' EnumEntry } '>'
   9  EnumType2 ::= 'enum' '<' EnumEntry { ';' EnumEntry } '>'
  10  
  11  EnumType ::= EnumType1 | EnumType2
     
The only difference between Enum1 and Enum2, EnumType1 and EnumType2 is the comma and 
semicolon. When comma(s) are used, the enum items are not combinable; but when
semicolon(s) are used, they can be combined as flags.

 0.2  Examples 

Enum types can be declared in the same way as C++ enum:
     
   1  enum MyEnum
   2  {
   3      AA,
   4      BB,
   5      CC
   6  }
     
Then it can be used in the following way:
     
   1  e1 = MyEnum::BB   # with constant folding;
   2  e2 = MyEnum.BB    # without constant folding;
   3  e3 : MyEnum = $BB # with auto conversion;
     
All e1, e2 and e3 will be an enum value with integer value equal to 1 and string symbol 
equal to "BB". The last is equivalent to:
     
   1  # Use enum type on the fly:
   2  e3 : enum<AA,BB,CC> = $BB
     


Enum values can be used in switch-case statements, which can be optimized to table
lookup, if the enums are explicitly typed or can be inferred. For example,
     
   1  switch( (any)e1 ){
   2  case MyEnum::AA : ...
   3  case MyEnum::BB : ...
   4  case MyEnum::CC : ...
   5  }
   6  
   7  switch( e1 ){
   8  case $AA : ...
   9  case $BB : ...
  10  case $CC : ...
  11  }
     
Both will be optimized into table lookup, because the case values have well defined types
(the cases in the second example have types inferred from the expression in switch() ). 
But not the following example,
     
   1  switch( (any)e1 ){
   2  case $AA : ...
   3  case $BB : ...
   4  case $CC : ...
   5  }
     
because the value type of the expression inside switch() is not well defined, so the
symbols in the cases are not well typed.

Enum can be very useful function parameter list. For example, if you want a parameter can
only accept three different values representing red, green and blue, you can simply use 
color :enum<red,green,blue>!