Ignore:
Timestamp:
Jul 24, 2024, 7:11:32 PM (5 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
5aeb1a9
Parents:
e561551 (diff), b6923b17 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

conclude merge

Location:
doc/theses/jiada_liang_MMath
Files:
4 edited

Legend:

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

    re561551 ra03ed29  
    11\chapter{\CFA Enumeration}
    2 
    32
    43% \CFA supports C enumeration using the same syntax and semantics for backwards compatibility.
     
    98\begin{clang}[identifierstyle=\linespread{0.9}\it]
    109$\it enum$-specifier:
    11         enum @(type-specifier$\(_{opt}\)$)@ identifier$\(_{opt}\)$ { enumerator-list-noinit }
    12         enum @(type-specifier$\(_{opt}\)$)@ identifier$\(_{opt}\)$ { enumerator-list-noinit , }
     10        enum @(type-specifier$\(_{opt}\)$)@ identifier$\(_{opt}\)$ { cfa-enumerator-list }
     11        enum @(type-specifier$\(_{opt}\)$)@ identifier$\(_{opt}\)$ { cfa-enumerator-list , }
    1312        enum @(type-specifier$\(_{opt}\)$)@ identifier
    14 enumerator-list-noinit:
     13cfa-enumerator-list:
     14        cfa-enumerator
     15        cfa-enumerator, cfa-enumerator-list
     16cfa-enumerator:
    1517        enumeration-constant
    16         enumerator-list-noinit , enumeration-constant
     18        $\it inline$ identifier
     19        enumeration-constant = expression
    1720\end{clang}
    18 \CFA enumerations, or \CFA enums, have optional type declaration in a bracket next to the enum keyword.
     21A \newterm{\CFA enumeration}, or \newterm{\CFA enum}, has an optional type declaration in the bracket next to the @enum@ keyword.
    1922Without optional type declarations, the syntax defines "opaque enums".
    2023Otherwise, \CFA enum with type declaration are "typed enums".
     
    284287Note, 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.
    285288
    286 
    287 
    288 \section{Enumeration Traits}
    289 
    290 \CFA defines the set of traits containing operators and helper functions for @enum@.
    291 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
    292 Each trait is discussed in detail.
    293 
    294 The trait @CfaEnum@:
    295 \begin{cfa}
    296 forall( E ) trait CfaEnum {
    297         char * label( E e );
    298         unsigned int posn( E e );
    299 };
    300 \end{cfa}
    301 
    302 describes an enumeration as a named constant with position. And @TypeEnum@
    303 \begin{cfa}
    304 forall( E, V ) trait TypeEnum {
    305         V value( E e );
    306 };     
    307 \end{cfa}
    308 asserts two types @E@ and @T@, with @T@ being the base type for the enumeration @E@.
    309 
    310 The declarative syntax
    311 \begin{cfa}
    312 enum(T) E { A = ..., B = ..., C = ... };
    313 \end{cfa}
    314 creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically.
    315 
    316 \begin{cfa}
    317 void foo( T t ) { ... }
    318 void bar(E e) {
    319         choose (e) {
    320                 case A: printf("\%d", posn(e));
    321                 case B: printf("\%s", label(e));
    322                 case C: foo(value(e));
    323         }
    324 }
    325 \end{cfa}
    326 
    327 Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg:
    328 \begin{cfa}
    329 #include <string.hfa>
    330 forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} )
    331 string formatEnum( E e ) {
    332         unsigned int v = toUnsigned(value(e));
    333         string out = label(e) + '(' + v +')';
    334         return out;
    335 }
    336 printEunm( Week.Mon );
    337 printEnum( RGB.Green );
    338 \end{cfa}
    339 
    340 \CFA does not define attribute functions for C style enumeration. But it is possilbe for users to explicitly implement
    341 enumeration traits for C enum and any other types.
    342 
    343 \begin{cfa}
    344 enum Fruit { Apple, Bear, Cherry };                     $\C{// C enum}$
    345 char * label(Fruit f) {
    346         switch(f) {
    347                 case Apple: "A"; break;
    348                 case Bear: "B"; break;
    349                 case Cherry: "C"; break;
    350         }
    351 }
    352 unsigned posn(Fruit f) { return f; }
    353 char* value(Fruit f) { return ""; }             $\C{// value can return any non void type}$
    354 formatEnum( Apple );                                                    $\C{// Fruit is now a Cfa enum}$
    355 \end{cfa}
    356 
    357 A type that implements trait @CfaEnum@, \ie, a type has no @value@, is called an opaque enum.
    358 
    359 % \section{Enumerator Opaque Type}
    360 
    361 % \CFA provides a special opaque enumeration type, where the internal representation is chosen by the compiler and only equality operations are available.
    362 \begin{cfa}
    363 enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
    364 \end{cfa}
    365 
    366 
    367 In addition, \CFA implements @Bound@ and @Serial@ for \CFA Enums.
    368 \begin{cfa}
    369 forall( E ) trait Bounded {
    370         E first();
    371         E last();
    372 };
    373 \end{cfa}
    374 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
    375 \begin{cfa}
    376 Workday day = first();                                  $\C{// Mon}$
    377 Planet outermost = last();                              $\C{// NEPTUNE}$
    378 \end{cfa}
    379 @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.
    380 Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
    381 \begin{cfa}
    382 @first();@                                                              $\C{// ambiguous because both Workday and Planet implement Bounded}$
    383 sout | @last()@;
    384 Workday day = first();                                  $\C{// day provides type Workday}$
    385 void foo( Planet p );
    386 foo( last() );                                                  $\C{// parameter provides type Planet}$
    387 \end{cfa}
    388 
    389 The trait @Serial@:
    390 \begin{cfa}
    391 forall( E | Bounded( E ) ) trait Serial {
    392         unsigned fromInstance( E e );
    393         E fromInt( unsigned int posn );
    394         E succ( E e );
    395         E pred( E e );
    396 };
    397 \end{cfa}
    398 is a @Bounded@ trait, where elements can be mapped to an integer sequence.
    399 A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value.
    400 %However, the inverse may not be possible, and possible requires a bound check.
    401 The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
    402 The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
    403 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@.
    404 
    405 The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
    406 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()$.
    407 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
    408 
    409 Finally, there is an associated trait defining comparison operators among enumerators.
    410 \begin{cfa}
    411 forall( E, T | CfaEnum( E, T ) ) {
    412         // comparison
    413         int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
    414         int ?!=?( E l, E r );           $\C{// true if l and r are different enumerators}$
    415         int ?!=?( E l, zero_t );        $\C{// true if l is not the first enumerator}$
    416         int ?<?( E l, E r );            $\C{// true if l is an enumerator before r}$
    417         int ?<=?( E l, E r );           $\C{// true if l before or the same as r}$
    418         int ?>?( E l, E r );            $\C{// true if l is an enumerator after r}$
    419         int ?>=?( E l, E r );           $\C{// true if l after or the same as r}$         
    420 }
    421 \end{cfa}
    422 
    423 
    424 
    425 
    426 
    427289\section{Enumerator Control Structures}
    428290
     
    433295
    434296For 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.
    435 \begin{cquote}
    436 \begin{cfa}
     297(For this discussion, ignore the fact that @case@ requires a compile-time constant.)
     298\begin{cfa}[belowskip=0pt]
    437299enum Count { First, Second, Third, Fourth };
    438300Count e;
    439301\end{cfa}
    440 \begin{tabular}{ll}
    441 \begin{cfa}
     302\begin{cquote}
     303\setlength{\tabcolsep}{15pt}
     304\noindent
     305\begin{tabular}{@{}ll@{}}
     306\begin{cfa}[aboveskip=0pt]
    442307
    443308choose( e ) {
     
    449314\end{cfa}
    450315&
    451 \begin{cfa}
     316\begin{cfa}[aboveskip=0pt]
    452317// rewrite
    453318choose( @value@( e ) ) {
     
    465330enum Count { First, Second, Third @= First@, Fourth };
    466331\end{cfa}
    467 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
     332making @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
    468333To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context.
    469334For conditional clauses and switch statements, \CFA uses the robust position implementation.
    470335\begin{cfa}
    471 choose( @position@( e ) ) {
    472         case @position@( First ): ...;
    473         case @position@( Second ): ...;
    474         case @position@( Third ): ...;
    475         case @position@( Fourth ): ...;
    476 }
    477 \end{cfa}
    478 
    479 \begin{cfa}
    480 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
    481 p(variable_a); // 0
    482 p(variable_b); // 1
    483 p(variable_c); // "Third"
    484 p(variable_d); // 3
    485 \end{cfa}
    486 
    487 \begin{cfa}
    488 for (d; Workday) { sout | d; }
    489 for (p; +~=Planet) { sout | p; }
    490 for (c: -~=Alphabet ) { sout | c; }
    491 \end{cfa}
    492 The @range loop@ for enumeration is a syntax sugar that loops over all enumerators and assigns each enumeration to a variable in every iteration.
    493 The loop control of the range loop consists of two parts: a variable declaration and a @range expression@, with the type of the variable
    494 can be inferred from the range expression.
    495 
    496 The range expression is an enumeration type, optionally prefixed by @+~=@ or @-~=@. Without a prefix, or prefixed with @+~=@, the control
    497 loop over all enumerators from the first to the last. With a @-~=@ prefix, the control loops backward.
    498 
    499 On a side note, the loop syntax
    500 \begin{cfa}
    501 for ( typeof(Workday) d; d <= last(); d = succ(d) );
    502 \end{cfa}
    503 does not work. When d == last(), the loop control will still attempt to assign succ(d) to d, which causes an @enumBound@ exception.
    504 
    505 \CFA reduces conditionals to its "if case" if the predicate is not equal to ( @!=@ ) zero, and the "else case" otherwise.
    506 Overloading the @!=@ operator with an enumeration type against the zero defines a conceptual conversion from
    507 enum to boolean, which can be used as predicates.
    508 
     336if ( @posn@( e ) < posn( Third ) ) ...
     337choose( @posn@( e ) ) {
     338        case @posn@( First ): ...;
     339        case @posn@( Second ): ...;
     340        case @posn@( Third ): ...;
     341        case @posn@( Fourth ): ...;
     342}
     343\end{cfa}
     344
     345\CFA provides a special form of for-control for enumerating through an enumeration, where the range is a type.
     346\begin{cfa}
     347for ( cx; @Count@ ) { sout | cx | nonl; } sout | nl;
     348for ( cx; +~= Count ) { sout | cx | nonl; } sout | nl;
     349for ( cx; -~= Count ) { sout | cx | nonl; } sout | nl;
     350First Second Third Fourth
     351First Second Third Fourth
     352Fourth Third Second First
     353\end{cfa}
     354The 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.
     355The prefix @+~=@ or @-~=@ iterate forward or backwards through the inclusive enumeration range, where no prefix defaults to @+~=@.
     356
     357C has an idiom for @if@ and loop predicates of comparing the predicate result ``not equal to 0''.
     358\begin{cfa}
     359if ( x + y /* != 0 */ ) ...
     360while ( p /* != 0 */ ) ...
     361\end{cfa}
     362This 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.
     363For example, such a conversion exists for all numerical types (integral and floating-point).
     364It is possible to explicitly extend this idiom to any typed enumeration by overloading the @!=@ operator.
     365\begin{cfa}
     366bool ?!=?( Name n, zero_t ) { return n != Fred; }
     367Name n = Mary;
     368if ( n ) ... // result is true
     369\end{cfa}
     370Specialize meanings are also possible.
    509371\begin{cfa}
    510372enum(int) ErrorCode { Normal = 0, Slow = 1, Overheat = 1000, OutOfResource = 1001 };
    511 bool ?!=?(ErrorCode lhs, zero_t) { return value(lhs) >= 1000; }
    512 ErrorCode code = /.../
    513 if (code) { scream(); }
    514 \end{cfa}
    515 
    516 Incidentally, \CFA does not define boolean conversion for enumeration. If no
    517 @?!=?(ErrorCode, zero_t)@
    518 overloading defined,
    519 \CFA looks for the boolean conversion in terms of its value and gives a compiler error if no such conversion is available.
    520 
    521 \begin{cfa}
    522 enum(int) Weekday { Mon, Tues, Wed, Thurs, Fri, Sat, Sun, };
    523 enum() Colour { Red, Green, Blue };
    524 enum(S) Fruit { Apple, Banana, Cherry }
    525 Weekday w = ...; Colour c = ...; Fruit f = ...;
    526 if (w) { ... } // w is true if and only if w != Mon, because value(Mon) == 0 (auto initialized)
    527 if (c) { ... } // error
    528 if (s) { ... } // depends on ?!=?(S lhs, zero_t ), and error if no such overloading available
    529 \end{cfa}
    530 
    531 As an alternative, users can define the boolean conversion for CfaEnum:
    532 
    533 \begin{cfa}
    534 forall(E | CfaEnum(E))
    535 bool ?!=?(E lhs, zero_t) {
    536         return posn(lhs) != 0;
    537 }
    538 \end{cfa}
    539 which effectively turns the first enumeration as a logical zero and non-zero for others.
    540 
    541 \section{Enumerated Arrays}
    542 Enumerated arrays use an \CFA array as their index.
    543 \begin{cfa}
    544 enum() Colour {
    545         Red, Orange, Yellow, Green, Blue, Indigo, Violet
    546 };
    547 
    548 string colourCode[Colour] = { "#e81416", "#ffa500", "#ffa500", "#ffa500", "#487de7", "#4b369d", "#70369d" };
    549 sout | "Colour Code of Orange is " | colourCode[Orange];
    550 \end{cfa}
     373bool ?!=?( ErrorCode ec, zero_t ) { return ec >= Overheat; }
     374ErrorCode code = ...;
     375if ( code ) { problem(); }
     376\end{cfa}
     377
     378
     379\section{Enumeration Dimension}
     380
     381\VRef{s:EnumeratorTyping} introduced the harmonizing problem between an enumeration and secondary information.
     382When possible, using a typed enumeration for the secondary information is the best approach.
     383However, there are times when combining these two types is not possible.
     384For example, the secondary information might precede the enumeration and/or its type is needed directly to declare parameters of functions.
     385In these cases, having secondary arrays of the enumeration size are necessary.
     386
     387To support some level of harmonizing in these cases, an array dimension can be defined using an enumerator type, and the enumerators used as subscripts.
     388\begin{cfa}
     389enum E { A, B, C, N }; // possibly predefined
     390float H1[N] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // C
     391float H2[@E@] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // CFA
     392\end{cfa}
     393(Note, C uses the symbol, @'='@ for designator initialization, but \CFA had to change to @':'@ because of problems with tuple syntax.)
     394This approach is also necessary for a predefined typed enumeration (unchangeable), when additional secondary-information need to be added.
    551395
    552396
     
    568412\small
    569413\begin{cfa}
    570 struct MR { double mass, radius; };
     414struct MR { double mass, radius; };                     $\C{// planet definition}$
    571415enum( @MR@ ) Planet {                                           $\C{// typed enumeration}$
    572416        //                      mass (kg)   radius (km)
  • doc/theses/jiada_liang_MMath/background.tex

    re561551 ra03ed29  
    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;
     
    5151        int va[r];
    5252}
    53 
    54 
    5553\end{clang}
    5654\end{tabular}
    5755\end{cquote}
    58 However, statically initialized identifiers can not appear in constant-expression contexts, \eg @case@.
     56However, statically initialized identifiers cannot appear in constant-expression contexts, \eg @case@.
    5957Dynamically initialized identifiers may appear in initialization and array dimensions in @g++@, which allows variable-sized arrays on the stack.
    6058Again, this form of aliasing is not an enumeration.
    61 
    6259
    6360\section{C Enumeration}
     
    129126
    130127
    131 \subsection{Representation}
    132 
    133 C standard specifies 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).
     128\subsection{Implementation}
     129\label{s:CenumImplementation}
     130
     131In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values.
     132In 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).
     133However, type @int@ is defined as:
     134\begin{quote}
     135A ``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}
     136\end{quote}
     137Howeveer, @int@ means a 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture.
     138Whereas, @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.
     139In reality, both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based its initialization.
     140\begin{cfa}
     141enum E { IMin = INT_MIN, IMax = INT_MAX,
     142                         ILMin = LONG_MIN, ILMax = LONG_MAX,
     143                         ILLMin = LLONG_MIN, ILLMax = LLONG_MAX };
     144int main() {
     145        printf( "%zd %d %d\n%zd %ld %ld\n%zd %ld %ld\n",
     146                         sizeof(IMin), IMin, IMax,
     147                         sizeof(ILMin), ILMin, ILMax,
     148                         sizeof(ILLMin), ILLMin, ILLMax );
     149}
     1504 -2147483648 2147483647
     1518 -9223372036854775808 9223372036854775807
     1528 -9223372036854775808 9223372036854775807
     153\end{cfa}
     154Hence, initialization in the range @INT_MIN@..@INT_MAX@ is 4 bytes, and outside this range is 8 bytes.
    135155
    136156\subsection{Usage}
     
    150170enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun };
    151171switch ( week ) {
    152         case Mon: case Tue: case Wed: case Thu: case Fri:
     172        case Mon ... Fri:                               $\C{// gcc case range}$
    153173                printf( "weekday\n" );
    154174        case Sat: case Sun:
    155175                printf( "weekend\n" );
    156176}
    157 for ( enum Week day = Mon; day <= Sun; day += 1 ) { // step of 1
     177for ( enum Week day = Mon; day <= Sun; day += 1 ) { $\C{// step of 1}$
    158178        printf( "day %d\n", day ); // 0-6
    159179}
     
    177197}
    178198\end{cfa}
    179 However, for typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.
    180 
    181 This idiom leads to another C idiom using an enumeration with matching companion information.
     199However, for non-integral typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.
     200
     201This idiom is used in another C idiom for matching companion information.
    182202For example, an enumeration is linked with a companion array of printable strings.
    183203\begin{cfa}
     
    196216
    197217\bigskip
    198 While C provides a true enumeration, it is restricted, has unsafe semantics, and does provide useful enumeration features in other programming languages.
     218While C provides a true enumeration, it is restricted, has unsafe semantics, and does not provide useful enumeration features in other programming languages.
    199219
    200220\section{\CFA Polymorphism}
     
    238258\subsection{Constructor and Destructor}
    239259In \CFA, all objects are initialized by @constructors@ during its allocation, including basic types,
    240 which are initialized by constructors default-generated by a compiler.
     260which are initialized by auto-generated basic type constructors.
    241261
    242262Constructors are overloadable functions with name @?{}@, return @void@, and have at least one parameter, which is a reference
  • doc/theses/jiada_liang_MMath/implementation.tex

    re561551 ra03ed29  
    11\chapter{Enumeration Implementation}
     2
     3\section{Enumeration Traits}
     4
     5\CFA defines a set of traits containing operators and helper functions for @enum@.
     6A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
     7Each trait is discussed in detail.
     8
     9The trait @CfaEnum@:
     10\begin{cfa}
     11forall( E ) trait CfaEnum {
     12        const char * @label@( E e );
     13        unsigned int @posn@( E e );
     14};
     15\end{cfa}
     16asserts an enumeration type @E@ has named enumerator constants (@label@) with positions (@posn@).
     17
     18The trait @TypedEnum@ extends @CfaEnum@:
     19\begin{cfa}
     20forall( E, V | CfaEnum( E ) ) trait TypedEnum {
     21        V @value@( E e );
     22};
     23\end{cfa}
     24asserting an enumeration type @E@ can have homogeneous enumerator values of type @V@.
     25
     26The declarative syntax
     27\begin{cfa}
     28enum(T) E { A = ..., B = ..., C = ... };
     29\end{cfa}
     30creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically.
     31\begin{cfa}
     32void foo( T t ) { ... }
     33void bar(E e) {
     34        choose ( e ) {
     35                case A: printf( "\%d", posn( e) );
     36                case B: printf( "\%s", label( e ) );
     37                case C: foo( value( e ) );
     38        }
     39}
     40\end{cfa}
     41
     42Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg:
     43\begin{cfa}
     44#include <string.hfa>
     45forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} )
     46string formatEnum( E e ) {
     47        unsigned int v = toUnsigned( value( e ) );
     48        string out = label(e) + '(' + v +')';
     49        return out;
     50}
     51formatEnum( Week.Mon );
     52formatEnum( RGB.Green );
     53\end{cfa}
     54
     55\CFA does not define attribute functions for C-style enumeration.
     56But it is possible for users to explicitly implement enumeration traits for C enum and any other types.
     57\begin{cfa}
     58enum Fruit { Apple, Pear, Cherry };                     $\C{// C enum}$
     59const char * label( Fruit f ) {
     60        choose ( f ) {
     61                case Apple: return "Apple";
     62                case Bear: return "Pear";
     63                case Cherry: return "Cherry";
     64        }
     65}
     66unsigned posn( Fruit f ) { return f; }
     67const char * value( Fruit f ) { return ""; } $\C{// value can return any non void type}$
     68formatEnum( Apple );                                            $\C{// Fruit is now a \CFA enum}$
     69\end{cfa}
     70
     71A type that implements trait @CfaEnum@, \ie, a type has no @value@, is called an opaque enum.
     72
     73% \section{Enumerator Opaque Type}
     74
     75% \CFA provides a special opaque enumeration type, where the internal representation is chosen by the compiler and only equality operations are available.
     76\begin{cfa}
     77enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
     78\end{cfa}
     79
     80
     81In addition, \CFA implements @Bound@ and @Serial@ for \CFA enumerations.
     82\begin{cfa}
     83forall( E ) trait Bounded {
     84        E first();
     85        E last();
     86};
     87\end{cfa}
     88The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
     89\begin{cfa}
     90Workday day = first();                                  $\C{// Mon}$
     91Planet outermost = last();                              $\C{// NEPTUNE}$
     92\end{cfa}
     93@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.
     94Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
     95\begin{cfa}
     96@first();@                                                              $\C{// ambiguous because both Workday and Planet implement Bounded}$
     97sout | @last()@;
     98Workday day = first();                                  $\C{// day provides type Workday}$
     99void foo( Planet p );
     100foo( last() );                                                  $\C{// argument provides type Planet}$
     101\end{cfa}
     102
     103The trait @Serial@:
     104\begin{cfa}
     105forall( E | Bounded( E ) ) trait Serial {
     106        unsigned fromInstance( E e );
     107        E fromInt( unsigned int posn );
     108        E succ( E e );
     109        E pred( E e );
     110};
     111\end{cfa}
     112is a @Bounded@ trait, where elements can be mapped to an integer sequence.
     113A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value.
     114%However, the inverse may not be possible, and possible requires a bound check.
     115The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
     116The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
     117Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@.
     118
     119The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
     120Specifically, 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()$.
     121The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
     122
     123Finally, there is an associated trait defining comparison operators among enumerators.
     124\begin{cfa}
     125forall( E, T | CfaEnum( E, T ) ) {
     126        // comparison
     127        int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
     128        int ?!=?( E l, E r );           $\C{// true if l and r are different enumerators}$
     129        int ?!=?( E l, zero_t );        $\C{// true if l is not the first enumerator}$
     130        int ?<?( E l, E r );            $\C{// true if l is an enumerator before r}$
     131        int ?<=?( E l, E r );           $\C{// true if l before or the same as r}$
     132        int ?>?( E l, E r );            $\C{// true if l is an enumerator after r}$
     133        int ?>=?( E l, E r );           $\C{// true if l after or the same as r}$         
     134}
     135\end{cfa}
     136
     137As an alternative, users can define the boolean conversion for CfaEnum:
     138
     139\begin{cfa}
     140forall(E | CfaEnum(E))
     141bool ?!=?(E lhs, zero_t) {
     142        return posn(lhs) != 0;
     143}
     144\end{cfa}
     145which effectively turns the first enumeration as a logical zero and non-zero for others.
     146
     147\begin{cfa}
     148Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
     149p(variable_a); // 0
     150p(variable_b); // 1
     151p(variable_c); // "Third"
     152p(variable_d); // 3
     153\end{cfa}
     154
     155
     156\section{Enumeration Variable}
     157
     158Although \CFA enumeration captures three different attributes, an enumeration instance does not store all this information.
     159The @sizeof@ a \CFA enumeration instance is always 4 bytes, the same size as a C enumeration instance (@sizeof( int )@).
     160It comes from the fact that:
     161\begin{enumerate}
     162\item
     163a \CFA enumeration is always statically typed;
     164\item
     165it is always resolved as one of its attributes regarding real usage.
     166\end{enumerate}
     167When creating an enumeration instance @colour@ and assigning it with the enumerator @Color.Green@, the compiler allocates an integer variable and stores the position 1.
     168The invocations of $positions()$, $value()$, and $label()$ turn into calls to special functions defined in the prelude:
     169\begin{cfa}
     170position( green );
     171>>> position( Colour, 1 ) -> int
     172value( green );
     173>>> value( Colour, 1 ) -> T
     174label( green );
     175>>> label( Colour, 1) -> char *
     176\end{cfa}
     177@T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example.
     178These generated functions are $Companion Functions$, they take an $companion$ object and the position as parameters.
     179
    2180
    3181\section{Enumeration Data}
  • doc/theses/jiada_liang_MMath/intro.tex

    re561551 ra03ed29  
    44Constants can be overloaded among types, \eg @0@ is a null pointer for all pointer types, and the value zero for integer and floating-point types.
    55(In \CFA, the constants @0@ and @1@ can be overloaded for any type.)
    6 A constant's symbolic name is dictated by language syntax related to types.
     6A constant's symbolic name is dictated by language syntax related to types, \eg @5.@ (double), @5.0f@ (float), @5l@ (long double).
    77In general, the representation of a constant's value is \newterm{opaque}, so the internal representation can be chosen arbitrarily.
    88In theory, there are an infinite set of constant names per type representing an infinite set of values.
     
    1313
    1414Many programming languages capture this important software-engineering capability through a mechanism called \newterm{constant} or \newterm{literal} naming, where a new constant is aliased to an existing constant.
    15 Its purpose is for readability, replacing a constant name that directly represents a value with a name that is more symbolic and meaningful in the context of the program.
     15Its purpose is for readability: replacing a constant name that directly represents a value with a name that is more symbolic and meaningful in the context of the program.
    1616Thereafter, changing the aliasing of the new constant to another constant automatically distributes the rebinding, preventing errors.
    1717% and only equality operations are available, \eg @O_RDONLY@, @O_WRONLY@, @O_CREAT@, @O_TRUNC@, @O_APPEND@.
     
    6767\label{s:Terminology}
    6868
    69 The term \newterm{enumeration} defines a type with a set of new constants, and the term \newterm{enumerator} represents an arbitrary alias name \see{\VRef{s:CEnumeration} for the name derivation}.
    70 As well, an enumerated type can have three fundamental properties, \newterm{label}, \newterm{order}, and \newterm{value}.
     69The term \newterm{enumeration} defines a type with a set of new constants, and the term \newterm{enumerator} represents an arbitrary alias name \see{\VRef{s:CEnumeration} for the name derivations}.
     70An enumerated type can have three fundamental properties, \newterm{label} (name), \newterm{order} (position), and \newterm{value} (payload).
    7171\begin{cquote}
    7272\sf\setlength{\tabcolsep}{3pt}
     
    111111\end{cfa}
    112112The alias name is logically replaced in the program text by its matching constant.
    113 It is possible to compare aliases, if the constants allow it, \eg @Size < Pi@;
    114 whereas \eg @Pi < Name@ might be disallowed depending on the language.
     113It is possible to compare aliases, if the constants allow it, \eg @Size < Pi@, whereas @Pi < Name@ might be disallowed depending on the language.
    115114
    116115Aliasing is not macro substitution, \eg @#define Size 20@, where a name is replaced by its value \emph{before} compilation, so the name is invisible to the programming language.
     
    133132Any reordering of the enumerators requires manual renumbering.
    134133\begin{cfa}
    135 const Sun = 1, Mon = 2, Tue = 3, Wed = 4, Thu = 5, Fri = 6, Sat = 7;
     134const @Sun = 1@, Mon = 2, Tue = 3, Wed = 4, Thu = 5, Fri = 6, Sat = 7;
    136135\end{cfa}
    137136For these reasons, aliasing is sometimes called an enumeration.
Note: See TracChangeset for help on using the changeset viewer.