Changeset 32490deb for doc/proposals/enum.tex
- Timestamp:
- Jan 31, 2024, 6:40:25 PM (20 months ago)
- Branches:
- master
- Children:
- 496ffc17
- Parents:
- c75b30a (diff), e71b09a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/enum.tex
rc75b30a r32490deb 7 7 \usepackage{graphics} 8 8 \usepackage{xspace} 9 \usepackage{relsize} % must be after change to small or selects old size 10 \usepackage{calc} % latex arithmetic 9 11 10 12 \makeatletter … … 22 24 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 23 25 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 26 27 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}} 28 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 29 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 30 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}} 31 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}} 32 33 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 34 \newlength{\columnposn} 35 \setlength{\gcolumnposn}{3in} 36 \setlength{\columnposn}{\gcolumnposn} 37 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} 38 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstCommentStyle{#2}}} 39 \newcommand{\CD}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstBasicStyle{#2}}} 40 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 24 41 \makeatother 25 42 … … 48 65 \newcommand{\CCIcon}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}} % C++ icon 49 66 \newcommand{\CC}[1][]{\protect\CCIcon{#1}\xspace} % C++ symbolic name 67 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\relsize{2}$^\sharp$}\xspace} % C# symbolic name 50 68 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 51 69 … … 56 74 57 75 \lstdefinestyle{CStyle}{ 58 % backgroundcolor=\color{backgroundColour}, 76 % backgroundcolor=\color{backgroundColour}, 59 77 % commentstyle=\color{mGreen}, 60 78 % keywordstyle=\color{magenta}, … … 64 82 basicstyle=\small\linespread{0.9}\sf, % reduce line spacing and use sanserif font 65 83 % basicstyle=\footnotesize, 66 breakatwhitespace=false, 67 % breaklines=true, 68 captionpos=b, 69 keepspaces=true, 84 breakatwhitespace=false, 85 % breaklines=true, 86 captionpos=b, 87 keepspaces=true, 70 88 escapechar=\$, % LaTeX escape in CFA code 71 % numbers=left, 72 % numbersep=5pt, 89 % numbers=left, 90 % numbersep=5pt, 73 91 % numberstyle=\tiny\color{mGray}, 74 % showspaces=false, 92 % showspaces=false, 75 93 showstringspaces=false, 76 % showtabs=false, 94 % showtabs=false, 77 95 showlines=true, % show blank lines at end of code 78 96 tabsize=5, … … 93 111 94 112 \begin{abstract} 95 An enumeration is a type that defines a list of named constant values in C (and other languages). 96 C and \CC use an integral type as the underlying representation of an enumeration. 97 \CFA extends C enumerations to allow all basic and custom types for the inner representation. 113 An enumeration is a type defining an ordered set of named constant values, where a name abstracts a value, e.g., @PI@ versus @3.145159@. 114 C restrict an enumeration type to the integral type @signed int@, which \CC support , meaning enumeration names bind to integer constants. 115 \CFA extends C enumerations to allow all basic and custom types for the enumeration type, like other modern programming languages. 116 Furthermore, \CFA adds other useful features for enumerations to support better software-engineering practices and simplify program development. 98 117 \end{abstract} 99 118 119 \section{Background} 120 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc. 122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time (noon, New Years). 123 Many programming languages capture this important capability through a mechanism called an \newterm{enumeration}. 124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set. 125 Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms. 126 127 Specifically, an enumerated type is a type whose values are restricted to a fixed set of named constants. 128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc. 129 However, the values for basic types are not named, other than the programming-language supplied constants. 130 131 100 132 \section{C-Style Enum} 101 133 102 \CFA supports the C-Style enumeration using the samesyntax and semantics.134 The C-Style enumeration has the following syntax and semantics. 103 135 \begin{lstlisting}[label=lst:weekday] 104 enum Weekday { Monday, Tuesday, Wednesday, Thursday =10, Friday, Saturday, Sunday };105 $\(\uparrow\)$ $\(\uparrow\)$106 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}}107 \end{lstlisting} 108 The example defines an enumeration type @Weekday@ with ordered enumerators @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.136 enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday }; 137 $\(\uparrow\)$ $\(\uparrow\)$ 138 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}} 139 \end{lstlisting} 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 109 141 The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@. 110 A C enumeration is an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value by the programmer.111 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@ by the programmer, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler.142 A C enumeration is implemented by an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value. 143 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler. 112 144 113 145 There are 3 attributes for an enumeration: \newterm{position}, \newterm{label}, and \newterm{value}: … … 118 150 \it position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 119 151 \it label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 120 \it value & 0 & 1 & 2 & 10& 11 & 12 & 13152 \it value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13 121 153 \end{tabular} 122 154 \end{cquote} 123 155 124 156 The enumerators of an enumeration are unscoped, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 157 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types. 125 158 \begin{lstlisting}[label=lst:enum_scope] 126 159 { 127 enum Weekday { ... }; // enumerators implicitly projected into local scope160 enum Weekday { ... }; $\C{// enumerators implicitly projected into local scope}$ 128 161 Weekday weekday = Monday; 129 weekday = Friday; 130 int i = Sunday // i == 13 162 weekday = Friday; $\C{// weekday == 11}$ 163 int i = Sunday $\C{// i == 13}$ 164 weekday = 10000; $\C{// undefined behaviour}$ 131 165 } 132 int j = Wednesday; // ERROR! Wednesday is not declared in this scope166 int j = Wednesday; $\C{// ERROR! Wednesday is not declared in this scope}$ 133 167 \end{lstlisting} 134 168 135 169 \section{\CFA-Style Enum} 136 170 137 A \CFA enumeration is parameterized by a type specifying each enumerator's type. 138 \CFA allows any object type for the enumerators, and values assigned to enumerators must be from the declared type. 171 \CFA supports C-Style enumeration using the same syntax and semantics for backwards compatibility. 172 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 173 174 \subsection{Enumerator Typing} 175 176 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 139 177 \begin{lstlisting}[label=lst:color] 140 enum Colour( @char *@ ) { Red = "R", Green = "G", Blue = "B" }; 141 \end{lstlisting} 142 The type of @Colour@ is @char *@ and each enumerator is initialized with a C string. 143 Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 178 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 179 enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642 }; // mass 180 enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue" }; 181 enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection 182 \end{lstlisting} 183 The types of the enumerators are @char@, @double@, and @char *@ and each enumerator is initialized with corresponding type values. 184 % Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 144 185 145 186 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. … … 151 192 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope. 152 193 \begin{lstlisting} 153 enum Colour( char * ) @!@ { ... }; 194 enum Weekday @!@ { /* as above */ }; 195 enum Colour( char * ) @!@ { /* as above */ }; 154 196 \end{lstlisting} 155 197 where the @'!'@ implies the enumerators are \emph{not} projected. … … 158 200 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$ 159 201 \begin{lstlisting} 160 Colour colour = @Colour.@Red; // qualification 202 Weekday weekday = @Weekday.Monday@; $\C{// qualification}$ 203 Colour colour = @Colour.@Red; 161 204 colour = @Colour.@Blue; 162 205 \end{lstlisting} 163 206 164 \section{Enumeration Pseudo-functions} 165 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. Instead, the call to functions will be substituted into other expressions in compilation time. 166 167 \subsection{Enumerator Attributes} 168 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 207 \subsection{Enumeration Pseudo-functions} 208 209 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. 210 Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture.. 211 212 \subsubsection{Enumerator Attributes} 213 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 169 214 \begin{lstlisting} 170 int green_pos = @position@( Colour.Green ); // 1 171 char * green_value = @value@( Colour.Green ); / "G" 172 char * green_label = @label@( Colour.Green ); // "Green" 173 \end{lstlisting} 174 175 \subsection{enumerate()} 215 int green_pos = @position@( Colour.Green ); $\C{// 1}$ 216 char * green_value = @value@( Colour.Green ); $\C{// "G"}$ 217 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$ 218 \end{lstlisting} 219 220 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 221 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 222 223 \subsubsection{\lstinline{enumerate()}} 224 176 225 \begin{lstlisting}[label=lst:c_switch] 177 226 enum(int) C_ENUM { First, Second, Third = First, Fourth }; 178 int v(C_ENUM e) { 179 switch( e ) { 180 case First: return 0; break; 181 case Second: return 1; break; 182 // case Thrid: return 2; break; 183 // case Fourth: return 3; break; 184 }; 185 }; 186 \end{lstlisting} 187 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. Case First and Third, or Second and Fourth, has duplicate case values. 188 189 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 227 int v( C_ENUM e ) { 228 switch( e ) { 229 case First: return 0; break; 230 case Second: return 1; break; 231 // case Third: return 2; break; 232 // case Fourth: return 3; break; 233 }; 234 }; 235 \end{lstlisting} 236 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. 237 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. 238 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values. 239 240 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 190 241 \begin{lstlisting}[label=lst:c_switch_enumerate] 191 242 enum(double) C_ENUM { First, Second, Third = First, Fourth }; 192 C_ENUM variable_a = First, variable_b = Second, variable_c = Th rid, variable_d = Fourth;193 int v(C_ENUM e) { 194 195 196 197 case Thrid: return label( e ); break;198 199 243 C_ENUM variable_a = First, variable_b = Second, variable_c = Third, variable_d = Fourth; 244 int v(C_ENUM e) { 245 switch( enumeratate( e ) ) { 246 case First: return e; break; 247 case Second: return value( e ); break; 248 case Third: return label( e ); break; 249 case Fourth: return position( e ); break; 250 }; 200 251 }; 201 252 p(variable_a); // 0 … … 205 256 \end{lstlisting} 206 257 258 207 259 \section{Enumeration Storage} 260 208 261 209 262 \subsection{Enumeration Variable} … … 228 281 >>> label( Colour, 1) -> char * 229 282 \end{lstlisting} 230 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 283 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 231 284 These generated functions are $Companion Functions$, they take an $companion$ object and the position as parameters. 232 285 286 233 287 \subsection{Enumeration Data} 288 234 289 \begin{lstlisting}[label=lst:enumeration_backing_data] 235 290 enum(T) E { ... }; 236 291 // backing data 237 T* E_values; 238 char** E_labels; 239 \end{lstlisting} 240 Storing values and labels as arrays can sometimes help support enumeration features. However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 292 T * E_values; 293 char ** E_labels; 294 \end{lstlisting} 295 Storing values and labels as arrays can sometimes help support enumeration features. 296 However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 241 297 \begin{itemize} 242 \item Only generates the data array if necessary 243 \item The compilation units share the data structures. No extra overhead if the data structures are requested multiple times. 298 \item Only generates the data array if necessary 299 \item The compilation units share the data structures. 300 No extra overhead if the data structures are requested multiple times. 244 301 \end{itemize} 245 302 246 303 247 \248 304 \section{Unification} 249 305 250 306 \subsection{Enumeration as Value} 251 307 \label{section:enumeration_as_value} 252 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 308 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 253 309 \begin{lstlisting}[label=lst:implicit_conversion] 254 310 char * green_value = Colour.Green; // "G" 255 // Is equivalent to 311 // Is equivalent to 256 312 // char * green_value = value( Color.Green ); "G" 257 313 \end{lstlisting} 258 314 315 259 316 \subsection{Unification Distance} 317 260 318 \begin{lstlisting}[label=lst:unification_distance_example] 261 319 T_2 Foo(T1); … … 265 323 @path(A, B)@ is a compiler concept that returns one of the following: 266 324 \begin{itemize} 267 268 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 269 270 325 \item Zero or 0, if and only if $A == B$. 326 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 327 \item Unsafe, if B loses its precision when used as A, or A is a subtype of B. 328 \item Infinite, if B cannot be used as A. A is not a subtype of B and B is not a subtype of A. 271 329 \end{itemize} 272 330 … … 278 336 The arithmetic of distance is the following: 279 337 \begin{itemize} 280 281 \item $Safe * k < Unsafe$, for finite k. 282 283 338 \item $Zero + v= v$, for some value v. 339 \item $Safe * k < Unsafe$, for finite k. 340 \item $Unsafe * k < Infinite$, for finite k. 341 \item $Infinite + v = Infinite$, for some value v. 284 342 \end{itemize} 285 343 … … 288 346 289 347 \subsection{Variable Overloading and Parameter Unification} 348 290 349 \CFA allows variable names to be overloaded. It is possible to overload a variable that has type T and an enumeration with type T. 291 350 \begin{lstlisting}[label=lst:variable_overload] … … 304 363 Similarly, functions can be overloaded with different signatures. \CFA picks the correct function entity based on the distance between parameter types and the arguments. 305 364 \begin{lstlisting}[label=lst:function_overload] 306 Colour green = Colour.Green; 365 Colour green = Colour.Green; 307 366 void foo(Colour c) { sout | "It is an enum"; } // First foo 308 367 void foo(char * s) { sout | "It is a string"; } // Second foo … … 326 385 % The @EnumInstType@ is convertible to other types. 327 386 % A \CFA enumeration expression is implicitly \emph{overloaded} with its three different attributes: value, position, and label. 328 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 387 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 329 388 330 389 % \begin{lstlisting}[caption={Null Context}, label=lst:null_context] … … 379 438 % } 380 439 % \end{lstlisting} 381 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 440 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 382 441 % Backward conversion: 383 442 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] … … 389 448 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 390 449 % { 391 % 450 % Unification( EnumInstType<Colour>, int ) >>> label 392 451 % } 393 452 % \end{lstlisting} 394 453 % @int@ can be unified with the label of Colour. 395 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 454 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 396 455 % \begin{lstlisting} 397 456 % { 398 % enum Colour colour = Colour.Green;457 % enum Colour colour = Colour.Green; 399 458 % } 400 459 % \end{lstlisting} … … 411 470 % { 412 471 % enum T (int) { ... } // Declaration 413 % enum T t = 1; 472 % enum T t = 1; 414 473 % } 415 474 % \end{lstlisting} … … 423 482 % return the FIRST enumeration constant that has the value 1, by searching through the values array 424 483 % \end{enumerate} 425 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 484 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 426 485 427 486 % \subsection{Casting} … … 431 490 % (int) Foo.A; 432 491 % \end{lstlisting} 433 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 492 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 434 493 435 494 % \subsection{Value Conversion} … … 445 504 % int j = value( Foo, a ) 446 505 % \end{lstlisting} 447 % Similarly, the generated code for the third line is 506 % Similarly, the generated code for the third line is 448 507 % \begin{lstlisting} 449 508 % char * j = label( Foo, a ) … … 455 514 456 515 \subsection{C Enumeration Rule} 457 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 516 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 458 517 459 518 \subsection{Auto Initializable} … … 478 537 Odd ?++( Odd t1 ) { return Odd( t1.i + 2); }; 479 538 \end{lstlisting} 480 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 539 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 481 540 \begin{lstlisting}[label=lst:sample_auto_Initializable_usage] 482 541 enum AutoInitUsage(Odd) { … … 514 573 @alph@ is the iterating enumeration object, which returns the value of an @Alphabet@ in this context according to the precedence rule. 515 574 516 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 575 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 517 576 \begin{lstlisting}[label=lst:range_functions] 518 577 for ( Alphabet alph ) { sout | alph; } … … 567 626 >>> 10 11 12 13 14 15 16 17 18 568 627 \end{lstlisting} 569 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 628 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 570 629 \begin{lstlisting}[label=lst:range_function_stepping_converted] 571 630 for ( typeof( value(Sequence.A) ) s=value( Sequence.A ); s <= Sequence.D; s+=1 ) { sout | alph; } … … 579 638 for ( char * alph; Alphabet ) 580 639 \end{lstlisting} 581 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to the chwith type @char *@ in this case.640 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. 582 641 If the value can also be resolved as the @char *@, you might iterate the labels explicitly with the array iteration. 583 642 \begin{lstlisting}[label=lst:range_functions_label_implicit] … … 591 650 % \begin{lstlisting} 592 651 % enum T( int, char * ) { 593 % 652 % a=42, b="Hello World" 594 653 % }; 595 654 % \end{lstlisting} 596 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 655 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 597 656 598 657 \subsection{Enumeration Inheritance} … … 602 661 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; 603 662 \end{lstlisting} 604 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 663 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 605 664 \begin{lstlisting}[label=lst:EnumInline] 606 665 Name Fred; … … 610 669 If enumeration A declares @inline B@ in its enumeration body, enumeration A is the "inlining enum" and enumeration B is the "inlined enum". 611 670 612 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 671 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 613 672 \begin{lstlisting}[label=lst:EnumInline] 614 673 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; … … 625 684 \begin{lstlisting}[label=lst:static_attr] 626 685 enum( char * ) Colour { 627 Red = "red", Blue = "blue", Green = "green" 628 }; 629 \end{lstlisting} 630 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 686 Red = "red", Blue = "blue", Green = "green" 687 }; 688 \end{lstlisting} 689 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 631 690 632 691 \subsection{Runtime Attribute Expression and Weak Referenced Data} … … 638 697 An enumeration variable c is equivalent to an integer variable with the value of @position( c )@ In Example~\ref{lst:dynamic_attr}, the value of enumeration variable c is unknown at compile time. In this case, the pseudo-function calls are reduced to expression that returns the enumerator values at runtime. 639 698 640 \CFA stores the variables and labels in const arrays to provide runtime lookup for enumeration information.699 \CFA stores the variables and labels in @const@ arrays to provide runtime lookup for enumeration information. 641 700 642 701 \begin{lstlisting}[label=lst:attr_array] … … 651 710 \end{lstlisting} 652 711 653 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 712 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 654 713 655 714 \subsection{Enum Prelude} … … 657 716 \begin{lstlisting}[label=lst:enum_func_dec] 658 717 forall( T ) { 659 660 661 718 unsigned position( unsigned ); 719 T value( unsigned ); 720 char * label( unsigned ); 662 721 } 663 722 \end{lstlisting} … … 670 729 forall(T) 671 730 class EnumDecl { 672 673 731 T* values; 732 char** label; 674 733 }; 675 734 \end{lstlisting} … … 679 738 \begin{lstlisting}[label=lst:EnumInstType] 680 739 class EnumInstType { 681 682 740 EnumDecl enumDecl; 741 int position; 683 742 }; 684 743 \end{lstlisting} … … 700 759 % struct Companion { 701 760 % const T * const values; 702 % 761 % const char * label; 703 762 % int length; 704 763 % }; … … 706 765 % \CFA generates companion objects, an instance of structure that encloses @necessary@ data to represent an enumeration. The size of the companion is unknown at the compilation time, and it "grows" in size to compensate for the @usage@. 707 766 708 % The companion object is singleton across the compilation (investigation). 767 % The companion object is singleton across the compilation (investigation). 709 768 710 769 % \CFA generates the definition of companion functions. … … 727 786 \begin{lstlisting}[label=lst:companion_trait] 728 787 forall(T1) { 729 730 731 732 733 788 trait Companion(otype T2<otype T1>) { 789 T1 value((otype T2<otype T1> const &); 790 int position(otype T2<otype T1> const &); 791 char * label(otype T2<otype T1> const &); 792 } 734 793 } 735 794 \end{lstlisting} … … 743 802 \begin{lstlisting} 744 803 enum(int) Weekday { 745 804 Monday=10, Tuesday, ... 746 805 }; 747 806 … … 758 817 \subsection{User Define Enumeration Functions} 759 818 760 Companion objects make extending features for \CFA enumeration easy. 819 Companion objects make extending features for \CFA enumeration easy. 761 820 \begin{lstlisting}[label=lst:companion_user_definition] 762 char * charastic_string( Companion o, int position ) { 763 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 821 char * charastic_string( Companion o, int position ) { 822 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 764 823 } 765 824 printf( charactic_string ( Color, 1 ) ); … … 776 835 Similarly, the user can work with the enumeration type itself: (see section ref...) 777 836 \begin{lstlisting}[ label=lst:companion_user_definition] 778 void print_enumerators ( Companion o ) { 837 void print_enumerators ( Companion o ) { 779 838 for ( c : Companion o ) { 780 839 sout | label (c) | value( c ) ; 781 } 840 } 782 841 } 783 842 print_enumerators( Colour ); … … 795 854 It ensures that the name of an enumerator is unique within the enumeration body, and checks if all values of the enumerator have the declaration type. 796 855 If the declared type is not @AutoInitializable@, \CFA rejects the enumeration definition. 797 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 856 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 798 857 799 858 \begin{lstlisting}[label=lst:init] … … 803 862 T ?+?( T & lhs, T & rhs ) { ... }; 804 863 805 enum (T) Sample { 806 Zero: 0 /* zero_t */, 864 enum (T) Sample { 865 Zero: 0 /* zero_t */, 807 866 One: Zero + 1 /* ?+?( Zero, one_t ) */ , ... 808 867 }; … … 826 885 \subsection{Qualified Expression} 827 886 828 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 887 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 829 888 \begin{lstlisting}[label=lst:qualified_expression] 830 889 aggregation_name.field; … … 837 896 838 897 \subsection{\lstinline{with} Clause/Statement} 898 839 899 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible. 840 900 \begin{lstlisting}[label=lst:declaration] … … 842 902 enum Animal( int ) { Cat=10, Dog=20 }; 843 903 with ( Color, Animal ) { 844 845 904 char * red_string = Red; // value( Color.Red ) 905 int cat = Cat; // value( Animal.Cat ) 846 906 } 847 907 \end{lstlisting} … … 851 911 enum RGB( int ) { Red=0, Green=1, Blue=2 }; 852 912 with ( Color, RGB ) { 853 // int red = Red; 913 // int red = Red; 854 914 } 855 915 \end{lstlisting} … … 865 925 The declaration \CFA-enumeration variable has the same syntax as the C-enumeration. Internally, such a variable will be represented as an EnumInstType. 866 926 927 \section{Related Work} 928 929 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and Algebraic data type in functional programming. 930 There are a large set of overlapping features for all the languages, but each language has its own unique restrictions and extensions. 931 932 \subsection{Pascal} 933 934 \subsection{Ada} 935 936 \subsection{\Csharp} 937 938 \subsection{\CC} 939 940 Because \CC is backwards compatible with C, it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration; 941 hence, the values in a \CC enumeration can only be its enumerators. 942 943 \CC{11} extended enumeration with a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), where the enumerators are local to the enumeration and are accessed using type qualification, e.g., @Weekday::Monday@. 944 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration. 945 946 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type that is large enough to hold all enumerated values; it does not have to be the smallest possible type. 947 The underlying integral type can be explicitly specified: 948 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}] 949 enum class RGB : @long@ { Red, Green, Blue }; 950 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' }; 951 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 }; 952 \end{lstlisting} 953 954 \subsection{Go} 955 956 \subsection{Java} 957 958 \subsection{Modula-3} 959 960 \subsection{Rust} 961 962 \subsection{Swift} 963 964 \subsection{Python} 965 966 \subsection{Algebraic Data Type} 867 967 868 968 \end{document}
Note:
See TracChangeset
for help on using the changeset viewer.