Ignore:
Timestamp:
Jul 24, 2024, 7:11:32 PM (6 weeks 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

File:
1 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)
Note: See TracChangeset for help on using the changeset viewer.