- Timestamp:
- Mar 28, 2021, 11:08:44 PM (3 years ago)
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/user/user.tex
r9e234f0b rb202dc2 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : S un Mar 7 21:50:24202114 %% Update Count : 4 57413 %% Last Modified On : Sat Mar 27 09:55:55 2021 14 %% Update Count : 4796 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 2164 2164 2165 2165 2166 \section{Enumeration} 2167 2168 An \newterm{enumeration} is a compile-time mechanism to give names to constants. 2169 There is no runtime manifestation of an enumeration. 2170 Their purpose is code-readability and maintenance -- changing an enum's value automatically updates all name usages during compilation. 2171 2172 An 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} 2174 enum Days { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // enumeration type definition, set of 7 names 2175 Days days = Mon; // enumeration type declaration and initialization 2176 \end{cfa} 2177 The set of enums are injected into the scope of the definition and use the variable namespace. 2178 Hence, enums may be overloaded with enum/variable/function names. 2179 \begin{cfa} 2180 enum Foo { Bar }; 2181 enum Goo { Bar }; $\C[1.75in]{// overload Foo.Bar}$ 2182 int Foo; $\C{// type/variable separate namespace}$ 2183 double Bar; $\C{// overload Foo.Bar, Goo.Bar}\CRT$ 2184 \end{cfa} 2185 An anonymous enumeration is used to inject enums with specific values into a scope: 2186 \begin{cfa} 2187 enum { Prime = 103, BufferSize = 1024 }; 2188 \end{cfa} 2189 An enumeration is better than using the C \Index{preprocessor} 2190 \begin{cfa} 2191 #define Mon 0 2192 ... 2193 #define Sun 6 2194 \end{cfa} 2195 or C constant declarations 2196 \begin{cfa} 2197 const int Mon = 0, ..., Sun = 6; 2198 \end{cfa} 2199 because the enumeration is succinct, has automatic numbering, can appear in ©case© labels, does not use storage, and is part of the language type-system. 2200 Finally, the type of an enum is implicitly or explicitly specified and the constant value can be implicitly or explicitly specified. 2201 Note, enum values may be repeated in an enumeration. 2202 2203 2204 \subsection{Enum type} 2205 2206 While 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. 2208 The default enum type is ©int©. 2209 Hence, ©Days© is the set type ©Mon©, ©Tue©, ...\,, ©Sun©, while the type of each enum is ©int© and each enum represents a fixed integral value. 2210 If no values are specified for an integral enum type, the enums are automatically numbered by one from left to right starting at zero. 2211 Hence, the value of enum ©Mon© is 0, ©Tue© is 1, ...\,, ©Sun© is 6. 2212 If a value is specified, numbering continues by one from that value. 2213 It an enum value is an expression, the compiler performs constant-folding to obtain a constant value. 2214 2215 Other integral types with associated values can be explicitly specified. 2216 \begin{cfa} 2217 enum( @char@ ) Letter { A @= 'A'@, B, C, I @= 'I'@, J, K }; 2218 enum( @long long int@ ) BigNum { X = 123_456_789_012_345, Y = 345_012_789_456_123 }; 2219 \end{cfa} 2220 For 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©. 2221 Note, an enum is an immutable constant, \ie ©A = B© is disallowed; 2222 by transitivity, an enum's type is implicitly ©const©. 2223 Hence, a constant/enum cannot appear in a mutuable context nor is a constant/enum addressable (rvalue). 2224 2225 Non-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 2228 enum( double ) Math { PI_2 = 1.570796, PI = 3.141597, E = 2.718282 } 2229 // pointer 2230 enum( char * ) Name { Fred = "Fred", Mary = "Mary", Jane = "Jane" }; 2231 int i, j, k; 2232 enum( int * ) ptr { I = &i, J = &j, K = &k }; 2233 enum( int & ) ref { I = i, J = j, K = k }; 2234 // tuple 2235 enum( [int, int] ) { T = [ 1, 2 ] }; 2236 // function 2237 void f() {...} void g() {...} 2238 enum( void (*)() ) funs { F = f, F = g }; 2239 // aggregate 2240 struct S { int i, j; }; 2241 enum( S ) s { A = { 3, 4 }, B = { 7, 8 } }; 2242 // enumeration 2243 enum( Letter ) Greek { Alph = A, Beta = B, /* more enums */ }; // alphabet intersection 2244 \end{cfa} 2245 Enumeration ©Greek© may have more or less enums than ©Letter©, but the enum values \emph{must} be from ©Letter©. 2246 Therefore, ©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 2248 The following examples illustrate the difference between the enumeration type and the type of its enums. 2249 \begin{cfa} 2250 Math m = PI; $\C[1.5in]{// allowed}$ 2251 double d = PI; $\C{// allowed, conversion to base type}$ 2252 m = E; $\C{// allowed}$ 2253 m = Alph; $\C{// {\color{red}disallowed}}$ 2254 m = 3.141597; $\C{// {\color{red}disallowed}}$ 2255 d = E; $\C{// allowed, conversion to base type}$ 2256 d = m; $\C{// {\color{red}disallowed}}$ 2257 d = Alph; $\C{// {\color{red}disallowed}}$ 2258 Letter l = A; $\C{// allowed}$ 2259 Greek g = Alph; $\C{// allowed}$ 2260 l = Alph; $\C{// allowed, conversion to base type}$ 2261 g = A; $\C{// {\color{red}disallowed}}\CRT$ 2262 \end{cfa} 2263 2264 A constructor \emph{cannot} be used to initialize enums because a constructor executes at runtime. 2265 A fallback is to substitute C-style initialization overriding the constructor with ©@=©. 2266 \begin{cfa} 2267 enum( struct vec3 ) Axis { Up $@$= { 1, 0, 0 }, Left $@$= ..., Front $@$= ... } 2268 \end{cfa} 2269 Finally, 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} 2276 enum( const char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" }; 2277 enum @/* inferred */@ Name3 { @inline Name@, @inline Name2@, Sue = "Sue", Tom = "Tom" }; 2278 \end{cfa} 2279 Enumeration ©Name2© inherits all the enums and their values from enumeration ©Name© by containment, and a ©Name© enumeration is a subtype of enumeration ©Name2©. 2280 Note, enums must be unique in inheritance but enum values may be repeated. 2281 The enum type for the inheriting type must be the same as the inherited type; 2282 hence the enum type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for ©Name3©. 2283 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 2284 2285 Specifically, the inheritance relationship for ©Name©s is: 2286 \begin{cfa} 2287 Name $\(\subseteq\)$ Name2 $\(\subseteq\)$ Name3 $\(\subseteq\)$ const char * // enum type of Name 2288 \end{cfa} 2289 Hence, given 2290 \begin{cfa} 2291 void f( Name ); 2292 void g( Name2 ); 2293 void h( Name3 ); 2294 void j( const char * ); 2295 \end{cfa} 2296 the following calls are valid 2297 \begin{cfa} 2298 f( Fred ); 2299 g( Fred ); g( Jill ); 2300 h( Fred ); h( Jill ); h( Sue ); 2301 j( Fred ); j( Jill ); j( Sue ); j( 'W' ); 2302 \end{cfa} 2303 Note, 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 2305 Enums cannot be created at runtime, so inheritence problems, such as contra-variance do not apply. 2306 Only instances of the enum base-type may be created at runtime. 2307 2308 \begin{comment} 2309 The 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 2311 The 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 * 2315 enum char * Fred { A = "A", B = "B", C = "C" }; 2316 // Jack is a subset of Fred 2317 enum enum Fred Jack { W = A, Y = C}; 2318 // Mary is a superset of Fred 2319 enum 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 2328 char * vcs; 2329 Fred vf; 2330 Jack vj; 2331 Mary 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 2337 vf = B ; frj ( vf ); // can't assign B to frj.x0 2338 vcs = "bye"; frf ( vcs ); // can't assign "bye" to frf.x0 2339 \end{cfa} 2340 2341 This example is really great. However, I think it's work explicitly doing one with ©const &©. 2342 \end{comment} 2343 2344 2166 2345 \section{Routine Definition} 2167 2346 2168 \CFA alsosupports 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. 2169 2348 The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg: 2170 2349 \begin{cfa} … … 2174 2353 \end{cfa} 2175 2354 where 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 2355 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. 2177 2356 2178 2357 In 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{ … … 2200 2379 int (*f(x))[ 5 ] int x; {} 2201 2380 \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 xof type array of 5 integers.2381 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. 2203 2382 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string. 2204 2383 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity: … … 4120 4299 \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. 4121 4300 4122 The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, w here it should appearas the first item in a cascade list, \eg:4301 The 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: 4123 4302 \begin{cfa} 4124 4303 $\emph{thread\(_1\)}$ : sout | @acquire@ | "abc " | "def "; // manipulator … … 4142 4321 In 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. 4143 4322 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 lockfor the object's duration, \eg:4323 To 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: 4145 4324 \begin{cfa} 4146 4325 { // acquire sout for block duration
Note: See TracChangeset
for help on using the changeset viewer.