Changes in / [2363147:b522435]


Ignore:
Files:
4 edited

Legend:

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

    r2363147 rb522435  
    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
     12C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the name @enum@ is misleading (@const@ would be better).
     13Given the existence of this form, it is straightforward to extend it with types other than @int@.
     14\begin{cfa}
     15enum E { Size = 20u, PI = 3.14159L, Jack = L"John" };
     16\end{cfa}
     17which matches with @const@ aliasing in other programming languages.
     18Here, the type of the enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@.
     19Auto-initialization is restricted to the case where all constants are @int@, matching with C.
     20As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations.
    2321
    2422
     
    3028
    3129The \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.
     30Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name.
    3431Finally, qualification and casting are provided to disambiguate any ambiguous situations.
    3532\begin{cfa}
     
    3835E1 f() { return Third; }                                $\C{// overloaded functions, different return types}$
    3936E2 f() { return Fourth; }
    40 void g(E1 e);
    41 void h(E2 e);
    4237void foo() {
    4338        E1 e1 = First;   E2 e2 = First;         $\C{// initialization}$
    4439        e1 = Second;   e2 = Second;                     $\C{// assignment}$
    45         e1 = f();   e2 = f();                           $\C{// function return}$
    46         g(First); h(First);                                     $\C{// function parameter}$
     40        e1 = f();   e2 = f();                           $\C{// function call}$
    4741        int i = @E1.@First + @E2.@First;        $\C{// disambiguate with qualification}$
    4842        int j = @(E1)@First + @(E2)@First;      $\C{// disambiguate with cast}$
     
    7872
    7973
    80 \section{Enumeration Traits}
    81 
    82 \CFA defines the set of traits containing operators and helper functions for @enum@.
     74\section{Enumeration Trait}
     75
     76The header file \lstinline[deletekeywords=enum]{<enum.hfa>} defines the set of traits containing operators and helper functions for @enum@.
    8377A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA.
    8478Each trait is discussed in detail.
    8579
    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.
     80The trait @Bounded@:
    16081\begin{cfa}
    16182forall( E ) trait Bounded {
     
    16485};
    16586\end{cfa}
    166 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg:
     87defines the bounds of the enumeration, where @first()@ returns the first enumerator and @last()@ returns the last, \eg:
    16788\begin{cfa}
    16889Workday day = first();                                  $\C{// Mon}$
     
    17293Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration.
    17394\begin{cfa}
    174 @first();@                                                              $\C{// ambiguous because both Workday and Planet implement Bounded}$
     95@first();@                                                              $\C{// ambiguous Workday and Planet implement Bounded}$
    17596sout | @last()@;
    17697Workday day = first();                                  $\C{// day provides type Workday}$
     
    195116Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@.
    196117
    197 The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal.
     118The @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.
    198119Specifically, 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()$.
    199120The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@.
    200121
     122The trait @TypedEnum@:
     123\begin{cfa}
     124forall( E, T ) trait TypedEnum {
     125        T valueE( E e );
     126        char * labelE( E e );
     127        unsigned int posE( E e );
     128};
     129\end{cfa}
     130captures 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 { ... };@.
     132Implementing general functions across all enumeration types is possible by asserting @TypeEnum( E, T )@, \eg:
     133\begin{cfa}
     134forall( E, T | TypeEnum( E, T ) )
     135void printEnum( E e ) {
     136        sout | "Enum "| labelE( e );
     137}
     138printEunm( MARS );
     139\end{cfa}
     140
    201141Finally, there is an associated trait defining comparison operators among enumerators.
    202142\begin{cfa}
    203 forall( E, T | CfaEnum( E, T ) ) {
     143forall( E, T | TypedEnum( E, T ) ) {
    204144        // comparison
    205145        int ?==?( E l, E r );           $\C{// true if l and r are same enumerators}$
     
    212152}
    213153\end{cfa}
    214 
    215 \section{Typed Enum}
     154Note, the overloaded operators are defined only when the header @<enum.hfa>@ is included.
     155If 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>
     158enum( int ) Fruits { APPLE = 2, BANANA = 10, CHERRY = 2 };
     159APPLE == CHERRY; // true because valueE( APPLE ) == valueE( CHERRY )
     160
     161#include <enum.hfa>
     162APPLE == CHERRY; // false because posE( APPLE ) != posE( CHERRY )
     163\end{cfa}
     164An enumerator returns its @position@ by default.
     165In particular, @printf( ... )@ from @<stdio.h>@ functions provides no context to its parameter type, so it prints @position@.
     166On 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}
     168printf( "Position of BANANA is \%d", BANANA ); // Position of BANANA is 1
     169sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10
     170\end{cfa}
     171Programmers 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}
    216191\label{s:EnumeratorTyping}
    217192
     
    281256calling constructors happens at runtime (dynamic).
    282257
     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}
     263enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE };
     264\end{cfa}
     265
     266
    283267\section{Enumeration Inheritance}
    284268
    285269\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 
    287270\begin{cfa}
    288271enum( char * ) Names { /* as above */ };
    289272enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" };
    290 enum( char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
    291 \end{cfa}
    292 
     273@***@enum /* inferred */ Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" };
     274\end{cfa}
    293275Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@.
    294 Note, 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@.
     276Note, enumerators must be unique in inheritance but enumerator values may be repeated.
     277
     278The enumeration type for the inheriting type must be the same as the inherited type;
     279hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@.
    298280% When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
    299281Specifically, the inheritance relationship for @Names@ is:
    300282\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}$
     283Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$
    308284\end{cfa}
    309285For the given function prototypes, the following calls are valid.
     
    321297g( Fred );   g( Jill );
    322298h( Fred );   h( Jill );   h( Sue );
    323 j( Fred );    j( Jill );    j( Sue );    j( "WILL" );
     299 j( Fred );    j( Jill );    j( Sue );    j( "WILL" );
    324300\end{cfa}
    325301\end{tabular}
     
    327303Note, 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.
    328304
     305
    329306\section{Enumerator Control Structures}
    330307
     
    332309In most programming languages, an enumerator is implicitly converted to its value (like a typed macro substitution).
    333310However, enumerator synonyms and typed enumerations make this implicit conversion to value incorrect in some contexts.
    334 In these contexts, a programmer's initition assumes an implicit conversion to position.
    335 
    336 For 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.
     311In these contexts, a programmer's initition assumes an implicit conversion to postion.
     312
     313For 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.
    337314\begin{cquote}
    338315\begin{cfa}
     
    367344enum Count { First, Second, Third @= First@, Fourth };
    368345\end{cfa}
    369 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.
     346which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses.
    370347To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context.
    371 For conditional clauses and switch statements, \CFA uses the robust position implementation.
     348For conditional clauses and switch statments, \CFA uses the robust position implementation.
    372349\begin{cfa}
    373350choose( @position@( e ) ) {
     
    387364\end{cfa}
    388365
    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 
    411 \begin{cfa}
    412 enum(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.
     366
     367@if@ statement
     368
     369@switch@ statement
     370
     371looping statements
     372
    442373
    443374\section{Enumerated Arrays}
    444 Enumerated arrays use an \CFA array as their index.
     375Enumerated array use an \CFA array as their index.
    445376\begin{cfa}
    446377enum() Colour {
     
    457388\VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating most of the \CFA enumeration features.
    458389@Planet@ is an enumeration of type @MR@.
    459 Each planet enumerator is initialized to a specific mass/radius, @MR@, value.
     390Each of the planet enumerators is initialized to a specific mass/radius, @MR@, value.
    460391The unnamed enumeration provides the gravitational-constant enumerator @G@.
    461392Function @surfaceGravity@ uses the @with@ clause to remove @p@ qualification from fields @mass@ and @radius@.
    462393The 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@.
    463394The resulting random orbital-body is used in a @choose@ statement.
    464 The enumerators in the @case@ clause use the enumerator position for testing.
     395The enumerators in the @case@ clause use enumerator position for testing.
    465396The prints use @label@ to print an enumerator's name.
    466397Finally, a loop enumerates through the planets computing the weight on each planet for a given earth mass.
  • libcfa/src/enum.cfa

    r2363147 rb522435  
    4242        if ( eof( is ) ) throwResume ExceptionInst( missing_data );
    4343
    44         // Match longest input enumerator string to enumerator labels, where enumerator names are unique.
    45 
     44        // Match input enumerator string to enumerator labels.
    4645        int N = Countof( e ), lnths[N], max = 0;
    4746//      printf( "N %d\n", N );
     
    6160        for ( c; max ) {
    6261                int args = fmt( is, "%c", &ch );                                // read character
    63           if ( eof( is ) ) {
     62                if ( eof( is ) ) {
    6463//                      fprintf( stderr, "Eof1\n" );
    6564                        if ( c == 0 ) return is;                                        // no characters read ?
    66                         clear( is );                                                            // => read something => reset EOF => detect again on next read
     65                        clear( is );                                                            // => reset EOF => detect again on next read
    6766//                      fprintf( stderr, "Eof2\n" );
    68                         break;
    69                 } // if
     67                        goto W;
     68                }
    7069                if ( args != 1 ) throwResume ExceptionInst( missing_data );
    71 
    7270//              printf( "read '%c'\n", ch );
    73                 for ( i; N ) {                                                                  // scan enumeration strings for winner
     71                for ( i; N ) {
    7472//                      printf( "%d %d %d\n", c, i, lnths[i] );
    7573                        if ( c < lnths[i] ) {                                           // eligible for this checking round ?
    7674                                char match = label( fromInt( i ) )[c];  // optimization
    7775//                              printf( "%c '%c'\n", match, ch );
    78                                 // Stop on first match, could be other matches.
    7976                                if ( (match == ch) && (c == 0 || curr == label( fromInt( i ) )[c - 1]) ) {
    8077//                                      printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, i, lnths[i], match, ch, prev, label( fromInt( i ) )[c - 1] );
     
    9592//              fprintf( stderr, "finished2 %d\n", win );
    9693        } // for
    97   W: ;
    98         for ( i; N ) {                                                                          // scan enumeration strings for winner
     94  W :;
     95        for ( i; N ) {                                                                          // scan for winner, must succeed
    9996                if ( win == lnths[i] - 1 ) {
    10097                        char match = label( fromInt( i ) )[win];        // optimization
     
    103100                                e = fromInt( i );
    104101                                break;
    105                         } // if
     102                        }
    106103                } // if
    107104        } else {
  • libcfa/src/iostream.cfa

    r2363147 rb522435  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 15 08:16:48 2024
    13 // Update Count     : 2020
     12// Last Modified On : Fri Jul 12 05:45:45 2024
     13// Update Count     : 2019
    1414//
    1515
     
    781781                // Optional leading whitespace at start of strings.
    782782                fmt( is, " " FALSE "%n", &len );                                // try false
    783                 if ( len != sizeof( FALSE ) - 1 ) {                             // -1 removes null terminate
     783                if ( len != sizeof( FALSE ) - 1 ) {                             // remove null terminate
    784784                        fmt( is, " " TRUE "%n", &len );                         // try true
    785785                        if ( len != sizeof( TRUE ) - 1 ) throwResume ExceptionInst( missing_data );
  • src/ResolvExpr/CandidateFinder.cpp

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