Changeset 10a99d87 for doc/theses
- Timestamp:
- Jul 24, 2024, 11:24:08 AM (5 months ago)
- Branches:
- master
- Children:
- d1276f8
- Parents:
- 46651fb
- Location:
- doc/theses/jiada_liang_MMath
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r46651fb r10a99d87 7 7 The following sections detail all of my new contributions to enumerations in \CFA. 8 8 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 theenumerator 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 12 {\color{red}@***@} 13 C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the keyword @enum@ is misleading (@const@ is better). 14 However, given the existence of this form, it is straightforward to extend it with heterogeneous types, \ie types other than @int@. 15 \begin{cfa} 16 enum { Size = 20u, PI = 3.14159L, Jack = L"John" }; $\C{// not an ADT nor an enumeration}$ 17 \end{cfa} 18 which matches with @const@ aliasing in other programming languages. 19 (See \VRef{s:CenumImplementation} on how @gcc@/@clang@ are doing this for integral types.) 20 Here, the type of each enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@. 21 Auto-initialization is impossible in this case because some types do not support arithmetic. 22 As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations. 23 23 24 24 … … 30 30 31 31 The \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. 34 Finally, qualification and casting are provided to disambiguate any ambiguous situations. 32 Furthermore, \CFA uses the environment, such as the left-hand of assignment and function arguments, to pinpoint the best overloaded name. 33 \VRef[Figure]{f:EnumeratorVisibility} shows enumeration overloading and how qualification and casting are used to disambiguate ambiguous situations. 34 \CFA overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources, like include files. 35 Experience from \CFA developers is that the type system implicitly and correctly disambiguates the majority of overloaded names. 36 That is, it is rare to get an incorrect selection or ambiguity, even among hundreds of overloaded variables and functions, that requires disambiguation using qualification or casting. 37 38 \begin{figure} 35 39 \begin{cfa} 36 40 enum E1 { First, Second, Third, Fourth }; … … 38 42 E1 f() { return Third; } $\C{// overloaded functions, different return types}$ 39 43 E2 f() { return Fourth; } 40 void g( E1 e);41 void h( E2 e);42 void foo() { 44 void g( E1 e ); 45 void h( E2 e ); 46 void foo() { $\C{// different resolutions and dealing with ambiguities}$ 43 47 E1 e1 = First; E2 e2 = First; $\C{// initialization}$ 44 48 e1 = Second; e2 = Second; $\C{// assignment}$ 45 49 e1 = f(); e2 = f(); $\C{// function return}$ 46 g( First); h(First); $\C{// function parameter}$50 g( First ); h( First ); $\C{// function argument}$ 47 51 int i = @E1.@First + @E2.@First; $\C{// disambiguate with qualification}$ 48 52 int j = @(E1)@First + @(E2)@First; $\C{// disambiguate with cast}$ 49 53 } 50 54 \end{cfa} 51 \ CFA overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources, like include files.52 Experience from \CFA developers is that the type system implicitly and correctly disambiguates the majority of overloaded names, \ie it is rare to get an incorrect selection or ambiguity, even among hundreds of overloaded variables and functions. 53 Any ambiguity can be resolved using qualification or casting. 55 \caption{Enumerator Visibility and Disambiguating} 56 \label{f:EnumeratorVisibility} 57 \end{figure} 54 58 55 59 … … 68 72 rgb = @RGB.@Blue; 69 73 \end{cfa} 70 It is possible to toggle back to unscopingusing the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}).74 {\color{red}@***@}It is possible to toggle back to unscoped using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}). 71 75 \begin{cfa} 72 76 with ( @Week@, @RGB@ ) { $\C{// type names}$ … … 78 82 79 83 80 \section{Enumeration Traits} 81 82 \CFA defines the set of traits containing operators and helper functions for @enum@. 83 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA. 84 Each trait is discussed in detail. 85 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. 160 \begin{cfa} 161 forall( E ) trait Bounded { 162 E first(); 163 E last(); 164 }; 165 \end{cfa} 166 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively. \eg: 167 \begin{cfa} 168 Workday day = first(); $\C{// Mon}$ 169 Planet outermost = last(); $\C{// NEPTUNE}$ 170 \end{cfa} 171 @first()@ and @last()@ are overloaded with return types only, so in the example, the enumeration type is found on the left-hand side of the assignment. 172 Calling either functions without a context results in a type ambiguity, except in the rare case where the type environment has only one enumeration. 173 \begin{cfa} 174 @first();@ $\C{// ambiguous because both Workday and Planet implement Bounded}$ 175 sout | @last()@; 176 Workday day = first(); $\C{// day provides type Workday}$ 177 void foo( Planet p ); 178 foo( last() ); $\C{// parameter provides type Planet}$ 179 \end{cfa} 180 181 The trait @Serial@: 182 \begin{cfa} 183 forall( E | Bounded( E ) ) trait Serial { 184 unsigned fromInstance( E e ); 185 E fromInt( unsigned int posn ); 186 E succ( E e ); 187 E pred( E e ); 188 }; 189 \end{cfa} 190 is a @Bounded@ trait, where elements can be mapped to an integer sequence. 191 A type @T@ matching @Serial@ can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value. 192 %However, the inverse may not be possible, and possible requires a bound check. 193 The mapping from a serial type to integer is defined by @fromInstance@, which returns the enumerator's position. 194 The inverse operation is @fromInt@, which performs a bound check using @first()@ and @last()@ before casting the integer into an enumerator. 195 Specifically, for enumerator @E@ declaring $N$ enumerators, @fromInt( i )@ returns the $i-1_{th}$ enumerator, if $0 \leq i < N$, or raises the exception @enumBound@. 196 197 The @succ( E e )@ and @pred( E e )@ imply the enumeration positions are consecutive and ordinal. 198 Specifically, 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()$. 199 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@. 200 201 Finally, there is an associated trait defining comparison operators among enumerators. 202 \begin{cfa} 203 forall( E, T | CfaEnum( E, T ) ) { 204 // comparison 205 int ?==?( E l, E r ); $\C{// true if l and r are same enumerators}$ 206 int ?!=?( E l, E r ); $\C{// true if l and r are different enumerators}$ 207 int ?!=?( E l, zero_t ); $\C{// true if l is not the first enumerator}$ 208 int ?<?( E l, E r ); $\C{// true if l is an enumerator before r}$ 209 int ?<=?( E l, E r ); $\C{// true if l before or the same as r}$ 210 int ?>?( E l, E r ); $\C{// true if l is an enumerator after r}$ 211 int ?>=?( E l, E r ); $\C{// true if l after or the same as r}$ 212 } 213 \end{cfa} 214 215 \section{Typed Enum} 84 \section{Enumerator Typing} 216 85 \label{s:EnumeratorTyping} 217 86 … … 251 120 int i, j, k; 252 121 enum( @int *@ ) ptr { I = &i, J = &j, K = &k }; 253 122 @***@enum( @int &@ ) ref { I = i, J = j, K = k }; 254 123 // tuple 255 124 @***@enum( @[int, int]@ ) { T = [ 1, 2 ] }; $\C{// new \CFA type}$ 256 125 // function 257 126 void f() {...} void g() {...} … … 281 150 calling constructors happens at runtime (dynamic). 282 151 152 153 \section{Opaque Enumeration} 154 155 \CFA provides a special opaque (pure) enumeration type with only assignment and equality operations, and no implicit conversion to any base-type. 156 \begin{cfa} 157 enum@()@ Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 158 Mode mode = O_RDONLY; 159 if ( mode == O_CREAT ) ... 160 bool b = mode == O_RDONLY || mode @<@ O_APPEND; $\C{// disallowed}$ 161 int www @=@ mode; $\C{// disallowed}$ 162 \end{cfa} 163 164 165 \section{Enumeration Operators} 166 167 168 \subsection{Conversion} 169 170 \CFA only proves an implicit safe conversion between an enumeration and its base type (like \CC), whereas C allows an unsafe conversion from base type to enumeration. 171 \begin{cfa} 172 enum(int) Colour { Red, Blue, Green }; 173 int w = Red; $\C[1.5in]{// allowed}$ 174 Colour color = 0; $\C{// disallowed}\CRT$ 175 \end{cfa} 176 Unfortunately, there must be one confusing case between C enumerations and \CFA enumeration for type @int@. 177 \begin{cfa} 178 enum Colour { Red = 42, Blue, Green }; 179 enum(int) Colour2 { Red = 16, Blue, Green }; 180 int w = Redy; $\C[1.5in]{// 42}\CRT$ 181 \end{cfa} 182 Programmer intuition is that the assignment to @w@ is ambiguous. 183 However, converting from @color@ to @int@ is zero cost (no conversion), while from @Colour2@ to @int@ is a safe conversion, which is a higher cost. 184 This semantics means fewer backwards-compatibility issues with overloaded C and \CFA enumerators. 185 186 187 \subsection{Properties} 188 189 \VRef{s:Terminology} introduced three fundamental enumeration properties: label, position, and value. 190 \CFA provides direct access to these three properties via the functions: @label@, @posn@, and @value@. 191 \begin{cfa} 192 enum( const char * ) Name { Fred = "FRED", Mary = "MARY", Jane = "JANE" }; 193 Name name = Fred; 194 sout | name | label( name ) | posn( name ) | value( name ); 195 FRED Fred 0 FRED 196 \end{cfa} 197 The default meaning for an enumeration variable in an expression is its value. 198 199 200 \subsection{Range} 201 202 The following helper function are used to access and control enumeration ranges (enumerating). 203 204 The pseudo-function @countof@ (like @sizeof@) provides the size (range) of an enumeration or an enumeration instance. 205 \begin{cfa} 206 enum(int) Colour { Red, Blue, Green }; 207 Colour c = Red 208 sout | countof( Colour ) | countof( c ); 209 3 3 210 \end{cfa} 211 @countof@ is a pseudo-function because it takes a type as an argument. 212 The function @fromInt@ provides a safe subscript of the enumeration. 213 \begin{cfa} 214 Colour r = fromInt( prng( countof( Colour ) ) ); // select random colour 215 \end{cfa} 216 The functions @lowerBound@, @upperBound@, @succ@, and @pred@ are for enumerating. 217 \begin{cfa} 218 for ( Colour c = lowerBound();; ) { 219 sout | c | nonl; 220 if ( c == upperBound() ) break; 221 c = succ( c ); 222 } 223 \end{cfa} 224 Note, the mid-exit loop is necessary to prevent triggering a @succ@ bound check, as in: 225 \begin{cfa} 226 for ( Colour c = lowerBound(); c <= upperBound(); c = succ( c ) ) ... // generates error 227 \end{cfa} 228 When @c == upperBound()@, the loop control still invokes @succ( c )@, which causes an @enumBound@ exception. 229 Finally, there is operational overlap between @countof@ and @upperBound@. 230 231 283 232 \section{Enumeration Inheritance} 284 233 285 234 \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 287 \begin{cfa} 288 enum( char * ) Names { /* as above */ }; 289 enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" }; 290 enum( char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" }; 291 \end{cfa} 292 235 \begin{cfa} 236 enum( const char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" }; 237 enum( const char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" }; 238 enum( const char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" }; 239 \end{cfa} 293 240 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Names@ by containment, and a @Names@ enumeration is a subtype of enumeration @Name2@. 294 241 Note, that enumerators must be unique in inheritance but enumerator values may be repeated. … … 299 246 Specifically, the inheritance relationship for @Names@ is: 300 247 \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}$ 248 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\C{// enum type of Names}$ 249 \end{cfa} 250 A subtype can be cast to its supertype, assigned to a supertype variable, or used as a function argument that expects the supertype. 251 \begin{cfa} 252 Names fred = Names.Fred; 253 (Names2)fred; (Names3)fred; (Names3)Names2.Jack; $\C{// cast to super type}$ 254 Names2 fred2 = fred; Names3 fred3 = fred2; $\C{// assign to super type}$ 255 \end{cfa} 256 As well, there is the implicit cast to an enumerator's base-type. 257 \begin{cfa} 258 const char * name = fred; 308 259 \end{cfa} 309 260 For the given function prototypes, the following calls are valid. … … 327 278 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. 328 279 280 329 281 \section{Enumerator Control Structures} 330 282 … … 335 287 336 288 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. 337 \begin{cquote} 338 \begin{cfa} 289 (For this discussion, ignore the fact that @case@ requires a compile-time constant.) 290 \begin{cfa}[belowskip=0pt] 339 291 enum Count { First, Second, Third, Fourth }; 340 292 Count e; 341 293 \end{cfa} 342 \begin{tabular}{ll} 343 \begin{cfa} 294 \begin{cquote} 295 \setlength{\tabcolsep}{15pt} 296 \noindent 297 \begin{tabular}{@{}ll@{}} 298 \begin{cfa}[aboveskip=0pt] 344 299 345 300 choose( e ) { … … 351 306 \end{cfa} 352 307 & 353 \begin{cfa} 308 \begin{cfa}[aboveskip=0pt] 354 309 // rewrite 355 310 choose( @value@( e ) ) { … … 367 322 enum Count { First, Second, Third @= First@, Fourth }; 368 323 \end{cfa} 369 which make@Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses.324 making @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicate @case@ clauses. 370 325 To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context. 371 326 For conditional clauses and switch statements, \CFA uses the robust position implementation. 372 327 \begin{cfa} 373 choose( @position@( e ) ) { 374 case @position@( First ): ...; 375 case @position@( Second ): ...; 376 case @position@( Third ): ...; 377 case @position@( Fourth ): ...; 378 } 379 \end{cfa} 380 381 \begin{cfa} 382 Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 383 p(variable_a); // 0 384 p(variable_b); // 1 385 p(variable_c); // "Third" 386 p(variable_d); // 3 387 \end{cfa} 388 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 328 if ( @posn@( e ) < posn( Third ) ) ... 329 choose( @posn@( e ) ) { 330 case @posn@( First ): ...; 331 case @posn@( Second ): ...; 332 case @posn@( Third ): ...; 333 case @posn@( Fourth ): ...; 334 } 335 \end{cfa} 336 337 \CFA provides a special form of for-control for enumerating through an enumeration, where the range is a type. 338 \begin{cfa} 339 for ( cx; @Count@ ) { sout | cx | nonl; } sout | nl; 340 for ( cx; +~= Count ) { sout | cx | nonl; } sout | nl; 341 for ( cx; -~= Count ) { sout | cx | nonl; } sout | nl; 342 First Second Third Fourth 343 First Second Third Fourth 344 Fourth Third Second First 345 \end{cfa} 346 The enumeration type is syntax sugar for looping over all enumerators and assigning each enumerator to the loop index, whose type is inferred from the range type. 347 The prefix @+~=@ or @-~=@ iterate forward or backwards through the inclusive enumeration range, where no prefix defaults to @+~=@. 348 349 C has an idiom for @if@ and loop predicates of comparing the predicate result ``not equal to 0''. 350 \begin{cfa} 351 if ( x + y /* != 0 */ ) ... 352 while ( p /* != 0 */ ) ... 353 \end{cfa} 354 This idiom extends to enumerations because there is a boolean conversion in terms of the enumeration value, if and only if such a conversion is available. 355 For example, such a conversion exists for all numerical types (integral and floating-point). 356 It is possible to explicitly extend this idiom to any typed enumeration by overloading the @!=@ operator. 357 \begin{cfa} 358 bool ?!=?( Name n, zero_t ) { return n != Fred; } 359 Name n = Mary; 360 if ( n ) ... // result is true 361 \end{cfa} 362 Specialize meanings are also possible. 411 363 \begin{cfa} 412 364 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. 442 443 \section{Enumerated Arrays} 444 Enumerated arrays use an \CFA array as their index. 445 \begin{cfa} 446 enum() Colour { 447 Red, Orange, Yellow, Green, Blue, Indigo, Violet 448 }; 449 450 string colourCode[Colour] = { "#e81416", "#ffa500", "#ffa500", "#ffa500", "#487de7", "#4b369d", "#70369d" }; 451 sout | "Colour Code of Orange is " | colourCode[Orange]; 452 \end{cfa} 365 bool ?!=?( ErrorCode ec, zero_t ) { return ec >= Overheat; } 366 ErrorCode code = ...; 367 if ( code ) { problem(); } 368 \end{cfa} 369 370 371 \section{Enumeration Dimension} 372 373 \VRef{s:EnumeratorTyping} introduced the harmonizing problem between an enumeration and secondary information. 374 When possible, using a typed enumeration for the secondary information is the best approach. 375 However, there are times when combining these two types is not possible. 376 For example, the secondary information might precede the enumeration and/or its type is needed directly to declare parameters of functions. 377 In these cases, having secondary arrays of the enumeration size are necessary. 378 379 To support some level of harmonizing in these cases, an array dimension can be defined using an enumerator type, and the enumerators used as subscripts. 380 \begin{cfa} 381 enum E { A, B, C, N }; // possibly predefined 382 float H1[N] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // C 383 float H2[@E@] = { [A] : 3.4, [B] : 7.1, [C] : 0.01 }; // CFA 384 \end{cfa} 385 (Note, C uses the symbol, @'='@ for designator initialization, but \CFA had to change to @':'@ because of problems with tuple syntax.) 386 This approach is also necessary for a predefined typed enumeration (unchangeable), when additional secondary-information need to be added. 453 387 454 388 … … 470 404 \small 471 405 \begin{cfa} 472 struct MR { double mass, radius; }; 406 struct MR { double mass, radius; }; $\C{// planet definition}$ 473 407 enum( @MR@ ) Planet { $\C{// typed enumeration}$ 474 408 // mass (kg) radius (km) -
doc/theses/jiada_liang_MMath/background.tex
r46651fb r10a99d87 6 6 The following discussion covers C enumerations. 7 7 8 As discussed in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants.8 As mentioned in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants. 9 9 \begin{clang} 10 10 #define Mon 0 … … 33 33 C can simulate the aliasing @const@ declarations \see{\VRef{s:Aliasing}}, with static and dynamic initialization. 34 34 \begin{cquote} 35 \begin{tabular}{@{}l @{}l@{}}36 \multicolumn{1}{@{}c @{}}{\textbf{static initialization}} & \multicolumn{1}{c@{}}{\textbf{dynamic intialization}} \\35 \begin{tabular}{@{}ll@{}} 36 \multicolumn{1}{@{}c}{\textbf{static initialization}} & \multicolumn{1}{c@{}}{\textbf{dynamic intialization}} \\ 37 37 \begin{clang} 38 38 static const int one = 0 + 1; … … 56 56 \end{tabular} 57 57 \end{cquote} 58 However, statically initialized identifiers can 58 However, statically initialized identifiers cannot appear in constant-expression contexts, \eg @case@. 59 59 Dynamically initialized identifiers may appear in initialization and array dimensions in @g++@, which allows variable-sized arrays on the stack. 60 60 Again, this form of aliasing is not an enumeration. … … 130 130 131 131 \subsection{Implementation} 132 \label{s:CenumImplementation} 132 133 133 134 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values. 134 In practice, C uses @int@ as the underlying type for enumeration variables, because of the restriction to integral constants, which have type @int@ (unless qualified with a size suffix). 135 In practice, C defines @int@~\cite[\S~6.4.4.3]{C11} as the underlying type for enumeration variables, restricting initialization to integral constants, which have type @int@ (unless qualified with a size suffix). 136 However, type @int@ is defined as: 137 \begin{quote} 138 A ``plain'' @int@ object has the natural size suggested by the architecture of the execution environment (large enough to contain any value in the range @INT_MIN@ to @INT_MAX@ as defined in the header @<limits.h>@).~\cite[\S~6.2.5(5)]{C11} 139 \end{quote} 140 Howeveer, @int@ means a 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture. 141 Whereas, @long int@ means 4 bytes on a 32-bit and 8 bytes on 64-bit architectures, and @long long int@ means 8 bytes on both 32/64-bit architectures, where 64-bit operations are simulated on 32-bit architectures. 142 In reality, both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based its initialization. 143 \begin{cfa} 144 enum E { IMin = INT_MIN, IMax = INT_MAX, 145 ILMin = LONG_MIN, ILMax = LONG_MAX, 146 ILLMin = LLONG_MIN, ILLMax = LLONG_MAX }; 147 int main() { 148 printf( "%zd %d %d\n%zd %ld %ld\n%zd %ld %ld\n", 149 sizeof(IMin), IMin, IMax, 150 sizeof(ILMin), ILMin, ILMax, 151 sizeof(ILLMin), ILLMin, ILLMax ); 152 } 153 4 -2147483648 2147483647 154 8 -9223372036854775808 9223372036854775807 155 8 -9223372036854775808 9223372036854775807 156 \end{cfa} 157 Hence, initialization in the range @INT_MIN@..@INT_MAX@ is 4 bytes, and outside this range is 8 bytes. 135 158 136 159 … … 151 174 enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 152 175 switch ( week ) { 153 case Mon : case Tue: case Wed: case Thu: case Fri:176 case Mon ... Fri: $\C{// gcc case range}$ 154 177 printf( "weekday\n" ); 155 178 case Sat: case Sun: 156 179 printf( "weekend\n" ); 157 180 } 158 for ( enum Week day = Mon; day <= Sun; day += 1 ) { // step of 1181 for ( enum Week day = Mon; day <= Sun; day += 1 ) { $\C{// step of 1}$ 159 182 printf( "day %d\n", day ); // 0-6 160 183 } … … 178 201 } 179 202 \end{cfa} 180 However, for typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails.181 182 This idiom leads to another C idiom using an enumeration withmatching companion information.203 However, for non-integral typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails. 204 205 This idiom is used in another C idiom for matching companion information. 183 206 For example, an enumeration is linked with a companion array of printable strings. 184 207 \begin{cfa} … … 197 220 198 221 \bigskip 199 While C provides a true enumeration, it is restricted, has unsafe semantics, and does provide useful enumeration features in other programming languages.222 While C provides a true enumeration, it is restricted, has unsafe semantics, and does not provide useful enumeration features in other programming languages.
Note: See TracChangeset
for help on using the changeset viewer.