Changeset d1276f8


Ignore:
Timestamp:
Jul 24, 2024, 11:25:16 AM (4 hours ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
35c792f
Parents:
10a99d87
Message:

move enumeration trait material into implementation chapter

File:
1 edited

Legend:

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

    r10a99d87 rd1276f8  
    11\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@.
     8A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
     9Each trait is discussed in detail.
     10
     11The trait @CfaEnum@:
     12\begin{cfa}
     13forall( E ) trait CfaEnum {
     14        const char * @label@( E e );
     15        unsigned int @posn@( E e );
     16};
     17\end{cfa}
     18asserts an enumeration type @E@ has named enumerator constants (@label@) with positions (@posn@).
     19
     20The trait @TypedEnum@ extends @CfaEnum@:
     21\begin{cfa}
     22forall( E, V | CfaEnum( E ) ) trait TypedEnum {
     23        V @value@( E e );
     24};
     25\end{cfa}
     26asserting an enumeration type @E@ can have homogeneous enumerator values of type @V@.
     27
     28The declarative syntax
     29\begin{cfa}
     30enum(T) E { A = ..., B = ..., C = ... };
     31\end{cfa}
     32creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically.
     33\begin{cfa}
     34void foo( T t ) { ... }
     35void 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
     44Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg:
     45\begin{cfa}
     46#include <string.hfa>
     47forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} )
     48string formatEnum( E e ) {
     49        unsigned int v = toUnsigned( value( e ) );
     50        string out = label(e) + '(' + v +')';
     51        return out;
     52}
     53formatEnum( Week.Mon );
     54formatEnum( RGB.Green );
     55\end{cfa}
     56
     57\CFA does not define attribute functions for C-style enumeration.
     58But it is possible for users to explicitly implement enumeration traits for C enum and any other types.
     59\begin{cfa}
     60enum Fruit { Apple, Pear, Cherry };                     $\C{// C enum}$
     61const char * label( Fruit f ) {
     62        choose ( f ) {
     63                case Apple: return "Apple";
     64                case Bear: return "Pear";
     65                case Cherry: return "Cherry";
     66        }
     67}
     68unsigned posn( Fruit f ) { return f; }
     69const char * value( Fruit f ) { return ""; } $\C{// value can return any non void type}$
     70formatEnum( Apple );                                            $\C{// Fruit is now a \CFA enum}$
     71\end{cfa}
     72
     73A 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}
     79enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
     80\end{cfa}
     81
     82
     83In addition, \CFA implements @Bound@ and @Serial@ for \CFA enumerations.
     84\begin{cfa}
     85forall( E ) trait Bounded {
     86        E first();
     87        E last();
     88};
     89\end{cfa}
     90The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
     91\begin{cfa}
     92Workday day = first();                                  $\C{// Mon}$
     93Planet 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.
     96Calling 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}$
     99sout | @last()@;
     100Workday day = first();                                  $\C{// day provides type Workday}$
     101void foo( Planet p );
     102foo( last() );                                                  $\C{// argument provides type Planet}$
     103\end{cfa}
     104
     105The trait @Serial@:
     106\begin{cfa}
     107forall( 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}
     114is a @Bounded@ trait, where elements can be mapped to an integer sequence.
     115A 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.
     117The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position.
     118The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator.
     119Specifically, 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
     121The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
     122Specifically, 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()$.
     123The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
     124
     125Finally, there is an associated trait defining comparison operators among enumerators.
     126\begin{cfa}
     127forall( 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
     139As an alternative, users can define the boolean conversion for CfaEnum:
     140
     141\begin{cfa}
     142forall(E | CfaEnum(E))
     143bool ?!=?(E lhs, zero_t) {
     144        return posn(lhs) != 0;
     145}
     146\end{cfa}
     147which effectively turns the first enumeration as a logical zero and non-zero for others.
     148
     149\begin{cfa}
     150Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth;
     151p(variable_a); // 0
     152p(variable_b); // 1
     153p(variable_c); // "Third"
     154p(variable_d); // 3
     155\end{cfa}
    2156
    3157
Note: See TracChangeset for help on using the changeset viewer.