Changes in / [2363147:b522435]
- Files:
-
- 4 edited
-
doc/theses/jiada_liang_MMath/CFAenum.tex (modified) (15 diffs)
-
libcfa/src/enum.cfa (modified) (4 diffs)
-
libcfa/src/iostream.cfa (modified) (2 diffs)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r2363147 rb522435 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 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 12 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). 13 Given the existence of this form, it is straightforward to extend it with types other than @int@. 14 \begin{cfa} 15 enum E { Size = 20u, PI = 3.14159L, Jack = L"John" }; 16 \end{cfa} 17 which matches with @const@ aliasing in other programming languages. 18 Here, the type of the enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@. 19 Auto-initialization is restricted to the case where all constants are @int@, matching with C. 20 As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations. 23 21 24 22 … … 30 28 31 29 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. 30 Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name. 34 31 Finally, qualification and casting are provided to disambiguate any ambiguous situations. 35 32 \begin{cfa} … … 38 35 E1 f() { return Third; } $\C{// overloaded functions, different return types}$ 39 36 E2 f() { return Fourth; } 40 void g(E1 e);41 void h(E2 e);42 37 void foo() { 43 38 E1 e1 = First; E2 e2 = First; $\C{// initialization}$ 44 39 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}$ 47 41 int i = @E1.@First + @E2.@First; $\C{// disambiguate with qualification}$ 48 42 int j = @(E1)@First + @(E2)@First; $\C{// disambiguate with cast}$ … … 78 72 79 73 80 \section{Enumeration Trait s}81 82 \CFAdefines the set of traits containing operators and helper functions for @enum@.74 \section{Enumeration Trait} 75 76 The header file \lstinline[deletekeywords=enum]{<enum.hfa>} defines the set of traits containing operators and helper functions for @enum@. 83 77 A \CFA enumeration satisfies all of these traits allowing it to interact with runtime features in \CFA. 84 78 Each trait is discussed in detail. 85 79 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. 80 The trait @Bounded@: 160 81 \begin{cfa} 161 82 forall( E ) trait Bounded { … … 164 85 }; 165 86 \end{cfa} 166 The function @first()@ and @last()@ of enumerated type E return the first and the last enumerator declared in E, respectively.\eg:87 defines the bounds of the enumeration, where @first()@ returns the first enumerator and @last()@ returns the last, \eg: 167 88 \begin{cfa} 168 89 Workday day = first(); $\C{// Mon}$ … … 172 93 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 94 \begin{cfa} 174 @first();@ $\C{// ambiguous because bothWorkday and Planet implement Bounded}$95 @first();@ $\C{// ambiguous Workday and Planet implement Bounded}$ 175 96 sout | @last()@; 176 97 Workday day = first(); $\C{// day provides type Workday}$ … … 195 116 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 117 197 The @ succ( E e )@ and @pred( E e )@imply the enumeration positions are consecutive and ordinal.118 The @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. 198 119 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 120 The exception @enumRange@ is raised if the result of either operation is outside the range of type @E@. 200 121 122 The trait @TypedEnum@: 123 \begin{cfa} 124 forall( E, T ) trait TypedEnum { 125 T valueE( E e ); 126 char * labelE( E e ); 127 unsigned int posE( E e ); 128 }; 129 \end{cfa} 130 captures 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 { ... };@. 132 Implementing general functions across all enumeration types is possible by asserting @TypeEnum( E, T )@, \eg: 133 \begin{cfa} 134 forall( E, T | TypeEnum( E, T ) ) 135 void printEnum( E e ) { 136 sout | "Enum "| labelE( e ); 137 } 138 printEunm( MARS ); 139 \end{cfa} 140 201 141 Finally, there is an associated trait defining comparison operators among enumerators. 202 142 \begin{cfa} 203 forall( E, T | CfaEnum( E, T ) ) {143 forall( E, T | TypedEnum( E, T ) ) { 204 144 // comparison 205 145 int ?==?( E l, E r ); $\C{// true if l and r are same enumerators}$ … … 212 152 } 213 153 \end{cfa} 214 215 \section{Typed Enum} 154 Note, the overloaded operators are defined only when the header @<enum.hfa>@ is included. 155 If 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> 158 enum( int ) Fruits { APPLE = 2, BANANA = 10, CHERRY = 2 }; 159 APPLE == CHERRY; // true because valueE( APPLE ) == valueE( CHERRY ) 160 161 #include <enum.hfa> 162 APPLE == CHERRY; // false because posE( APPLE ) != posE( CHERRY ) 163 \end{cfa} 164 An enumerator returns its @position@ by default. 165 In particular, @printf( ... )@ from @<stdio.h>@ functions provides no context to its parameter type, so it prints @position@. 166 On 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} 168 printf( "Position of BANANA is \%d", BANANA ); // Position of BANANA is 1 169 sout | "Value of BANANA is " | BANANA; // Value of BANANA is 10 170 \end{cfa} 171 Programmers 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} 216 191 \label{s:EnumeratorTyping} 217 192 … … 281 256 calling constructors happens at runtime (dynamic). 282 257 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} 263 enum@()@ Planets { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }; 264 \end{cfa} 265 266 283 267 \section{Enumeration Inheritance} 284 268 285 269 \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 270 \begin{cfa} 288 271 enum( char * ) Names { /* as above */ }; 289 272 enum( 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} 293 275 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 Note, thatenumerators 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@.276 Note, enumerators must be unique in inheritance but enumerator values may be repeated. 277 278 The enumeration type for the inheriting type must be the same as the inherited type; 279 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@. 298 280 % When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important. 299 281 Specifically, the inheritance relationship for @Names@ is: 300 282 \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}$ 283 Names $\(\subset\)$ Names2 $\(\subset\)$ Names3 $\(\subset\)$ const char * $\C{// enum type of Names}$ 308 284 \end{cfa} 309 285 For the given function prototypes, the following calls are valid. … … 321 297 g( Fred ); g( Jill ); 322 298 h( Fred ); h( Jill ); h( Sue ); 323 j( Fred ); j( Jill ); j( Sue ); j( "WILL" );299 j( Fred ); j( Jill ); j( Sue ); j( "WILL" ); 324 300 \end{cfa} 325 301 \end{tabular} … … 327 303 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 304 305 329 306 \section{Enumerator Control Structures} 330 307 … … 332 309 In most programming languages, an enumerator is implicitly converted to its value (like a typed macro substitution). 333 310 However, 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 pos ition.335 336 For example, an intuitive use of enumerations is with the \CFA @switch@/@choose@ statement, where @choose@ performs an implic it @break@ rather than a fall-through at the end of a @case@ clause.311 In these contexts, a programmer's initition assumes an implicit conversion to postion. 312 313 For 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. 337 314 \begin{cquote} 338 315 \begin{cfa} … … 367 344 enum Count { First, Second, Third @= First@, Fourth }; 368 345 \end{cfa} 369 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplica te @case@ clauses.346 which make @Third == First@ and @Fourth == Second@, causing a compilation error because of duplicase @case@ clauses. 370 347 To better match with programmer intuition, \CFA toggles between value and position semantics depending on the language context. 371 For conditional clauses and switch stat ements, \CFA uses the robust position implementation.348 For conditional clauses and switch statments, \CFA uses the robust position implementation. 372 349 \begin{cfa} 373 350 choose( @position@( e ) ) { … … 387 364 \end{cfa} 388 365 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 371 looping statements 372 442 373 443 374 \section{Enumerated Arrays} 444 Enumerated array suse an \CFA array as their index.375 Enumerated array use an \CFA array as their index. 445 376 \begin{cfa} 446 377 enum() Colour { … … 457 388 \VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating most of the \CFA enumeration features. 458 389 @Planet@ is an enumeration of type @MR@. 459 Each planet enumeratoris initialized to a specific mass/radius, @MR@, value.390 Each of the planet enumerators is initialized to a specific mass/radius, @MR@, value. 460 391 The unnamed enumeration provides the gravitational-constant enumerator @G@. 461 392 Function @surfaceGravity@ uses the @with@ clause to remove @p@ qualification from fields @mass@ and @radius@. 462 393 The 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@. 463 394 The resulting random orbital-body is used in a @choose@ statement. 464 The enumerators in the @case@ clause use theenumerator position for testing.395 The enumerators in the @case@ clause use enumerator position for testing. 465 396 The prints use @label@ to print an enumerator's name. 466 397 Finally, a loop enumerates through the planets computing the weight on each planet for a given earth mass. -
libcfa/src/enum.cfa
r2363147 rb522435 42 42 if ( eof( is ) ) throwResume ExceptionInst( missing_data ); 43 43 44 // Match longest input enumerator string to enumerator labels, where enumerator names are unique. 45 44 // Match input enumerator string to enumerator labels. 46 45 int N = Countof( e ), lnths[N], max = 0; 47 46 // printf( "N %d\n", N ); … … 61 60 for ( c; max ) { 62 61 int args = fmt( is, "%c", &ch ); // read character 63 if ( eof( is ) ) {62 if ( eof( is ) ) { 64 63 // fprintf( stderr, "Eof1\n" ); 65 64 if ( c == 0 ) return is; // no characters read ? 66 clear( is ); // => re ad something => reset EOF => detect again on next read65 clear( is ); // => reset EOF => detect again on next read 67 66 // fprintf( stderr, "Eof2\n" ); 68 break;69 } // if67 goto W; 68 } 70 69 if ( args != 1 ) throwResume ExceptionInst( missing_data ); 71 72 70 // printf( "read '%c'\n", ch ); 73 for ( i; N ) { // scan enumeration strings for winner71 for ( i; N ) { 74 72 // printf( "%d %d %d\n", c, i, lnths[i] ); 75 73 if ( c < lnths[i] ) { // eligible for this checking round ? 76 74 char match = label( fromInt( i ) )[c]; // optimization 77 75 // printf( "%c '%c'\n", match, ch ); 78 // Stop on first match, could be other matches.79 76 if ( (match == ch) && (c == 0 || curr == label( fromInt( i ) )[c - 1]) ) { 80 77 // printf( "match %d %d %d '%c' '%c' '%c' '%c' 'c'\n", c, i, lnths[i], match, ch, prev, label( fromInt( i ) )[c - 1] ); … … 95 92 // fprintf( stderr, "finished2 %d\n", win ); 96 93 } // for 97 W :;98 for ( i; N ) { // scan enumeration strings for winner94 W :; 95 for ( i; N ) { // scan for winner, must succeed 99 96 if ( win == lnths[i] - 1 ) { 100 97 char match = label( fromInt( i ) )[win]; // optimization … … 103 100 e = fromInt( i ); 104 101 break; 105 } // if102 } 106 103 } // if 107 104 } else { -
libcfa/src/iostream.cfa
r2363147 rb522435 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jul 15 08:16:48202413 // Update Count : 20 2012 // Last Modified On : Fri Jul 12 05:45:45 2024 13 // Update Count : 2019 14 14 // 15 15 … … 781 781 // Optional leading whitespace at start of strings. 782 782 fmt( is, " " FALSE "%n", &len ); // try false 783 if ( len != sizeof( FALSE ) - 1 ) { // -1 removesnull terminate783 if ( len != sizeof( FALSE ) - 1 ) { // remove null terminate 784 784 fmt( is, " " TRUE "%n", &len ); // try true 785 785 if ( len != sizeof( TRUE ) - 1 ) throwResume ExceptionInst( missing_data ); -
src/ResolvExpr/CandidateFinder.cpp
r2363147 rb522435 1485 1485 1486 1486 void Finder::postvisit( const ast::CountExpr * countExpr ) { 1487 const ast::UntypedExpr * untyped = nullptr;1487 const ast::UntypedExpr * untyped; 1488 1488 if ( countExpr->type ) { 1489 1489 auto enumInst = countExpr->type.as<ast::EnumInstType>();
Note:
See TracChangeset
for help on using the changeset viewer.