Changeset 1dd5fd1


Ignore:
Timestamp:
Jul 15, 2024, 10:39:57 PM (3 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
2363147
Parents:
d796be70 (diff), 09dd830 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
3 added
2 edited

Legend:

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

    rd796be70 r1dd5fd1  
    77The following sections detail all of my new contributions to enumerations in \CFA.
    88
    9 
    10 \section{Aliasing}
    11 
    12 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).
    13 Given the existence of this form, it is straightforward to extend it with types other than @int@.
    14 \begin{cfa}
    15 enum E { Size = 20u, PI = 3.14159L, Jack = L"John" };
    16 \end{cfa}
    17 which matches with @const@ aliasing in other programming languages.
    18 Here, the type of the enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@.
    19 Auto-initialization is restricted to the case where all constants are @int@, matching with C.
    20 As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations.
     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.
    2123
    2224
     
    2830
    2931The \CFA type-system allows extensive overloading, including enumerators.
    30 Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name.
     32Furthermore, \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.
    3134Finally, qualification and casting are provided to disambiguate any ambiguous situations.
    3235\begin{cfa}
     
    3538E1 f() { return Third; }                                $\C{// overloaded functions, different return types}$
    3639E2 f() { return Fourth; }
     40void g(E1 e);
     41void h(E2 e);
    3742void foo() {
    3843        E1 e1 = First;   E2 e2 = First;         $\C{// initialization}$
    3944        e1 = Second;   e2 = Second;                     $\C{// assignment}$
    40         e1 = f();   e2 = f();                           $\C{// function call}$
     45        e1 = f();   e2 = f();                           $\C{// function return}$
     46        g(First); h(First);                                     $\C{// function parameter}$
    4147        int i = @E1.@First + @E2.@First;        $\C{// disambiguate with qualification}$
    4248        int j = @(E1)@First + @(E2)@First;      $\C{// disambiguate with cast}$
     
    7278
    7379
    74 \section{Enumeration Trait}
    75 
    76 The header file \lstinline[deletekeywords=enum]{<enum.hfa>} defines the set of traits containing operators and helper functions for @enum@.
     80\section{Enumeration Traits}
     81
     82\CFA defines the set of traits containing operators and helper functions for @enum@.
    7783A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
    7884Each trait is discussed in detail.
    7985
    80 The trait @Bounded@:
     86The trait @CfaEnum@:
     87\begin{cfa}
     88forall( E ) trait CfaEnum {
     89        char * label( E e );
     90        unsigned int posn( E e );
     91};
     92\end{cfa}
     93
     94describes an enumeration as a named constant with position. And @TypeEnum@
     95\begin{cfa}
     96forall( E, V ) trait TypeEnum {
     97        V value( E e );
     98};     
     99\end{cfa}
     100asserts two types @E@ and @T@, with @T@ being the base type for the enumeration @E@.
     101
     102The declarative syntax
     103\begin{cfa}
     104enum(T) E { A = ..., B = ..., C = ... };
     105\end{cfa}
     106creates an enumerated type E with @label@, @posn@ and @value@ implemented automatically.
     107
     108\begin{cfa}
     109void foo( T t ) { ... }
     110void 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
     119Implementing general functions across all enumeration types is possible by asserting @CfaEnum( E, T )@, \eg:
     120\begin{cfa}
     121#include <string.hfa>
     122forall( E, T | CfaEnum( E, T ) | {unsigned int toUnsigned(T)} )
     123string formatEnum( E e ) {
     124        unsigned int v = toUnsigned(value(e));
     125        string out = label(e) + '(' + v +')';
     126        return out;
     127}
     128printEunm( Week.Mon );
     129printEnum( 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
     133enumeration traits for C enum and any other types.
     134
     135\begin{cfa}
     136enum Fruit { Apple, Bear, Cherry };                     $\C{// C enum}$
     137char * label(Fruit f) {
     138        switch(f) {
     139                case Apple: "A"; break;
     140                case Bear: "B"; break;
     141                case Cherry: "C"; break;
     142        }
     143}
     144unsigned posn(Fruit f) { return f; }
     145char* value(Fruit f) { return ""; }             $\C{// value can return any non void type}$
     146formatEnum( Apple );                                                    $\C{// Fruit is now a Cfa enum}$
     147\end{cfa}
     148
     149A 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}
     155enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
     156\end{cfa}
     157
     158
     159In addition, \CFA implements @Bound@ and @Serial@ for \CFA Enums.
    81160\begin{cfa}
    82161forall( E ) trait Bounded {
     
    85164};
    86165\end{cfa}
    87 defines the bounds of the enumeration, where @first()@ returns the first enumerator and @last()@ returns the last, \eg:
     166The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
    88167\begin{cfa}
    89168Workday day = first();                                  $\C{// Mon}$
     
    93172Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
    94173\begin{cfa}
    95 @first();@                                                              $\C{// ambiguous Workday and Planet implement Bounded}$
     174@first();@                                                              $\C{// ambiguous because both Workday and Planet implement Bounded}$
    96175sout | @last()@;
    97176Workday day = first();                                  $\C{// day provides type Workday}$
     
    116195Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@.
    117196
    118 The @Serial@ trait also requires interface functions @succ( E e )@ and @pred( E e )@ be implemented for a serial type, which imply the enumeration positions are consecutive and ordinal.
     197The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
    119198Specifically, 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()$.
    120199The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
    121200
    122 The trait @TypedEnum@:
    123 \begin{cfa}
    124 forall( E, T ) trait TypedEnum {
    125         T valueE( E e );
    126         char * labelE( E e );
    127         unsigned int posE( E e );
    128 };
    129 \end{cfa}
    130 captures three basic attributes of an enumeration type: value, label, and position.
    131 @TypedEnum@ asserts two types @E@ and @T@, with @T@ being the base type of the enumeration @E@, \eg @enum( T ) E { ... };@.
    132 Implementing general functions across all enumeration types is possible by asserting @TypeEnum( E, T )@, \eg:
    133 \begin{cfa}
    134 forall( E, T | TypeEnum( E, T ) )
    135 void printEnum( E e ) {
    136         sout | "Enum "| labelE( e );
    137 }
    138 printEunm( MARS );
    139 \end{cfa}
    140 
    141201Finally, there is an associated trait defining comparison operators among enumerators.
    142202\begin{cfa}
    143 forall( E, T | TypedEnum( E, T ) ) {
     203forall( E, T | CfaEnum( E, T ) ) {
    144204        // comparison
    145205        int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
     
    152212}
    153213\end{cfa}
    154 Note, the overloaded operators are defined only when the header @<enum.hfa>@ is included.
    155 If not, the compiler converts an enumerator to its value, and applies the operators defined for the value type @E@, \eg:
    156 \begin{cfa}
    157 // if not include <enum.hfa>
    158 enum( int ) Fruits { APPLE = 2, BANANA = 10, CHERRY = 2 };
    159 APPLE == CHERRY; // true because valueE( APPLE ) == valueE( CHERRY )
    160 
    161 #include <enum.hfa>
    162 APPLE == CHERRY; // false because posE( APPLE ) != posE( CHERRY )
    163 \end{cfa}
    164 An enumerator returns its @position@ by default.
    165 In particular, @printf( ... )@ from @<stdio.h>@ functions provides no context to its parameter type, so it prints @position@.
    166 On the other hand, the pipeline operator @?|?( ostream os, E enumType )@ provides type context for type @E@, and \CFA has overwritten this operator to print the enumeration @value@ over @position@.
    167 \begin{cfa}
    168 printf( "Position of BANANA is \%d", BANANA ); // Position of BANANA is 1
    169 sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10
    170 \end{cfa}
    171 Programmers can overwrite this behaviour by overloading the pipeline operator themselves.
    172 \PAB{This needs discussing because including \lstinline{<enum.hfa>} can change the entire meaning of a program.}
    173 
    174 
    175 % \section{Enumeration Pseudo-functions}
    176 
    177 % Pseudo-functions are function-like operators that do not result in any run-time computations, \ie like @sizeof@, @alignof@, @typeof@.
    178 % A pseudo-function call is often substituted with information extracted from the compilation symbol-table, like storage size or alignment associated with the underlying architecture.
    179 
    180 % The attributes of an enumerator are accessed by pseudo-functions @posE@, @valueE@, and @labelE@.
    181 % \begin{cfa}
    182 % int jane_pos = @posE@( Names.Jane );   $\C{// 2}$
    183 % char * jane_value = @valueE@( Names.Jane ); $\C{// "JANE"}$
    184 % char * jane_label = @labelE@( Names.Jane ); $\C{// "Jane"}$
    185 % sout | posE( Names.Jane) | labelE( Names.Jane ) | valueE( Names.Jane );
    186 % \end{cfa}
    187 % Note the ability to print all of an enumerator's properties.
    188 
    189 
    190 \section{Enumerator Typing}
     214
     215\section{Typed Enum}
    191216\label{s:EnumeratorTyping}
    192217
     
    256281calling constructors happens at runtime (dynamic).
    257282
    258 
    259 \section{Enumerator Opaque Type}
    260 
    261 \CFA provides a special opaque enumeration type, where the internal representation is chosen by the compiler and only equality operations are available.
    262 \begin{cfa}
    263 enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
    264 \end{cfa}
    265 
    266 
    267283\section{Enumeration Inheritance}
    268284
    269285\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
    270287\begin{cfa}
    271288enum( char * ) Names { /* as above */ };
    272289enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" };
    273 @***@enum /* inferred */ Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
    274 \end{cfa}
     290enum( char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
     291\end{cfa}
     292
    275293Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@.
    276 Note, enumerators must be unique in inheritance but enumerator values may be repeated.
    277 
    278 The enumeration type for the inheriting type must be the same as the inherited type;
    279 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@.
     294Note, that enumerators must be unique in inheritance but enumerator values may be repeated.
     295
     296% The enumeration type for the inheriting type must be the same as the inherited type;
     297% hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@.
    280298% When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
    281299Specifically, the inheritance relationship for @Names@ is:
    282300\begin{cfa}
    283 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$
     301Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\C{// enum type of Names}$
     302\end{cfa}
     303A 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}
     305Names fred = Name.Fred;
     306(Names2) fred; (Names3) fred; (Name3) Names.Jack;  $\C{// cast to super type}$
     307Names2 fred2 = fred; Names3 fred3 = fred2; $\C{// assign to super type}$
    284308\end{cfa}
    285309For the given function prototypes, the following calls are valid.
     
    297321g( Fred );   g( Jill );
    298322h( Fred );   h( Jill );   h( Sue );
    299  j( Fred );    j( Jill );    j( Sue );    j( "WILL" );
     323j( Fred );    j( Jill );    j( Sue );    j( "WILL" );
    300324\end{cfa}
    301325\end{tabular}
     
    303327Note, 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.
    304328
    305 
    306329\section{Enumerator Control Structures}
    307330
     
    309332In most programming languages, an enumerator is implicitly converted to its value (like a typed macro substitution).
    310333However, enumerator synonyms and typed enumerations make this implicit conversion to value incorrect in some contexts.
    311 In these contexts, a programmer's initition assumes an implicit conversion to postion.
    312 
    313 For example, an intuitive use of enumerations is with the \CFA @switch@/@choose@ statement, where @choose@ performs an implict @break@ rather than a fall-through at the end of a @case@ clause.
     334In these contexts, a programmer's initition assumes an implicit conversion to position.
     335
     336For 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.
    314337\begin{cquote}
    315338\begin{cfa}
     
    344367enum Count { First, Second, Third @= First@, Fourth };
    345368\end{cfa}
    346 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses.
     369which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
    347370To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context.
    348 For conditional clauses and switch statments, \CFA uses the robust position implementation.
     371For conditional clauses and switch statements, \CFA uses the robust position implementation.
    349372\begin{cfa}
    350373choose( @position@( e ) ) {
     
    364387\end{cfa}
    365388
    366 
    367 @if@ statement
    368 
    369 @switch@ statement
    370 
    371 looping statements
    372 
     389\begin{cfa}
     390for (d; Workday) { sout | d; }
     391for (p; +~=Planet) { sout | p; }
     392for (c: -~=Alphabet ) { sout | c; }
     393\end{cfa}
     394The @range loop@ for enumeration is a syntax sugar that loops over all enumerators and assigns each enumeration to a variable in every iteration.
     395The loop control of the range loop consists of two parts: a variable declaration and a @range expression@, with the type of the variable
     396can be inferred from the range expression.
     397
     398The range expression is an enumeration type, optionally prefixed by @+~=@ or @-~=@. Without a prefix, or prefixed with @+~=@, the control
     399loop over all enumerators from the first to the last. With a @-~=@ prefix, the control loops backward.
     400
     401On a side note, the loop syntax
     402\begin{cfa}
     403for ( typeof(Workday) d; d <= last(); d = succ(d) );
     404\end{cfa}
     405does 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.
     408Overloading the @!=@ operator with an enumeration type against the zero defines a conceptual conversion from
     409enum to boolean, which can be used as predicates.
     410
     411\begin{cfa}
     412enum(int) ErrorCode { Normal = 0, Slow = 1, Overheat = 1000, OutOfResource = 1001 };
     413bool ?!=?(ErrorCode lhs, zero_t) { return value(lhs) >= 1000; }
     414ErrorCode code = /.../
     415if (code) { scream(); }
     416\end{cfa}
     417
     418Incidentally, \CFA does not define boolean conversion for enumeration. If no
     419@?!=?(ErrorCode, zero_t)@
     420overloading 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}
     424enum(int) Weekday { Mon, Tues, Wed, Thurs, Fri, Sat, Sun, };
     425enum() Colour { Red, Green, Blue };
     426enum(S) Fruit { Apple, Banana, Cherry }
     427Weekday w = ...; Colour c = ...; Fruit f = ...;
     428if (w) { ... } // w is true if and only if w != Mon, because value(Mon) == 0 (auto initialized)
     429if (c) { ... } // error
     430if (s) { ... } // depends on ?!=?(S lhs, zero_t ), and error if no such overloading available
     431\end{cfa}
     432
     433As an alternative, users can define the boolean conversion for CfaEnum:
     434
     435\begin{cfa}
     436forall(E | CfaEnum(E))
     437bool ?!=?(E lhs, zero_t) {
     438        return posn(lhs) != 0;
     439}
     440\end{cfa}
     441which effectively turns the first enumeration as a logical zero and non-zero for others.
    373442
    374443\section{Enumerated Arrays}
    375 Enumerated array use an \CFA array as their index.
     444Enumerated arrays use an \CFA array as their index.
    376445\begin{cfa}
    377446enum() Colour {
     
    388457\VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating most of the \CFA enumeration features.
    389458@Planet@ is an enumeration of type @MR@.
    390 Each of the planet enumerators is initialized to a specific mass/radius, @MR@, value.
     459Each planet enumerator is initialized to a specific mass/radius, @MR@, value.
    391460The unnamed enumeration provides the gravitational-constant enumerator @G@.
    392461Function @surfaceGravity@ uses the @with@ clause to remove @p@ qualification from fields @mass@ and @radius@.
    393462The program main uses the pseudo function @countof@ to obtain the number of enumerators in @Planet@, and safely converts the random value into a @Planet@ enumerator using @fromInt@.
    394463The resulting random orbital-body is used in a @choose@ statement.
    395 The enumerators in the @case@ clause use enumerator position for testing.
     464The enumerators in the @case@ clause use the enumerator position for testing.
    396465The prints use @label@ to print an enumerator's name.
    397466Finally, a loop enumerates through the planets computing the weight on each planet for a given earth mass.
  • src/ResolvExpr/CandidateFinder.cpp

    rd796be70 r1dd5fd1  
    14851485
    14861486        void Finder::postvisit( const ast::CountExpr * countExpr ) {
    1487                 const ast::UntypedExpr * untyped;
     1487                const ast::UntypedExpr * untyped = nullptr;
    14881488                if ( countExpr->type ) {
    14891489                        auto enumInst = countExpr->type.as<ast::EnumInstType>();
Note: See TracChangeset for help on using the changeset viewer.