Changeset d1276f8 for doc/theses/jiada_liang_MMath
- Timestamp:
- Jul 24, 2024, 11:25:16 AM (4 months ago)
- Branches:
- master
- Children:
- 35c792f
- Parents:
- 10a99d87
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/implementation.tex
r10a99d87 rd1276f8 1 1 \chapter{Enumeration Implementation} 2 3 4 5 \section{Enumeration Traits} 6 7 \CFA defines a set of traits containing operators and helper functions for @enum@. 8 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA. 9 Each trait is discussed in detail. 10 11 The trait @CfaEnum@: 12 \begin{cfa} 13 forall( E ) trait CfaEnum { 14 const char * @label@( E e ); 15 unsigned int @posn@( E e ); 16 }; 17 \end{cfa} 18 asserts an enumeration type @E@ has named enumerator constants (@label@) with positions (@posn@). 19 20 The trait @TypedEnum@ extends @CfaEnum@: 21 \begin{cfa} 22 forall( E, V | CfaEnum( E ) ) trait TypedEnum { 23 V @value@( E e ); 24 }; 25 \end{cfa} 26 asserting an enumeration type @E@ can have homogeneous enumerator values of type @V@. 27 28 The declarative syntax 29 \begin{cfa} 30 enum(T) E { A = ..., B = ..., C = ... }; 31 \end{cfa} 32 creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically. 33 \begin{cfa} 34 void foo( T t ) { ... } 35 void bar(E e) { 36 choose ( e ) { 37 case A: printf( "\%d", posn( e) ); 38 case B: printf( "\%s", label( e ) ); 39 case C: foo( value( e ) ); 40 } 41 } 42 \end{cfa} 43 44 Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg: 45 \begin{cfa} 46 #include <string.hfa> 47 forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} ) 48 string formatEnum( E e ) { 49 unsigned int v = toUnsigned( value( e ) ); 50 string out = label(e) + '(' + v +')'; 51 return out; 52 } 53 formatEnum( Week.Mon ); 54 formatEnum( RGB.Green ); 55 \end{cfa} 56 57 \CFA does not define attribute functions for C-style enumeration. 58 But it is possible for users to explicitly implement enumeration traits for C enum and any other types. 59 \begin{cfa} 60 enum Fruit { Apple, Pear, Cherry }; $\C{// C enum}$ 61 const char * label( Fruit f ) { 62 choose ( f ) { 63 case Apple: return "Apple"; 64 case Bear: return "Pear"; 65 case Cherry: return "Cherry"; 66 } 67 } 68 unsigned posn( Fruit f ) { return f; } 69 const char * value( Fruit f ) { return ""; } $\C{// value can return any non void type}$ 70 formatEnum( Apple ); $\C{// Fruit is now a \CFA enum}$ 71 \end{cfa} 72 73 A type that implements trait @CfaEnum@, \ie, a type has no @value@, is called an opaque enum. 74 75 % \section{Enumerator Opaque Type} 76 77 % \CFA provides a special opaque enumeration type, where the internal representation is chosen by the compiler and only equality operations are available. 78 \begin{cfa} 79 enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }; 80 \end{cfa} 81 82 83 In addition, \CFA implements @Bound@ and @Serial@ for \CFA enumerations. 84 \begin{cfa} 85 forall( E ) trait Bounded { 86 E first(); 87 E last(); 88 }; 89 \end{cfa} 90 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg: 91 \begin{cfa} 92 Workday day = first(); $\C{// Mon}$ 93 Planet outermost = last(); $\C{// NEPTUNE}$ 94 \end{cfa} 95 @first()@ and @last()@ are overloaded with return types only, so in the example, the enumeration type is found on the left-hand side of the assignment. 96 Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration. 97 \begin{cfa} 98 @first();@ $\C{// ambiguous because both Workday and Planet implement Bounded}$ 99 sout | @last()@; 100 Workday day = first(); $\C{// day provides type Workday}$ 101 void foo( Planet p ); 102 foo( last() ); $\C{// argument provides type Planet}$ 103 \end{cfa} 104 105 The trait @Serial@: 106 \begin{cfa} 107 forall( E | Bounded( E ) ) trait Serial { 108 unsigned fromInstance( E e ); 109 E fromInt( unsigned int posn ); 110 E succ( E e ); 111 E pred( E e ); 112 }; 113 \end{cfa} 114 is a @Bounded@ trait, where elements can be mapped to an integer sequence. 115 A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value. 116 %However, the inverse may not be possible, and possible requires a bound check. 117 The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position. 118 The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator. 119 Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@. 120 121 The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal. 122 Specifically, if @e@ is the $i_{th}$ enumerator, @succ( e )@ returns the $i+1_{th}$ enumerator when $e \ne last()$, and @pred( e )@ returns the $i-1_{th}$ enumerator when $e \ne first()$. 123 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@. 124 125 Finally, there is an associated trait defining comparison operators among enumerators. 126 \begin{cfa} 127 forall( E, T | CfaEnum( E, T ) ) { 128 // comparison 129 int ?==?( E l, E r ); $\C{// true if l and r are same enumerators}$ 130 int ?!=?( E l, E r ); $\C{// true if l and r are different enumerators}$ 131 int ?!=?( E l, zero_t ); $\C{// true if l is not the first enumerator}$ 132 int ?<?( E l, E r ); $\C{// true if l is an enumerator before r}$ 133 int ?<=?( E l, E r ); $\C{// true if l before or the same as r}$ 134 int ?>?( E l, E r ); $\C{// true if l is an enumerator after r}$ 135 int ?>=?( E l, E r ); $\C{// true if l after or the same as r}$ 136 } 137 \end{cfa} 138 139 As an alternative, users can define the boolean conversion for CfaEnum: 140 141 \begin{cfa} 142 forall(E | CfaEnum(E)) 143 bool ?!=?(E lhs, zero_t) { 144 return posn(lhs) != 0; 145 } 146 \end{cfa} 147 which effectively turns the first enumeration as a logical zero and non-zero for others. 148 149 \begin{cfa} 150 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 151 p(variable_a); // 0 152 p(variable_b); // 1 153 p(variable_c); // "Third" 154 p(variable_d); // 3 155 \end{cfa} 2 156 3 157
Note: See TracChangeset
for help on using the changeset viewer.