Changeset e11cdc0 for doc/proposals
- Timestamp:
- Feb 5, 2024, 10:21:52 AM (11 months ago)
- Branches:
- master
- Children:
- 23a0e576, b08ab18
- Parents:
- 47bd204
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
r47bd204 re11cdc0 117 117 \end{abstract} 118 118 119 \section{ Background}119 \section{Introduction} 120 120 121 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc. 122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time(noon, New Years).122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), specific times (noon, New Years). 123 123 Many programming languages capture this important software-engineering capability through a mechanism called an \newterm{enumeration}. 124 124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set. … … 126 126 127 127 Specifically, an enumerated type restricts its values to a fixed set of named constants. 128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc. 129 However, the values for basic types are not named, other than the programming-language supplied constants. 130 131 132 \section{C-Style Enum} 133 134 The C-Style enumeration has the following syntax and semantics, and is representative of enumerations in many other programming languages (see Section~\ref{s:RelatedWork}). 135 \begin{lstlisting}[label=lst:weekday] 136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 137 $\(\uparrow\)$ $\(\uparrow\)$ 138 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}} 139 \end{lstlisting} 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 141 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constants. 142 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and has no address, it is an rvalue\footnote{ 143 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}. 144 Enumerators without explicitly designated constants are auto-initialized by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 145 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants 0--2, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants 11--13. 146 Hence, there are 3 universal enumeration attributes: \newterm{position}, \newterm{label}, and \newterm{value}: 128 While all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc., these values are not named, other than the programming-language supplied constants. 129 130 Fundamentally, all enumeration systems have an \newterm{enumeration} type with its associated \newterm{enumerator} constants. 131 These components have three universal attributes, \newterm{position}, \newterm{label}, and \newterm{value}, as shown by this representative enumeration, where position and value can be different. 147 132 \begin{cquote} 148 133 \small\sf\setlength{\tabcolsep}{3pt} 149 134 \begin{tabular}{rccccccccccc} 150 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday = 10,& Friday, & Saturday, & Sunday \}; \\ 151 \it\color{red}position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 152 \it\color{red}label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 153 \it\color{red}value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13 135 \it\color{red}enumeration & \multicolumn{7}{c}{\it\color{red}enumerators} \\ 136 $\downarrow$\hspace*{25pt} & \multicolumn{7}{c}{$\downarrow$} \\ 137 @enum@ Weekday \{ & Monday, & Tuesday, & Wednesday, & Thursday,& Friday, & Saturday, & Sunday \}; \\ 138 \it\color{red}position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 139 \it\color{red}label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 140 \it\color{red}value & 0 & 1 & 2 & 3 & 4 & 5 & 6 154 141 \end{tabular} 155 142 \end{cquote} 156 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 143 Here, the \newterm{enumeration} @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 144 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constant values. 145 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and an enumerator has no address, it is an \newterm{rvalue}\footnote{ 146 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}. 147 148 149 \section{C-Style Enum} 150 151 The C-Style enumeration has the following syntax and semantics. 152 \begin{lstlisting} 153 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 154 \end{lstlisting} 155 Enumerators without an explicitly designated constant value are \newterm{auto-initialized} by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 156 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants @0@--@2@, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants @11@--@13@. 157 Initialization may occur in any order. 158 \begin{lstlisting} 159 enum Weekday { Thursday@ = 10@, Friday, Saturday, Sunday, Monday@ = 0@, Tuesday, Wednesday }; 160 \end{lstlisting} 161 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma. 162 \begin{lstlisting} 163 enum Weekday { 164 Thursday = 10, Friday, Saturday, Sunday, 165 Monday = 0, Tuesday, Wednesday@,@ // terminating comma 166 }; 167 \end{lstlisting} 168 This feature allow enumerator lines to be interchanged without moving a comma.\footnote{ 169 A terminating comma appears in other C syntax, e.g., the initializer list.} 170 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible (projected) in the enclosing scope of the @enum@ type. 157 171 158 172 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values. 159 In practice, since integral constants in Chave type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.160 F urthermore, there is an implicit bidirectional conversion between an enumeration and integral types.173 In practice, since integral constants are used, which have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables. 174 Finally, there is an implicit bidirectional conversion between an enumeration and integral types. 161 175 \begin{lstlisting}[label=lst:enum_scope] 162 176 { 163 enum Weekday { ... };$\C{// enumerators implicitly projected into local scope}$177 enum Weekday { /* as above */ }; $\C{// enumerators implicitly projected into local scope}$ 164 178 Weekday weekday = Monday; $\C{// weekday == 0}$ 165 179 weekday = Friday; $\C{// weekday == 11}$ 166 int i = Sunday $\C{// implicit conversion to int, i == 13}$180 int i = Sunday; $\C{// implicit conversion to int, i == 13}$ 167 181 weekday = 10000; $\C{// UNDEFINED! implicit conversion to Weekday}$ 168 182 } … … 171 185 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error. 172 186 187 It is common for C programmers to ``believe'' there are 3 equivalent forms of constant enumeration. 188 \begin{lstlisting}[label=lst:enum_scope] 189 #define Monday 0 190 static const int Monday = 0; 191 enum { Monday }; 192 \end{lstlisting} 193 For @#define@, the programmer has to play compiler and explicitly manage the enumeration values; 194 furthermore, these are independent constants outside of any language type mechanism. 195 The same explicit management is true for @const@ declarations, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{ 196 C allows variable-length array-declarations (VLA), so this case does work, but it fails in \CC, which does not support VLAs, unless it is \lstinline{g++}.} and immediate operands of assembler instructions. 197 Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations. 198 199 173 200 \section{\CFA-Style Enum} 174 201 … … 176 203 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 177 204 205 206 \subsection{Enumerator Name Resolution} 207 \label{s:EnumeratorNameResolution} 208 209 In C, unscoping of enumerators presents a \newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names. 210 There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may not be possible. 211 212 The \CFA type-system allows extensive overloading, including enumerators. 213 Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name. 214 Finally, qualification is provided to disambiguate any ambiguous situations. 215 \begin{lstlisting} 216 enum C1 { First, Second, Third, Fourth }; 217 enum C2 { @Fourth@, @Third@, @Second@, @First@ }; 218 C1 p() { return Third; } $\C{// correctly resolved duplicate names}$ 219 C2 p() { return Fourth; } 220 void foo() { 221 C1 e1 = First; C2 e2 = First; 222 e1 = Second; e2 = Second; 223 e1 = p(); e2 = p(); 224 e1 = @C1.@First + @C1.@First; $\C{// ambiguous without qualification (and dangerous)}$ 225 } 226 \end{lstlisting} 227 \CFA overloading allows programmers to use the most meaningful names with little fear of unresolvable clashes from included files, which can always be corrected. 228 229 230 \subsection{Enumerator Scoping} 231 232 An enumeration can be scoped, so the enumerator constants are not projected into the enclosing scope, using @'!'@. 233 \begin{lstlisting} 234 enum Weekday @!@ { /* as above */ }; 235 enum( char * ) Names @!@ { /* as above */ }; 236 \end{lstlisting} 237 Now the enumerators must be qualified with the associated enumeration. 238 \begin{lstlisting} 239 Weekday weekday = @Weekday@.Monday; 240 Names names = @Names.@Fred; 241 names = @Names.@Jane; 242 \end{lstlisting} 243 It is possible to toggle back to unscoping using the \CFA @with@ clause/statement. 244 \begin{lstlisting} 245 Weekday weekday; 246 with ( @Weekday@, @Names@ ) { $\C{// type names}$ 247 Names names = @Fred@; 248 names = @Jane@; 249 weekday = Saturday; 250 } 251 \end{lstlisting} 252 As in section~\ref{s:EnumeratorNameResolution}, opening multiple unscoped enumerations can result in duplicate enumeration names, but \CFA type resolution and falling back to explicit qualification handles ambiguities. 253 254 178 255 \subsection{Enumerator Typing} 179 256 180 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 181 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerators. 182 183 Typed enumerates deals with \emph{harmonizing} problem between an enumeration and its companion data. 184 The following example is from the \CFA compiler, written in \CC. 185 \begin{lstlisting} 186 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 187 char * integral_names[NO_OF_ITYPES] = { 188 "char", "signed char", "unsigned char", 189 "signed short int", "unsigned short int", 190 "signed int", "unsigned int", 191 ... 192 }; 193 \end{lstlisting} 194 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit. 195 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment). 196 The typed enumeration largely solves this problem by combining and managing the two data types. 197 \begin{lstlisting} 198 enum( char * ) integral_types { 199 chr = "char", schar = "signed char", uschar = "unsigned char", 200 sshort = "signed short int", ushort = "unsigned short int", 201 sint = "signed int", usint = "unsigned int", 202 ... 203 }; 204 \end{lstlisting} 257 \CFA extends the enumeration declaration by parameterizing with a type (like a generic type), allowing enumerators to be assigned any values from the declared type. 258 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerator constants. 259 Note, the synonyms @Liz@ and @Beth@ in the last declaration. 205 260 206 261 % \begin{lstlisting}[label=lst:color] … … 223 278 enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i }; 224 279 // pointer 225 enum( @char *@ ) Names { Fred = "F red", Mary = "Mary", Jane = "Jane" };280 enum( @char *@ ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" }; 226 281 int i, j, k; 227 282 enum( @int *@ ) ptr { I = &i, J = &j, K = &k }; 228 283 enum( @int &@ ) ref { I = i, J = j, K = k }; 229 284 // tuple 230 enum( @[int, int]@ ) { T = [ 1, 2 ] }; 285 enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$ 231 286 // function 232 287 void f() {...} void g() {...} … … 234 289 // aggregate 235 290 struct Person { char * name; int age, height; }; 236 enum( @Person@ ) friends { Liz = { "Elizabeth", 22, 170 }, Beth = Liz, Jon = { "Jonathan", 35, 190 } };291 @***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz, Jon = { "JONATHAN", 35, 190 } }; 237 292 \end{lstlisting} 238 293 \caption{Enumerator Typing} … … 240 295 \end{figure} 241 296 297 Typed enumerations deals with the \emph{harmonizing} problem between an enumeration and any companion data. 298 The following example is from the \CFA compiler, written in \CC. 299 \begin{lstlisting} 300 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 301 char * integral_names[NO_OF_ITYPES] = { 302 "char", "signed char", "unsigned char", 303 "signed short int", "unsigned short int", 304 "signed int", "unsigned int", 305 ... 306 }; 307 \end{lstlisting} 308 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit. 309 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment). 310 The typed enumeration largely solves this problem by combining and managing the two data types. 311 \begin{lstlisting} 312 enum( char * ) integral_types { 313 chr = "char", schar = "signed char", uschar = "unsigned char", 314 sshort = "signed short int", ushort = "unsigned short int", 315 sint = "signed int", usint = "unsigned int", 316 ... 317 }; 318 \end{lstlisting} 319 242 320 \subsection{Pure Enumerators} 243 321 … … 247 325 \begin{lstlisting} 248 326 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 249 Mode iomode = O_RDONLY;327 @***@Mode iomode = O_RDONLY; 250 328 int i = iomode; $\C{\color{red}// disallowed}$ 251 sout | O_TRUNC; $\C{\color{red}// disallowed}$252 329 \end{lstlisting} 253 330 254 331 \subsection{Enumerator Subset} 255 332 256 If follows from enumerator typing that the type of the enumeratorscan be another enumerator.333 If follows from enumerator typing that the enumerator type can be another enumerator. 257 334 \begin{lstlisting} 258 335 enum( char ) Letter { A = 'A', B = 'B', C = 'C', ..., Z = 'Z' }; 259 enum( Letter ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection 260 Letter letter = A; 261 Greak greek = Alph; 262 letter = Alph; $\C{// allowed}$ 263 greek = A; $\C{\color{red}// disallowed}$ 336 enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection 264 337 \end{lstlisting} 265 338 Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@. 266 339 Therefore, @Greek@ enumerators are a subset of type @Letter@ and are type compatible with enumeration @Letter@, but @Letter@ enumerators are not type compatible with enumeration @Greek@. 340 \begin{lstlisting} 341 Letter letter = A; 342 @***@Greak greek = Beta; 343 letter = Beta; $\C{// allowed, letter == B}$ 344 greek = A; $\C{\color{red}// disallowed}$ 345 \end{lstlisting} 346 267 347 268 348 \subsection{Enumeration Inheritance} … … 270 350 \CFA Plan-9 inheritance may be used with enumerations. 271 351 \begin{lstlisting} 272 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" }; 273 enum /* inferred */ Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" }; 274 \end{lstlisting} 275 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Name@ by containment, and a @Name@ enumeration is a subtype of enumeration @Name2@. 352 enum( char * ) Names { /* as above */ }; 353 enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" }; 354 @***@enum /* inferred */ Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" }; 355 \end{lstlisting} 356 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@. 276 357 Note, enumerators must be unique in inheritance but enumerator values may be repeated. 277 358 278 359 The enumeration type for the inheriting type must be the same as the inherited type; 279 360 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@. 280 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 281 282 Specifically, the inheritance relationship for Names is: 283 \begin{lstlisting} 284 Name $\(\subset\)$ Name2 $\(\subset\)$ Name3 $\(\subset\)$ const char * // enum type of Name 361 % When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 362 Specifically, the inheritance relationship for @Names@ is: 363 \begin{lstlisting} 364 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$ 285 365 \end{lstlisting} 286 366 For the given function prototypes, the following calls are valid. … … 288 368 \begin{tabular}{ll} 289 369 \begin{lstlisting} 290 void f( Name );291 void g( Name 2 );292 void h( Name 3 );370 void f( Names ); 371 void g( Names2 ); 372 void h( Names3 ); 293 373 void j( const char * ); 294 374 \end{lstlisting} … … 298 378 g( Fred ); g( Jill ); 299 379 h( Fred ); h( Jill ); h( Sue ); 300 j( Fred ); j( Jill ); j( Sue ); j( "W ill" );380 j( Fred ); j( Jill ); j( Sue ); j( "WILL" ); 301 381 \end{lstlisting} 302 382 \end{tabular} … … 304 384 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. 305 385 306 \subsection{Enumerator Scoping}307 308 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope.309 \begin{lstlisting}310 enum Weekday @!@ { /* as above */ };311 enum Colour( char * ) @!@ { /* as above */ };312 \end{lstlisting}313 where the @'!'@ implies the enumerators are \emph{not} projected.314 The enumerators of a scoped enumeration are accessed using qualifications, like the fields of an aggregate.315 % The syntax of $qualified\_expression$ for \CFA-enum is the following:316 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$317 \begin{lstlisting}318 Weekday weekday = @Weekday.Monday@; $\C{// qualification}$319 Colour colour = @Colour.@Red;320 colour = @Colour.@Blue;321 \end{lstlisting}322 386 323 387 \subsection{Enumeration Pseudo-functions} … … 326 390 Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture.. 327 391 392 328 393 \subsubsection{Enumerator Attributes} 329 394 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 330 395 \begin{lstlisting} 331 int green_pos = @position@( Colour.Green ); $\C{// 1}$ 332 char * green_value = @value@( Colour.Green ); $\C{// "G"}$ 333 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$ 334 \end{lstlisting} 335 336 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 337 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 396 @***@int jane_pos = position( Names.Jane ); $\C{// 2}$ 397 @***@char * jane_value = value( Names.Jane ); $\C{// "JANE"}$ 398 @***@char * jane_label = label( Names.Jane ); $\C{// "Jane"}$ 399 \end{lstlisting} 338 400 339 401 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. … … 341 403 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum. 342 404 343 \subsubsection{\lstinline{enumerate()}} 344 345 \begin{lstlisting}[label=lst:c_switch] 346 enum(int) C_ENUM { First, Second, Third = First, Fourth }; 347 int v( C_ENUM e ) { 348 switch( e ) { 349 case First: return 0; break; 350 case Second: return 1; break; 351 // case Third: return 2; break; 352 // case Fourth: return 3; break; 353 }; 354 }; 355 \end{lstlisting} 356 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. 357 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. 358 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values. 359 360 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 361 \begin{lstlisting}[label=lst:c_switch_enumerate] 362 enum(double) C_ENUM { First, Second, Third = First, Fourth }; 363 C_ENUM variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 364 int v(C_ENUM e) { 365 switch( enumeratate( e ) ) { 366 case First: return e; break; 367 case Second: return value( e ); break; 368 case Third: return label( e ); break; 369 case Fourth: return position( e ); break; 370 }; 371 }; 405 406 \subsubsection{\lstinline{switch/choose} Statement} 407 408 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. 409 \begin{lstlisting} 410 enum Count { First, Second, Third, Fourth }; 411 Count e; 412 \end{lstlisting} 413 \begin{cquote} 414 \begin{tabular}{ll} 415 \begin{lstlisting} 416 choose( e ) { 417 case @First@: ...; 418 case @Second@: ...; 419 case @Third@: ...; 420 case @Fourth@: ...; 421 } 422 \end{lstlisting} 423 & 424 \begin{lstlisting} 425 choose( @value@( e ) ) { 426 case @value@( First ): ...; 427 case @value@( Second ): ...; 428 case @value@( Third ): ...; 429 case @value@( Fourth ): ...; 430 } 431 \end{lstlisting} 432 \end{tabular} 433 \end{cquote} 434 Here, the intuitive implementation on the right uses the value of the enumeration and enumerators. 435 However, this implementation is fragile, e.g., if the enumeration is changed to: 436 \begin{lstlisting} 437 enum Count { First, Second, Third @= First@, Fourth }; 438 \end{lstlisting} 439 which make @Third == First@ and @Fourth == Second@, causing duplicase @case@ clauses. 440 To better match with programmer intuition, \CFA uses a more robust implementation form when the type of a @switch@ expression is an enumeration. 441 \begin{lstlisting} 442 choose( @position@( e ) ) { 443 case @position@( First ): ...; 444 case @position@( Second ): ...; 445 case @position@( Third ): ...; 446 case @position@( Fourth ): ...; 447 } 448 \end{lstlisting} 449 450 \begin{lstlisting} 451 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 372 452 p(variable_a); // 0 373 453 p(variable_b); // 1 … … 1015 1095 If the @aggregation_name@ is identified as a \CFA enumeration, the compiler checks if @field@ presents in the declared \CFA enumeration. 1016 1096 1017 \subsection{\lstinline{with} Clause/Statement}1018 1019 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible.1020 \begin{lstlisting}[label=lst:declaration]1021 enum Color( char * ) { Red="R", Green="G", Blue="B" };1022 enum Animal( int ) { Cat=10, Dog=20 };1023 with ( Color, Animal ) {1024 char * red_string = Red; // value( Color.Red )1025 int cat = Cat; // value( Animal.Cat )1026 }1027 \end{lstlisting}1028 The \lstinline{with} might introduce ambiguity to a scope. Consider the example:1029 \begin{lstlisting}[label=lst:declaration]1030 enum Color( char * ) { Red="R", Green="G", Blue="B" };1031 enum RGB( int ) { Red=0, Green=1, Blue=2 };1032 with ( Color, RGB ) {1033 // int red = Red;1034 }1035 \end{lstlisting}1036 \CFA will not try to resolve the expression with ambiguity. It would report an error. In this case, it is necessary to qualify @Red@ even inside of the \lstinline{with} clause.1037 1038 1097 \subsection{Instance Declaration} 1039 1098
Note: See TracChangeset
for help on using the changeset viewer.