Changeset 10a99d87 for doc/theses


Ignore:
Timestamp:
Jul 24, 2024, 11:24:08 AM (5 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
d1276f8
Parents:
46651fb
Message:

proofread last push of CFA enumerations

Location:
doc/theses/jiada_liang_MMath
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • doc/theses/jiada_liang_MMath/CFAenum.tex

    r46651fb r10a99d87  
    77The following sections detail all of my new contributions to enumerations in \CFA.
    88
    9 \begin{comment}
    10         Not support.
    11 \end{comment}
    12 % \section{Aliasing}
    13 
    14 % C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the name @enum@ is misleading (@const@ would be better).
    15 % Given the existence of this form, it is straightforward to extend it with types other than @int@.
    16 % \begin{cfa}
    17 % enum E { Size = 20u, PI = 3.14159L, Jack = L"John" };
    18 % \end{cfa}
    19 % which matches with @const@ aliasing in other programming languages.
    20 % Here, the type of the enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@.
    21 % Auto-initialization is restricted to the case where all constants are @int@, matching with C.
    22 % As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations.
     9
     10\section{Aliasing}
     11
     12{\color{red}@***@}
     13C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the keyword @enum@ is misleading (@const@ is better).
     14However, given the existence of this form, it is straightforward to extend it with heterogeneous types, \ie types other than @int@.
     15\begin{cfa}
     16enum { Size = 20u, PI = 3.14159L, Jack = L"John" }; $\C{// not an ADT nor an enumeration}$
     17\end{cfa}
     18which matches with @const@ aliasing in other programming languages.
     19(See \VRef{s:CenumImplementation} on how @gcc@/@clang@ are doing this for integral types.)
     20Here, the type of each enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@.
     21Auto-initialization is impossible in this case because some types do not support arithmetic.
     22As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations.
    2323
    2424
     
    3030
    3131The \CFA type-system allows extensive overloading, including enumerators.
    32 Furthermore, \CFA uses the environment, such as the left-had of assignment and function parameter, to pinpoint the best overloaded name.
    33 % Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name.
    34 Finally, qualification and casting are provided to disambiguate any ambiguous situations.
     32Furthermore, \CFA uses the environment, such as the left-hand of assignment and function arguments, to pinpoint the best overloaded name.
     33\VRef[Figure]{f:EnumeratorVisibility} shows enumeration overloading and how qualification and casting are used to disambiguate ambiguous situations.
     34\CFA overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources, like include files.
     35Experience from \CFA developers is that the type system implicitly and correctly disambiguates the majority of overloaded names.
     36That is, it is rare to get an incorrect selection or ambiguity, even among hundreds of overloaded variables and functions, that requires disambiguation using qualification or casting.
     37
     38\begin{figure}
    3539\begin{cfa}
    3640enum E1 { First, Second, Third, Fourth };
     
    3842E1 f() { return Third; }                                $\C{// overloaded functions, different return types}$
    3943E2 f() { return Fourth; }
    40 void g(E1 e);
    41 void h(E2 e);
    42 void foo() {
     44void g( E1 e );
     45void h( E2 e );
     46void foo() {                                                    $\C{// different resolutions and dealing with ambiguities}$
    4347        E1 e1 = First;   E2 e2 = First;         $\C{// initialization}$
    4448        e1 = Second;   e2 = Second;                     $\C{// assignment}$
    4549        e1 = f();   e2 = f();                           $\C{// function return}$
    46         g(First); h(First);                                     $\C{// function parameter}$
     50        g( First );   h( First );                       $\C{// function argument}$
    4751        int i = @E1.@First + @E2.@First;        $\C{// disambiguate with qualification}$
    4852        int j = @(E1)@First + @(E2)@First;      $\C{// disambiguate with cast}$
    4953}
    5054\end{cfa}
    51 \CFA overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources, like include files.
    52 Experience from \CFA developers is that the type system implicitly and correctly disambiguates the majority of overloaded names, \ie it is rare to get an incorrect selection or ambiguity, even among hundreds of overloaded variables and functions.
    53 Any ambiguity can be resolved using qualification or casting.
     55\caption{Enumerator Visibility and Disambiguating}
     56\label{f:EnumeratorVisibility}
     57\end{figure}
    5458
    5559
     
    6872rgb = @RGB.@Blue;
    6973\end{cfa}
    70 It is possible to toggle back to unscoping using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}).
     74{\color{red}@***@}It is possible to toggle back to unscoped using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}).
    7175\begin{cfa}
    7276with ( @Week@, @RGB@ ) {                                $\C{// type names}$
     
    7882
    7983
    80 \section{Enumeration Traits}
    81 
    82 \CFA defines the set of traits containing operators and helper functions for @enum@.
    83 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
    84 Each trait is discussed in detail.
    85 
    86 The trait @CfaEnum@:
    87 \begin{cfa}
    88 forall( E ) trait CfaEnum {
    89         char * label( E e );
    90         unsigned int posn( E e );
    91 };
    92 \end{cfa}
    93 
    94 describes an enumeration as a named constant with position. And @TypeEnum@
    95 \begin{cfa}
    96 forall( E, V ) trait TypeEnum {
    97         V value( E e );
    98 };     
    99 \end{cfa}
    100 asserts two types @E@ and @T@, with @T@ being the base type for the enumeration @E@.
    101 
    102 The declarative syntax
    103 \begin{cfa}
    104 enum(T) E { A = ..., B = ..., C = ... };
    105 \end{cfa}
    106 creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically.
    107 
    108 \begin{cfa}
    109 void foo( T t ) { ... }
    110 void bar(E e) {
    111         choose (e) {
    112                 case A: printf("\%d", posn(e));
    113                 case B: printf("\%s", label(e));
    114                 case C: foo(value(e));
    115         }
    116 }
    117 \end{cfa}
    118 
    119 Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg:
    120 \begin{cfa}
    121 #include <string.hfa>
    122 forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} )
    123 string formatEnum( E e ) {
    124         unsigned int v = toUnsigned(value(e));
    125         string out = label(e) + '(' + v +')';
    126         return out;
    127 }
    128 printEunm( Week.Mon );
    129 printEnum( RGB.Green );
    130 \end{cfa}
    131 
    132 \CFA does not define attribute functions for C style enumeration. But it is possilbe for users to explicitly implement
    133 enumeration traits for C enum and any other types.
    134 
    135 \begin{cfa}
    136 enum Fruit { Apple, Bear, Cherry };                     $\C{// C enum}$
    137 char * label(Fruit f) {
    138         switch(f) {
    139                 case Apple: "A"; break;
    140                 case Bear: "B"; break;
    141                 case Cherry: "C"; break;
    142         }
    143 }
    144 unsigned posn(Fruit f) { return f; }
    145 char* value(Fruit f) { return ""; }             $\C{// value can return any non void type}$
    146 formatEnum( Apple );                                                    $\C{// Fruit is now a Cfa enum}$
    147 \end{cfa}
    148 
    149 A type that implements trait @CfaEnum@, \ie, a type has no @value@, is called an opaque enum.
    150 
    151 % \section{Enumerator Opaque Type}
    152 
    153 % \CFA provides a special opaque enumeration type, where the internal representation is chosen by the compiler and only equality operations are available.
    154 \begin{cfa}
    155 enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
    156 \end{cfa}
    157 
    158 
    159 In addition, \CFA implements @Bound@ and @Serial@ for \CFA Enums.
    160 \begin{cfa}
    161 forall( E ) trait Bounded {
    162         E first();
    163         E last();
    164 };
    165 \end{cfa}
    166 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
    167 \begin{cfa}
    168 Workday day = first();                                  $\C{// Mon}$
    169 Planet outermost = last();                              $\C{// NEPTUNE}$
    170 \end{cfa}
    171 @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.
    172 Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
    173 \begin{cfa}
    174 @first();@                                                              $\C{// ambiguous because both Workday and Planet implement Bounded}$
    175 sout | @last()@;
    176 Workday day = first();                                  $\C{// day provides type Workday}$
    177 void foo( Planet p );
    178 foo( last() );                                                  $\C{// parameter provides type Planet}$
    179 \end{cfa}
    180 
    181 The trait @Serial@:
    182 \begin{cfa}
    183 forall( E | Bounded( E ) ) trait Serial {
    184         unsigned fromInstance( E e );
    185         E fromInt( unsigned int posn );
    186         E succ( E e );
    187         E pred( E e );
    188 };
    189 \end{cfa}
    190 is a @Bounded@ trait, where elements can be mapped to an integer sequence.
    191 A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value.
    192 %However, the inverse may not be possible, and possible requires a bound check.
    193 The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
    194 The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
    195 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@.
    196 
    197 The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
    198 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()$.
    199 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
    200 
    201 Finally, there is an associated trait defining comparison operators among enumerators.
    202 \begin{cfa}
    203 forall( E, T | CfaEnum( E, T ) ) {
    204         // comparison
    205         int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
    206         int ?!=?( E l, E r );           $\C{// true if l and r are different enumerators}$
    207         int ?!=?( E l, zero_t );        $\C{// true if l is not the first enumerator}$
    208         int ?<?( E l, E r );            $\C{// true if l is an enumerator before r}$
    209         int ?<=?( E l, E r );           $\C{// true if l before or the same as r}$
    210         int ?>?( E l, E r );            $\C{// true if l is an enumerator after r}$
    211         int ?>=?( E l, E r );           $\C{// true if l after or the same as r}$         
    212 }
    213 \end{cfa}
    214 
    215 \section{Typed Enum}
     84\section{Enumerator Typing}
    21685\label{s:EnumeratorTyping}
    21786
     
    251120        int i, j, k;
    252121        enum( @int *@ ) ptr { I = &i,  J = &j,  K = &k };
    253         enum( @int &@ ) ref { I = i,   J = j,   K = k };
     122@***@enum( @int &@ ) ref { I = i,   J = j,   K = k };
    254123// tuple
    255         enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$
     124@***@enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$
    256125// function
    257126        void f() {...}   void g() {...}
     
    281150calling constructors happens at runtime (dynamic).
    282151
     152
     153\section{Opaque Enumeration}
     154
     155\CFA provides a special opaque (pure) enumeration type with only assignment and equality operations, and no implicit conversion to any base-type.
     156\begin{cfa}
     157enum@()@ Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
     158Mode mode = O_RDONLY;
     159if ( mode == O_CREAT ) ...
     160bool b = mode == O_RDONLY || mode @<@ O_APPEND; $\C{// disallowed}$
     161int www @=@ mode;                                               $\C{// disallowed}$
     162\end{cfa}
     163
     164
     165\section{Enumeration Operators}
     166
     167
     168\subsection{Conversion}
     169
     170\CFA only proves an implicit safe conversion between an enumeration and its base type (like \CC), whereas C allows an unsafe conversion from base type to enumeration.
     171\begin{cfa}
     172enum(int) Colour { Red, Blue, Green };
     173int w = Red;            $\C[1.5in]{// allowed}$
     174Colour color = 0;       $\C{// disallowed}\CRT$
     175\end{cfa}
     176Unfortunately, there must be one confusing case between C enumerations and \CFA enumeration for type @int@.
     177\begin{cfa}
     178enum Colour { Red = 42, Blue, Green };
     179enum(int) Colour2 { Red = 16, Blue, Green };
     180int w = Redy;           $\C[1.5in]{// 42}\CRT$
     181\end{cfa}
     182Programmer intuition is that the assignment to @w@ is ambiguous.
     183However, converting from @color@ to @int@ is zero cost (no conversion), while from @Colour2@ to @int@ is a safe conversion, which is a higher cost.
     184This semantics means fewer backwards-compatibility issues with overloaded C and \CFA enumerators.
     185
     186
     187\subsection{Properties}
     188
     189\VRef{s:Terminology} introduced three fundamental enumeration properties: label, position, and value.
     190\CFA provides direct access to these three properties via the functions: @label@, @posn@, and @value@.
     191\begin{cfa}
     192enum( const char * ) Name { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
     193Name name = Fred;
     194sout | name | label( name ) | posn( name ) | value( name );
     195FRED Fred 0 FRED
     196\end{cfa}
     197The default meaning for an enumeration variable in an expression is its value.
     198
     199
     200\subsection{Range}
     201
     202The following helper function are used to access and control enumeration ranges (enumerating).
     203
     204The pseudo-function @countof@ (like @sizeof@) provides the size (range) of an enumeration or an enumeration instance.
     205\begin{cfa}
     206enum(int) Colour { Red, Blue, Green };
     207Colour c = Red
     208sout | countof( Colour ) | countof( c );
     2093 3
     210\end{cfa}
     211@countof@ is a pseudo-function because it takes a type as an argument.
     212The function @fromInt@ provides a safe subscript of the enumeration.
     213\begin{cfa}
     214Colour r = fromInt( prng( countof( Colour ) ) ); // select random colour
     215\end{cfa}
     216The functions @lowerBound@, @upperBound@, @succ@, and @pred@ are for enumerating.
     217\begin{cfa}
     218for ( Colour c = lowerBound();; ) {
     219        sout | c | nonl;
     220  if ( c == upperBound() ) break;
     221        c = succ( c );
     222}
     223\end{cfa}
     224Note, the mid-exit loop is necessary to prevent triggering a @succ@ bound check, as in:
     225\begin{cfa}
     226for ( Colour c = lowerBound(); c <= upperBound(); c = succ( c ) ) ... // generates error
     227\end{cfa}
     228When @c == upperBound()@, the loop control still invokes @succ( c )@, which causes an @enumBound@ exception.
     229Finally, there is operational overlap between @countof@ and @upperBound@.
     230
     231
    283232\section{Enumeration Inheritance}
    284233
    285234\CFA Plan-9 inheritance may be used with enumerations, where Plan-9 inheritance is containment inheritance with implicit unscoping (like a nested unnamed @struct@/@union@ in C).
    286 
    287 \begin{cfa}
    288 enum( char * ) Names { /* as above */ };
    289 enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" };
    290 enum( char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
    291 \end{cfa}
    292 
     235\begin{cfa}
     236enum( const char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
     237enum( const char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" };
     238enum( const char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
     239\end{cfa}
    293240Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@.
    294241Note, that enumerators must be unique in inheritance but enumerator values may be repeated.
     
    299246Specifically, the inheritance relationship for @Names@ is:
    300247\begin{cfa}
    301 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\C{// enum type of Names}$
    302 \end{cfa}
    303 A subtype can be cast to its supertype, assigned to a supertype variable, or be used as a function argument that expects the supertype.
    304 \begin{cfa}
    305 Names fred = Name.Fred;
    306 (Names2) fred; (Names3) fred; (Name3) Names.Jack;  $\C{// cast to super type}$
    307 Names2 fred2 = fred; Names3 fred3 = fred2; $\C{// assign to super type}$
     248Names  $\(\subset\)$  Names2  $\(\subset\)$  Names3  $\C{// enum type of Names}$
     249\end{cfa}
     250A subtype can be cast to its supertype, assigned to a supertype variable, or used as a function argument that expects the supertype.
     251\begin{cfa}
     252Names fred = Names.Fred;
     253(Names2)fred;   (Names3)fred;   (Names3)Names2.Jack;  $\C{// cast to super type}$
     254Names2 fred2 = fred;   Names3 fred3 = fred2;    $\C{// assign to super type}$
     255\end{cfa}
     256As well, there is the implicit cast to an enumerator's base-type.
     257\begin{cfa}
     258const char * name = fred;
    308259\end{cfa}
    309260For the given function prototypes, the following calls are valid.
     
    327278Note, the validity of calls is the same for call-by-reference as for call-by-value, and @const@ restrictions are the same as for other types.
    328279
     280
    329281\section{Enumerator Control Structures}
    330282
     
    335287
    336288For example, an intuitive use of enumerations is with the \CFA @switch@/@choose@ statement, where @choose@ performs an implicit @break@ rather than a fall-through at the end of a @case@ clause.
    337 \begin{cquote}
    338 \begin{cfa}
     289(For this discussion, ignore the fact that @case@ requires a compile-time constant.)
     290\begin{cfa}[belowskip=0pt]
    339291enum Count { First, Second, Third, Fourth };
    340292Count e;
    341293\end{cfa}
    342 \begin{tabular}{ll}
    343 \begin{cfa}
     294\begin{cquote}
     295\setlength{\tabcolsep}{15pt}
     296\noindent
     297\begin{tabular}{@{}ll@{}}
     298\begin{cfa}[aboveskip=0pt]
    344299
    345300choose( e ) {
     
    351306\end{cfa}
    352307&
    353 \begin{cfa}
     308\begin{cfa}[aboveskip=0pt]
    354309// rewrite
    355310choose( @value@( e ) ) {
     
    367322enum Count { First, Second, Third @= First@, Fourth };
    368323\end{cfa}
    369 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
     324making @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
    370325To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context.
    371326For conditional clauses and switch statements, \CFA uses the robust position implementation.
    372327\begin{cfa}
    373 choose( @position@( e ) ) {
    374         case @position@( First ): ...;
    375         case @position@( Second ): ...;
    376         case @position@( Third ): ...;
    377         case @position@( Fourth ): ...;
    378 }
    379 \end{cfa}
    380 
    381 \begin{cfa}
    382 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
    383 p(variable_a); // 0
    384 p(variable_b); // 1
    385 p(variable_c); // "Third"
    386 p(variable_d); // 3
    387 \end{cfa}
    388 
    389 \begin{cfa}
    390 for (d; Workday) { sout | d; }
    391 for (p; +~=Planet) { sout | p; }
    392 for (c: -~=Alphabet ) { sout | c; }
    393 \end{cfa}
    394 The @range loop@ for enumeration is a syntax sugar that loops over all enumerators and assigns each enumeration to a variable in every iteration.
    395 The loop control of the range loop consists of two parts: a variable declaration and a @range expression@, with the type of the variable
    396 can be inferred from the range expression.
    397 
    398 The range expression is an enumeration type, optionally prefixed by @+~=@ or @-~=@. Without a prefix, or prefixed with @+~=@, the control
    399 loop over all enumerators from the first to the last. With a @-~=@ prefix, the control loops backward.
    400 
    401 On a side note, the loop syntax
    402 \begin{cfa}
    403 for ( typeof(Workday) d; d <= last(); d = succ(d) );
    404 \end{cfa}
    405 does not work. When d == last(), the loop control will still attempt to assign succ(d) to d, which causes an @enumBound@ exception.
    406 
    407 \CFA reduces conditionals to its "if case" if the predicate is not equal to ( @!=@ ) zero, and the "else case" otherwise.
    408 Overloading the @!=@ operator with an enumeration type against the zero defines a conceptual conversion from
    409 enum to boolean, which can be used as predicates.
    410 
     328if ( @posn@( e ) < posn( Third ) ) ...
     329choose( @posn@( e ) ) {
     330        case @posn@( First ): ...;
     331        case @posn@( Second ): ...;
     332        case @posn@( Third ): ...;
     333        case @posn@( Fourth ): ...;
     334}
     335\end{cfa}
     336
     337\CFA provides a special form of for-control for enumerating through an enumeration, where the range is a type.
     338\begin{cfa}
     339for ( cx; @Count@ ) { sout | cx | nonl; } sout | nl;
     340for ( cx; +~= Count ) { sout | cx | nonl; } sout | nl;
     341for ( cx; -~= Count ) { sout | cx | nonl; } sout | nl;
     342First Second Third Fourth
     343First Second Third Fourth
     344Fourth Third Second First
     345\end{cfa}
     346The enumeration type is syntax sugar for looping over all enumerators and assigning each enumerator to the loop index, whose type is inferred from the range type.
     347The prefix @+~=@ or @-~=@ iterate forward or backwards through the inclusive enumeration range, where no prefix defaults to @+~=@.
     348
     349C has an idiom for @if@ and loop predicates of comparing the predicate result ``not equal to 0''.
     350\begin{cfa}
     351if ( x + y /* != 0 */ ) ...
     352while ( p /* != 0 */ ) ...
     353\end{cfa}
     354This idiom extends to enumerations because there is a boolean conversion in terms of the enumeration value, if and only if such a conversion is available.
     355For example, such a conversion exists for all numerical types (integral and floating-point).
     356It is possible to explicitly extend this idiom to any typed enumeration by overloading the @!=@ operator.
     357\begin{cfa}
     358bool ?!=?( Name n, zero_t ) { return n != Fred; }
     359Name n = Mary;
     360if ( n ) ... // result is true
     361\end{cfa}
     362Specialize meanings are also possible.
    411363\begin{cfa}
    412364enum(int) ErrorCode { Normal = 0, Slow = 1, Overheat = 1000, OutOfResource = 1001 };
    413 bool ?!=?(ErrorCode lhs, zero_t) { return value(lhs) >= 1000; }
    414 ErrorCode code = /.../
    415 if (code) { scream(); }
    416 \end{cfa}
    417 
    418 Incidentally, \CFA does not define boolean conversion for enumeration. If no
    419 @?!=?(ErrorCode, zero_t)@
    420 overloading defined,
    421 \CFA looks for the boolean conversion in terms of its value and gives a compiler error if no such conversion is available.
    422 
    423 \begin{cfa}
    424 enum(int) Weekday { Mon, Tues, Wed, Thurs, Fri, Sat, Sun, };
    425 enum() Colour { Red, Green, Blue };
    426 enum(S) Fruit { Apple, Banana, Cherry }
    427 Weekday w = ...; Colour c = ...; Fruit f = ...;
    428 if (w) { ... } // w is true if and only if w != Mon, because value(Mon) == 0 (auto initialized)
    429 if (c) { ... } // error
    430 if (s) { ... } // depends on ?!=?(S lhs, zero_t ), and error if no such overloading available
    431 \end{cfa}
    432 
    433 As an alternative, users can define the boolean conversion for CfaEnum:
    434 
    435 \begin{cfa}
    436 forall(E | CfaEnum(E))
    437 bool ?!=?(E lhs, zero_t) {
    438         return posn(lhs) != 0;
    439 }
    440 \end{cfa}
    441 which effectively turns the first enumeration as a logical zero and non-zero for others.
    442 
    443 \section{Enumerated Arrays}
    444 Enumerated arrays use an \CFA array as their index.
    445 \begin{cfa}
    446 enum() Colour {
    447         Red, Orange, Yellow, Green, Blue, Indigo, Violet
    448 };
    449 
    450 string colourCode[Colour] = { "#e81416", "#ffa500", "#ffa500", "#ffa500", "#487de7", "#4b369d", "#70369d" };
    451 sout | "Colour Code of Orange is " | colourCode[Orange];
    452 \end{cfa}
     365bool ?!=?( ErrorCode ec, zero_t ) { return ec >= Overheat; }
     366ErrorCode code = ...;
     367if ( code ) { problem(); }
     368\end{cfa}
     369
     370
     371\section{Enumeration Dimension}
     372
     373\VRef{s:EnumeratorTyping} introduced the harmonizing problem between an enumeration and secondary information.
     374When possible, using a typed enumeration for the secondary information is the best approach.
     375However, there are times when combining these two types is not possible.
     376For example, the secondary information might precede the enumeration and/or its type is needed directly to declare parameters of functions.
     377In these cases, having secondary arrays of the enumeration size are necessary.
     378
     379To support some level of harmonizing in these cases, an array dimension can be defined using an enumerator type, and the enumerators used as subscripts.
     380\begin{cfa}
     381enum E { A, B, C, N }; // possibly predefined
     382float H1[N] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // C
     383float H2[@E@] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // CFA
     384\end{cfa}
     385(Note, C uses the symbol, @'='@ for designator initialization, but \CFA had to change to @':'@ because of problems with tuple syntax.)
     386This approach is also necessary for a predefined typed enumeration (unchangeable), when additional secondary-information need to be added.
    453387
    454388
     
    470404\small
    471405\begin{cfa}
    472 struct MR { double mass, radius; };
     406struct MR { double mass, radius; };                     $\C{// planet definition}$
    473407enum( @MR@ ) Planet {                                           $\C{// typed enumeration}$
    474408        //                      mass (kg)   radius (km)
  • doc/theses/jiada_liang_MMath/background.tex

    r46651fb r10a99d87  
    66The following discussion covers C enumerations.
    77
    8 As discussed in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants.
     8As mentioned in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants.
    99\begin{clang}
    1010#define Mon 0
     
    3333C can simulate the aliasing @const@ declarations \see{\VRef{s:Aliasing}}, with static and dynamic initialization.
    3434\begin{cquote}
    35 \begin{tabular}{@{}l@{}l@{}}
    36 \multicolumn{1}{@{}c@{}}{\textbf{static initialization}} &  \multicolumn{1}{c@{}}{\textbf{dynamic intialization}} \\
     35\begin{tabular}{@{}ll@{}}
     36\multicolumn{1}{@{}c}{\textbf{static initialization}} &  \multicolumn{1}{c@{}}{\textbf{dynamic intialization}} \\
    3737\begin{clang}
    3838static const int one = 0 + 1;
     
    5656\end{tabular}
    5757\end{cquote}
    58 However, statically initialized identifiers can not appear in constant-expression contexts, \eg @case@.
     58However, statically initialized identifiers cannot appear in constant-expression contexts, \eg @case@.
    5959Dynamically initialized identifiers may appear in initialization and array dimensions in @g++@, which allows variable-sized arrays on the stack.
    6060Again, this form of aliasing is not an enumeration.
     
    130130
    131131\subsection{Implementation}
     132\label{s:CenumImplementation}
    132133
    133134In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values.
    134 In practice, C uses @int@ as the underlying type for enumeration variables, because of the restriction to integral constants, which have type @int@ (unless qualified with a size suffix).
     135In practice, C defines @int@~\cite[\S~6.4.4.3]{C11} as the underlying type for enumeration variables, restricting initialization to integral constants, which have type @int@ (unless qualified with a size suffix).
     136However, type @int@ is defined as:
     137\begin{quote}
     138A ``plain'' @int@ object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range @INT_MIN@ to @INT_MAX@ as defined in the header @<limits.h>@).~\cite[\S~6.2.5(5)]{C11}
     139\end{quote}
     140Howeveer, @int@ means a 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture.
     141Whereas, @long int@ means 4 bytes on a 32-bit and 8 bytes on 64-bit architectures, and @long long int@ means 8 bytes on both 32/64-bit architectures, where 64-bit operations are simulated on 32-bit architectures.
     142In reality, both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based its initialization.
     143\begin{cfa}
     144enum E { IMin = INT_MIN, IMax = INT_MAX,
     145                         ILMin = LONG_MIN, ILMax = LONG_MAX,
     146                         ILLMin = LLONG_MIN, ILLMax = LLONG_MAX };
     147int main() {
     148        printf( "%zd %d %d\n%zd %ld %ld\n%zd %ld %ld\n",
     149                         sizeof(IMin), IMin, IMax,
     150                         sizeof(ILMin), ILMin, ILMax,
     151                         sizeof(ILLMin), ILLMin, ILLMax );
     152}
     1534 -2147483648 2147483647
     1548 -9223372036854775808 9223372036854775807
     1558 -9223372036854775808 9223372036854775807
     156\end{cfa}
     157Hence, initialization in the range @INT_MIN@..@INT_MAX@ is 4 bytes, and outside this range is 8 bytes.
    135158
    136159
     
    151174enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    152175switch ( week ) {
    153         case Mon: case Tue: case Wed: case Thu: case Fri:
     176        case Mon ... Fri:                               $\C{// gcc case range}$
    154177                printf( "weekday\n" );
    155178        case Sat: case Sun:
    156179                printf( "weekend\n" );
    157180}
    158 for ( enum Week day = Mon; day <= Sun; day += 1 ) { // step of 1
     181for ( enum Week day = Mon; day <= Sun; day += 1 ) { $\C{// step of 1}$
    159182        printf( "day %d\n", day ); // 0-6
    160183}
     
    178201}
    179202\end{cfa}
    180 However, for typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.
    181 
    182 This idiom leads to another C idiom using an enumeration with matching companion information.
     203However, for non-integral typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.
     204
     205This idiom is used in another C idiom for matching companion information.
    183206For example, an enumeration is linked with a companion array of printable strings.
    184207\begin{cfa}
     
    197220
    198221\bigskip
    199 While C provides a true enumeration, it is restricted, has unsafe semantics, and does provide useful enumeration features in other programming languages.
     222While C provides a true enumeration, it is restricted, has unsafe semantics, and does not provide useful enumeration features in other programming languages.
Note: See TracChangeset for help on using the changeset viewer.