Changes in / [6abb6dc:2ca7fc2]
- Files:
-
- 7 added
- 3 deleted
- 20 edited
-
doc/theses/jiada_liang_MMath/CEnum.tex (added)
-
doc/theses/jiada_liang_MMath/CFAenum.tex (modified) (14 diffs)
-
doc/theses/jiada_liang_MMath/Cenum.tex (deleted)
-
doc/theses/jiada_liang_MMath/background.tex (modified) (26 diffs)
-
doc/theses/jiada_liang_MMath/benchmarks.tex (added)
-
doc/theses/jiada_liang_MMath/conclusion.tex (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/glossary.tex (added)
-
doc/theses/jiada_liang_MMath/intro.tex (modified) (9 diffs)
-
doc/theses/jiada_liang_MMath/offsetAlgorithm.cc (deleted)
-
doc/theses/jiada_liang_MMath/performance.tex (added)
-
doc/theses/jiada_liang_MMath/relatedwork.tex (modified) (44 diffs)
-
doc/theses/jiada_liang_MMath/test.adb (modified) (2 diffs)
-
doc/theses/jiada_liang_MMath/test.cc (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/test.go (modified) (4 diffs)
-
doc/theses/jiada_liang_MMath/test.pas (modified) (4 diffs)
-
doc/theses/jiada_liang_MMath/test.py (modified) (6 diffs)
-
doc/theses/jiada_liang_MMath/test.swift (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/test1.cfa (modified) (6 diffs)
-
doc/theses/jiada_liang_MMath/test1.java (modified) (2 diffs)
-
doc/theses/jiada_liang_MMath/test2.cc (added)
-
doc/theses/jiada_liang_MMath/test20.cfa (added)
-
doc/theses/jiada_liang_MMath/test3.cfa (added)
-
doc/theses/jiada_liang_MMath/trait.tex (modified) (6 diffs)
-
doc/theses/jiada_liang_MMath/user_define_enum.cfa (deleted)
-
doc/theses/jiada_liang_MMath/uw-ethesis-frontpgs.tex (modified) (2 diffs)
-
libcfa/src/collections/string.hfa (modified) (3 diffs)
-
libcfa/src/enum.cfa (modified) (3 diffs)
-
libcfa/src/enum.hfa (modified) (1 diff)
-
libcfa/src/heap.cfa (modified) (2 diffs)
-
src/Validate/ImplementEnumFunc.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r6abb6dc r2ca7fc2 1 \chapter{\ texorpdfstring{\CFA}{Cforall}Enumeration}2 3 \CFA extends C-Style enumeration by adding a number of new features that bring enumerations in line with other modern programming languages.4 Any enumeration extensions must be intuitive to C programmers in syntax and semantics.5 The following sections detail my new contributions to enumerations in \CFA.6 7 8 \section{ Syntax}9 10 \CFA extends the C enumeration declaration \see{\VRef{s:CEnumeration}} by parameterizing with a type (like a generic type) and adding Plan-9 inheritance \see{\VRef{s:CFAInheritance}} using an @inline@ to another enumeration type.1 \chapter{\CFA Enumeration} 2 3 \CFA extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 4 Any enumeration extensions must be intuitive to C programmers both in syntax and semantics. 5 The following sections detail all of my new contributions to enumerations in \CFA. 6 7 8 \section{Enumeration Syntax} 9 10 \CFA extends the C enumeration declaration \see{\VRef{s:CEnumeration}} by parameterizing with a type (like a generic type), and adding Plan-9 inheritance \see{\VRef{s:EnumerationInheritance}} using an @inline@ to another enumeration type. 11 11 \begin{cfa}[identifierstyle=\linespread{0.9}\it] 12 12 $\it enum$-specifier: … … 24 24 25 25 26 \section{ Operations}26 \section{Enumeration Operations} 27 27 28 28 \CFA enumerations have access to the three enumerations properties \see{\VRef{s:Terminology}}: label, order (position), and value via three overloaded functions @label@, @posn@, and @value@ \see{\VRef{c:trait} for details}. … … 43 43 A A @0@ 3 44 44 \end{cfa} 45 Finally, \CFA introduces an additional enumeration pseudo-function @countof@ (like @sizeof@, @typeof@) that returns the number of enumerators in an enumeration. 46 \begin{cfa} 47 enum(int) E { A, B, C, D } e; 48 countof( E ); // 4, type argument 49 countof( e ); // 4, variable argument 50 \end{cfa} 51 This built-in function replaces the C idiom for automatically computing the number of enumerators \see{\VRef{s:Usage}}. 45 Finally, there is an additional enumeration routine @countof@ (like @sizeof@, @typeof@) that returns the number of enumerators in an enumeration. 46 \begin{cfa} 47 enum(int) E { A, B, C, D }; 48 countof( E ); // 4 49 \end{cfa} 50 This auto-generated function replaces the C idiom for automatically computing the number of enumerators \see{\VRef{s:Usage}}. 52 51 \begin{cfa} 53 52 enum E { A, B, C, D, @N@ }; // N == 4 … … 56 55 The underlying representation of \CFA enumeration object is its position, saved as an integral type. 57 56 Therefore, the size of a \CFA enumeration is consistent with a C enumeration. 58 Attribute function @posn@ performs type substitution on an expression from \CFA type to an integral type. 59 The label and value of an enumerator are stored in a global data structure for each enumeration, where attribute functions @label@/@value@ map an \CFA enumeration object to the corresponding data. 60 These operations do not apply to C Enums because backward compatibility means the necessary backing data structures cannot be supplied. 61 57 Attribute function @posn@ performs type substitution on an expression from \CFA type to integral type. 58 The label and value of an enumerator is stored in a global data structure for each enumeration, where attribute functions @label@/@value@ map an \CFA enumeration object to the corresponding data. 59 These operations do not apply to C Enums because backwards compatibility means the necessary backing data structures cannot be supplied. 62 60 63 61 \section{Opaque Enumeration} 64 62 \label{s:OpaqueEnum} 65 63 66 When an enumeration type is empty . it isan \newterm{opaque} enumeration.64 When an enumeration type is empty is it an \newterm{opaque} enumeration. 67 65 \begin{cfa} 68 66 enum@()@ Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 69 67 \end{cfa} 70 Here, the compiler chooses the internal representation, which ishidden, so the enumerators cannot be initialized.71 Compared to the C enum, opaque enums are more restrictive regardingtyping and cannot be implicitly converted to integers.68 Here, the internal representation is chosen by the compiler and hidden, so the enumerators cannot be initialized. 69 Compared to the C enum, opaque enums are more restrictive in terms of typing and cannot be implicitly converted to integers. 72 70 \begin{cfa} 73 71 Mode mode = O_RDONLY; 74 72 int www @=@ mode; $\C{// disallowed}$ 75 73 \end{cfa} 76 Opaque enumerations have only two attribute properties ,@label@ and @posn@.74 Opaque enumerations have only two attribute properties @label@ and @posn@. 77 75 \begin{cfa} 78 76 char * s = label( O_TRUNC ); $\C{// "O\_TRUNC"}$ 79 77 int open = posn( O_WRONLY ); $\C{// 1}$ 80 78 \end{cfa} 81 Equality and relational operations are available.79 The equality and relational operations are available. 82 80 \begin{cfa} 83 81 if ( mode @==@ O_CREAT ) ... … … 89 87 \label{s:EnumeratorTyping} 90 88 91 When an enumeration type is specified, all enumerators have that type and can be initialized with constants of that type or compile-time convert ible to that type.92 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use d with an enumeration, and each type's values areused to set the enumerator constants.93 Note the use of the synonyms @Liz@ and @Beth@ in the last declaration.89 When an enumeration type is specified, all enumerators have that type and can be initialized with constants of that type or compile-time convertable to that type. 90 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's values used to set the enumerator constants. 91 Note, the use of the synonyms @Liz@ and @Beth@ in the last declaration. 94 92 Because enumerators are constants, the enumeration type is implicitly @const@, so all the enumerator types in Figure~\ref{f:EumeratorTyping} are logically rewritten with @const@. 95 93 … … 132 130 }; 133 131 \end{cfa} 134 Note thatthe enumeration type can be a structure (see @Person@ in Figure~\ref{f:EumeratorTyping}), so it is possible to have the equivalent of multiple arrays of companion data using an array of structures.132 Note, the enumeration type can be a structure (see @Person@ in Figure~\ref{f:EumeratorTyping}), so it is possible to have the equivalent of multiple arrays of companion data using an array of structures. 135 133 136 134 While the enumeration type can be any C aggregate, the aggregate's \CFA constructors are \emph{not} used to evaluate an enumerator's value. … … 164 162 bar( x ); $\C{// costs (1, 0, 0, 0, 0, 0, 0, 0) or (0, 1, 0, 0, 0, 0, 0, 0)}$ 165 163 \end{cfa} 166 Here, the candidate (1) has a @value@ conversion cost to convert to the base type, while the candidate (2) has an @unsafe@ conversion from @double@ to @int@, 167 which is a more expensive conversion. 164 Here, candidate (1) has a value conversion cost to convert to the base type, while candidate (2) has an unsafe conversion from @double@ to @int@. 168 165 Hence, @bar( x )@ resolves @x@ as type @Math@. 169 166 … … 179 176 180 177 \section{Auto Initialization} 181 \CFA extends C's auto-initialization scheme to \CFA enumeration. For an enumeration type with base type T, the initialization scheme is the following: 178 179 A partially implemented feature is auto-initialization, which works for the C integral type with constant expressions. 180 \begin{cfa} 181 enum Week { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun }; // 0-2, 10-13 182 \end{cfa} 183 The complexity of the constant expression depends on the level of computation the compiler implements, \eg \CC \lstinline[language={[GNU]C++}]{constexpr} provides complex compile-time computation across multiple types, which blurs the compilation/runtime boundary. 184 185 If \CFA had powerful compilation expression evaluation, auto initialization would be implemented as follows. 186 \begin{cfa} 187 enum E(T) { A, B, C }; 188 \end{cfa} 182 189 \begin{enumerate} 183 \item the first enumerator is initialized with @T@'s @zero_t@.184 \item Every other enumerator is initialized with its previous enumerator's value "+1", where "+1" is defined in terms of overloaded operator @?+?(T, one_t)@.190 \item the first enumerator, @A@, is initialized with @T@'s @zero_t@. 191 \item otherwise, the next enumerator is initialized with the previous enumerator's value using operator @?++@, where @?++( T )@ can be overloaded for any type @T@. 185 192 \end{enumerate} 186 193 187 \begin{cfa} 188 struct S { int i; }; 189 S ?+?( S & s, one_t ) { return s.i++; } 190 void ?{}( S & s, zero_t ) { s.i = 0; } 191 enum(S) E { A, B, C, D }; 192 \end{cfa} 193 194 \section{Subset} 195 196 An enumeration's type can be another enumeration. 197 \begin{cfa} 198 enum( char ) Letter { A = 'A', ..., Z = 'Z' }; 199 enum( @Letter@ ) Greek { Alph = @A@, Beta = @B@, Gamma = @G@, ..., Zeta = @Z@ }; // alphabet intersection 200 \end{cfa} 201 Enumeration @Greek@ may have more or less enumerators than @Letter@, but its enumerator values \emph{must} be from @Letter@. 202 Therefore, the set of @Greek@ enumerator values in a subset of the @Letter@ enumerator values. 203 @Letter@ is type compatible with enumeration @Letter@ because value conversions are inserted whenever @Letter@ is used in place of @Greek@. 204 \begin{cfa} 205 Letter l = A; $\C{// allowed}$ 206 Greek g = Alph; $\C{// allowed}$ 207 l = Alph; $\C{// allowed, conversion to base type}$ 208 g = A; $\C{// {\color{red}disallowed}}$ 209 void foo( Letter ); 210 foo( Beta ); $\C{// allowed, conversion to base type}$ 211 void bar( Greek ); 212 bar( A ); $\C{// {\color{red}disallowed}}$ 213 \end{cfa} 214 Hence, @Letter@ enumerators are not type-compatible with the @Greek@ enumeration, but the reverse is true. 215 216 217 \section{Inheritance} 218 \label{s:CFAInheritance} 194 Unfortunately, constant expressions in C are not powerful and \CFA is only a transpiler, relying on generated C code to perform the detail work. 195 It is currently beyond the scope of the \CFA project to implement a complex runtime interpreter in the transpiler to evaluate complex expressions across multiple builtin and user-defined type. 196 Nevertheless, the necessary language concepts exist to support this feature. 197 198 199 \section{Enumeration Inheritance} 200 \label{s:EnumerationInheritance} 219 201 220 202 \CFA Plan-9 inheritance may be used with \CFA enumerations, where Plan-9 inheritance is containment inheritance with implicit unscoping (like a nested unnamed @struct@/@union@ in C). 221 203 Containment is nominative: an enumeration inherits all enumerators from another enumeration by declaring an @inline statement@ in its enumerator lists. 222 204 \begin{cfa} 223 enum( char * ) Names { /* $\see{\VRef[Figure]{ f:EumeratorTyping}}$ */};205 enum( char * ) Names { /* $\see{\VRef[Figure]{s:EnumerationInheritance}}$ */ }; 224 206 enum( char * ) Names2 { @inline Names@, Jack = "JACK", Jill = "JILL" }; 225 207 enum( char * ) Names3 { @inline Names2@, Sue = "SUE", Tom = "TOM" }; … … 234 216 235 217 Inheritance can be nested, and a \CFA enumeration can inline enumerators from more than one \CFA enumeration, forming a tree-like hierarchy. 236 However, the uniqueness of the enumeration name applies to enumerators, including those from supertypes, meaning an enumeration cannot name an enumerator with the same label as its subtype's membersor inherits237 from multiple enumeration that has overlapping enumerator label s. Consequently, a new type cannot inherit from an enumeration and its supertypeor two enumerations with a238 common supertype (the diamond problem) since such would unavoidably introduce duplicate enumerator labels.218 However, the uniqueness of enumeration name applies to enumerators, including those from supertypes, meaning an enumeration cannot name enumerator with the same label as its subtype's members, or inherits 219 from multiple enumeration that has overlapping enumerator label. As a consequence, a new type cannot inherits from both an enumeration and its supertype, or two enumerations with a 220 common supertype (the diamond problem), since such would unavoidably introduce duplicate enumerator labels. 239 221 240 222 The base type must be consistent between subtype and supertype. 241 When an enumeration inherits enumerators from another enumeration, it copies the enumerators' @value@ and @label@, even if the @value@ is auto -initialized.223 When an enumeration inherits enumerators from another enumeration, it copies the enumerators' @value@ and @label@, even if the @value@ is auto initialized. 242 224 However, the position of the underlying representation is the order of the enumerator in the new enumeration. 243 225 \begin{cfa} 244 enum() E1 { B }; $\C{// B}$245 enum() E2 { C, D }; $\C{// C D}$246 enum() E3 { inline E1, inline E2, E }; $\C{// {\color{red}[\(_{E1}\)} B {\color{red}]} {\color{red}[\(_{E2}\)} C D {\color{red}]} E}$247 enum() E4 { A, inline E3, F}; $\C{// A {\color{blue}[\(_{E3}\)} {\color{red}[\(_{E1}\)} B {\color{red}]} {\color{red}[\(_{E2}\)} C D {\color{red}]} E {\color{blue}]} F}$ 248 \end{cfa} 249 In the example, @B@ is at position 0 in @E1@ and @E3@, but position 1 in @E4@ as @A@ takes position 0 in @E4@.250 @C@ is at position 0 in @E2@, 1 in @E3@, and 2 in @E4@.251 @D@ is at position 1 in @E2@, 2 in @E3@, and 3 in @E4@.252 253 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost , called \newterm{enumeration conversion}.226 enum() E1 { A }; 227 enum() E2 { B, C }; 228 enum() E3 { inline E1, inline E2, D }; 229 \end{cfa} 230 Here, @A@ has position 0 in @E1@ and @E3@. 231 @B@ has position 0 in @E2@ and 1 in @E3@. 232 @C@ has position 1 in @E2@ and position 2 in @E3@. 233 @D@ has position 3 in @E3@. 234 235 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost. 254 236 \begin{cfa} 255 237 enum E2 e2 = C; 256 posn( e2 ); $\C[1.75in]{// 0}$257 enum E3 e3 = e2; $\C{// Assignment with enumeration conversion E2 to E3}$258 posn( e2 ); $\C{// 1 cost}$238 posn( e2 ); $\C[1.75in]{// 1}$ 239 enum E3 e3 = e2; 240 posn( e2 ); $\C{// 2}$ 259 241 void foo( E3 e ); 260 foo( e2 ); $\C{// Type compatible with enumeration conversion E2 to E3}$261 posn( (E3)e2 ); $\C{// Explicit cast with enumeration conversion E2 to E3}$262 E3 e31 = B; $\C{// No conversion: E3.B}$263 posn( e31 ); $\C{// 0 cost}\CRT$242 foo( e2 ); 243 posn( (E3)e2 ); $\C{// 2}$ 244 E3 e31 = B; 245 posn( e31 ); $\C{// 1}\CRT$ 264 246 \end{cfa} 265 247 The last expression is unambiguous. 266 While both @E2.B@ and @E3.B@ are valid candidates, @E2.B@ has an associated safe cost and @E3.B@ needs no conversion (@zero@ cost). 267 \CFA selects the lowest cost candidate @E3.B@. 248 While both @E2.B@ and @E3.B@ are valid candidate, @E2.B@ has an associated safe cost and \CFA selects the zero cost candidate @E3.B@. 249 Hence, as discussed in \VRef{s:OpaqueEnum}, \CFA chooses position as a representation of the \CFA enum. 250 Therefore, conversion involves both a change of type and possibly position. 251 252 When converting a subtype to a supertype, its position can only be a larger value. 253 The difference between the position in the subtype and in the supertype is its \newterm{offset}. 254 \VRef[Figure]{s:OffsetSubtypeSuperType} show the algorithm to determine the offset for an subtype enumerator to its super type. 255 \PAB{You need to explain the algorithm.} 256 257 \begin{figure} 258 \begin{cfa} 259 struct Enumerator; 260 struct CFAEnum { 261 vector<variant<CFAEnum, Enumerator>> members; 262 }; 263 pair<bool, int> calculateEnumOffset( CFAEnum dst, Enumerator e ) { 264 int offset = 0; 265 for ( auto v: dst.members ) { 266 if ( v.holds_alternative<Enumerator>() ) { 267 auto m = v.get<Enumerator>(); 268 if ( m == e ) return make_pair( true, 0 ); 269 offset++; 270 } else { 271 auto p = calculateEnumOffset( v, e ); 272 if ( p.first ) return make_pair( true, offset + p.second ); 273 offset += p.second; 274 } 275 } 276 return make_pair( false, offset ); 277 } 278 \end{cfa} 279 \caption{Compute Offset from Subtype Enumerator to Super Type} 280 \label{s:OffsetSubtypeSuperType} 281 \end{figure} 268 282 269 283 For the given function prototypes, the following calls are valid. … … 288 302 289 303 290 \subsection{Offset Calculation} 291 292 As discussed in \VRef{s:OpaqueEnum}, \CFA chooses position as a representation of a \CFA enumeration variable. 293 When a cast or implicit conversion moves an enumeration from subtype to supertype, the position can be unchanged or increase. 294 \CFA determines the position offset with an \newterm{offset calculation} function. 295 296 \begin{figure} 297 \begin{cfa} 298 struct Enumerator; 299 struct CFAEnum { vector<variant<CFAEnum, Enumerator>> members; string name; }; 300 inline static bool operator==(CFAEnum& lhs, CFAEnum& rhs) { return lhs.name == rhs.name; } 301 pair<bool, int> calculateEnumOffset(CFAEnum src, CFAEnum dst) { 302 int offset = 0; 303 if ( src == dst ) return make_pair(true, 0); 304 for ( auto v : dst.members ) { 305 if ( holds_alternative<Enumerator>(v) ) { 306 offset++; 307 } else { 308 auto m = get<CFAEnum>(v); 309 if ( m == src ) @return@ make_pair( true, offset ); 310 auto dist = calculateEnumOffset( src, m ); 311 if ( dist.first ) { 312 @return@ make_pair( true, offset + dist.second ); 313 } else { 314 offset += dist.second; 315 } 316 } 317 } 318 @return@ make_pair( false, offset ); 319 } 320 \end{cfa} 321 \caption{Compute Offset from Subtype Enumeration to a Supertype} 322 \label{s:OffsetSubtypeSuperType} 323 \end{figure} 324 325 Figure~\ref{s:OffsetSubtypeSuperType} shows an outline of the offset calculation in \CC. 326 Structure @CFAEnum@ represents the \CFA enumeration with a vector of variants of @CFAEnum@ or @Enumerator@. 327 The algorithm takes two @CFAEnums@ parameters, @src@ and @dst@, with @src@ being the type of expression the conversion applies to, and @dst@ being the type the expression is cast to. 328 The algorithm iterates over the members in @dst@ to find @src@. 329 If a member is an enumerator of @dst@, the positions of all subsequent members are incremented by one. 330 If the current member is @dst@, the function returns true indicating \emph{found} and the accumulated offset. 331 Otherwise, the algorithm recurses into the current @CFAEnum@ @m@ to check if its @src@ is convertible to @m@. 332 If @src@ is convertible to the current member @m@, this means @src@ is a subtype-of-subtype of @dst@. 333 The offset between @src@ and @dst@ is the sum of the offset of @m@ in @dst@ and the offset of @src@ in @m@. 334 If @src@ is not a subtype of @m@, the loop continues but with the offset shifted by the size of @m@. 335 If the loop ends, than @src@ is not convertible to @dst@, and false is returned. 336 337 338 \section{Control Structures} 304 \section{Enumerator Control Structures} 339 305 340 306 Enumerators can be used in multiple contexts. … … 426 392 427 393 428 \section{ Dimension}394 \section{Enumeration Dimension} 429 395 430 396 \VRef{s:EnumeratorTyping} introduces the harmonizing problem between an enumeration and secondary information. … … 443 409 \footnotetext{C uses symbol \lstinline{'='} for designator initialization, but \CFA changes it to \lstinline{':'} because of problems with tuple syntax.} 444 410 This approach is also necessary for a predefined typed enumeration (unchangeable), when additional secondary-information need to be added. 411 445 412 The array subscript operator, namely @?[?]@, is overloaded so that when a \CFA enumerator is used as an array index, it implicitly converts to its position over value to sustain data harmonization. 446 413 This behaviour can be reverted by explicit overloading: … … 448 415 float ?[?]( float * arr, E2 index ) { return arr[ value( index ) ]; } 449 416 \end{cfa} 450 Wh ile enumerator labels @A@, @B@ and @C@ are being defined twice in different enumerations, they are unambiguous within thecontext.451 Designators in @H1@ are unambiguous becasue @E2@ has a @value@ cost to @int@, which is more expensive than @safe@ cost from C-Enum @E1@ to @int@.452 Designators in @H2@ are resolved as @E2@ because when a \CFA enumeration type is being used as an array dimension, \CFA adds the enumeration type to the initializer's resolution context. 453 454 455 \section{ I/O}456 457 As seen in multiple examples, \CFAenumerations can be printed and the default property printed is the enumerator's label, which is similar in other programming languages.417 When an enumeration type is being used as an array dimension, \CFA adds the enumeration type to the initializer's context. 418 As a result, @H2@'s array destinators @A@, @B@ and @C@ are resolved unambiguously to type @E2@. 419 (@H1@'s destinators are also resolved unambiguously to @E1@ because @E2@ has a @value@ cost.) 420 421 422 \section{Enumeration I/O} 423 424 As seen in multiple examples, enumerations can be printed and the default property printed is the enumerator's label, which is similar in other programming languages. 458 425 However, very few programming languages provide a mechanism to read in enumerator values. 459 426 Even the @boolean@ type in many languages does not have a mechanism for input using the enumerators @true@ or @false@. 460 427 \VRef[Figure]{f:EnumerationI/O} show \CFA enumeration input based on the enumerator labels. 461 428 When the enumerator labels are packed together in the input stream, the input algorithm scans for the longest matching string. 462 For basic types in \CFA, the rule is that the same constants used to initialize a variable in a program are available to initialize a variable using input, where string constants can be quoted or unquoted.429 For basic types in \CFA, the rule is that the same constants used to initialize a variable in a program are available to initialize a variable using input, where strings constants can be quoted or unquoted. 463 430 464 431 \begin{figure} … … 506 473 \label{f:EnumerationI/O} 507 474 \end{figure} 475 508 476 509 477 -
doc/theses/jiada_liang_MMath/background.tex
r6abb6dc r2ca7fc2 1 1 \chapter{Background} 2 2 3 This chapter covers background material for C enumerations and \CFA features used in later discussion s.3 This chapter covers background material for C enumerations and \CFA features used in later discussion. 4 4 5 5 … … 14 14 \begin{enumerate}[leftmargin=*] 15 15 \item 16 For @#define@, the programmer mustexplicitly manage the constant name and value.17 Furthermore, these C preprocessor macro names are outside the C typesystem and can incorrectly change random text in a program.16 For @#define@, the programmer has to explicitly manage the constant name and value. 17 Furthermore, these C preprocessor macro names are outside of the C type-system and can incorrectly change random text in a program. 18 18 \item 19 19 The same explicit management is true for the @const@ declaration, and the @const@ variable cannot appear in constant-expression locations, like @case@ labels, array dimensions,\footnote{ 20 C allows variable-length array declarations (VLA), so this case does work. Still, it fails in \CC, which does not support VLAs, unless it is \lstinline{g++}.} immediate oper\-ands of assembler instructionsand occupies storage.20 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++}.} immediate oper\-ands of assembler instructions, and occupies storage. 21 21 \begin{clang} 22 22 $\$$ nm test.o … … 28 28 29 29 30 \subsection{C \ texorpdfstring{\lstinline{const}}{const}}30 \subsection{C \lstinline{const}} 31 31 \label{s:Cconst} 32 32 … … 87 87 enum { Size = 20, Max = 10, MaxPlus10 = Max + 10, @Max10Plus1@, Fred = -7 }; 88 88 \end{clang} 89 Here, the aliased constants are 20, 10, 20, 21, and -7.90 Direct initialization is achieved by a compile-time expression that generatesa constant value.91 Indirect initialization (without aninitializer, @Max10Plus1@) is called \newterm{auto-initialization}, where enumerators are assigned values from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.89 Here, the aliased constants are: 20, 10, 20, 21, and -7. 90 Direct initialization is by a compile-time expression generating a constant value. 91 Indirect initialization (without initializer, @Max10Plus1@) is called \newterm{auto-initialization}, where enumerators are assigned values from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 92 92 Because multiple independent enumerators can be combined, enumerators with the same values can occur. 93 The enumerators are @rvalues@, so theassignment is disallowed.93 The enumerators are rvalues, so assignment is disallowed. 94 94 Finally, enumerators are \newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) outside into the enclosing scope of the @enum@ type. 95 This semantic is required for unnamed enumerationsbecause there is no type name for scoped qualification.96 97 As noted, this aliasing declaration is not an enumeration, even though it is declared using an @enum@ in C.95 For unnamed enumerations, this semantic is required because there is no type name for scoped qualification. 96 97 As noted, this kind of aliasing declaration is not an enumeration, even though it is declared using an @enum@ in C. 98 98 While the semantics is misleading, this enumeration form matches with aggregate types: 99 99 \begin{cfa} … … 112 112 enum @Week@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun }; 113 113 \end{clang} 114 and adopts the same semantics as direct and auto initialization.114 and adopts the same semantics with respect to direct and auto intialization. 115 115 For example, @Mon@ to @Wed@ are implicitly assigned with constants @0@--@2@, @Thu@ is explicitly set to constant @10@, and @Fri@ to @Sun@ are implicitly assigned with constants @11@--@13@. 116 116 As well, initialization may occur in any order. … … 121 121 }; 122 122 \end{clang} 123 Note the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.\footnote{123 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.\footnote{ 124 124 A terminating comma appears in other C syntax, \eg the initializer list.} 125 This feature allow senumerator lines to be interchanged without moving a comma.125 This feature allow enumerator lines to be interchanged without moving a comma. 126 126 Named enumerators are also unscoped. 127 127 … … 130 130 \label{s:CenumImplementation} 131 131 132 Theoretically, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values.132 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values. 133 133 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). 134 134 However, type @int@ is defined as: … … 136 136 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} 137 137 \end{quote} 138 However, @int@ means 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture.139 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.140 \VRef[Figure]{f:gccEnumerationStorageSize} shows both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based onits initialization.141 Hence, initialization in the range @INT_MIN@..@INT_MAX@ results in a 4-byte enumerator, and outside this range ,the enumerator is 8 bytes.138 However, @int@ means a 4 bytes on both 32/64-bit architectures, which does not seem like the ``natural'' size for a 64-bit architecture. 139 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. 140 \VRef[Figure]{f:gccEnumerationStorageSize} shows both @gcc@ and @clang@ partially ignore this specification and type the integral size of an enumerator based its initialization. 141 Hence, initialization in the range @INT_MIN@..@INT_MAX@ results in a 4-byte enumerator, and outside this range the enumerator is 8 bytes. 142 142 Note that @sizeof( typeof( IMin ) ) != sizeof( E )@, making the size of an enumerator different than is containing enumeration type, which seems inconsistent, \eg @sizeof( typeof( 3 ) ) == sizeof( int )@. 143 143 … … 168 168 \label{s:Usage} 169 169 170 C proves an implicit \emph{bidirectional} conversion between an enumeration and its integral type and between two different enumerations.170 C proves an implicit \emph{bidirectional} conversion between an enumeration and its integral type, and between two different enumerations. 171 171 \begin{clang} 172 172 enum Week week = Mon; $\C{// week == 0}$ … … 178 178 @week = Winter;@ $\C{// UNDEFINED! implicit conversion to Week}$ 179 179 \end{clang} 180 While converting an enumerator to its underlying type is sound, the implicit conversion from the base or another enumeration type to an enumeration is a common source of error.180 While converting an enumerator to its underlying type is useful, the implicit conversion from the base or another enumeration type to an enumeration is a common source of error. 181 181 182 182 Enumerators can appear in @switch@ and looping statements. … … 194 194 \end{cfa} 195 195 For iterating using arithmetic to make sense, the enumerator values \emph{must} have a consecutive ordering with a fixed step between values. 196 For example, a previous gap introduced by @Thu = 10@ results in iterating over the values 0--13, where values 3--9 are not @Week@ values.197 Note that the bidirectional conversionallows incrementing @day@: @day@ is converted to @int@, integer @1@ is added, and the result is converted back to @Week@ for the assignment to @day@.196 For example, a previous gap introduced by @Thu = 10@, results in iterating over the values 0--13, where values 3--9 are not @Week@ values. 197 Note, it is the bidirectional conversion that allows incrementing @day@: @day@ is converted to @int@, integer @1@ is added, and the result is converted back to @Week@ for the assignment to @day@. 198 198 For safety, \CC does not support the bidirectional conversion, and hence, an unsafe cast is necessary to increment @day@: @day = (Week)(day + 1)@. 199 199 200 There is a C idiom t hat computes the number of enumerators in an enumeration automatically.200 There is a C idiom to automatically compute the number of enumerators in an enumeration. 201 201 \begin{cfa} 202 202 enum E { A, B, C, D, @N@ }; // N == 4 203 203 for ( enum E e = A; e < @N@; e += 1 ) ... 204 204 \end{cfa} 205 Serendipitously,the auto-incrementing counts the number of enumerators and puts the total into the last enumerator @N@.206 This @N@ is often used as the dimension for an array assoc iated with the enumeration.205 Here, serendipitously the auto-incrementing counts the number of enumerators and puts the total into the last enumerator @N@. 206 This @N@ is often used as the dimension for an array assocated with the enumeration. 207 207 \begin{cfa} 208 208 E array[@N@]; … … 226 226 \end{cfa} 227 227 However, the companion idiom results in the \emph{harmonizing} problem because an update to the enumeration @Integral_Type@ often requires a corresponding update to the companion array \snake{Integral_Name}. 228 The requirement to harmonize is , at best,indicated by a comment before the enumeration.228 The requirement to harmonize is at best indicated by a comment before the enumeration. 229 229 This issue is exacerbated if enumeration and companion array are in different translation units. 230 230 231 231 \bigskip 232 While C provides a true enumeration, it is restricted, has unsafe semantics, and does not provide helpful/advanced enumeration features in other programming languages. 233 234 235 \section{\texorpdfstring{\CFA}{Cforall}} 236 237 \CFA in \emph{not} an object-oriented programming language, \ie functions cannot be nested in aggregate types, and hence, there is no \newterm{receiver} notation for calling functions, \eg @obj.method(...)@, where the first argument proceeds the call and becomes an implicit first (\lstinline[language=C++]{this}) parameter. 232 While C provides a true enumeration, it is restricted, has unsafe semantics, and does not provide useful/advanced enumeration features found in other programming languages. 233 234 \section{\CFA Polymorphism} 235 236 \subsection{Function Overloading} 237 Function overloading is programming languages feature wherein functions may share the same name, but with different function signatures. In both C++ and \CFA, function names can be overloaded 238 with different entities as long as they are different in terms of the number and type of parameters. 239 240 \section{\CFA} 241 242 \CFA in \emph{not} an object-oriented programming-language, \ie functions cannot be nested in aggregate types, and hence, there is no \newterm{receiver} notation for calling functions, \eg @obj.method(...)@, where the first argument proceeds the call and becomes an implicit first (\lstinline[language=C++]{this}) parameter. 238 243 The following sections provide short descriptions of \CFA features needed further in the thesis. 239 Other \CFA features are presented in situ with shortor no explanation because the feature is obvious to C programmers.244 Other \CFA features are presented in-situ with short explanations, or no explanation because the feature is obvious to C programmers. 240 245 241 246 242 247 \subsection{Overloading} 243 248 244 Overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources like includedfiles.249 Overloading allows programmers to use the most meaningful names without fear of name clashes within a program or from external sources, like include files. 245 250 \begin{quote} 246 251 There are only two hard things in Computer Science: cache invalidation and naming things. --- Phil Karlton … … 248 253 Experience from \CC and \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. 249 254 In many cases, a programmer has no idea there are name clashes, as they are silently resolved, simplifying the development process. 250 Depending on the language, ambiguous cases are resolved using some form of qualification and/or casting.255 Depending on the language, ambiguous cases are resolved using some form of qualification or casting. 251 256 252 257 … … 263 268 s1 = @?+?@( s1, s2 ); $\C{// direct call}\CRT$ 264 269 \end{cfa} 265 The type system examines each call size and selects the best matching overloaded function based on the number and types of arguments.266 If there are mixed-mode operands, @2 + 3.5@, the type system, like in C/\CC, attempts (safe) conversions, converting the argument type(s) tothe parameter type(s).270 The type system examines each call size and selects the best matching overloaded function based on the number and types of the arguments. 271 If there are intermixed operands, @2 + 3.5@, the type system attempts (safe) conversions changing the arguments to one or more of the parameter type(s). 267 272 268 273 269 274 \subsection{Function Overloading} 270 275 271 Both \CFA and \CC allow function names to be overloaded as long as their prototypes differ in the number and type of parameters and returns.276 Both \CFA and \CC allow function names to be overloaded, as long as their prototypes differ in the number and type of parameters and returns. 272 277 \begin{cfa} 273 278 void f( void ); $\C[1.75in]{// (1): no parameter}$ … … 277 282 \end{cfa} 278 283 In this case, the name @f@ is overloaded depending on the number and parameter types. 279 The type system examines each call size and selects the best match based on the number and types ofarguments.280 Here, the call @f( 'A' )@ is a perfect match forthe number and parameter type of function (2).281 282 Ada, Scala, and \CFA type-systems also use the return type to pinpoint the best-overloaded name in resolving a call.284 The type system examines each call size and selects the best matching based on the number and types of the arguments. 285 Here, there is a perfect match for the call, @f( 'A' )@ with the number and parameter type of function (2). 286 287 Ada, Scala, and \CFA type-systems also use the return type in resolving a call, to pinpoint the best overloaded name. 283 288 \begin{cfa} 284 289 int f( void ); $\C[1.75in]{// (4); overloaded on return type}$ … … 302 307 } 303 308 \end{cfa} 304 The \CFA type system treats overloaded variables as an overloaded function returning a value with no parameters.309 The \CFA type system simply treats overloaded variables as an overloaded function returning a value with no parameters. 305 310 Hence, no significant effort is required to support this feature. 306 311 … … 308 313 \subsection{Constructor and Destructor} 309 314 310 While \CFA i s not object-oriented, it adopts many language features commonly used in object-oriented languages;311 these features are independent ofobject-oriented programming.315 While \CFA in not object oriented, it adopts many language features commonly used in object-oriented languages; 316 these features are independent from object-oriented programming. 312 317 313 318 All objects in \CFA are initialized by @constructors@ \emph{after} allocation and de-initialized \emph{before} deallocation. 314 \CC cannot have constructors for basic types because they have no aggregate type \lstinline[language=C++]{struct/class} in which to insert a constructor definition.319 \CC cannot have constructors for basic-types because they have no aggregate type \lstinline[language=C++]{struct/class} in which to insert a constructor definition. 315 320 Like \CC, \CFA has multiple auto-generated constructors for every type. 316 321 317 322 The prototype for the constructor/destructor are @void ?{}( T &, ... )@ and @void ^?{}( T &, ... )@, respectively. 318 The first parameter is logically the \lstinline[language=C++]{this} or \lstinline[language=Python]{self} in other object-oriented languagesand implicitly passed.323 The first parameter is logically, the \lstinline[language=C++]{this} or \lstinline[language=Python]{self} in other object-oriented languages, and implicitly passed. 319 324 \VRef[Figure]{f:CFAConstructorDestructor} shows an example of creating and using a constructor and destructor. 320 325 Both constructor and destructor can be explicitly called to reuse a variable. … … 350 355 351 356 The C constants @0@ and @1@ have special meaning. 352 @0@ is the null pointer and isused in conditional expressions, where @if ( p )@ is rewritten @if ( p != 0 )@;357 @0@ is the null pointer and used in conditional expressions, where @if ( p )@ is rewritten @if ( p != 0 )@; 353 358 @1@ is an additive identity in unary operators @++@ and @--@. 354 359 Aware of their significance, \CFA provides a special type @zero_t@ and @one_t@ for custom types. … … 378 383 At the call size, the type parameter @T@ is bounded to @int@ from the argument @42@. 379 384 380 For polymorphic functions to be useful, the @forall@ clause needs \newterm{type assertion}s that restrict the polymorphic types it accepts.385 For polymorphic functions to be useful, the @forall@ clause needs \newterm{type assertion}s that restricts the polymorphic types it accepts. 381 386 \begin{cfa} 382 387 forall( T @| { void foo( T ); }@ ) void bar( T t ) { @foo( t );@ } … … 385 390 bar( s ); 386 391 \end{cfa} 387 The assertion on @T@ restricts the range of types that can be manipulated by @bar@ to only those that implement @foo@ with the matching signature, allowing @bar@'s call to @foo@ in its body. 388 Unlike templates in \CC, which are macro expansions at the call site, \CFA polymorphic functions are compiled, passing the call-site assertion functions as hidden parameters. 389 392 The assertion on @T@ restricts the range of types that can be manipulated by @bar@ to only those that have an implementation of @foo@ with the matching signature, allowing @bar@'s call to @foo@ in its body. 390 393 391 394 \subsection{Trait} 395 A @forall@ clause can asserts on multiple types and with multiple asserting functions. A common practice in \CFA is to group 396 the asserting functions in to a named \newterm{trait}. 397 398 \subsection{Trait} 392 399 393 400 A @forall@ clause can assert many restrictions on multiple types. 394 A common practice is refactoring the assertions into a named \newterm{trait}, similar to other languages like Go and Rust.401 A common practice is to refactor the assertions into a named \newterm{trait}. 395 402 \begin{cfa} 396 403 forall(T) trait @Bird@ { … … 407 414 bird_fly( 23, robin ); 408 415 \end{cfa} 409 Grouping type assertions into a named trait effectively creates a reusable interface for parametric polymorphic types.416 Grouping type assertions into a named trait effectively creates a reusable interface for parametric-polymorphic types. 410 417 411 418 … … 416 423 When multiple best matches exist, the resolution is ambiguous. 417 424 418 The \CFA resolver attempts to identi fy thebest candidate based on: first, the number of parameters and types, and second, when no exact match exists, the fewest implicit conversions and polymorphic variables.419 Finding an exact match is not discussed here, because the mechanism is fairly straightforward, even when the search space is ample;425 The \CFA resolver attempts to identity a best candidate based on: first, the number of parameters and types, and second, when no exact match exists, the fewest implicit conversions and polymorphic variables. 426 Finding an exact match is not discussed here, because the mechanism is fairly straightforward, even when the search space is large; 420 427 only finding a non-exact match is discussed in detail. 421 428 … … 425 432 426 433 Most programming languages perform some implicit conversions among basic types to facilitate mixed-mode arithmetic; 427 otherwise, the program becomes littered with many explicit casts which do not match the programmer's expectations.428 C is an aggressive language , providing conversions among almost allbasic types, even when the conversion is potentially unsafe or not meaningful, \ie @float@ to @bool@.434 otherwise, the program becomes littered with many explicit casts, which is not match programmer expectation. 435 C is an aggressive language as it provides conversions among almost all of the basic types, even when the conversion is potentially unsafe or not meaningful, \ie @float@ to @bool@. 429 436 C defines the resolution pattern as ``usual arithmetic conversion''~\cite[\S~6.3.1.8]{C11}, in which C looks for a \newterm{common type} between operands, and converts one or both operands to the common type. 430 A common type is the smallest type in terms of thesize of representation that both operands can be converted into without losing their precision, called a \newterm{widening} or \newterm{safe conversion}.437 Loosely defined, a common type is a the smallest type in terms of size of representation that both operands can be converted into without losing their precision, called a \newterm{widening} or \newterm{safe conversion}. 431 438 432 439 \CFA generalizes ``usual arithmetic conversion'' to \newterm{conversion cost}. … … 438 445 @poly@ is the number of polymorphic function parameters, and 439 446 \item 440 @safe@ is thesum of the degree of safe (widening) conversions.447 @safe@ is sum of the degree of safe (widening) conversions. 441 448 \end{enumerate} 442 449 Sum of degree is a method to quantify C's integer and floating-point rank. 443 Every pair of widening conversion types is assigned a \newterm{distance}, and the distance between the two same typesis 0.444 For example, the distance from @char@ to @int@ is 2, from @int@ to @long@ is 1, andfrom @int@ to @long long int@ is 2.450 Every pair of widening conversion types is assigned a \newterm{distance}, and distance between the two same type is 0. 451 For example, the distance from @char@ to @int@ is 2, distance from @int@ to @long@ is 1, and distance from @int@ to @long long int@ is 2. 445 452 This distance does not mirror C's rank system. 446 For example, the @char@ and @signed char@ ranksare the same in C, but the distance from @char@ to @signed char@ is assigned 1.447 @safe@ cost is summing all pairs of argument sto parameter safe conversion distances.448 Among the three costs in Bilson's model, @unsafe@ is the most significant cost , and @safe@ is the least significant, implying that \CFA always choosesa candidate with the lowest @unsafe@, if possible.449 450 For example, assume the overloaded function @foo@ is called with two @int@ parameter s.451 The cost for every overloaded @foo@ has been list ed along with the following:453 For example, the rank of @char@ and @signed char@ are the same in C, but the distance from @char@ to @signed char@ is assigned 1. 454 @safe@ cost is summing all pairs of argument to parameter safe conversion distances. 455 Among the three costs in Bilson's model, @unsafe@ is the most significant cost and @safe@ is the least significant, with an implication that \CFA always choose a candidate with the lowest @unsafe@, if possible. 456 457 For example, assume the overloaded function @foo@ is called with two @int@ parameter. 458 The cost for every overloaded @foo@ has been list along: 452 459 \begin{cfa} 453 460 void foo( char, char ); $\C[2.5in]{// (1) (2, 0, 0)}$ … … 462 469 foo( i, j ); $\C{// convert j to long and call (8)}\CRT$ 463 470 \end{cfa} 464 The overloaded instances are ordered from the highest to the lowest cost, and \CFA select sthe last candidate (8).471 The overloaded instances are ordered from the highest to the lowest cost, and \CFA select the last candidate (8). 465 472 466 473 In the next iteration of \CFA, Schluntz and Aaron~\cite{Moss18} expanded conversion cost to a 7-tuple with 4 additional categories, @(unsafe, poly, safe, sign, vars, specialization, reference)@, with the following interpretations: … … 469 476 \item \textit{Poly} 470 477 \item \textit{Safe} 471 \item \textit{Sign} is the number of sign/unsign variable conversion s.472 \item \textit{Vars} is the number of polymorphic type variables.473 \item \textit{Specialization} is the negative value of the number of type assertions.478 \item \textit{Sign} is the number of sign/unsign variable conversion. 479 \item \textit{Vars} is the number of polymorphics type variable. 480 \item \textit{Specialization} is negative value of the number of type assertion. 474 481 \item \textit{Reference} is number of reference-to-rvalue conversion. 475 482 \end{itemize} 476 483 The extended conversion-cost model looks for candidates that are more specific and less generic. 477 484 @vars@ disambiguates @forall( T, V ) foo( T, V )@ and @forall( T ) void foo( T, T )@, where the extra type parameter @V@ makes is more generic. 478 A more generic type means fewerconstraints on its parameter types.485 A more generic type means less constraints on its parameter types. 479 486 \CFA favours candidates with more restrictions on polymorphism, so @forall( T ) void foo( T, T )@ has lower cost. 480 487 @specialization@ is an arbitrary count-down value starting at zero. 481 For every type assertion in the@forall@ clause (no assertions in the above example), \CFA subtracts one from @specialization@.482 More type assertions mean more constraints on argument types, making the function less generic.488 For every type assertion in @forall@ clause (no assertions in the above example), \CFA subtracts one from @specialization@. 489 More type assertions means more constraints on argument types, making the function less generic. 483 490 484 491 \CFA defines two special cost values: @zero@ and @infinite@. 485 A conversion cost is @zero@ when the argument and parameter have an exact match, and a conversion cost is @infinite@ when there is no defined conversion between thetwo types.492 A conversion cost is @zero@ when argument and parameter has an exact match, and a conversion cost is @infinite@ when there is no defined conversion between two types. 486 493 For example, the conversion cost from @int@ to a @struct S@ is @infinite@. 487 494 488 In \CFA, the meaning of a C-style cast is determined by its @Cast Cost@. 489 For most cast-expression resolutions, a cast cost equals a conversion cost. 490 Cast cost exists as an independent matrix for conversion that cannot happen implicitly while being possible with an explicit cast. 491 These conversions are often defined as having an infinite conversion cost and a non-infinite cast cost. 495 In \CFA, the meaning of a C style cast is determined by its @Cast Cost@. For most cast expression resolution, a cast cost is equal to a conversion cost. 496 Cast cost exists as an independent matrix for conversion that cannot happen implcitly, while being possible with an explicit cast. These conversions are often defined to have 497 infinite conversion cost and non-infinite cast cost. -
doc/theses/jiada_liang_MMath/conclusion.tex
r6abb6dc r2ca7fc2 2 2 \label{c:conclusion} 3 3 4 The goal of this work is to extend the simple and unsafe enumeration type in the C programming language into a complex and safe enumeration type in the \CFA programming language while maintaining backward compatibility with C. 5 Within this goal, the new \CFA enumeration should align with the analogous enumeration features in other languages to match modern programming expectations. 6 Hence, the \CFA enumeration features are borrowed from a number of programming languages, but engineered to work and play with \CFA's type system and feature set. 4 The goal of this thesis is to adapt enumeration in \CFA to be aligned with the analogous features in 5 other languages while being backward-compatiable to C. 6 The presented features are based off on tools and techniques that widely used in 7 other languages but they were adapted to better fix \CFA's feature set. Additionally, the thesis provides 8 an improvement on safety and productivity of C enumeration, including enumerator overloading, 9 name scoping and type checking. 7 10 8 Strong type-checking of enumeration initialization and assignment provides additional safety, ensuring an enumeration only contains its enumerators. 9 Overloading and scoping of enumerators significantly reduces the naming problem, providing a better software-engineering environment, with fewer name clashes and the ability to disambiguate those that cannot be implicitly resolved. 10 Typed enumerations solve the data-harmonization problem increasing safety through better software engineering. 11 Moreover, integrating enumerations with existing control structures provides a consistent upgrade for programmers and a succinct and secure mechanism to enumerate with the new loop-range feature. 12 Generalization and reuse are supported by incorporating the new enumeration type using the \CFA trait system. 13 Enumeration traits define the meaning of an enumeration, allowing functions to be written that work on any enumeration, such as the reading and printing an enumeration. 14 Using advanced duck typing, existing C enumerations can be extended so they work with all of the enumeration features, providing for legacy C code to be moved forward into the modern \CFA programming domain. 15 Finally, I expanded the \CFA project's test-suite with multiple enumeration features tests with respect to implicit conversions, control structures, inheritance, interaction with the polymorphic types, and the features built on top of enumeration traits. 16 These tests ensure future \CFA work does not accidentally break the new enumeration system. 11 To further explores the potential of enumerated types, this thesis presents a new \CFA enumeration 12 that is independent on C enumeration. The \CFA enumeration aims to solve the data harmonization problem 13 and have natural support to \CFA generic type, along with some new features that fit with \CFA's 14 programming pattern, such as enumerator conctrol structures. 17 15 18 The conclusion is that the new \CFA enumeration mechanisms achieve the initial goals, providing C programmers with an intuitive enumeration mechanism for handling modern programming requirements. 16 The \CFA project's test suite has been expanded to test the enumerations with respect to its 17 implicit conversions, inheritance, interaction with the polymorphic types, and the features 18 built on top of enumeration traits. 19 19 20 The enumerated type is an attempt to adapt classic data types into \CFA unique type system. It brings 21 valuable new feature to \CFA in its own right, but also serve as a motivation to adapt other data types 22 in \CFA. 20 23 21 \section{Future Work}24 % \section{Future Work} 22 25 23 The following are ideas to improve and extend the work in this thesis.24 \begin{enumerate}25 \item26 There are still corner cases being found in the current \CFA enumeration implementation.27 Fixing some of these corner cases requires changes to the \CFA resolver or extensions to \CFA. %, like compile-time constant-expression evaluation.28 When these changes are made, it should be straightforward to update the \CFA enumeration implementation to work with them.29 \item30 Currently, some aspects of the enumeration trait system require explicitly including the file @enum.hfa@, which can lead to problems.31 It should be possible to have this file included implicitly by updating the \CFA prelude.32 \item33 There are multiple \CFA features being developed in parallel with enumerations.34 Two closely related features are iterator and namespace.35 Enumerations may have to be modified to dovetail with these features.36 For example, enumerating with range loops does not align with the current iterator design, so some changes will be necessary.37 \item38 C already provides @const@-style aliasing using the \emph{unnamed} enumerator \see{\VRef{s:TypeName}}, even if the name @enum@ is misleading (@const@ would be better).39 Given the existence of this form, it is conceivable to extend it with types other than @int@.40 \begin{cfa}41 enum { Size = 20u, PI = 3.14159L, Jack = L"John" };42 \end{cfa}43 which matches with @const@ aliasing in other programming languages.44 Here, the type of the enumerator is the type of the initialization constant, \eg @typeof( 20u )@ for @Size@ implies @unsigned int@.45 Auto-initialization is restricted to the case where all constants are @int@, matching with C.46 As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations.47 \begin{cfa}48 enum( unsigned int ) { Size = 20u };49 enum( long double ) { PI = 3.14159L };50 enum( wchar_t * ) { Jack = L"John" };51 \end{cfa}52 \item53 Currently enumeration scoping is all or nothing. In some cases, it might be useful to54 increase the scoping granularity to individual enumerators.55 \begin{cfa}56 enum E1 { @!@A, @^@B, C };57 enum E2 @!@ { @!@A, @^@B, C };58 \end{cfa}59 Here, @'!'@ means the enumerator is scoped, and @'^'@ means the enumerator is unscoped.60 For @E1@, @A@ is scoped; @B@ and @C@ are unscoped.61 For @E2@, @A@, and @C@ are scoped; @B@ is unscoped.62 Finding a use case is important to justify this extension.63 \item64 An extension mentioned in \VRef{s:Ada} is using @typedef@ to create an enumerator alias.65 \begin{cfa}66 enum(int) RGB { @Red@, @Green@, Blue };67 enum(int) Traffic_Light { @Red@, Yellow, @Green@ };68 typedef RGB.Red OtherRed; // alias69 \end{cfa}70 \end{enumerate} -
doc/theses/jiada_liang_MMath/intro.tex
r6abb6dc r2ca7fc2 1 1 \chapter{Introduction} 2 2 3 All basic types in a programming language have a set of constants (symbols), and these constants represent computable values, \eg integer types have constants @-1@, @17@, @0xff@ representing whole numbers, floating-point types have constants @5.3@, @2.3E-5@, @0xff.ffp0@ representing real numbers, character types have constants @'a'@, @"abc\n"@, \mbox{\lstinline{u8"}\texttt{\guillemotleft{na\"{i}ve}\guillemotright}\lstinline{"}} representing (human readable) text, \etc.3 All basic types in a programming language have a set of constants (symbols), and these constants represent computable values, \eg integer types have constants @-1@, @17@, @0xff@ representing whole numbers, floating-point types have constants @5.3@, @2.3E-5@, @0xff.ffp0@ representing real numbers, character types have constants @'a'@, @"abc\n"@, \mbox{\lstinline{u8"}\texttt{\guillemotleft{na\"{i}ve}\guillemotright}\lstinline{"}} representing (human readable) text, \etc. 4 4 Constants can be overloaded among types, \eg @0@ is a null pointer for all pointer types, and the value zero for integer and floating-point types. 5 5 (In \CFA, the constants @0@ and @1@ can be overloaded for any type.) … … 12 12 A constant's symbolic name is dictated by language syntax related to types, \eg @5.@ (double), @5.0f@ (float), @5l@ (long double). 13 13 In general, the representation of a constant's value is \newterm{opaque}, so the internal representation can be chosen arbitrarily, \eg two's complement, IEEE floating-point. 14 In theory, there isan infinite set of constant names per type representing an infinite set of values.14 In theory, there are an infinite set of constant names per type representing an infinite set of values. 15 15 16 16 It is common in mathematics, engineering, and computer science to alias new constants to existing constants so they have the same value, \eg $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), K(k), M, G, T for powers of 2\footnote{Overloaded with SI powers of 10.} often prefixing bits (b) or bytes (B), \eg Gb, MB, and in general situations, \eg specific times (noon, New Years), cities (Big Apple), flowers (Lily), \etc. … … 23 23 Because an aliased name is a constant, it cannot appear in a mutable context, \eg \mbox{$\pi$ \lstinline{= 42}} is meaningless, and a constant has no address, \ie it is an \newterm{rvalue}\footnote{ 24 24 The term rvalue defines an expression that can only appear on the right-hand side of an assignment expression.}. 25 In theory, there is an infinite set of possible aliasing;in practice, the number of aliasing per program is finite and small.25 In theory, there are an infinite set of possible aliasing, in practice, the number of aliasing per program is finite and small. 26 26 27 27 Aliased constants can form an (ordered) set, \eg days of a week, months of a year, floors of a building (basement, ground, 1st), colours in a rainbow, \etc. … … 59 59 \end{sloppypar} 60 60 \item 61 The alias names are constants, which follow transitively from their binding to other constants.61 The alias names are constants, which follows transitively from their binding to other constants. 62 62 \item 63 63 Defines a type for generating instants (variables). … … 140 140 \end{cfa} 141 141 For these reasons, aliasing is sometimes called an enumeration. 142 However, there is no type to create a type-checked instance or iterator cursor, so there is no ability to enumerate.142 However, there is no type to create a type-checked instance or iterator cursor, so there is no ability for enumerating. 143 143 Hence, there are multiple enumeration aspects not provided by aliasing, justifying a separate enumeration type in a programming language. 144 144 … … 158 158 the ADT has three variants (constructors), @A@, @B@, @C@, with associated types @Int@, @Double@, and @S@. 159 159 The constructors create an initialized value of the specific type that is bound to the immutable variables @foo@, @bar@, and @baz@. 160 Hence, the ADT @Foo@ is like a union containing values of the associated types, and a constructor name is used to in itialize and access the value using dynamic pattern-matching.160 Hence, the ADT @Foo@ is like a union containing values of the associated types, and a constructor name is used to intialize and access the value using dynamic pattern-matching. 161 161 \begin{cquote} 162 162 \setlength{\tabcolsep}{20pt} … … 194 194 baz = Z 5; 195 195 \end{haskell} 196 Here, the constructor name gives different meaning sto the values in the common \lstinline[language=Haskell]{Int} type, \eg the value @3@ has different interpretations depending on the constructor name in the pattern matching.196 Here, the constructor name gives different meaning to the values in the common \lstinline[language=Haskell]{Int} type, \eg the value @3@ has different interpretations depending on the constructor name in the pattern matching. 197 197 198 198 Note, the term \newterm{variant} is often associated with ADTs. 199 199 However, there are multiple languages with a @variant@ type that is not an ADT \see{Algol68~\cite{Algol68} or \CC \lstinline{variant}}. 200 Here, the type (and possibly the position for equivalent types) is used to discrimina tethe specific \emph{variant} within the variant instance.200 Here, the type (and possibly the position for equivalent types) is used to discriminant the specific \emph{variant} within the variant instance. 201 201 For example, \VRef[Figure]{f:C++variant} shows the \CC equivalent of the two Haskell ADT types using variant types. 202 202 In these languages, the variant cannot be used to simulate an enumeration. … … 246 246 data Week = Mon | Tue | Wed | Thu | Fri | Sat | Sun deriving(Enum, Eq, Show) 247 247 \end{haskell} 248 the default type for each constructor is the unit type, and deriving from @Enum@ enforces no other associated types . The@Eq@ allows equality comparison, and @Show@ is for printing.249 The nullary constructors for the unit types are numbered left-to-right from $0$ to @maxBound@$- 1$, and provide enumerating operations @succ@, @pred@, @enumFrom@, @enumFromTo@.248 the default type for each constructor is the unit type, and deriving from @Enum@ enforces no other associated types, @Eq@ allows equality comparison, and @Show@ is for printing. 249 The nullary constructors for the unit types are numbered left-to-right from $0$ to @maxBound@$- 1$, and provides enumerating operations @succ@, @pred@, @enumFrom@, @enumFromTo@. 250 250 \VRef[Figure]{f:HaskellEnumeration} shows enumeration comparison and iterating (enumerating). 251 251 … … 296 296 However, when extended with advanced features, enumerations become complex for both the type system and the runtime implementation. 297 297 298 The contribution sof this work are:298 The contribution of this work are: 299 299 \begin{enumerate} 300 300 \item 301 safety: Define a safe enumeration conversion scheme, both for C and \CFA, and replace ad-hoc C idioms with safer software-engineering approaches. 302 \item 303 overloading: Provide a pattern to overload functions, literals, and variables for polymorphic enumerations using the \CFA type system. 304 \item 305 scoping: Add a namespace for enumerations and qualified access into the namespace to deal with the naming problem. 306 \item 307 generalization: Support all language types for enumerators with associated values providing enumeration constants for any type. 308 \item 309 reuse: Implement subset and containment inheritance for enumerations. 310 \item 311 control flow: Extend control-flow structures making it safer and easier to enumerate over an enumeration. 312 \item 313 I/O: Provide input and output of enumerations based on enumerator names. 301 overloading: provides a pattern to overload functions, literal, and variable for polymorphic enumerations. 302 \item 303 scoping: adds name space for enumerations. 304 \item 305 safety: defines a safe enumeration conversion scheme. 306 \item 307 harmonization: allows enumeration to be mapped with data. 308 \item 309 inheritance: implements containment inheritance for enumerations. 314 310 \end{enumerate} 315 311 -
doc/theses/jiada_liang_MMath/relatedwork.tex
r6abb6dc r2ca7fc2 18 18 \end{comment} 19 19 20 Enumeration-like features exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, OCaml~\cite{OCaml} \CC, Go~\cite{Go}, Haskell~\cite{Haskell} \see{discussion in \VRef{s:AlgebraicDataType}}, Java~\cite{Java}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}.21 Among these languages, there isa large set of overlapping features, but each language has its own unique extensions and restrictions.20 Enumeration-like features exist in many popular programming languages, both past and present, \eg Pascal~\cite{Pascal}, Ada~\cite{Ada}, \Csharp~\cite{Csharp}, OCaml~\cite{OCaml} \CC, Go~\cite{Go}, Haskell~\cite{Haskell}, Java~\cite{Java}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}. 21 Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions. 22 22 23 23 … … 39 39 \end{pascal} 40 40 Object initialization and assignment are restricted to the enumerators of this type. 41 Enumerators are auto-initialized from left to right, starting at zero andincrementing by 1.41 Enumerators are auto-initialized from left to right, starting at zero, incrementing by 1. 42 42 Enumerators \emph{cannot} be explicitly initialized. 43 43 Pascal provides a predefined type \lstinline[language=Pascal]{Boolean} defined as: … … 56 56 \end{cquote} 57 57 58 Pascal provides \emph{consecutive} sub setting of an enumeration using asubrange type.58 Pascal provides \emph{consecutive} subtyping of an enumeration using subrange type. 59 59 \begin{pascal} 60 60 type Week = ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); 61 Weekday = @Mon..Fri@; { subtype }62 Weekend = @Sat..Sun@;61 Weekday = @Mon..Fri@; 62 Weekend = @Sat..Sun@; 63 63 var day : Week; 64 wday : Weekday;65 wend : Weekend;64 wday : Weekday; 65 wend : Weekend; 66 66 \end{pascal} 67 67 Hence, the ordering of the enumerators is crucial to provide the necessary ranges. 68 There is abidirectional assignment between the enumeration and its subranges.68 There is bidirectional assignment between the enumeration and its subranges. 69 69 \begin{pascal} 70 70 day := Sat; … … 77 77 day := wend; $\C{\{ no check \}}\CRT$ 78 78 \end{pascal} 79 A static/dynamic range check should be performed to verify thevalues assigned to subtypes.79 There should be a static/dynamic range check to verify values assigned to subtypes. 80 80 (Free Pascal does not check and aborts in certain situations, like writing an invalid enumerator.) 81 81 … … 85 85 \begin{tabular}{@{}ll@{}} 86 86 \begin{pascal} 87 day := Mon;88 87 if @day@ = wday then 89 88 Writeln( day ); 90 89 if @day@ <= Fri then 91 90 Writeln( 'weekday'); 92 Mon 93 weekday 91 92 94 93 \end{pascal} 95 94 & 96 95 \begin{pascal} 97 98 96 case @day@ of 99 97 Mon..Fri : … … 102 100 Writeln( 'weekend') 103 101 end; 104 weekday105 102 \end{pascal} 106 103 \end{tabular} … … 110 107 \begin{tabular}{@{}ll@{}} 111 108 \begin{pascal} 112 while day <= Sun do begin 109 day := Mon; 110 while day <= Sat do begin 113 111 Write( day, ' ' ); 114 112 day := succ( day ); 115 113 end; 116 Mon Tue Wed Thu Fri Sat Sun114 Mon Tue Wed Thu Fri Sat 117 115 \end{pascal} 118 116 & 119 117 \begin{pascal} 120 for day := Mon to Sun do begin 118 119 for day := Mon to Sat do begin 121 120 Write( day, ' ' ); 122 121 123 122 end; 124 Mon Tue Wed Thu Fri Sat Sun123 Mon Tue Wed Thu Fri Sat 125 124 \end{pascal} 126 125 \end{tabular} 127 126 \end{cquote} 128 Note that subtypes@Weekday@ and @Weekend@ cannot be used to define a case or loop range.127 Note, subtype @Weekday@ and @Weekend@ cannot be used to define a case or loop range. 129 128 130 129 An enumeration type can be used as an array dimension and subscript. … … 150 149 \end{pascal} 151 150 152 The underlying type is an implementation-defined integral type large enough to hold all enumerated values; it does not have to be the smallest possible type.151 The underlying type is an implementation-defined integral-type large enough to hold all enumerated values; it does not have to be the smallest possible type. 153 152 The integral size can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, \eg: 154 153 \begin{pascal} … … 161 160 162 161 \section{Ada} 163 \label{s:Ada}164 162 165 163 An Ada enumeration type is a set of ordered, unscoped identifiers (enumerators) bound to \emph{unique} \newterm{literals}.\footnote{% … … 174 172 type Traffic_Light is ( @Red@, Yellow, @Green@ ); 175 173 \end{ada} 176 Like \CFA, Ada uses a type-resolution algorithm , including the left-hand side of the assignment,to disambiguate among overloaded identifiers.177 \VRef[Figure]{f:AdaEnumeration} shows how ambiguity is handled using a cast, \ eg\lstinline[language=ada]{RGB'(Red)}.174 Like \CFA, Ada uses a type-resolution algorithm including the left-hand side of assignmente to disambiguate among overloaded identifiers. 175 \VRef[Figure]{f:AdaEnumeration} shows how ambiguity is handled using a cast, \ie \lstinline[language=ada]{RGB'(Red)}. 178 176 179 177 \begin{figure} … … 196 194 \end{ada} 197 195 \caption{Ada Enumeration Overload Resolution} 198 \label{f:AdaEnumeration} 196 \label{f:AdaEnumeration} 199 197 \end{figure} 200 198 … … 203 201 \begin{ada} 204 202 type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); 205 for Week use ( Mon => 0, Tue => 1, Wed => 2, Thu => @10@, Fri => 11, Sat => 14, Sun => 15 );206 \end{ada} 207 The enumeration operators are the equality and relational operators, @=@, @/=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of a scending enumerators.203 for Week use ( Mon => 0, Tue => 1, Wed => 2, Thu => @10@, Fri => 11, Sat => 14, Sun => 15 ); 204 \end{ada} 205 The enumeration operators are the equality and relational operators, @=@, @/=@, @<@, @<=@, @=@, @/=@, @>=@, @>@, where the ordering relationship is given implicitly by the sequence of acsending enumerators. 208 206 209 207 Ada provides an alias mechanism, \lstinline[language=ada]{renames}, for aliasing types, which is useful to shorten package identifiers. … … 261 259 if @Flag@ then ... -- conditional 262 260 \end{ada} 263 Since only types derived from @Boolean@ can be conditional, @Boolean@ is essentiallya builtin type.264 265 Ada provides \emph{consecutive} sub setting of an enumeration using \lstinline[language=ada]{range}.261 Since only types derived from @Boolean@ can be a conditional, @Boolean@ is essentially a builtin type. 262 263 Ada provides \emph{consecutive} subtyping of an enumeration using \lstinline[language=ada]{range}. 266 264 \begin{ada} 267 265 type Week is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); … … 327 325 \label{s:C++RelatedWork} 328 326 329 \CC enumeration is largely backward compatible with C, so it inherited C's enumerations with some modifications and additions.327 \CC enumeration is largely backwards compatible with C, so it inherited C's enumerations with some modifications and additions. 330 328 331 329 \CC has aliasing using @const@ declarations, like C \see{\VRef{s:Cconst}}, with type inferencing, plus static/dynamic initialization. … … 353 351 whereas C @const@ declarations without @static@ are marked @R@. 354 352 355 The following \CC non-backward compatible change is made~\cite[C.1.5.7.2]{C++}, plus the safe-assignment change shown in~\VRef{s:TypeSafety}. 356 \begin{description}[parsep=0pt] 357 \item[Change:] In \CC, the type of an enumerator is its enumeration. 358 In C, the type of an enumerator is @int@. 353 The following \CC non-backwards compatible changes are made \see{\cite[\S~7.2]{ANSI98:c++}}. 354 \begin{cquote} 355 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type. 356 In C, objects of enumeration type can be assigned values of any integral type. \\ 357 Example: 358 \begin{c++} 359 enum color { red, blue, green }; 360 color c = 1; $\C{// valid C, invalid c++}$ 361 \end{c++} 362 \textbf{Rationale}: The type-safe nature of \CC. \\ 363 \textbf{Effect on original feature}: Deletion of semantically well-defined feature. \\ 364 \textbf{Difficulty of converting}: Syntactic transformation. (The type error produced by the assignment can be automatically corrected by applying an explicit cast.) \\ 365 \textbf{How widely used}: Common. 366 \end{cquote} 367 368 \begin{cquote} 369 Change: In \CC, the type of an enumerator is its enumeration. 370 In C, the type of an enumerator is @int@. \\ 359 371 Example: 360 372 \begin{c++} 361 373 enum e { A }; 362 374 sizeof(A) == sizeof(int) $\C{// in C}$ 363 sizeof(A) == sizeof(e) $\C{// in \CC}$375 sizeof(A) == sizeof(e) $\C{// in c++}$ 364 376 /* and sizeof(int) is not necessary equal to sizeof(e) */ 365 377 \end{c++} 366 \ item[Rationale:] In \CC, an enumeration is a distinct type.367 \ item[Effect on original feature:] Change to semantics of well-defined feature.368 \ item[Difficulty of converting:] Semantic transformation.369 \ item[How widely used:]Seldom. The only time this affects existing C code is when the size of an enumerator is taken.378 \textbf{Rationale}: In \CC, an enumeration is a distinct type. \\ 379 \textbf{Effect on original feature}: Change to semantics of well-defined feature. \\ 380 \textbf{Difficulty of converting}: Semantic transformation. \\ 381 \textbf{How widely used}: Seldom. The only time this affects existing C code is when the size of an enumerator is taken. 370 382 Taking the size of an enumerator is not a common C coding practice. 371 \end{ description}383 \end{cquote} 372 384 Hence, the values in a \CC enumeration can only be its enumerators (without a cast). 373 374 385 While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@. 375 386 \begin{c++} … … 433 444 0 1 2 @3 4 5 6 7 8 9@ 10 11 12 13 434 445 \end{c++} 435 As a consequence, there is no meaningful enumerating mechanism.436 437 446 An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript. 438 There is no mechanism to sub setor inherit from an enumeration.439 440 441 \section{C\ texorpdfstring{\raisebox{-0.7ex}{\LARGE$^\sharp$}\xspace}{Csharp}} % latex bug: cannot use \relsize{2} so use \LARGE447 There is no mechanism to subtype or inherit from an enumeration. 448 449 450 \section{C\raisebox{-0.7ex}{\LARGE$^\sharp$}\xspace} % latex bug: cannot use \relsize{2} so use \LARGE 442 451 \label{s:Csharp} 443 452 … … 446 455 % https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/enums 447 456 448 \Csharp is a dynamically-typed programming language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}.457 \Csharp is a dynamically-typed programming-language with a scoped, integral enumeration similar to \CC \lstinline[language=C++]{enum class}. 449 458 \begin{csharp} 450 enum Week : @long@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun }459 enum Week : @long@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun@,@ } // terminating comma 451 460 enum RGB { Red, Green, Blue } 452 461 \end{csharp} 453 The default underlying integral type is @int@ , with auto-incrementing and implicit/explicit initialization.462 The default underlying integral type is @int@ (no @char@), with auto-incrementing, implicit/explicit initialization, and terminating comma. 454 463 A method cannot be defined in an enumeration type (extension methods are possible). 455 464 There is an explicit bidirectional conversion between an enumeration and its integral type, and an implicit conversion to the enumerator label in display contexts. … … 462 471 Console.WriteLine( Week.Fri ); $\C{// print label Fri}$ 463 472 \end{csharp} 464 % The majority of the integral operators (relational and arithmetic) work with enumerations, except @*@ and @/@. 465 % Relational and arithmetic operators are defined in terms of its numeric value only. 466 % Therefore, enumerators are not ordered and not enumerable like \CC. 467 Like \CC, \Csharp defines enumeration relational and arithmetic operators in terms of value. 468 Enumerators have no defined positional meaning. 473 The majority of the integral operators (relational and arithmetic) work with enumerations, except @*@ and @/@. 469 474 \begin{csharp} 470 day = day++ - 5; $\C{// value manipulation}$475 day = day++ - 5; $\C{// unsafe}$ 471 476 day = day & day; 472 477 \end{csharp} 473 \begin{csharp}474 for ( Week d = Mon; d <= Sun; @d += 1@ ) {475 Console.Write( d + " " );476 }477 Mon Tue Wed @3 4 5 6 7 8 9@ Thu Fri Sat Sun478 \end{csharp}479 As a consequence, there is no direct meaningful enumerating mechanism.480 478 481 479 An enumeration can be used in the @if@ and @switch@ statements. … … 504 502 \end{tabular} 505 503 \end{cquote} 506 507 To indirectly enumerate, \Csharp's Enum library has @Enum.GetValues@, a pseudo-method that retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 504 However, there is no mechanism to iterate through an enumeration without an unsafe cast to increment and positions versus values is not handled. 505 \begin{csharp} 506 for ( Week d = Mon; d <= Sun; @d += 1@ ) { 507 Console.Write( d + " " ); 508 } 509 Mon Tue Wed @3 4 5 6 7 8 9@ Thu Fri Sat Sun 510 \end{csharp} 511 The @Enum.GetValues@ pseudo-method retrieves an array of the enumeration constants for looping over an enumeration type or variable (expensive operation). 508 512 \begin{csharp} 509 513 foreach ( Week d in @Enum.GetValues@( typeof(Week) ) ) { … … 512 516 Mon 0, Tue 1, Wed 2, Thu 10, Fri 11, Sat 12, Sun 13, 513 517 \end{csharp} 514 Hence, enumerating is not supplied directly by the enumeration, but indirectly through the enumerable array type.518 Hence, enumerating is not supplied directly by the enumeration, but indirectly through another enumerable type, array. 515 519 516 520 An enumeration type cannot declare an array dimension but an enumerator can be used as a subscript. 517 There is no mechanism to sub setor inherit from an enumeration.521 There is no mechanism to subtype or inherit from an enumeration. 518 522 519 523 The @Flags@ attribute creates a bit-flags enumeration, making bitwise operators @&@, @|@, @~@ (complement), @^@ (xor) sensible. … … 529 533 530 534 531 \section{Go }532 \label{s:Go }533 534 Go has a no enumeration.535 \section{Golang} 536 \label{s:Golang} 537 538 Golang has a no enumeration. 535 539 It has @const@ aliasing declarations, similar to \CC \see{\VRef{s:C++RelatedWork}}, for basic types with type inferencing and static initialization (constant expression). 536 540 \begin{Go} … … 541 545 const V = 3.1; const W = 3.1; 542 546 \end{Go} 543 Since these declarations are immutable variables, they are unscoped and Gohas no overloading.544 545 Go provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization.547 Since these declarations are unmutable variables, they are unscoped and Golang has no overloading. 548 549 Golang provides an enumeration-like feature to group together @const@ declaration into a block and introduces a form of auto-initialization. 546 550 \begin{Go} 547 551 const ( R = 0; G; B ) $\C{// implicit initialization: 0 0 0}$ … … 570 574 \begin{Go} 571 575 const ( Mon = iota; Tue; Wed; // 0, 1, 2 572 @Thu = 10@; Fri; Sat; @Sun = itoa@ ) $\C{// 10, 10, 10, {\color{red}6}}$576 @Thu = 10@; Fri; Sat; Sun = itoa ) // 10, 10, 10, 6 573 577 \end{Go} 574 Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing a tmost \emph{one} \lstinline[language=Go]{iota}.578 Auto-initialization from \lstinline[language=Go]{iota} is restarted and \lstinline[language=Go]{iota} reinitialized with an expression containing as most \emph{one} \lstinline[language=Go]{iota}. 575 579 \begin{Go} 576 580 const ( V1 = iota; V2; @V3 = 7;@ V4 = @iota@ + 1; V5 ) // 0 1 7 4 5 577 581 const ( Mon = iota; Tue; Wed; // 0, 1, 2 578 @Thu = 10;@ Fri = @iota @ - Wed + Thu - 1; Sat; Sun ) // 10, 11, 12, 13582 @Thu = 10;@ Fri = @iota - Wed + Thu - 1@; Sat; Sun ) // 10, 11, 12, 13 579 583 \end{Go} 580 Here, @V4@ and @Fri@ restart auto-incrementing from \lstinline[language=Go]{iota} and reset \lstinline[language=Go]{iota} to 4 and 11, respectively, because of the in itialization expressions containing \lstinline[language=Go]{iota}.584 Here, @V4@ and @Fri@ restart auto-incrementing from \lstinline[language=Go]{iota} and reset \lstinline[language=Go]{iota} to 4 and 11, respectively, because of the intialization expressions containing \lstinline[language=Go]{iota}. 581 585 Note, because \lstinline[language=Go]{iota} is incremented for an explicitly initialized identifier or @_@, 582 586 at @Fri@ \lstinline[language=Go]{iota} is 4 requiring the minus one to compute the value for @Fri@. … … 621 625 A basic Java enumeration is an opaque enumeration, where the enumerators are constants. 622 626 \begin{Java} 623 enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun; } 627 enum Week { 628 Mon, Tue, Wed, Thu, Fri, Sat, Sun; 629 } 624 630 Week day = Week.Sat; 625 631 \end{Java} 626 The enumerator 's members are scoped and cannot be made \lstinline[language=java]{public}, hence requiringqualification.632 The enumerators members are scoped and cannot be made \lstinline[language=java]{public}, hence require qualification. 627 633 The value of an enumeration instance is restricted to its enumerators. 628 634 629 The position (ordinal) and label (name) are accessible but there is no value property.635 The position (ordinal) and label are accessible but there is no value. 630 636 \begin{Java} 631 637 System.out.println( day.!ordinal()! + " " + !day! + " " + day.!name()! ); … … 633 639 \end{Java} 634 640 Since @day@ has no value, it prints its label (name). 635 The member @valueOf@ is the inverse of @name@ converting a string to anenumerator.641 The member @valueOf@ is the inverse of @name@ converting a string to enumerator. 636 642 \begin{Java} 637 643 day = Week.valueOf( "Wed" ); … … 687 693 Notice enumerators in the @switch@ statement do not require qualification. 688 694 689 There are no arith metic operations on enumerations, so there is no arithmetic way to iterate through an enumeration without making the implementation type \lstinline[language=Java]{public}.695 There are no arithemtic operations on enumerations, so there is no arithmetic way to iterate through an enumeration without making the implementation type \lstinline[language=Java]{public}. 690 696 Like \Csharp, looping over an enumeration is done using method @values@, which returns an array of enumerator values (expensive operation). 691 697 \begin{Java} … … 776 782 #[repr(u8)] 777 783 enum ADT { 778 I(isize) @= 5@, 784 I(isize) @= 5@, // ??? 779 785 F(f64) @= 10@, 780 786 S(S) @= 0@, … … 785 791 Through this integral tag, it is possible to enumerate, and when all tags represent the unit type, it behaves like \CC \lstinline[language=C++]{enum class}. 786 792 When tags represent non-unit types, Rust largely precludes accessing the tag because the semantics become meaningless. 787 Hence, the two mechanisms are largely disjoint, and on ly the enumeration component is discussed.788 789 In detail, the @enum@ type has an implicit integer tag (discriminant) with a unique value for each variant type.790 Direct initialization is achieved by a compile-time expression that generatesa constant value.793 Hence, the two mechanisms are largely disjoint, and ony the enumeration component is discussed. 794 795 In detail, the @enum@ type has an implicit integer tag (discriminant), with a unique value for each variant type. 796 Direct initialization is by a compile-time expression generating a constant value. 791 797 Indirect initialization (without initialization, @Fri@/@Sun@) is auto-initialized: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 792 798 There is an explicit cast from the tag to integer. … … 823 829 \end{c++} 824 830 An enumeration type cannot declare an array dimension nor as a subscript. 825 There is no mechanism to sub setor inherit from an enumeration.831 There is no mechanism to subtype or inherit from an enumeration. 826 832 827 833 … … 872 878 \end{tabular} 873 879 \end{cquote} 874 Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@. 880 (Note, after an @adt@'s type is know, the enumerator is inferred without qualification, \eg @.I(3)@.) 875 881 876 882 An enumeration is created when \emph{all} the enumerators are unit-type, which is like a scoped, opaque enumeration. 877 883 \begin{swift} 878 enum Week { case Mon, Tue, Wed, Thu, Fri, Sat, Sun }; // unit-type 884 enum Week { 885 case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type 886 }; 879 887 var week : Week = @Week.Mon@; 880 888 \end{swift} … … 903 911 An enumeration can have methods. 904 912 \begin{swift} 905 enum Week: @Comparable@{913 enum Week: Comparable { 906 914 case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type 907 func @isWeekday() -> Bool@ { return self <= .Fri } // methods908 func @isWeekend() -> Bool@ { return .Sat <= self } 915 func @isWeekday() -> Bool@ { return self <= .Fri } // method 916 func @isWeekend() -> Bool@ { return .Sat <= self } // method 909 917 }; 910 918 \end{swift} … … 930 938 \end{tabular} 931 939 \end{cquote} 940 932 941 Enumerating is accomplished by inheriting from @CaseIterable@ without any associated values. 933 942 \begin{swift} … … 935 944 case Mon, Tue, Wed, Thu, Fri, Sat, Sun // unit-type 936 945 }; 946 var weeki : Week = Week.Mon; 947 if weeki <= .Fri { 948 print( "weekday" ); 949 } 937 950 for day in Week@.allCases@ { 938 951 print( day, terminator:" " ) 939 952 } 953 weekday 940 954 Mon Tue Wed Thu Fri Sat Sun 941 955 \end{swift} 942 956 The @enum.allCases@ property returns a collection of all the cases for looping over an enumeration type or variable (expensive operation). 943 957 944 A typed enumeration is accomplished by inheriting from any Swift type, and accessing the underlying enumerator value is done with theattribute @rawValue@.945 Type @Int@ has auto-incrementing from theprevious enumerator;958 A typed enumeration is accomplished by inheriting from any Swift type, and accessing the underlying enumerator value is done with attribute @rawValue@. 959 Type @Int@ has auto-incrementing from previous enumerator; 946 960 type @String@ has auto-incrementing of the enumerator label. 947 961 \begin{cquote} … … 972 986 \end{cquote} 973 987 974 There is a bidirectional conversion from typed enumerator to @rawValue@ and vi ce versa.988 There is a bidirectional conversion from typed enumerator to @rawValue@ and vise versa. 975 989 \begin{swift} 976 990 var weekInt : WeekInt = WeekInt.Mon; … … 988 1002 989 1003 Python is a dynamically-typed reflexive programming language with multiple incompatible versions. 990 The generality of the language makes it possible to extend existing or build new language features.991 As a result, discussing Python enumerations is a moving target, because if a feature does not exist, it can often be created with varying levels of complexity within the language.1004 The generality of the language makes it is possible to extend existing or build new language features. 1005 As a result, discussing Python enumerations is a moving target, because if a features does not exist, it can often be created with varying levels of complexity within the language. 992 1006 Therefore, the following discussion is (mostly) restricted to the core enumeration features in Python 3.13. 993 1007 994 1008 A Python enumeration is not a basic type; 995 1009 it is a @class@ inheriting from the @Enum@ class. 996 The @Enum@ class presents a set of scoped enumerators, where each enumerator is a pair object with a \emph{constant} string name and a n arbitrary value.1010 The @Enum@ class presents a set of scoped enumerators, where each enumerator is a pair object with a \emph{constant} string name and arbitrary value. 997 1011 Hence, an enumeration instance is a fixed type (enumeration pair), and its value is the type of one of the enumerator pairs. 998 1012 … … 1001 1015 class Week(!Enum!): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1002 1016 \end{python} 1003 and/or explicitly auto -initialized, \eg:1017 and/or explicitly auto initialized, \eg: 1004 1018 \begin{python} 1005 1019 class Week(Enum): Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = !auto()!; Sat = 4; Sun = !auto()! 1006 1020 Mon : 1 Tue : 2 Wed : 3 Thu : 10 Fri : !11! Sat : 4 Sun : !12! 1007 1021 \end{python} 1008 where @auto@ increments by 1 from the previous @auto@ value \see{Go \lstinline[language=Go]{iota}, \VRef{s:Go}}.1022 where @auto@ increments by 1 from the previous @auto@ value \see{Golang \lstinline[language=Go]{iota}, \VRef{s:Golang}}. 1009 1023 @auto@ is controlled by member @_generate_next_value_()@, which can be overridden: 1010 1024 \begin{python} … … 1014 1028 \end{python} 1015 1029 1016 There is no direct concept of restricting the enumerators in an enumeration \emph{instance} because dynamic typing changes the type.1030 There is no direct concept of restricting the enumerators in an enumeration \emph{instance} because the dynamic typing changes the type. 1017 1031 \begin{python} 1018 1032 class RGB(Enum): Red = 1; Green = 2; Blue = 3 … … 1072 1086 class Week(!OrderedEnum!): 1073 1087 Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 1074 def !isWeekday(self)!: # method s1088 def !isWeekday(self)!: # method 1075 1089 return Week(self.value) !<=! Week.Fri 1076 def !isWeekend(self)!: 1090 def !isWeekend(self)!: # method 1077 1091 return Week.Sat !<=! Week(self.value) 1078 1092 \end{python} … … 1123 1137 class WeekEnd(WeekE): Sat = 6; Sun = 7 1124 1138 \end{python} 1125 Here, type @WeekE@ is an abstract type because dynamic typing never uses it.1139 Here, type @WeekE@ is an abstract type because the dynamic typing never uses it. 1126 1140 \begin{cquote} 1127 1141 \setlength{\tabcolsep}{25pt} … … 1151 1165 @Flag@ is the same as @IntFlag@ but cannot be combined with, nor compared against, any other @Flag@ enumeration, nor @int@. 1152 1166 Auto increment for @IntFlag@ and @Flag@ is by powers of 2. 1153 Enumerators that are combinations of single-bit enumerators are aliases and,hence, invisible.1167 Enumerators that are a combinations of single bit enumerators are aliases, and hence, invisible. 1154 1168 The following is an example for @Flag@. 1155 1169 \begin{python} … … 1234 1248 \end{cquote} 1235 1249 (Note, after an @adtv@'s type is know, the enumerator is inferred without qualification, \eg @I(3)@.) 1236 The type names are independent of the type valueand mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@.1250 The type names are independent from the type value, and mapped to an opaque, ascending, integral tag, starting from 0, supporting relational operators @<@, @<=@, @>@, and @>=@. 1237 1251 \begin{cquote} 1238 1252 \setlength{\tabcolsep}{10pt} … … 1274 1288 As seen, a type tag can be used in the @if@ and \lstinline[language=ocaml]{match} statements, where \lstinline[language=ocaml]{match} must be exhaustive or have a default case. 1275 1289 1276 While OCaml enumerators have an ordering following the definition order, they are not enumerable. 1277 To iterate over all enumerators, an OCaml type needs to derive from the @enumerate@ preprocessor, which appends a list of all enumerators to the program abstract syntax tree (AST). 1278 However, the list of values may not persist in the defined ordering. 1279 As a consequence, there is no meaningful enumerating mechanism. 1280 1281 Enumeration subsetting is allowed but inheritance is restricted to classes not types. 1290 Enumerating is accomplished by deriving from @enumerate@. 1291 1292 Enumeration subtyping is allowed but inheritance is restricted to classes not types. 1282 1293 \begin{ocaml} 1283 1294 type weekday = Mon | Tue | Wed | Thu | Fri … … 1507 1518 \section{Comparison} 1508 1519 1509 \VRef[Table]{t:FeatureLanguageComparison} shows a comparison of enumeration features and programming languages with the explaination of categories below. 1510 The features are high-level and may not capture nuances within a particular language. 1520 \VRef[Table]{t:FeatureLanguageComparison} shows a comparison of enumeration features and programming languages. 1521 The features are high level and may not capture nuances within a particular language 1522 The @const@ feature is simple macros substitution and not a typed enumeration. 1511 1523 1512 1524 \begin{table} … … 1517 1529 \newcommand{\CM}{\checkmark} 1518 1530 \begin{tabular}{r|c|c|c|c|c|c|c|c|c|c|c|c|c} 1519 &Pascal & Ada &\Csharp & OCaml & Java &Golang & Rust & Swift& Python& C & \CC & \CFA \\1531 &Pascal & Ada &\Csharp& OCaml & Java &Modula-3&Golang& Rust & Swift & Python& C & \CC & \CFA \\ 1520 1532 \hline 1521 enum &Dialect& \CM & \CM & ADT & \CM & @const@ &ADT/\CM &ADT/\CM & \CM &\CM &\CM &\CM\\1533 @const@ & \CM & & & & & & \CM & & & & & \CM & \\ 1522 1534 \hline 1523 1535 \hline 1524 opaque & \CM & & & \CM & \CM & & \CM & \CM& & & & \CM \\1536 opaque & & & & & & & & & & & & & \CM \\ 1525 1537 \hline 1526 typed & Int & Int & Integral & H & U & H & U/H & U/H & H & Int & Integral& U\\1538 typed & & & & & & & & & & & @int@ & integral & @T@ \\ 1527 1539 \hline 1528 safe ty & \CM & \CM & & \CM & \CM & & \CM & \CM& & & \CM & \CM \\1540 safe & & & & & & & & & & & & \CM & \CM \\ 1529 1541 \hline 1530 posn ordered & Implied & Implied & & \CM & & & & & & && \CM \\1542 ordered & & & & & & & & & & & \CM & \CM & \CM \\ 1531 1543 \hline 1532 unique values & \CM & \CM & & & & & & \CM & & & &\\1544 dup. values & & & & & & & & & & alias & \CM & \CM & \CM \\ 1533 1545 \hline 1534 auto-init & \CM & all or none & \CM & & & \CM & \CM & \CM & \CM& \CM & \CM & \CM \\1546 setable & & & & & & & & & & & \CM & \CM & \CM \\ 1535 1547 \hline 1536 (Un)Scoped & U & U & S & S & S & U & S & S & S & U & U/S & U/S\\1548 auto-init & & & & & & & & & & & \CM & \CM & \CM \\ 1537 1549 \hline 1538 overload & & \CM & & & & & & & & & & \CM\\1550 (Un)Scoped & & & & & & & & & & & U & U/S & U/S \\ 1539 1551 \hline 1540 loop & \CM & \CM & & & & & & & \CM & && \CM \\1552 overload & & \CM & & & & & & & & & & \CM & \CM \\ 1541 1553 \hline 1542 arr. dim. & \CM & \CM & & & & & & & & & & \CM\\1554 switch & & & & & & & & & & & \CM & \CM & \CM \\ 1543 1555 \hline 1544 subset & \CM & \CM & & \CM & & & && & & & \CM \\1556 loop & & & & & & & & & & & & & \CM \\ 1545 1557 \hline 1546 superset & & & & & & & & & & & & \CM \\ 1558 array/subscript & & & & & & & & & & & \CM & & \CM \\ 1559 \hline 1560 subtype & & & & & & & & & & & & & \CM \\ 1561 \hline 1562 inheritance & & & & & & & & & & & & & \CM \\ 1547 1563 \end{tabular} 1548 1564 \end{table} 1549 1550 \begin{enumerate}1551 \item opaque: an enumerator cannot be used as its underlying representation or implemented in terms of an ADT.1552 \item typed: H $\Rightarrow$ heterogeneous, \ie enumerator values may be different types. \\1553 U $\Rightarrow$ homogenous, \ie enumerator values have the same type.1554 \item safety: An enumeration variable can only hold a value from its defined enumerators.1555 \item posn ordered: enumerators have defined ordering based on enumerator declaration order.1556 Position ordered is implied if the enumerator values must be strictly increasingly.1557 \item unique value: enumerators must have a unique value.1558 \item auto-init: Values are auto-initializable by language specification, often being "+1" of the predecessor.1559 \item (Un)Scoped: U $\Rightarrow$ enumerators are projected into the containing scope.1560 S $\Rightarrow$ enumerators are contained in the enumeration scope and require qualification.1561 \item overload: An enumerator label can be used without type qualification in a context where multiple enumerations have defined the label.1562 \item loop: Enumerate without the need to convert an enumeration to another data structure.1563 \item arr. dim: An enumeration can be used directly as an array dimension, and enumerators can be mapped to an array element (not a conversion to integer type).1564 \item subset: Name a subset of enumerators as a new type.1565 \item superset: Create a new enumeration that contains all enumerators from pre-defined enumerations.1566 \end{enumerate} -
doc/theses/jiada_liang_MMath/test.adb
r6abb6dc r2ca7fc2 2 2 -- with Ada.Standard; use Ada.Standard; 3 3 procedure test is 4 type GBR is ( Green, Blue, Red );5 4 type RGB is ( Red, Green, Blue ); 6 for RGB use ( Red => 10, Green => 20, Blue => 21);5 for RGB use ( Red => 10, Green => 20, Blue => 30 ); 7 6 Colour : RGB := Red; 8 7 … … 96 95 97 96 if B then null; end if; 98 99 B := False;100 Colour := Green;101 102 Put_Line ( Boolean'Image( B ) & " " );103 Put_Line ( RGB'Image( RGB'Enum_Val( 10 ) ) & " " );104 97 end test; 105 98 -
doc/theses/jiada_liang_MMath/test.cc
r6abb6dc r2ca7fc2 61 61 eca[A] = EC::A; 62 62 63 enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat = 8, Sun }; 64 if ( Fri < Sat ) cout << "hmm" << endl; 65 else cout << "ahh" << std::endl; 63 enum Week { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; 66 64 Week day = Mon; 67 65 if ( day <= Fri ) cout << "weekday" << endl; -
doc/theses/jiada_liang_MMath/test.go
r6abb6dc r2ca7fc2 20 20 21 21 22 const ( R = 0; G = 3; B = 3; TT = 3 ) // implicit: 0 3 322 const ( R = 0; G = 3; B ) // implicit: 0 0 0 23 23 const ( Fred = "Fred"; Mary = "Mary"; Jane = "Jane" ) // Fred Mary Jane 24 24 const ( H = 0; Jack = "Jack"; J; K = 0; I ) // type change, implicit: 0 Jack Jack 25 25 const ( C = iota + G; M = iota; Y ) 26 26 const ( Mon = iota; Tue; Wed; // 0, 1, 2 27 Thu = 10; Fri = iota - Wed + Thu - 1; Sat; Sun = 0) // 10, 11, 12, 1327 Thu = 10; Fri = iota - Wed + Thu - 1; Sat; Sun = iota ) // 10, 11, 12, 13 28 28 const ( O1 = iota + 1; _; O3; _; O5 ) // 1, 3, 5 29 29 const ( V1 = iota; V2; V3 = 7; V4 = iota + 1; V5 ) … … 34 34 35 35 func main() { 36 fmt.Println( "Go:")37 36 if 3 == R {}; 38 37 fmt.Println( R, G, B ) … … 46 45 47 46 day := Mon; 48 day = Sun;49 50 47 switch day { 51 48 case Mon, Tue, Wed, Thu, Fri: 52 49 fmt.Println( "weekday" ); 53 case Sat :50 case Sat, Sun: 54 51 fmt.Println( "weekend" ); 55 52 } … … 57 54 fmt.Println( i ) 58 55 } 59 fmt.Println(B < TT); 56 57 var ar[Sun] int 58 ar[Mon] = 3 60 59 } // main 61 62 // go build test.go -
doc/theses/jiada_liang_MMath/test.pas
r6abb6dc r2ca7fc2 4 4 Weekday = Mon..Fri; 5 5 Weekend = Sat..Sun; 6 type Count = ( Zero, One, Two, Ten = 10, Eleven=10 ); 7 type RR = ( A, B, C ); 8 6 type Count = ( Zero, One, Two, Ten = 10, Eleven ); 9 7 var day : Week; 10 8 wday : Weekday; … … 12 10 lunch : array[Week] of Integer; 13 11 cnt : Count; 14 // procedure P1(v:Week);15 // begin16 // Writeln('Week');17 // end;18 procedure P1(v:Weekday);19 begin20 Writeln('Weekday');21 end;22 procedure P1(v:RR);23 begin24 Writeln('RR');25 end;26 12 begin 27 13 day := Sat; … … 54 40 Writeln(); 55 41 for day := Mon to Sat do 56 lunch[day] := ord(day) * 10;57 for day := Mon to Sun do58 42 Write( lunch[day], ' ' ); 59 43 Writeln(); … … 61 45 Write( ord( cnt ), ' ' ); 62 46 end; 63 day := Tue;64 P1( day );65 47 Writeln(); 66 67 case (day) of68 Mon: writeln('Excellent!' );69 Tue: writeln('Well done' );70 end;71 48 end. 72 49 -
doc/theses/jiada_liang_MMath/test.py
r6abb6dc r2ca7fc2 25 25 # Mon = 1; Tue = 2; Wed = 3; Thu = 10; Fri = 10; Sat = 16; Sun = 17 26 26 class Week(OrderedEnum): 27 Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 027 Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; Sat = 6; Sun = 7 28 28 def isWeekday(self): 29 29 return Week(self.value) <= Week.Fri … … 34 34 return cls(date.isoweekday()) 35 35 36 day : Week = Week.Tue 36 day : Week = Week.Tue; 37 37 print( "weekday:", day.isWeekday() ) 38 38 print( "weekend:", day.isWeekend() ) 39 39 print( "today:", Week.today(date.today())) 40 40 41 print( Week.Thu.value == 4 ) 42 print( Week.Thu.name == "Thu" ) 43 print( Week( 4 ) == Week.Thu ) 44 print( Week["Thu"].value == 4 ) 41 print( Week.Thu.value == 4 ); 42 print( Week.Thu.name == "Thu" ); 43 print( Week( 4 ) == Week.Thu ); 44 print( Week["Thu"].value == 4 ); 45 45 46 46 if day <= Week.Fri : 47 print( "weekday" ) 47 print( "weekday" ); 48 48 match day: 49 49 case Week.Mon | Week.Tue | Week.Wed | Week.Thu | Week.Fri: 50 print( "weekday" ) 50 print( "weekday" ); 51 51 case Week.Sat | Week.Sun: 52 print( "weekend" ) 52 print( "weekend" ); 53 53 54 54 for day in Week: … … 80 80 print( isinstance(Week.Fri, Week) ) 81 81 82 class WeekE(OrderedEnum): pass 82 class WeekE(OrderedEnum): pass; 83 83 class WeekDay(WeekE): Mon = 1; Tue = 2; Wed = 3; Thu = 4; Fri = 5; 84 84 class WeekEnd(WeekE): Sat = 6; Sun = 7 … … 121 121 Weekend = Sat | Sun 122 122 print( f"0x{repr(WeekF.Weekday.value)} 0x{repr(WeekF.Weekend.value)}" ) 123 day : WeekF = WeekF.Mon | WeekF.Tue 123 day : WeekF = WeekF.Mon | WeekF.Tue; 124 124 print( type(day) ) 125 125 for day in WeekF: … … 164 164 match diffval: 165 165 case Diff.Int: 166 print( "diffval", diffval.value ) 166 print( "diffval", diffval.value ); 167 167 case Diff.Float: 168 print( "diffval", diffval.value ) 168 print( "diffval", diffval.value ); 169 169 case Diff.Str: 170 print( "diffval", diffval.value ) 170 print( "diffval", diffval.value ); 171 171 for i in Diff: 172 172 print( f"Diff type {type(i)}, {i}, {i.name}, {i.value} : " ) … … 197 197 return G * self.mass / (self.radius * self.radius) 198 198 def surfaceWeight(self, otherMass): 199 return otherMass * self.surfaceGravity() 200 201 class Cats(Enum): 202 pass 203 199 return otherMass * self.surfaceGravity(); 204 200 205 201 earthWeight : float = 100 206 earthMass : float = earthWeight / ( Planet.EARTH.surfaceGravity() ) 202 earthMass : float = earthWeight / ( Planet.EARTH.surfaceGravity() ); 207 203 208 204 p = by_position( Planet, random.randrange(8) ) # select a random orbiting body -
doc/theses/jiada_liang_MMath/test.swift
r6abb6dc r2ca7fc2 59 59 60 60 enum WeekInt: Int, CaseIterable { 61 case Mon, Tue, Wed, Thu = 10, Fri = 14,61 case Mon, Tue, Wed, Thu = 10, Fri, 62 62 Sat = 4, Sun // auto-incrementing 63 63 }; -
doc/theses/jiada_liang_MMath/test1.cfa
r6abb6dc r2ca7fc2 1 1 #include <fstream.hfa> // sout 2 2 #include <stdlib.hfa> // ato 3 #include <enum.hfa>4 3 5 4 // integral … … 10 9 enum( Letter ) Greek { Alph = A, Beta = B, Gamma = G, /* more enums */ Zeta = Z }; // alphabet intersection 11 10 12 // integral13 11 enum( char ) Currency { Dollar = '$', Cent = '¢', Yen = '¥', Pound = '£', Euro = 'E' }; // iso-latin-1 14 12 enum( Currency ) Europe { Euro = Currency.Euro, Pound = Currency.Pound }; … … 35 33 36 34 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 37 Mode mode = O_RDONLY; 38 void opaque() { 39 bool b = mode == O_RDONLY || mode < O_APPEND; // disallowed 40 //int www = mode; // disallowed 41 } 35 Mode iomode = O_RDONLY; 36 //bool b = iomode == O_RDONLY || iomode < O_APPEND; // disallowed 37 //int www = iomode; // disallowed 42 38 43 39 enum( char * ) Colour { Red = "red", Green = "green", Blue = "blue" }; 44 45 enum E1 { A1, B1, C1 = A1, D1 = B1 };46 enum(float) E2 { A2 = 3.5, B2 = 4.5, C2 = A, D2 = B };47 40 48 41 void fred() { … … 52 45 //greek = A; // disallowed 53 46 54 for ( Greek l = Alph; posn(l) < posn(Gamma); l = succ( l ) ) {47 for ( Greek l = Alph; posn(l) <= posn(Gamma); l = succ( l ) ) { 55 48 printf( "%s %c %d\n", label( l ), value( l ), posn( l ) ); 56 49 } 57 for ( Currency c = Dollar; posn(c) < posn(Currency.Euro); c = succ( c ) ) {50 for ( Currency c = Dollar; posn(c) <= posn(Currency.Euro); c = succ( c ) ) { 58 51 printf( "%s %c %d\n", label( c ), value( c ), posn( c ) ); 59 52 } 60 53 } 61 54 62 enum( const char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" }; 63 enum( const char * ) Names2 { inline Names, Jack = "JACK", Jill = "JILL" }; 64 enum( const char * ) Names3 { inline Names2, Sue = "SUE", Tom = "TOM" }; 65 void bar() { 66 Names fred = Names.Fred; 67 (Names2)fred; (Names3)fred; (Names3)Names2.Jack; // cast to super type 68 Names2 fred2 = fred; Names3 fred3 = fred2; // assign to super type 69 const char * name = fred; 70 Names name = Fred; 71 sout | name | label( name ) | posn( name ) | value( name ); 72 } 55 56 enum( char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" }; 57 enum( char * ) Names2 { inline Names, Jack = "JACK", Jill = "JILL" }; 58 enum( char * ) Names3 { inline Names2, Sue = "SUE", Tom = "TOM" }; 59 73 60 void f( Names n ) { sout | "Name" | posn( n ); } 74 61 void g( Names2 ); … … 76 63 void j( char * ); 77 64 78 enum CColour { Red, Blue, Green }; 79 CColour c0 = 0; 80 CColour c1 = 1; 81 CColour c = 2; 82 int w = Red; 83 84 void coo() { 85 enum(int) Color { Red, Blue, Green }; 86 Colour c = Red; 87 sout | countof( Colour ) | Countof( c ); 88 // sout | Countof( Colour ); 89 sout | countof( c ); 90 } 65 enum color { red, blue, green }; 66 //color c = 0; 67 //color c = 1; 68 color c = 2; 69 int w = red; 91 70 92 71 // enum(int) Week ! { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; … … 100 79 // } 101 80 102 void baz() {103 enum(int) Count { First, Second, Third/* = First*/, Fourth/* = Second*/ };104 enum CCount { First, Second, Third/* = First*/, Fourth/* = Second*/ };105 Count cnt = Second;106 CCount ccnt = Second;107 if ( cnt < Third ) sout | "less than Third";108 if ( cnt ) sout | "XXX";109 if ( ccnt ) sout | "YYY";110 enum(float) F {WWW = 0.0};111 F f;112 if ( f ) sout | "FFF";113 bool ?!=?( Name n, zero_t ) { sout | "DDD"; return n != Fred; }114 Name n = Mary;115 if ( n ) sout | "NAME";116 choose( cnt ) {117 case First: sout | "First";118 case Second: sout | "Second";119 case Third: sout | "Third";120 case Fourth: sout | "Fourth";121 }122 // for (d; Week) { sout | d; }123 // for (p; +~=Planet) { sout | p; }124 for ( cx; Count ) { sout | cx | nonl; } sout | nl;125 for ( cx; +~= Count ) { sout | cx | nonl; } sout | nl;126 for ( cx; -~= Count ) { sout | cx | nonl; } sout | nl;127 for ( Count cx = lowerBound();; ) {128 sout | cx | nonl;129 if ( cx == upperBound() ) break;130 cx = succ( cx );131 }132 sout | nl;133 }134 135 81 int main() { 136 82 fred(); 137 Names name = Names.Fred;83 Names name = Fred; 138 84 // f( name ); 139 85 140 86 int jane_pos = posn( Names.Jane ); 141 c onst char * jane_value = value( Names.Jane );142 c onst char * jane_label = label( Names.Jane );87 char * jane_value = value( Names.Jane ); 88 char * jane_label = label( Names.Jane ); 143 89 sout | Names.Jane | posn( Names.Jane) | label( Names.Jane ) | value( Names.Jane ); 144 145 bar();146 baz();147 coo();148 149 enum Ex { Ax, Bx, Cx, Nx };150 float H1[Nx] = { [Ax] : 3.4, [Bx] : 7.1, [Cx] : 0.01 }; // C151 // float H2[Ex] = { [Ax] : 3.4, [Bx] : 7.1, [Cx] : 0.01 }; // CFA152 153 enum(int) E { A = 3 } e = A;154 sout | A | label( A ) | posn( A ) | value( A );155 sout | e | label( e ) | posn( e ) | value( e );156 90 } -
doc/theses/jiada_liang_MMath/test1.java
r6abb6dc r2ca7fc2 3 3 public class test1 { 4 4 enum Weekday { 5 Mon(7), Tue(6), Wed(5), Thu(3), Fri( 4), Sat(3), Sun(7); // must appear first5 Mon(7), Tue(6), Wed(5), Thu(3), Fri(3), Sat(3), Sun(1); // must appear first 6 6 private long day; 7 7 private Weekday( long d ) { day = d; } … … 27 27 } 28 28 for ( Weekday icday : Weekday.values() ) { // position 29 System.out.print ln( icday + " " + icday.ordinal() + " " + icday.day + " " + icday.name() + ", " ); // label29 System.out.print( icday + " " + icday.ordinal() + " " + icday.day + " " + icday.name() + ", " ); // label 30 30 } 31 31 System.out.println(); 32 33 if (Weekday.Fri == Weekday.Sat) {34 System.out.println( "Alias ");35 }36 32 } 37 33 } -
doc/theses/jiada_liang_MMath/trait.tex
r6abb6dc r2ca7fc2 2 2 \label{c:trait} 3 3 4 \CC introduced the @std::is_enum@ trait in \CC{11} and concept feature in \CC{20}. 5 With this combination, it is possible to write a polymorphic function over an enumerated type. 6 \begin{c++} 4 % Despite parametric polymorphism being a pivotal feature of \CFA, for a long time, there was not 5 % a technique to write functions being polymorphic over enumerated types. 6 \CC introduced @std::is_enum@ trait on \CC{11} and @concepts@ on \CC{20}; with the combination, users can 7 write function polymorphic over enumerated type in \CC: 8 \begin{cfa} 7 9 #include <type_traits> 8 template<typename T> @concept Enumerable@ = std::is_enum<T>::value; 9 template<@Enumerable@ E> E f( E e ) { $\C{// constrainted type}$ 10 E w = e; $\C{// alloction and copy}$ 11 cout << e << ' ' << w << endl; $\C{// value}$ 12 return w; $\C{// copy}$ 13 } 14 int main() { 15 enum E { A = 42, B, C } e = C; 16 e = f( e ); 17 } 18 44 44 19 \end{c++} 20 The @std::is_enum@ and other \CC @traits@ are a compile-time interfaces to query type information. 21 While named the same as @trait@ in other programming languages, it is orthogonal to the \CFA trait, with the latter being defined as a collection of assertion to be satisfied by a polymorphic type. 22 23 The following sections cover the underlying implementation features I created to generalize and restrict enumerations in the \CFA type-system using the @trait@ mechanism. 24 25 26 \section{Traits \texorpdfstring{\lstinline{CfaEnum}{CfaEnum}} and \texorpdfstring{\lstinline{TypedEnum}}{TypedEnum}} 27 28 Traits @CfaEnum@ and @TypedEnum@ define the enumeration attributes: @label@, @posn@, @value@, and @Countof@. 29 These traits support polymorphic functions for \CFA enumeration, \eg: 30 \begin{cfa} 31 forall( E ) | @CfaEnum( E )@ ) 32 void f( E e ) { 33 // access enumeration properties for e 34 } 35 \end{cfa} 36 37 Trait @CfaEnum@ defines attribute functions @label@ and @posn@ for all \CFA enumerations, and internally \CFA enumerations fulfills this assertion. 10 11 template<typename T> 12 @concept Enumerable = std::is_enum<T>::value;@ 13 14 template<@Enumerable@ T> 15 void f(T) {} 16 \end{cfa} 17 The @std::is_enum@ and other \CC @traits@ are a compile-time interfaces to query type information. 18 While named the same as @trait@, it is orthogonal to \CFA trait, as the latter being defined as 19 a collection of assertion to be satisfied by a polymorphic type. 20 21 \CFA provides @CfaEnum@ and @TypedEnum@ traits to supports polymorphic functions for \CFA enumeration: 22 \begin{cfa} 23 forall(T | @CfaEnum(T)@) 24 void f(T) {} 25 \end{cfa} 26 27 \section{CfaEnum and TypedEnum} 28 \CFA defines attribute functions @label()@ and @posn()@ for all \CFA enumerations, 29 and therefore \CFA enumerations fulfills the type assertions with the combination. 30 With the observation, we define trait @CfaEnum@: 38 31 \begin{cfa} 39 32 forall( E ) trait CfaEnum { … … 42 35 }; 43 36 \end{cfa} 44 This trait covers opaque enumerations that do not have an explicit @value@. 45 46 The trait @TypedEnum@ extends @CfaEnum@ with the @value@ assertion for typed enumerations. 37 38 % The trait @TypedEnum@ extends @CfaEnum@ with an additional value() assertion: 39 Typed enumerations are \CFA enumeration with an additional @value@ attribute. Extending 40 CfaEnum traits, TypedEnum is a subset of CFAEnum that implements attribute function @value()@, 41 which includes all typed enumerations. 47 42 \begin{cfa} 48 43 forall( E, V | CfaEnum( E ) ) trait TypedEnum { … … 50 45 }; 51 46 \end{cfa} 52 Here, the associate type-parameter @V@ is the base type of the typed enumeration, and hence, the return type of @value@. 53 These two traits provide a way to define functions over all \CFA enumerations. 54 55 For example, \VRef[Figure]{f:GeneralizedEnumerationFormatter} shows a generalized enumeration formatter for any enumeration type. 56 The formatter prints an enumerator name and its value in the form @"label( value )"@. 57 The trait for @format_enum@ requires a function named @str@ for printing the value (payload) of the enumerator. 58 Hence, enumeration defines how its value appear and @format_enum@ displays this value within the label name. 59 60 \begin{figure} 61 \begin{cfa} 62 forall( @E, V | TypedEnum( E, V )@ | { string str( V ); } ) $\C{// format any enumeration}$ 63 string format_enum( E e ) { 64 return label( e ) + '(' + str( value( e ) ) + ')'; $\C{// "label( value )"}$ 65 } 66 enum(size_t) RGB { Red = 0xFF0000, Green = 0x00FF00, Blue = 0x0000FF }; 67 // string library has conversion function str from size_t to string 68 69 struct color_code { int R, G, B; }; 47 Type parameter V of TypedEnum trait binds to return type of @value()@, which is also the base 48 type for typed enumerations. CfaEnum and TypedEnum triats constitues a CfaEnum function interfaces, as well a way to define functions 49 over all CfaEnum enumerations. 50 \begin{cfa} 51 // for all type E that implements value() to return type T, where T is a type that convertible to string 52 forall( E, T | TypedEnum( E, T ) | { ?{}(string &, T ); } ) 53 string format_enum( E e ) { return label(E) + "(" + string(value(e)) + ")"; } 54 55 // int is convertible to string; implemented in the standard library 56 enum(int) RGB { Red = 0xFF0000, Green = 0x00FF00, Blue = 0x0000FF }; 57 58 struct color_code { int R; int G; int B }; 59 // Implement color_code to string conversion 60 ?{}(string & this, struct color_code p ) { 61 this = string(p.R) + ',' + string(p.G) + ',' + string(p.B); 62 } 70 63 enum(color_code) Rainbow { 71 Red = {255, 0, 0}, Orange = {255, 127, 0}, Yellow = {255, 255, 0}, Green = {0, 255, 0}, // ... 64 Red = {255, 0, 0}, Orange = {255, 127, 0}, Yellow = {255, 255, 0}, Green = {0, 255, 0}, 65 Blue = {0, 0, 255}, Indigo = {75, 0, 130}, Purple = {148, 0, 211} 72 66 }; 73 string str( color_code cc ) with( cc ) { $\C{// format payload, "ddd,ddd,ddd"}$ 74 return str( R ) + ',' + str( G ) + ',' + str( B ); $\C{// "R,G,B"}$ 75 } 76 int main() { 77 sout | format_enum( RGB.Green ); $\C{// "Green(65280)"}$ 78 sout | format_enum( Rainbow.Green ); $\C{// "Green(0,255,0)"}$ 79 } 80 \end{cfa} 81 \caption{Generalized Enumeration Formatter} 82 \label{f:GeneralizedEnumerationFormatter} 83 \end{figure} 84 85 Other types may work with traits @CfaEnum@ and @TypedEnum@, by supplying appropriate @label@, @posn@, and @value@ functions. 86 For example, \VRef[Figure]{f:ExtendCEnumeration} extends a (possibly predefined) C enumeration to work with all the \CFA extensions. 87 88 \begin{figure} 89 \begin{cfa} 90 enum Fruit { Apple, Banana, Cherry }; $\C{// C enum}$ 91 const char * @label@( Fruit f ) { 92 static const char * labels[] = { "Apple", "Banana", "Cherry" }; 93 return labels[f]; 94 } 95 int @posn@( Fruit f ) { return f; } 96 int @value@( Fruit f ) { 97 static const char values[] = { 'a', 'b', 'c' }; 98 return values[f]; 99 } 100 sout | format_enum( Cherry ); $\C{// "Cherry(c)"}$ 101 \end{cfa} 102 \caption{Extend C Enumeration to \CFA Enumeration} 103 \label{f:ExtendCEnumeration} 104 \end{figure} 105 106 107 \section{Discussion: Genericity} 108 109 At the start of this chapter, the \CC concept is introduced to constraint template types, \eg: 110 \begin{c++} 111 concept Enumerable = std::is_enum<T>::value; 112 \end{c++} 113 Here, @concept@ is referring directly to types with kind @enum@; 114 other @concept@s can refer to all types with kind @int@ with @long@ or @long long@ qualifiers, \etc. 115 Hence, the @concept@ is a first level of restriction allowing only the specified kinds of types and rejecting others. 116 The template expansion is the second level of restriction verifying if the type passing the @concept@ test provides the necessary functionality. 117 Hence, a @concept@ is querying precise aspects of the programming language set of types. 118 119 Alternatively, languages using traits, like \CFA, Scala, Go, and Rust, are defining a restriction based on a set of operations, variables, or structure fields that must exist to match with usages in a function or aggregate type. 120 Hence, the \CFA enumeration traits never connected with the specific @enum@ kind. 121 Instead, anything that can look like the @enum@ kind is considered an enumeration (duck typing). 122 However, Scala, Go, and Rust traits are nominative: a type explicitly declares a named traits to be of its type, while in \CFA, any type implementing all requirements declared in a trait implicitly satisfy its restrictions. 123 124 One of the key differences between concepts and traits, which is leveraged heavily by \CFA, is the ability to apply new \CFA features to C legacy code. 125 For example, \VRef[Figure]{f:GeneralizedEnumerationFormatter} shows that pre-existing C enumerations can be upgraded to work and play with new \CFA enumeration facilities. 126 Another example is adding constructors and destructors to pre-existing C types by simply declaring them for the old C type. 127 \CC fails at certain levels of legacy extension because many of the new \CC features must appear \emph{within} an aggregate definition due to the object-oriented nature of he type system, where it is impossible to change legacy library types. 67 68 format_enum(RGB.Green); // "Green(65280)" 69 format_enum(Rainbow.Green); // "Green(0,255,0)" 70 \end{cfa} 71 72 73 % Not only CFA enumerations can be used with CfaEnum trait, other types that satisfy 74 % CfaEnum assertions are all valid. 75 Types does not need be defined as \CFA enumerations to work with CfaEnum traits. CfaEnum applies to any type 76 with @label()@ and @value()@ being properly defined. 77 Here is an example on how to extend a C enumeration to comply CfaEnum traits: 78 \begin{cfa} 79 enum Fruit { Apple, Banana, Cherry }; $\C{// C enum}$ 80 const char * label( Fruit f ) { 81 choose( f ) { 82 case Apple: return "Apple"; 83 case Banana: return "Banana"; 84 case Cherry: return "Cherry"; 85 } 86 } 87 unsigned posn( Fruit f ) { return f; } 88 char value( Fruit f ) { 89 choose(f) { 90 case Apple: return 'a'; 91 case Banana: return 'b'; 92 case Cherry: return 'c'; 93 } 94 } 95 96 format_enum(Cherry); // "Cherry(c)" 97 \end{cfa} 98 99 \section{Discussion: Static Type Information} 100 @CfaEnum@ and @TypedEnum@ are approximations to \CFA Enumerations and Typed Enumerations: they are not 101 assertions on a type being an enumerated type, 102 but rather types being shared an interfaces with \CFA enumerations. 103 \CC's @type_traits@ is fundamentally different than \CFA's traits: \CC's @type_traits@ are descriptions 104 of compile time type information 105 \footnote{Concepts can check if a \CC class implement a certain method, 106 but it is to probe a static type information of a class having a such member.} 107 , while \CFA's trait describe how a type can be used, 108 which is a closer paradigm to a trait system in languages such as Scala and Rust. 109 However, Scala and Rust's traits are nominative: 110 a type explicitly declare a named traits to be of its type; while in \CFA, 111 type implements all functions declares in a trait to implicitly be of the trait type. 112 113 If to support static type information, \CFA needs new piece of syntax to distinguish static type 114 query from function calls, for example: 115 \begin{cfa} 116 forall(T | { T::is_enum; }); 117 \end{cfa} 118 When to call a polymorphic function @foo(T)@ with assertions set @S@ and function call argument @a@, \CFA 119 determines if there is an overloaded name @a@ that has non-zero conversion cost to all assertions in @S@. 120 As a consequence, @is_enum@ can be a \CFA directive that immediately trim down the search space of @a@ to 121 be some enumerated types. In fact, because \CFA stores symbols maps to enumeration in a standalone data structure. 122 Limiting search space to enumeration improve on \CFA resolution speed. 123 124 While assertion on static type information seems improvement on expressivity, it is a challenge to 125 extend its capability without a fully functional pre-processsor that evaluate constant expression as \CC 126 compilers does. The described @is_enum@ manipulate compiler behaviour, which cannot be easily extended to 127 other usage cases. Therefore, \CFA currently does not support @is_enum@ and utalizes traits as a workaround. 128 128 129 129 130 130 \section{Bounded and Serial} 131 132 A bounded trait defines a lower and upper bound for a type. 131 A bounded type defines a lower bound and a upper bound. 133 132 \begin{cfa} 134 133 forall( E ) trait Bounded { … … 136 135 E lowerBound(); 137 136 }; 138 \end{cfa} 139 Both functions are necessary for the implementation of \CFA enumeration, with @lowerBound@ returning the first enumerator and @upperBound@ returning the last enumerator. 140 \begin{cfa} 141 enum(int) Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 142 enum(int) Fruit { Apple, Banana, Cherry }; 143 Week first_day = lowerBound(); $\C{// Mon}$ 144 Fruit last_fruit = upperBound(); $\C{// Cherry}$ 145 \end{cfa} 146 The @lowerBound@ and @upperBound@ are functions overloaded on return type only, meaning their type resolution depends solely on the call-site context, such as the parameter type for a function argument or the left hand size of an assignment expression. 147 Calling either function without a context results in a type ambiguity, unless the type environment has only one type overloading the functions. 148 \begin{cfa} 149 sout | @lowerBound()@; $\C[2.5in]{// ambiguous as Week and Fruit implement Bounded}$ 150 void foo( Fruit ); 151 foo( lowerBound() ); $\C{// parameter provides type Fruit}$ 152 Week day = upperBound(); $\C{// day provides type Week}\CRT$ 153 \end{cfa} 154 155 Trait @Serial@ is a subset of @Bounded@, with functions mapping enumerators to integers, and implementing a sequential order between enumerators. 137 138 \end{cfa} 139 Both Bounded functions are implement for \CFA enumerations, with @lowerBound()@ returning the first enumerator and @upperBound()@ returning 140 the last enumerator. 141 \begin{cfa} 142 Workday day = lowerBound(); $\C{// Mon}$ 143 Planet outermost = upperBound(); $\C{// NEPTUNE}$ 144 \end{cfa} 145 146 The lowerBound() and upperBound() are functions overloaded on return type only, means their type resolution solely depend on the outer context, 147 including expected type as a function argument, or the left hand size of an assignment expression. 148 Calling either function without a context results in a type ambiguity, except in the rare case where the type environment has only one 149 type overloads the functions, including \CFA enumerations, which has Bounded functions automatic defined. 150 \begin{cfa} 151 @lowerBound();@ $\C{// ambiguous as both Workday and Planet implement Bounded}$ 152 sout | @lowerBound()@; 153 Workday day = first(); $\C{// day provides type Workday}$ 154 void foo( Planet p ); 155 foo( last() ); $\C{// argument provides type Planet}$ 156 \end{cfa} 157 158 @Serial@ is a subset of @Bounded@, with functions maps elements against integers, as well implements a sequential order between members. 156 159 \begin{cfa} 157 160 forall( E | Bounded( E ) ) trait Serial { 158 intfromInstance( E e );161 unsigned fromInstance( E e ); 159 162 E fromInt( unsigned int i ); 163 E succ( E e ); 160 164 E pred( E e ); 161 E succ( E e ); 162 unsigned Countof( E ); 165 unsigned Countof( E e ); 163 166 }; 164 167 \end{cfa} 165 Function @fromInstance@ projects a @Bounded@ member to a number and @fromInt@ is the inverse. 166 Function @pred@ and @succ@ are advancement functions: 167 @pred@ takes an enumerator and returns the previous enumerator, if there is one, in sequential order, and @succ@ returns the next enumerator. 168 \begin{cfa} 169 sout | fromInstance( Wed ) | fromInt( 2 ) | succ( Wed ) | pred( Wed ); 170 2 Wed Thu Tue 171 \end{cfa} 172 Bound checking is provided for @fromInt@, @pred@, and @succ@, and the program is terminated if the lower or upper bound is exceeded, \eg: 173 \begin{cfa} 174 fromInt( 100 ); 175 Cforall Runtime error: call to fromInt has index 100 outside of enumeration range 0-6. 176 \end{cfa} 177 Function @fromInstance@ or a position cast using @(int)@ is always safe, \ie within the enumeration range. 178 179 Function @Countof@ is the generic counterpart to the builtin pseudo-function @countof@. 180 @countof@ only works on enumeration types and instances, so it is locked into the language type system; 181 as such, @countof( enum-type)@ becomes a compile-time constant. 182 @Countof@ works on an any type that matches the @Serial@ trait. 183 Hence, @Countof@ does not use its argument; 184 only the parameter type is needed to compute the range size. 185 \begin{cfa} 186 int Countof( E ) { 187 E upper = upperBound(); 188 E lower = lowerBound(); 189 return fromInstance( upper ) + fromInstance( lower ) + 1; 190 } 191 \end{cfa} 192 193 @countof@ also works for any type @E@ that defines @Countof@ and @lowerBound@, becoming a call to @Countof( E )@. 194 The resolution step on expression @countof( E )@ are: 168 169 % A Serail type can project to an unsigned @int@ type, \ie an instance of type T has a corresponding integer value. 170 Function @fromInstance()@ projects a @Bounded@ member to a number and @fromInt@ is the inverser. Function @succ()@ take an element, returns the "next" 171 member in sequential order and @pred()@ returns the "last" member. 172 173 A Serial type E may not be having a one-to-one mapping to integer because of bound. An integer that cannot be mapping to a member of E is called the member \newterm{out of bound}. 174 Calling @succ()@ on @upperBound@ or @pred()@ on @lowerBound()@ results in out of bound. 175 176 \CFA implements Serial interface for CFA enumerations with \newterm{bound check} on @fromInt()@, @succ()@ and @pred()@, and abort the program if the function call results in out of bound. 177 Unlike a cast, conversion between \CFA enumeration and integer with @Serial@ interface is type safe. 178 Specifically for @fromInt@, \CFA abort if input i smaller than @fromInstance(lowerBound())@ or greater than @fromInstance(upperBound())@ 179 180 Function @Countof@ takes an object as a parameter and returns the number of elements in the Serial type, which is @fromInstance( upper ) - fromInstance( lower ) + 1@. 181 @Countof@ does not use its arugment as procedural input; it needs 182 an argument to anchor its polymorphic type T. 183 184 \CFA has an expression @countof@ (lower case) that returns the number of enumerators defined for enumerations. 185 \begin{cfa} 186 enum RGB {Red, Green, Blue}; 187 countof( RGB ); 188 countof( Red ); 189 \end{cfa} 190 Both expressions from the previous example are converted to constant expression @3@ with no function call at runtime. 191 @countof@ also works for any type T that defines @Countof@ and @lowerBound@, for which it turns into 192 a function call @Countof( T )@. The resolution step on expression @countof(e)@ works as the following with priority ordered: 195 193 \begin{enumerate} 196 \item Look for an enumeration named @E@, such as @enum E {... }@. 197 If such an enumeration @E@ exists, replace @countof( E )@ with the number of enumerators. 198 \item Look for a non-enumeration type named @E@ that defines @Countof@ and @lowerBound@, including @E@ being a polymorphic type, such as @forall( E )@. 199 If type @E@ exists, replaces it with @Countof(lowerBound())@, where @lowerBound@ is defined for type @E@. 200 \item Look for an enumerator @A@ defined in enumeration @E@. 201 If such an enumerator @A@ exists, replace @countof( A )@ with the number of enumerators in @E@. 202 \item Look for a name @A@ in the lexical context with type @E@. 203 If such name @A@ exists, replace @countof( A )@ with function call @Countof( E )@. 204 \item If 1-4 fail, report a type error on expression @countof( E )@. 194 \item Looks for an enumeration named e, such as @enum e {... }@. 195 If such an enumeration e exists, \CFA replace @countof(e)@ with constant expression with number of enumerator of e. 196 \item Looks for a non-enumeration type named e that defines @Countof@ and @lowerBound@, including e being a polymorphic type, such as @forall(e)@. 197 If type e exists, \CFA replaces it with @Countof(lowerBound())@, where lowerBound() is bounded to type e. 198 \item Looks for an enumerator e that defined in enumeration E. If such an enumeration e exists, \CFA replace @countof(e)@ with constant expression with number of enumerator of E. 199 \item Looks for a name e in the context with expression type E. If such name e exists, \CFA replace @countof(e)@ with function call @Countof(e)@. 200 \item If 1-4 fail, \CFA reports a type error on expression @countof(e)@. 205 201 \end{enumerate} 206 202 207 208 \section{Enumerating} 209 210 The fundamental aspect of an enumeration type is the ability to enumerate over its enumerators. 211 \CFA supports \newterm{for} loops, \newterm{while} loop, and \newterm{range} loop. This section covers @for@ loops and @range@ loops for enumeration, but the concept transition to @while@ loop. 212 203 \section{Iterating Over An Enumeration} 204 An fundamental aspect of an enumerated type is to be able to enumerate over its enumerators. \CFA supports \newterm{for} loops, 205 \newterm{while} loop, and \newterm{range} loop. This section covers @for@ loops and @range@ loops for 206 enumeration, but the concept transition to @while@ loop. 213 207 214 208 \subsection{For Loop} 215 216 A for-loop consists of loop control and body. 217 The loop control is often a 3-tuple: initializers, stopping condition, and advancement. 218 It is a common practice to declare one or more loop-index variables in initializers, checked these variables for stopping iteration, and updated the variables in advancement. 219 Such a variable is called an \newterm{index} and is available for reading and writing within the loop body. 220 (Some languages make the index read-only in the loop body.) 221 This style of iteration can be written for an enumeration using functions from the @Bounded@ and @Serial@ traits: 222 \begin{cfa} 223 enum() E { A, B, C, D }; 224 for ( unsigned int i = 0; i < countof(E); i += 1 ) $\C{// (1)}$ 225 sout | label( fromInt( i ) ) | nonl; 226 sout | nl; 227 for ( E e = lowerBound(); ; e = succ(e) ) { $\C{// (2)}$ 228 sout | label(e) | nonl; 229 if (e == upperBound()) break; 230 } 231 sout | nl; 232 A B C D 233 A B C D 234 \end{cfa} 235 236 A caveat in writing loop control using @pred@ and @succ@ is unintentionally exceeding the range. 237 \begin{cfa} 238 for ( E e = upperBound(); e >= lowerBound(); e = pred( e ) ) {} 239 for ( E e = lowerBound(); e <= upperBound(); e = succ( e ) ) {} 240 \end{cfa} 241 Both of these loops look correct but fail because these is an additional bound check within the advancement \emph{before} the conditional test to stop the loop, resulting in a failure at the endpoints of the iteration. 242 These loops must be restructured by moving the loop test to the end of the loop (@do-while@), as in loop (2) above, which is safe because an enumeration always at least one enumerator. 209 A for loop is constitued by a loop control and a loop body. 210 A loop control is often a 3-tuple, separated by semicolons: initializers, condition, and an expression. It is a common practice to declare 211 a variable, often in initializers, that be used in the condition and updated in the expression or loop body. Such variable is called \newterm{index}. 212 213 % With implemented @Bounded@ and @Serial@ interface for \CFA enumeration, a @for@ loop that iterates over \CFA enumeration can be implemented as the following: 214 A @for@ loop iterates an enumeration can be written with functions from @Bounded@ and @Serial@ interfaces: 215 \begin{cfa} 216 enum() Chars { A, B, C, D }; 217 for( unsigned i = 0; i < countof(E); i++ ) { sout | label(e); } $\C{// (1) A B C D}$ 218 for( Chars e = lowerBound(); ; e = succ(e) ) { $\C{// (2)}$ 219 sout |label((Chars)fromInt(i)) |' '; 220 if (e == upperBound()) break; 221 } 222 \end{cfa} 223 224 A caveat in writing loop using finite number as index is that the number can unintentionally be out the range: 225 \begin{cfa} 226 for( unsigned i = countof(Chars) - 1; i >= 0; i-- ) {} $\C{// 3}$ 227 for( Chars e = lowerBound(); e <= upperBound(); e = succ(e) ) {} $\C{// 4}$ 228 for( Chars e = upperBound(); e >= lowerBound(); e = pred(e) ) {} $\C{// 5}$ 229 \end{cfa} 230 Loop (3) is a value underflow: when @i@ reaches to @0@, decrement statement will still execute and cause 231 the @unsigned int@ value @i@ wraps to @UINT_MAX@, which fails to loop test and the loop cannot terminate. 232 233 In loop (4) and (5), when @e@ is at the @Bound@ (@upperBound@/@lowerBound@) and @succ@/@pred@ will result in @out of bounded@, \CFA 234 aborts its execution. Therefore, it is necessary to implement the condtional break within the loop body. 243 235 244 236 245 237 \subsection{Range Loop} 246 247 Instead of writing the traditional 3-tuple loop control, \CFA supports a \newterm{range loop}. 248 \begin{cfa} 249 for ( @E e; A ~= D@ ) { sout | label( e ) | nonl; } sout | nl; 250 for ( @e; A ~= D@ ) { sout | label( e ) | nonl; } sout | nl; 251 for ( @E e; A -~= D@ ) { sout | label( e ) | nonl; } sout | nl; 252 for ( @e; A -~= D ~ 2@ ) { sout | label( e ) | nonl; } sout | nl; 253 \end{cfa} 254 Every range loop above has an index declaration and a @range@ bounded by \newterm{left bound} @A@ and \newterm{right bound} @D@. 255 If the index declaration-type is omitted, the index type is the type of the lower bound (@typeof( A )@). 256 If a range is joined by @~=@ (range up equal) operator, the index variable is initialized by the left bound and advanced by 1 until it is greater than the right bound. 257 If a range is joined by @-~=@ (range down equal) operator, the index variable is initialized by the right bound and advanced by -1 until it is less than the left bound. 258 (Note, functions @pred@ and @succ@ are not used for advancement, so the advancement problem does not occur.) 259 A range can be suffixed by a positive \newterm{step}, \eg @~ 2@, so advancement is incremented/decremented by step. 260 261 Finally, a shorthand for enumerating over the entire set of enumerators (the most common case) is using the enumeration type for the range. 262 \begin{cfa} 263 for ( e; @E@ ) sout | label( e ) | nonl; sout | nl; $\C{// A B C D}$ 264 for ( e; @-~= E@ ) sout | label( e ) | nonl; sout | nl; $\C{// D C B A}$ 265 \end{cfa} 266 For a \CFA enumeration, the loop enumerates over all enumerators of the enumeration. 267 For a type matching the @Serial@ trait: the index variable is initialized to @lowerBound@ and loop control checks the index's value for greater than the @upperBound@. 268 If the range type is not a \CFA enumeration or does not match trait @Serial@, it is compile-time error. 269 238 Instead of specifying condition, \CFA supports @range loops@, for which a user specifies a range of values. 239 \begin{cfa}[label=lst:range_functions_2] 240 for ( Chars e; A ~= D ) { sout | label(e); } $\C{// (6)}$ 241 for ( e; A ~= D ) { sout | label(e); } $\C{// (7)}$ 242 for ( Chars e; A -~= D ) { sout | label(e); } $\C{// (8) D C B A}$ 243 for ( e; A -~=D ~ 2 ) { sout | label(e); } $\C{// (9) D B }$ 244 \end{cfa} 245 Every range loop above has an index declaration, and a @range@ bounded by \newterm{left bound} @A@ and \newterm{right bound} @D@. 246 An index declaration can have an optional type declaration, without which \CFA 247 implicitly declares index variable to be the type of the bounds (@typeof(A)@). 248 If a range is joined by @~=@ (range up equal) operator, the index variable will be initialized by 249 the @left bound@, and change incrementally until its position exceeds @right bound@. 250 On the other hand, if a range is defined with @-~=@ (range down equal) operation, the index variable will 251 have the value of the @right bound@. It change decrementally until its position is less than the @left bound@. 252 A range can be suffixed by an positive integal \newterm{step}, joined by @~@. The loop @(9)@ declares a step size of 2 so that 253 e updates @pred(pred(e))@ in every iteration. 254 255 \CFA manipulates the position of the index variable and breaks the loop if an index update can result in @out of range@. 256 257 \CFA provides a shorthand for range loop over a \CFA enumeration or a @Serial@: 258 \begin{cfa}[label=lst:range_functions_2] 259 for ( e; Chars ) { sout | label(e); } $\C{// (10) A B C D}$ 260 for ( e; E ) { $\C{// forall(E | CfaEnum(E) | Serial(E)) }$ 261 sout | label(e); 262 } 263 \end{cfa} 264 The shorthand syntax has a type name expression (@Char@ and @E@) as its range. If the range expression does not name 265 a \CFA enumeration or a @Serial@, \CFA reports a compile time error. When type name as range is a \CFA enumeration, 266 it turns into a loop that iterates all enumerators of the type. If the type name is a @Serial@, the index variable 267 will be initialized as the @lowerBound@. The loop control checks the index's position against the position of @upperBound@, 268 and terminate the loop when the index has a position greater than the @upperBound@. \CFA does not update the index with 269 @succ@ but manipulate its position directly to avoid @out of bound@. 270 270 271 271 \section{Overload Operators} 272 273 \CFA overloads the comparison operators for \CFA enumeration satisfying traits @Serial@ and @CfaEnum@. 274 These definitions require the operand types be the same and the appropriate comparison is made using the the positions of the operands. 275 \begin{cfa} 276 forall( E | CfaEnum( E ) | Serial( E ) ) @{@ $\C{// distribution block}$ 272 % Finally, there is an associated trait defining comparison operators among enumerators. 273 \CFA preemptively overloads comparison operators for \CFA enumeration with @Serial@ and @CfaEnum@. 274 They defines that two enumerators are equal only if the are the same enumerator, and compartors are 275 define for order comparison. 276 \begin{cfa} 277 forall( E | CfaEnum( E ) | Serial( E ) ) { 277 278 // comparison 278 279 int ?==?( E l, E r ); $\C{// true if l and r are same enumerators}$ … … 282 283 int ?>?( E l, E r ); $\C{// true if l is an enumerator after r}$ 283 284 int ?>=?( E l, E r ); $\C{// true if l after or the same as r}$ 284 @}@ 285 \end{cfa} 286 (Note, all the function prototypes are wrapped in a distribution block, where all qualifiers preceding the block are distributed to each declaration with the block, which eliminated tedious repeated qualification. 287 Distribution blocks can be nested.) 288 289 \CFA implements a few arithmetic operators for @CfaEnum@. 290 Unlike advancement functions in @Serial@, these operators perform direct arithmetic, so there is no implicit bound checks. 291 \begin{cfa} 292 forall( E | CfaEnum( E ) | Serial( E ) ) { $\C{// distribution block}$ 285 } 286 \end{cfa} 287 288 \CFA implements few arithmetic operators for @CfaEnum@. Unlike update functions in @Serial@, these 289 operator does not have bound checks, which rely on @upperBound@ and @lowerBound@. These operators directly manipulate 290 position, the underlying representation of a \CFA enumeration. 291 \begin{cfa} 292 forall( E | CfaEnum( E ) | Serial( E ) ) { 293 293 // comparison 294 294 E ++?( E & l ); … … 303 303 \end{cfa} 304 304 305 Lastly, \CFA does not define @zero_t@ for \CFA enumeration. 306 Users can define the boolean @false@ for \CFA enumerations on their own, \eg: 307 \begin{cfa} 308 forall( E | CfaEnum( E ) ) 309 int ?!=?( E lhs, zero_t ) { 310 return posn( lhs ) != 0; 311 } 312 \end{cfa} 313 which effectively turns the first enumeration to a logical @false@ and @true@ for the others. 305 Lastly, \CFA does not define @zero_t@ for \CFA enumeration. Users can define the boolean false for 306 \CFA enumerations on their own. Here is an example: 307 \begin{cfa} 308 forall(E | CfaEnum(E)) 309 bool ?!=?(E lhs, zero_t) { 310 return posn(lhs) != 0; 311 } 312 \end{cfa} 313 which effectively turns the first enumeration as a logical false and true for others. 314 315 % \begin{cfa} 316 % Count variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 317 % p(variable_a); // 0 318 % p(variable_b); // 1 319 % p(variable_c); // "Third" 320 % p(variable_d); // 3 321 % \end{cfa} 322 323 324 % \section{Iteration and Range} 325 326 327 328 % % It is convenient to iterate over a \CFA enumeration value, \eg: 329 % \CFA implements \newterm{range loop} for \CFA enumeration using the enumerated traits. The most basic form of @range loop@ is the follows: 330 % \begin{cfa}[label=lst:range_functions] 331 % for ( Alphabet alph; Alphabet ) { sout | alph; } 332 % >>> A B C ... D 333 % \end{cfa} 334 % % The @range loops@ iterates through all enumerators in the order defined in the enumeration. 335 % % @alph@ is the iterating enumeration object, which returns the value of an @Alphabet@ in this context according to the precedence rule. 336 % Enumerated @range loop@ extends the \CFA grammar as it allows a type name @Alphabet@ 337 338 % \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 339 % \begin{cfa}[label=lst:range_functions] 340 % for ( Alphabet alph ) { sout | alph; } 341 % >>> A B C ... D 342 % \end{cfa} 343 344 % The following are examples for constructing for-control using an enumeration. Note that the type declaration of the iterating variable is optional, because \CFA can infer the type as EnumInstType based on the range expression, and possibly convert it to one of its attribute types. 345 346 % \textbullet\ H is implicit up-to exclusive range [0, H). 347 % \begin{cfa}[label=lst:range_function_1] 348 % for ( alph; Alphabet.D ) { sout | alph; } 349 % >>> A B C 350 % \end{cfa} 351 352 % \textbullet\ ~= H is implicit up-to inclusive range [0,H]. 353 % \begin{cfa}[label=lst:range_function_2] 354 % for ( alph; ~= Alphabet.D ) { sout | alph; } 355 % >>> A B C D 356 % \end{cfa} 357 358 % \textbullet\ L ~ H is explicit up-to exclusive range [L,H). 359 % \begin{cfa}[label=lst:range_function_3] 360 % for ( alph; Alphabet.B ~ Alphabet.D ) { sout | alph; } 361 % // for ( Alphabet alph = Alphabet.B; alph < Alphabet.D; alph += 1 ); 1 is one_t 362 % >>> B C 363 % \end{cfa} 364 365 % \textbullet\ L ~= H is explicit up-to inclusive range [L,H]. 366 % \begin{cfa}[label=lst:range_function_4] 367 % for ( alph; Alphabet.B ~= Alphabet.D ) { sout | alph; } 368 % >>> B C D 369 % \end{cfa} 370 371 % \textbullet\ L -~ H is explicit down-to exclusive range [H,L), where L and H are implicitly interchanged to make the range down-to. 372 % \begin{cfa}[label=lst:range_function_5] 373 % for ( alph; Alphabet.D -~ Alphabet.B ) { sout | alph; } 374 % >>> D C 375 % \end{cfa} 376 377 % \textbullet\ L -~= H is explicit down-to exclusive range [H,L], where L and H are implicitly interchanged to make the range down-to. 378 % \begin{cfa}[label=lst:range_function_6] 379 % for ( alph; Alphabet.D -~= Alphabet.B ) { sout | alph; } 380 % >>> D C B 381 % \end{cfa} 382 383 % A user can specify the ``step size'' of an iteration. There are two different stepping schemes of enumeration for-loop. 384 % \begin{cfa}[label=lst:range_function_stepping] 385 % enum(int) Sequence { A = 10, B = 12, C = 14, D = 16, D = 18 }; 386 % for ( s; Sequence.A ~= Sequence.D ~ 1 ) { sout | alph; } 387 % >>> 10 12 14 16 18 388 % for ( s; Sequence.A ~= Sequence.D; s+=1 ) { sout | alph; } 389 % >>> 10 11 12 13 14 15 16 17 18 390 % \end{cfa} 391 % The first syntax is stepping to the next enumeration constant, which is the default stepping scheme if not explicitly specified. The second syntax, on the other hand, is to call @operator+=@ @one_type@ on the @value( s )@. Therefore, the second syntax is equivalent to 392 % \begin{cfa}[label=lst:range_function_stepping_converted] 393 % for ( typeof( value(Sequence.A) ) s=value( Sequence.A ); s <= Sequence.D; s+=1 ) { sout | alph; } 394 % >>> 10 11 12 13 14 15 16 17 18 395 % \end{cfa} 396 397 % % \PAB{Explain what each loop does.} 398 399 % It is also possible to iterate over an enumeration's labels, implicitly or explicitly: 400 % \begin{cfa}[label=lst:range_functions_label_implicit] 401 % for ( char * alph; Alphabet ) 402 % \end{cfa} 403 % This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to @ch@ with type @char *@ in this case. 404 % If the value can also be resolved as the @char *@, you might iterate the labels explicitly with the array iteration. 405 % \begin{cfa}[label=lst:range_functions_label_implicit] 406 % for ( char * ch; labels( Alphabet ) ) 407 % \end{cfa} -
doc/theses/jiada_liang_MMath/uw-ethesis-frontpgs.tex
r6abb6dc r2ca7fc2 141 141 One of the key properties of an enumeration is the ability to enumerate (iterate) through the constants, and hence, access their values, if present. 142 142 C restricts an enumeration to the integral type @signed int@, while \CC extends enumerations to all integral types, meaning enumeration names must bind to integer constants. 143 Other modern programming languages provide bindings to any type and additional features to extend enumeration capabilities for better software engineering practices.144 145 The \CFA (C-for-all) programming language is an evolutionary refinement of the C program ming language.146 One of its distinctive feature sis a parametric-polymorphic generic type.147 However, legacy data types from C, such as enumerations, do not adapt well to the \CFA generic type-system.143 Other modern programming languages provide bindings to any type and additional features to extend enumeration capabilities for better software-engineering practices. 144 145 The \CFA (C-for-all) programming language is an evolutionary refinement of the C programing language. 146 One of its distinctive feature is a parametric-polymorphic generic type. 147 However, legacy data types from C, such as enumerations, do not adapt well into the \CFA generic type-system. 148 148 149 149 This thesis extends the simple and unsafe enumeration type in the C programming language into a complex and safe enumeration type in the \CFA programming-language, while maintaining backwards compatibility with C. 150 150 The major contribution is an adaptation of enumerated types with the \CFA type-system in a way that integrates naturally with the generic types. 151 This thesis also presents several smaller refinementsto the \CFA overload resolution rules for enumerated types, each of which improves the intuitive nature of enumeration name resolution by the compiler.151 This thesis also presents a number of smaller refinement to the \CFA overload resolution rules for enumerated types, each of which improves the intuitive nature of enumeration name resolution by the compiler. 152 152 Finally, this work adds other useful features to enumerations that better support software-engineering practices and simplify program development. 153 153 … … 166 166 Thanks to Gregor Richards and Yzihou Zhang for reading my thesis. 167 167 168 Special thanks to Andrew James Beach for your insight on the theory development o fthe thesis.168 Special thanks to Andrew James Beach for your insight on the theory development on the thesis. 169 169 170 170 Thanks to Michael Brooks, Fangran Yu, Colby Parsons, Thierry Delisle, Mubeen Zulifiqar, 171 and the entire \CFA team for thedevelopment of the \CFA language, making it the best language it can be.171 and the entire \CFA team for development of the \CFA language, making it the best language it can be. 172 172 173 173 Finally, a special thank you to Huawei Canada for funding this work. -
libcfa/src/collections/string.hfa
r6abb6dc r2ca7fc2 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Aug 6 07:49:52202413 // Update Count : 1 3012 // Last Modified On : Mon Aug 5 23:06:14 2024 13 // Update Count : 128 14 14 // 15 15 … … 161 161 string ?+?( char c, const string & s ); // add a character to a copy of the string 162 162 string ?+?( const string & s, const string & s2 ); // copy and concatenate both strings 163 string ?+?( const char * s, char c ); // add a character to a copy of the string164 string ?+?( char c, const char * s ); // add a character to a copy of the string165 string ?+?( const char * c, const char * s ); // copy and add with two NULL-terminated string166 string ?+?( const char * c, string & s ); // copy and add with NULL-terminated string167 string ?+?( const string & s, const char * c ); // copy and addwith NULL-terminated string163 string ?+?( const char * s, char c ); // copy and concatenate both strings 164 string ?+?( char c, const char * s ); // copy and concatenate both strings 165 string ?+?( const char * s1, const char * s2 ); // copy and concatenate both strings 166 string ?+?( const char * s1, string & s2 ); // copy and concatenate both strings 167 string ?+?( const string & s, const char * c ); // copy and concatenate with NULL-terminated string 168 168 169 169 static inline string & strcat( string & s, const string & s2 ) { s += s2; return s; } … … 184 184 185 185 // Comparisons 186 int strcmp ( const string &, const string & );187 bool ?==?( const string &, const string & );188 bool ?!=?( const string &, const string & );189 bool ?>? ( const string &, const string & );190 bool ?>=?( const string &, const string & );191 bool ?<=?( const string &, const string & );192 bool ?<? ( const string &, const string & );193 194 int strcmp( const string &, const char * );195 bool ?==?( const string &, const char * );196 bool ?!=?( const string &, const char * );197 bool ?>? ( const string &, const char * );198 bool ?>=?( const string &, const char * );199 bool ?<=?( const string &, const char * );200 bool ?<? ( const string &, const char * );201 202 int strcmp( const char *, const string & );203 bool ?==?( const char *, const string & );204 bool ?!=?( const char *, const string & );205 bool ?>? ( const char *, const string & );206 bool ?>=?( const char *, const string & );207 bool ?<=?( const char *, const string & );208 bool ?<? ( const char *, const string & );186 int strcmp ( const string &, const string &); 187 bool ?==?( const string &, const string &); 188 bool ?!=?( const string &, const string &); 189 bool ?>? ( const string &, const string &); 190 bool ?>=?( const string &, const string &); 191 bool ?<=?( const string &, const string &); 192 bool ?<? ( const string &, const string &); 193 194 int strcmp( const string &, const char *); 195 bool ?==?( const string &, const char *); 196 bool ?!=?( const string &, const char *); 197 bool ?>? ( const string &, const char *); 198 bool ?>=?( const string &, const char *); 199 bool ?<=?( const string &, const char *); 200 bool ?<? ( const string &, const char *); 201 202 int strcmp( const char *, const string &); 203 bool ?==?( const char *, const string &); 204 bool ?!=?( const char *, const string &); 205 bool ?>? ( const char *, const string &); 206 bool ?>=?( const char *, const string &); 207 bool ?<=?( const char *, const string &); 208 bool ?<? ( const char *, const string &); 209 209 210 210 -
libcfa/src/enum.cfa
r6abb6dc r2ca7fc2 11 11 // It is okay to overflow as overflow will be theoretically caught by the other bound 12 12 if ( i < fromInstance( lower ) || i > fromInstance( upper ) ) 13 abort( "call to fromInt has index %d outside of enumeration range %d-%d.",13 abort( "call to fromInt has index %d outside enumeration range %d-%d", 14 14 i, fromInstance( lower ), fromInstance( upper ) ); 15 15 return fromInt_unsafe( i ); … … 19 19 E upper = upperBound(); 20 20 if ( fromInstance( e ) >= fromInstance( upper ) ) 21 abort( "call to succ() exceeds enumeration upper bound of %d .", fromInstance( upper ) );21 abort( "call to succ() exceeds enumeration upper bound of %d", fromInstance( upper ) ); 22 22 return succ_unsafe(e); 23 23 } … … 26 26 E lower = lowerBound(); 27 27 if ( fromInstance( e ) <= fromInstance(lower ) ) 28 abort( "call to pred() exceeds enumeration lower bound of %d .", fromInstance( lower ) );28 abort( "call to pred() exceeds enumeration lower bound of %d", fromInstance( lower ) ); 29 29 return pred_unsafe( e ); 30 30 } 31 31 32 int Countof( E) {32 int Countof( __attribute__((unused)) E e ) { 33 33 E upper = upperBound(); 34 34 E lower = lowerBound(); -
libcfa/src/enum.hfa
r6abb6dc r2ca7fc2 19 19 E succ( E e ); 20 20 E pred( E e ); 21 int Countof( E );21 int Countof( E e ); 22 22 } 23 23 -
libcfa/src/heap.cfa
r6abb6dc r2ca7fc2 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 7 10:14:47202413 // Update Count : 164 612 // Last Modified On : Sun Apr 7 21:54:29 2024 13 // Update Count : 1644 14 14 // 15 15 … … 582 582 __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText), 583 583 "CFA warning (UNIX pid:%ld) : program terminating with %td(%#tx) bytes of storage allocated but not freed.\n" 584 "Possible cause is mismatched allocation/deallocation calls (malloc/free), direct constructor call without a direct destructor call, or system/library routines not freeing storage.\n",584 "Possible cause is unfreed storage allocated by the program or system/library routines called from the program.\n", 585 585 (long int)getpid(), allocUnfreed, allocUnfreed ); // always print the UNIX pid 586 586 } // if -
src/Validate/ImplementEnumFunc.cpp
r6abb6dc r2ca7fc2 210 210 "value", 211 211 {new ast::ObjectDecl(getLocation(), "_i", new ast::EnumInstType(decl))}, 212 {new ast::ObjectDecl(getLocation(), "_ret", decl->base)}); 212 {new ast::ObjectDecl(getLocation(), "_ret", 213 ast::deepCopy(decl->base))}); 214 // else 215 // return genQuasiValueProto(); 213 216 } 214 217
Note:
See TracChangeset
for help on using the changeset viewer.