Changeset b202dc2


Ignore:
Timestamp:
Mar 28, 2021, 11:08:44 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
31fc80f, 659fb73
Parents:
9e234f0b
Message:

first draft of enumeration section

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    r9e234f0b rb202dc2  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun Mar  7 21:50:24 2021
    14 %% Update Count     : 4574
     13%% Last Modified On : Sat Mar 27 09:55:55 2021
     14%% Update Count     : 4796
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    21642164
    21652165
     2166\section{Enumeration}
     2167
     2168An \newterm{enumeration} is a compile-time mechanism to give names to constants.
     2169There is no runtime manifestation of an enumeration.
     2170Their purpose is code-readability and maintenance -- changing an enum's value automatically updates all name usages during compilation.
     2171
     2172An enumeration defines a type containing a set of names, each called an \newterm{enumeration constant} (shortened to \newterm{enum}) with a fixed (©const©) value.
     2173\begin{cfa}
     2174enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // enumeration type definition, set of 7 names
     2175Days days = Mon; // enumeration type declaration and initialization
     2176\end{cfa}
     2177The set of enums are injected into the scope of the definition and use the variable namespace.
     2178Hence, enums may be overloaded with enum/variable/function names.
     2179\begin{cfa}
     2180enum Foo { Bar };
     2181enum Goo { Bar };       $\C[1.75in]{// overload Foo.Bar}$
     2182int Foo;                        $\C{// type/variable separate namespace}$
     2183double Bar;                     $\C{// overload Foo.Bar, Goo.Bar}\CRT$
     2184\end{cfa}
     2185An anonymous enumeration is used to inject enums with specific values into a scope:
     2186\begin{cfa}
     2187enum { Prime = 103, BufferSize = 1024 };
     2188\end{cfa}
     2189An enumeration is better than using the C \Index{preprocessor}
     2190\begin{cfa}
     2191#define Mon 0
     2192...
     2193#define Sun 6
     2194\end{cfa}
     2195or C constant declarations
     2196\begin{cfa}
     2197const int Mon = 0, ..., Sun = 6;
     2198\end{cfa}
     2199because the enumeration is succinct, has automatic numbering, can appear in ©case© labels, does not use storage, and is part of the language type-system.
     2200Finally, the type of an enum is implicitly or explicitly specified and the constant value can be implicitly or explicitly specified.
     2201Note, enum values may be repeated in an enumeration.
     2202
     2203
     2204\subsection{Enum type}
     2205
     2206While an enumeration defines a new set-type of names, its underlying enums can be any ©const© type, and an enum's value comes from this type.
     2207\CFA provides an automatic conversion from an enum to its base type, \eg comparing/printing an enum compares/prints its value rather than the enum name.
     2208The default enum type is ©int©.
     2209Hence, ©Days© is the set type ©Mon©, ©Tue©, ...\,, ©Sun©, while the type of each enum is ©int© and each enum represents a fixed integral value.
     2210If no values are specified for an integral enum type, the enums are automatically numbered by one from left to right starting at zero.
     2211Hence, the value of enum ©Mon© is 0, ©Tue© is 1, ...\,, ©Sun© is 6.
     2212If a value is specified, numbering continues by one from that value.
     2213It an enum value is an expression, the compiler performs constant-folding to obtain a constant value.
     2214
     2215Other integral types with associated values can be explicitly specified.
     2216\begin{cfa}
     2217enum( @char@ ) Letter { A @= 'A'@,  B,  C,  I @= 'I'@,  J,  K };
     2218enum( @long long int@ ) BigNum { X = 123_456_789_012_345,  Y = 345_012_789_456_123 };
     2219\end{cfa}
     2220For enumeration ©Letter©, enum ©A©'s value is explicitly set to ©'A'©, with ©B© and ©C© implicitly numbered with increasing values from ©'A'©, and similarly for enums ©I©, ©J©, and ©K©.
     2221Note, an enum is an immutable constant, \ie ©A = B© is disallowed;
     2222by transitivity, an enum's type is implicitly ©const©.
     2223Hence, a constant/enum cannot appear in a mutuable context nor is a constant/enum addressable (rvalue).
     2224
     2225Non-integral enum types have the restriction that all enums \emph{must} be explicitly specified, \ie incrementing by one for the next enum is not done even if supported by the enum type, \eg ©double©.
     2226\begin{cfa}
     2227// non-integral numeric
     2228enum( double ) Math { PI_2 = 1.570796, PI = 3.141597,  E = 2.718282 }
     2229// pointer
     2230enum( char * ) Name { Fred = "Fred",  Mary = "Mary",  Jane = "Jane" };
     2231int i, j, k;
     2232enum( int * ) ptr { I = &i,  J = &j,  K = &k };
     2233enum( int & ) ref { I = i,  J = j,  K = k };
     2234// tuple
     2235enum( [int, int] ) { T = [ 1, 2 ] };
     2236// function
     2237void f() {...}   void g() {...}
     2238enum( void (*)() ) funs { F = f,  F = g };
     2239// aggregate
     2240struct S { int i, j; };
     2241enum( S ) s { A = { 3,  4 }, B = { 7,  8 } };
     2242// enumeration
     2243enum( Letter ) Greek { Alph = A, Beta = B, /* more enums */  }; // alphabet intersection
     2244\end{cfa}
     2245Enumeration ©Greek© may have more or less enums than ©Letter©, but the enum values \emph{must} be from ©Letter©.
     2246Therefore, ©Greek© enums are a subset of type ©Letter© and are type compatible with enumeration ©Letter©, but ©Letter© enums are not type compatible with enumeration ©Greek©.
     2247
     2248The following examples illustrate the difference between the enumeration type and the type of its enums.
     2249\begin{cfa}
     2250Math m = PI;    $\C[1.5in]{// allowed}$
     2251double d = PI;  $\C{// allowed, conversion to base type}$
     2252m = E;                  $\C{// allowed}$
     2253m = Alph;               $\C{// {\color{red}disallowed}}$
     2254m = 3.141597;   $\C{// {\color{red}disallowed}}$
     2255d = E;                  $\C{// allowed, conversion to base type}$
     2256d = m;                  $\C{// {\color{red}disallowed}}$
     2257d = Alph;               $\C{// {\color{red}disallowed}}$
     2258Letter l = A;   $\C{// allowed}$
     2259Greek g = Alph; $\C{// allowed}$
     2260l = Alph;               $\C{// allowed, conversion to base type}$
     2261g = A;                  $\C{// {\color{red}disallowed}}\CRT$
     2262\end{cfa}
     2263
     2264A constructor \emph{cannot} be used to initialize enums because a constructor executes at runtime.
     2265A fallback is to substitute C-style initialization overriding the constructor with ©@=©.
     2266\begin{cfa}
     2267enum( struct vec3 ) Axis { Up $@$= { 1, 0, 0 }, Left $@$= ..., Front $@$= ... }
     2268\end{cfa}
     2269Finally, enumeration variables are assignable and comparable only if the appropriate operators are defined for its enum type.
     2270
     2271
     2272\subsection{Inheritance}
     2273
     2274\Index{Plan-9}\index{inheritance!enumeration} inheritance may be used with enumerations.
     2275\begin{cfa}
     2276enum( const char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" };
     2277enum @/* inferred */@  Name3 { @inline Name@, @inline Name2@, Sue = "Sue", Tom = "Tom" };
     2278\end{cfa}
     2279Enumeration ©Name2© inherits all the enums and their values from enumeration ©Name© by containment, and a ©Name© enumeration is a subtype of enumeration ©Name2©.
     2280Note, enums must be unique in inheritance but enum values may be repeated.
     2281The enum type for the inheriting type must be the same as the inherited type;
     2282hence the enum type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for ©Name3©.
     2283When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
     2284
     2285Specifically, the inheritance relationship for ©Name©s is:
     2286\begin{cfa}
     2287Name $\(\subseteq\)$ Name2 $\(\subseteq\)$ Name3 $\(\subseteq\)$ const char * // enum type of Name
     2288\end{cfa}
     2289Hence, given
     2290\begin{cfa}
     2291void f( Name );
     2292void g( Name2 );
     2293void h( Name3 );
     2294void j( const char * );
     2295\end{cfa}
     2296the following calls are valid
     2297\begin{cfa}
     2298f( Fred );
     2299g( Fred );   g( Jill );
     2300h( Fred );   h( Jill );   h( Sue );
     2301j( Fred );    j( Jill );    j( Sue );    j( 'W' );
     2302\end{cfa}
     2303Note, 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.
     2304
     2305Enums cannot be created at runtime, so inheritence problems, such as contra-variance do not apply.
     2306Only instances of the enum base-type may be created at runtime.
     2307
     2308\begin{comment}
     2309The invariance of references, as I show at the bottom, is easy to overlook.  Not shown, but on the same topic, is that returns work in the opposite direction as parameters.  Hopefully our existing type rules already know both those facts, so that we'd only have to provide the rules that I suggest using the by-value parameters.
     2310
     2311The Fred, Jack, and Mary declarations are picked verbatim from our earlier whiteboard, just repeated here for reference.
     2312
     2313\begin{cfa}
     2314// Fred is a subset of char *
     2315enum char * Fred { A = "A", B = "B", C = "C" };
     2316// Jack is a subset of Fred
     2317enum enum Fred Jack { W = A, Y = C};
     2318// Mary is a superset of Fred
     2319enum Mary { inline Fred, D = "hello" };
     2320
     2321// Demonstrating invariance of references
     2322
     2323[void] frcs( & * char x ) { char * x0 = x; x = "bye"; }
     2324[void] frf ( & Fred   x ) { Fred   x0 = x; x = B;     }
     2325[void] frj ( & Jack   x ) { Jack   x0 = x; x = W;     }
     2326[void] frm ( & Mary   x ) { Mary   x0 = x; x = D;     }
     2327
     2328char * vcs;
     2329Fred   vf;
     2330Jack   vj;
     2331Mary   vm;
     2332
     2333// all variant calls: bad  (here are noteworthy examples)
     2334             frcs( vf  );  // can't assign "bye" to vf
     2335             frm ( vf  );  // can't assign D     to vf
     2336             frf ( vj  );  // can't assign B     to vj
     2337vf  = B    ; frj ( vf  );  // can't assign B     to frj.x0
     2338vcs = "bye"; frf ( vcs );  // can't assign "bye" to frf.x0
     2339\end{cfa}
     2340
     2341This example is really great. However, I think it's work explicitly doing one with ©const &©.
     2342\end{comment}
     2343
     2344
    21662345\section{Routine Definition}
    21672346
    2168 \CFA also supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
     2347\CFA supports a new syntax for routine definition, as well as \Celeven and K\&R routine syntax.
    21692348The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
    21702349\begin{cfa}
     
    21742353\end{cfa}
    21752354where routine ©f© has three output (return values) and three input parameters.
    2176 Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
     2355Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type-specifications.
    21772356
    21782357In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
     
    22002379int (*f(x))[ 5 ] int x; {}
    22012380\end{cfa}
    2202 The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
     2381The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter ©x© of type array of 5 integers.
    22032382Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
    22042383As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
     
    41204299\CFA provides a fine-grained solution where a \Index{recursive lock} is acquired and released indirectly via a manipulator ©acquire© or instantiating an \Index{RAII} type specific for the kind of stream: ©osacquire©\index{ostream@©ostream©!osacquire@©osacquire©} for output streams and ©isacquire©\index{isacquire@©isacquire©}\index{istream@©istream©!isacquire@©isacquire©} for input streams.
    41214300
    4122 The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, where it should appear as the first item in a cascade list, \eg:
     4301The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, with the manipulator appearing as the first item in a cascade list, \eg:
    41234302\begin{cfa}
    41244303$\emph{thread\(_1\)}$ : sout | @acquire@ | "abc " | "def ";   // manipulator
     
    41424321In summary, the stream lock is acquired by the ©acquire© manipulator and implicitly released at the end of the cascaded I/O expression ensuring all operations in the expression occur atomically.
    41434322
    4144 To lock a stream across multiple I/O operations, declare an instance of the appropriate ©osacquire© or ©isacquire© type to implicitly acquire and release the stream lock for the object's duration, \eg:
     4323To lock a stream across multiple I/O operations, an object of type ©osacquire© or ©isacquire© is declared to implicitly acquire/release the stream lock providing mutual exclusion for the object's duration, \eg:
    41454324\begin{cfa}
    41464325{       // acquire sout for block duration
Note: See TracChangeset for help on using the changeset viewer.