Changes in / [47bd204:a55ebcc]


Ignore:
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/enum.tex

    r47bd204 ra55ebcc  
    121121Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc.
    122122Naming 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 software-engineering capability through a mechanism called an \newterm{enumeration}.
     123Many programming languages capture this important capability through a mechanism called an \newterm{enumeration}.
    124124An 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.
    125125Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms.
    126126
    127 Specifically, an enumerated type restricts its values to a fixed set of named constants.
     127Specifically, an enumerated type is a type whose values are restricted to a fixed set of named constants.
    128128Fundamentally, 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.
    129129However, the values for basic types are not named, other than the programming-language supplied constants.
     
    132132\section{C-Style Enum}
    133133
    134 The C-Style enumeration has the following syntax and semantics, and is representative of enumerations in many other programming languages (see Section~\ref{s:RelatedWork}).
     134The C-Style enumeration has the following syntax and semantics.
    135135\begin{lstlisting}[label=lst:weekday]
    136136enum Weekday { Monday, Tuesday, Wednesday, Thursday@ = 10@, Friday, Saturday, Sunday };
     
    139139\end{lstlisting}
    140140Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.
    141 By convention, the successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@, independent of the associated enumerator constants.
    142 Because an enumerator is a constant, it cannot appear in a mutable context, e.g. @Mon = Sun@ is meaningless, and has no address, it is an rvalue\footnote{
    143 The term rvalue defines an expression that can only appear on the right-hand side of an assignment.}.
    144 Enumerators without explicitly designated constants are auto-initialized by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@.
    145 For example, @Monday@ to @Wednesday@ are implicitly assigned with constants 0--2, @Thursday@ is explicitly set to constant @10@, and @Friday@ to @Sunday@ are implicitly assigned with constants 11--13.
    146 Hence, there are 3 universal enumeration attributes: \newterm{position}, \newterm{label}, and \newterm{value}:
     141The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@.
     142A 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.
     143For 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.
     144
     145There are 3 attributes for an enumeration: \newterm{position}, \newterm{label}, and \newterm{value}:
    147146\begin{cquote}
    148147\small\sf\setlength{\tabcolsep}{3pt}
    149148\begin{tabular}{rccccccccccc}
    150 @enum@ Weekday \{       & Monday,       & Tuesday,      & Wednesday,    & Thursday = 10,& Friday,       & Saturday,     & Sunday \}; \\
    151 \it\color{red}position          & 0                     & 1                     & 2                             & 3                             & 4                     & 5                     & 6                     \\
    152 \it\color{red}label                     & Monday        & Tuesday       & Wednesday             & Thursday              & Friday        & Saturday      & Sunday        \\
    153 \it\color{red}value                     & 0                     & 1                     & 2                             & {\color{red}10}& 11           & 12            & 13
     149@enum@ Weekday \{       & Monday,       & Tuesday,      & Wednesday,    & Thursday=10,  & Friday,       & Saturday,     & Sunday \}; \\
     150\it position            & 0                     & 1                     & 2                             & 3                             & 4                     & 5                     & 6                     \\
     151\it label                       & Monday        & Tuesday       & Wednesday             & Thursday              & Friday        & Saturday      & Sunday        \\
     152\it value                       & 0                     & 1                     & 2                             & {\color{red}10}& 11           & 12            & 13
    154153\end{tabular}
    155154\end{cquote}
    156 Finally, C enumerators are \newterm{unscoped}, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type.
    157 
    158 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values.
    159 In practice, since integral constants in C have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables.
     155
     156The enumerators of an enumeration are unscoped, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type.
    160157Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types.
    161158\begin{lstlisting}[label=lst:enum_scope]
    162159{
    163160        enum Weekday { ... };                           $\C{// enumerators implicitly projected into local scope}$
    164         Weekday weekday = Monday;                       $\C{// weekday == 0}$
     161        Weekday weekday = Monday;
    165162        weekday = Friday;                                       $\C{// weekday == 11}$
    166         int i = Sunday                                          $\C{// implicit conversion to int, i == 13}$
    167         weekday = 10000;                                        $\C{// UNDEFINED! implicit conversion to Weekday}$
     163        int i = Sunday                                          $\C{// i == 13}$
     164        weekday = 10000;                                        $\C{// undefined behaviour}$
    168165}
    169166int j = Wednesday;                                              $\C{// ERROR! Wednesday is not declared in this scope}$
    170167\end{lstlisting}
    171 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error.
    172168
    173169\section{\CFA-Style Enum}
     
    179175
    180176\CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type.
    181 Figure~\ref{f:EumeratorTyping} shows a series of examples illustrating that all \CFA types can be use with an enumeration and each type's constants used to set the enumerators.
    182 
    183 Typed enumerates deals with \emph{harmonizing} problem between an enumeration and its companion data.
    184 The following example is from the \CFA compiler, written in \CC.
    185 \begin{lstlisting}
    186 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES };
    187 char * integral_names[NO_OF_ITYPES] = {
    188         "char", "signed char", "unsigned char",
    189         "signed short int", "unsigned short int",
    190         "signed int", "unsigned int",
    191         ...
    192 };
    193 \end{lstlisting}
    194 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit.
    195 It is up to the programmer to ensure changes made in one location are harmonized with the other location (by identifying this requirement within a comment).
    196 The typed enumeration largely solves this problem by combining and managing the two data types.
    197 \begin{lstlisting}
    198 enum( char * ) integral_types {
    199         chr = "char", schar = "signed char", uschar = "unsigned char",
    200         sshort = "signed short int", ushort = "unsigned short int",
    201         sint = "signed int", usint = "unsigned int",
    202         ...
    203 };
    204 \end{lstlisting}
    205 
    206 % \begin{lstlisting}[label=lst:color]
    207 % struct S { int i, j; };
    208 % enum( S ) s { A = { 3,  4 }, B = { 7,  8 } };
    209 % enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$'  };
    210 % enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642  }; // mass
    211 % enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue"  };
    212 % enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection
    213 % \end{lstlisting}
    214 
    215 \begin{figure}
    216 \begin{lstlisting}
    217 // integral
    218         enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$'  };
    219         enum( @signed char@ ) srgb { Red = -1, Green = 0, Blue = 1 };
    220         enum( @long long int@ ) BigNum { X = 123_456_789_012_345,  Y = 345_012_789_456_123 };
    221 // non-integral
    222         enum( @double@ ) Math { PI_2 = 1.570796, PI = 3.141597, E = 2.718282 };
    223         enum( @_Complex@ ) Plane { X = 1.5+3.4i, Y = 7+3i, Z = 0+0.5i };
    224 // pointer
    225         enum( @char *@ ) Names { Fred = "Fred", Mary = "Mary", Jane = "Jane" };
    226         int i, j, k;
    227         enum( @int *@ ) ptr { I = &i,  J = &j,  K = &k };
    228         enum( @int &@ ) ref { I = i,   J = j,   K = k };
    229 // tuple
    230         enum( @[int, int]@ ) { T = [ 1, 2 ] };
    231 // function
    232         void f() {...}   void g() {...}
    233         enum( @void (*)()@ ) funs { F = f,  G = g };
    234 // aggregate
    235         struct Person { char * name; int age, height; };
    236         enum( @Person@ ) friends { Liz = { "Elizabeth", 22, 170 }, Beth = Liz, Jon = { "Jonathan", 35, 190 } };
    237 \end{lstlisting}
    238 \caption{Enumerator Typing}
    239 \label{f:EumeratorTyping}
    240 \end{figure}
    241 
    242 \subsection{Pure Enumerators}
    243 
    244 An empty type, @enum()@, implies the enumerators are pure symbols without values;
    245 hence, there is no default conversion to @int@.
    246 
    247 \begin{lstlisting}
    248 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
    249 Mode iomode = O_RDONLY;
    250 int i = iomode;                                                 $\C{\color{red}// disallowed}$
    251 sout | O_TRUNC;                                                 $\C{\color{red}// disallowed}$
    252 \end{lstlisting}
    253 
    254 \subsection{Enumerator Subset}
    255 
    256 If follows from enumerator typing that the type of the enumerators can be another enumerator.
    257 \begin{lstlisting}
    258 enum( char ) Letter { A = 'A',  B = 'B', C = 'C', ..., Z = 'Z' };
    259 enum( Letter ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // alphabet intersection
    260 Letter letter = A;
    261 Greak greek = Alph;
    262 letter = Alph;                                                  $\C{// allowed}$
    263 greek = A;                                                              $\C{\color{red}// disallowed}$
    264 \end{lstlisting}
    265 Enumeration @Greek@ may have more or less enumerators than @Letter@, but the enumerator values must be from @Letter@.
    266 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@.
    267 
    268 \subsection{Enumeration Inheritance}
    269 
    270 \CFA Plan-9 inheritance may be used with enumerations.
    271 \begin{lstlisting}
    272 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" };
    273 enum /* inferred */ Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" };
    274 \end{lstlisting}
    275 Enumeration @Name2@ inherits all the enumerators and their values from enumeration @Name@ by containment, and a @Name@ enumeration is a subtype of enumeration @Name2@.
    276 Note, enumerators must be unique in inheritance but enumerator values may be repeated.
    277 
    278 The enumeration type for the inheriting type must be the same as the inherited type;
    279 hence the enumeration type may be omitted for the inheriting enumeration and it is inferred from the inherited enumeration, as for @Name3@.
    280 When inheriting from integral types, automatic numbering may be used, so the inheritance placement left to right is important.
    281 
    282 Specifically, the inheritance relationship for Names is:
    283 \begin{lstlisting}
    284 Name $\(\subset\)$ Name2 $\(\subset\)$ Name3 $\(\subset\)$ const char *         // enum type of Name
    285 \end{lstlisting}
    286 For the given function prototypes, the following calls are valid.
    287 \begin{cquote}
    288 \begin{tabular}{ll}
    289 \begin{lstlisting}
    290 void f( Name );
    291 void g( Name2 );
    292 void h( Name3 );
    293 void j( const char * );
    294 \end{lstlisting}
    295 &
    296 \begin{lstlisting}
    297 f( Fred );
    298 g( Fred );   g( Jill );
    299 h( Fred );   h( Jill );   h( Sue );
    300 j( Fred );   j( Jill );   j( Sue );   j( "Will" );
    301 \end{lstlisting}
    302 \end{tabular}
    303 \end{cquote}
    304 Note, the validity of calls is the same for call-by-reference as for call-by-value, and const restrictions are the same as for other types.
     177\begin{lstlisting}[label=lst:color]
     178enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$'  };
     179enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642  }; // mass
     180enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue"  };
     181enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection
     182\end{lstlisting}
     183The 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}).
     185
     186% An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name.
     187% The label can be retrieved by calling the function @label( <enum_instance> )@.
     188% Similarly, the @value()@ function returns the value used to initialize the \CFA-enum.
    305189
    306190\subsection{Enumerator Scoping}
     
    336220Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter.
    337221Therefore, 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.
    338 
    339 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name.
    340 % The label can be retrieved by calling the function @label( <enum_instance> )@.
    341 % Similarly, the @value()@ function returns the value used to initialize the \CFA-enum.
    342222
    343223\subsubsection{\lstinline{enumerate()}}
     
    1046926
    1047927\section{Related Work}
    1048 \label{s:RelatedWork}
    1049 
    1050 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and the algebraic data-type in functional programming.
    1051 There are a large set of overlapping features among these languages, but each language has its own unique restrictions and extensions.
    1052 
    1053 \subsection{(Free) Pascal}
    1054 
    1055 Free Pascal is a modern object-oriented version of the classic Pascal programming language.
    1056 It allows a C-style enumeration type, where enumerators must be in assigned in ascending numerical order with a constant expression and the range can be non-consecutive.
    1057 \begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}]
    1058 Type EnumType = ( one, two, three, forty @= 40@, fortyone );
    1059 \end{lstlisting}
    1060 Pseudo-functions @Pred@ and @Succ@ can only be used if the range is consecutive.
    1061 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.
    1062 The size underlying integral type can be explicitly specified using compiler directive @$PACKENUM@~$N$, where $N$ is the number of bytes, e.g.:
    1063 \begin{lstlisting}[language=pascal,{moredelim=**[is][\color{red}]{@}{@}}]
    1064 Type @{$\color{red}\$$PACKENUM 1}@ SmallEnum = ( one, two, three );
    1065             @{$\color{red}\$$PACKENUM 4}@ LargeEnum = ( BigOne, BigTwo, BigThree );
    1066 Var S : SmallEnum; { 1 byte }
    1067           L : LargeEnum; { 4 bytes}
    1068 \end{lstlisting}
    1069 
     928
     929Enumerations 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.
     930There 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}
    1070933
    1071934\subsection{Ada}
    1072935
    1073 An enumeration type is defined as a list of possible values:
    1074 \begin{lstlisting}[language=ada]
    1075 type RGB is (Red, Green, Blue);
    1076 \end{lstlisting}
    1077 Like for numeric types, where e.g., 1 is an integer literal, @Red@, @Green@ and @Blue@ are called the literals of this type.
    1078 There are no other values assignable to objects of this type.
    1079 
    1080 \paragraph{Operators and attributes} ~\newline
    1081 Apart from equality (@"="@), the only operators on enumeration types are the ordering operators: @"<"@, @"<="@, @"="@, @"/="@, @">="@, @">"@, where the order relation is given implicitly by the sequence of literals:
    1082 Each literal has a position, starting with 0 for the first, incremented by one for each successor.
    1083 This position can be queried via the @'Pos@ attribute; the inverse is @'Val@, which returns the corresponding literal. In our example:
    1084 \begin{lstlisting}[language=ada]
    1085 RGB'Pos (Red) = 0
    1086 RGB'Val (0)   = Red
    1087 \end{lstlisting}
    1088 There are two other important attributes: @Image@ and @Value@.
    1089 @Image@ returns the string representation of the value (in capital letters), @Value@ is the inverse:
    1090 \begin{lstlisting}[language=ada]
    1091 RGB'Image ( Red ) = "RED"
    1092 RGB'Value ("Red") =  Red
    1093 \end{lstlisting}
    1094 These attributes are important for simple IO (there are more elaborate IO facilities in @Ada.Text_IO@ for enumeration types).
    1095 Note that, since Ada is case-insensitive, the string given to @'Value@ can be in any case.
    1096 
    1097 \paragraph{Enumeration literals} ~\newline
    1098 Literals are overloadable, i.e. you can have another type with the same literals.
    1099 \begin{lstlisting}[language=ada]
    1100 type Traffic_Light is (Red, Yellow, Green);
    1101 \end{lstlisting}
    1102 Overload resolution within the context of use of a literal normally resolves which @Red@ is meant.
    1103 Only if you have an unresolvable overloading conflict, you can qualify with special syntax which @Red@ is meant:
    1104 \begin{lstlisting}[language=ada]
    1105 RGB'(Red)
    1106 \end{lstlisting}
    1107 Like many other declarative items, enumeration literals can be renamed.
    1108 In fact, such a literal is actually a function, so it has to be renamed as such:
    1109 \begin{lstlisting}[language=ada]
    1110 function Red return P.RGB renames P.Red;
    1111 \end{lstlisting}
    1112 Here, @RGB@ is assumed to be defined in package @P@, which is visible at the place of the renaming declaration.
    1113 Renaming makes @Red@ directly visible without necessity to resort the use-clause.
    1114 
    1115 Note that redeclaration as a function does not affect the staticness of the literal.
    1116 
    1117 \paragraph{Characters as enumeration literals} ~\newline
    1118 Rather unique to Ada is the use of character literals as enumeration literals:
    1119 \begin{lstlisting}[language=ada]
    1120 type ABC is ('A', 'B', 'C');
    1121 \end{lstlisting}
    1122 This literal @'A'@ has nothing in common with the literal @'A'@ of the predefined type @Character@ (or @Wide_Character@).
    1123 
    1124 Every type that has at least one character literal is a character type.
    1125 For every character type, string literals and the concatenation operator @"&"@ are also implicitly defined.
    1126 \begin{lstlisting}[language=ada]
    1127 type My_Character is (No_Character, 'a', Literal, 'z');
    1128 type My_String is array (Positive range <>) of My_Character;
    1129 
    1130 S: My_String := "aa" & Literal & "za" & 'z';
    1131 T: My_String := ('a', 'a', Literal, 'z', 'a', 'z');
    1132 \end{lstlisting}
    1133 In this example, @S@ and @T@ have the same value.
    1134 
    1135 Ada's @Character@ type is defined that way.
    1136 See Ada Programming/Libraries/Standard.
    1137 
    1138 \paragraph{Booleans as enumeration literals} ~\newline
    1139 Also Booleans are defined as enumeration types:
    1140 \begin{lstlisting}[language=ada]
    1141 type Boolean is (False, True);
    1142 \end{lstlisting}
    1143 There is special semantics implied with this declaration in that objects and expressions of this type can be used as conditions.
    1144 Note that the literals @False@ and @True@ are not Ada keywords.
    1145 
    1146 Thus it is not sufficient to declare a type with these literals and then hope objects of this type can be used like so:
    1147 \begin{lstlisting}[language=ada]
    1148 type My_Boolean is (False, True);
    1149 Condition: My_Boolean;
    1150 
    1151 if Condition then -- wrong, won't compile
    1152 \end{lstlisting}
    1153 
    1154 If you need your own Booleans (perhaps with special size requirements), you have to derive from the predefined Boolean:
    1155 \begin{lstlisting}[language=ada]
    1156 type My_Boolean is new Boolean;
    1157 Condition: My_Boolean;
    1158 
    1159 if Condition then -- OK
    1160 \end{lstlisting}
    1161 
    1162 \paragraph{Enumeration subtypes} ~\newline
    1163 You can use range to subtype an enumeration type:
    1164 \begin{lstlisting}[language=ada]
    1165 subtype Capital_Letter is Character range 'A' .. 'Z';
    1166 type Day_Of_Week is (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
    1167 subtype Working_Day is Day_Of_Week range Monday .. Friday;
    1168 \end{lstlisting}
    1169 
    1170 \paragraph{Using enumerations} ~\newline
    1171 Enumeration types being scalar subtypes, type attributes such as @First@ and @Succ@ will allow stepping through a subsequence of the values.
    1172 \begin{lstlisting}[language=ada]
    1173 case Day_Of_Week'First is
    1174         when Sunday =>
    1175            ISO (False);
    1176         when Day_Of_Week'Succ(Sunday) =>
    1177            ISO (True);
    1178         when Tuesday .. Saturday =>
    1179            raise Program_Error;
    1180 end case;
    1181 \end{lstlisting}
    1182 A loop will automatically step through the values of the subtype's range.
    1183 Filtering week days to include only working days with an even position number:
    1184 \begin{lstlisting}[language=ada]
    1185         for Day in Working_Day loop
    1186                 if Day_Of_Week'Pos(Day) mod 2 = 0 then
    1187                         Work_In_Backyard;
    1188                 end if;
    1189         end loop;
    1190 \end{lstlisting}
    1191 Enumeration types can be used as array index subtypes, yielding a table feature:
    1192 \begin{lstlisting}[language=ada]
    1193 type Officer_ID is range 0 .. 50;
    1194 type Schedule is array (Working_Day) of Officer_ID;
    1195 \end{lstlisting}
    1196 
    1197 \begin{lstlisting}[language=ada]
    1198 type Subtype_Name is (Id1, Id2, Id3 ... );
    1199 \end{lstlisting}
    1200 where @Id1@, @Id2@, etc. are identifiers or characters literals.
    1201 In either case, the legal values of the type are referred to as "enumeration literals."
    1202 Each of these values has a "position number" corresponding to its position in the list such that @Id1@ has position 0, @Id2@ has position 1, and the Nth value has position N-1.
    1203 
    1204 \paragraph{Attributes of Enumeration Types} ~\newline
    1205 An enumeration type, @T@, has the following attributes: @T'First@, @T'Last@, @T'Range@, @T'Pred@, @T'Succ@, @T'Min@, @T'Max@, @T'Image@, @T'Wide_Image@, @T'Value@, @T'Wide_Value@, @T'Pos@, and @T'Val@ (pronounced "T tick first", "T tick last", etc.).
    1206 Most of these are illustrated in the example program given below, and most of them produce what you would intuitively expect based on their names.
    1207 
    1208 @T'Image@ and @T'Value@ form a complementary pair of attributes.
    1209 The former takes a value in @T@ and returns a String representation of that value.
    1210 The latter takes a @String@ that is a representation of a value in @T@ and returns that value.
    1211 
    1212 @T'Pos@ and @T'Val@ form another complementary pair.
    1213 The former takes a value in @T@ and returns its position number.
    1214 The latter takes a position number and returns the corresponding value of type @T@.
    1215 
    1216 
    1217936\subsection{\Csharp}
    1218937
    1219938\subsection{\CC}
    1220939
    1221 \CC is backwards compatible with C, so it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration;
    1222 hence, the values in a \CC enumeration can only be its enumerators (without a cast).
    1223 There is no mechanism to iterate through an enumeration.
    1224 
    1225 \CC{11} added a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), so the enumerators are local to the enumeration and must be accessed using type qualification, e.g., @Weekday::Monday@.
     940Because \CC is backwards compatible with C, it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration;
     941hence, 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@.
    1226944\CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration.
    1227945
    1228 For both unscoped and scoped enumerations, 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.
    1229 In \CC{11}, the underlying integral type can be explicitly specified:
     946For 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.
     947The underlying integral type can be explicitly specified:
    1230948\begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]
    1231949enum class RGB : @long@ { Red, Green, Blue };
    1232950enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' };
    1233951enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 };
    1234 RGB colour1 = @RGB::@Red;
    1235 rgb colour2 = @rgb::@Red;
    1236 srgb colour3 = @srgb::@Red;
    1237952\end{lstlisting}
    1238953
  • src/GenPoly/Box.cpp

    r47bd204 ra55ebcc  
    2525#include "AST/GenericSubstitution.hpp" // for genericSubstitution
    2626#include "CodeGen/OperatorTable.h"     // for isAssignment
    27 #include "Common/Iterate.hpp"          // for group_iterate
    2827#include "Common/ScopedMap.h"          // for ScopedMap
    29 #include "Common/ToString.hpp"         // for toCString
    3028#include "Common/UniqueName.h"         // for UniqueName
     29#include "Common/utility.h"            // for toCString, group_iterate
    3130#include "GenPoly/FindFunction.h"      // for findFunction
    3231#include "GenPoly/GenPoly.h"           // for getFunctionType, ...
     
    237236        ) );
    238237        // TODO: Polymorphic types will be out of the struct declaration scope.
    239         // This breaks invariants until it is corrected later.
     238        // Should be removed by PolyGenericCalculator.
    240239        for ( auto const & member : enumerate( decl->members ) ) {
    241240                auto dwt = member.val.strict_as<ast::DeclWithType>();
     
    310309        ) );
    311310        // TODO: Polymorphic types will be out of the union declaration scope.
    312         // This breaks invariants until it is corrected later.
    313311        for ( auto const & member : decl->members ) {
    314312                auto dwt = member.strict_as<ast::DeclWithType>();
     
    577575                if ( adapters.contains( mangleName ) ) continue;
    578576                std::string adapterName = makeAdapterName( mangleName );
    579                 // NODE: This creates floating nodes, breaking invariants.
    580                 // This is corrected in the RewireAdapters sub-pass.
     577                // TODO: The forwarding here is problematic because these
     578                // declarations are not rooted anywhere in the translation unit.
    581579                adapters.insert(
    582580                        mangleName,
     
    641639
    642640        TypeVarMap exprTypeVars;
     641        // TODO: Should this take into account the variables already bound in
     642        // scopeTypeVars ([ex] remove them from exprTypeVars)?
    643643        makeTypeVarMap( function, exprTypeVars );
    644644        auto dynRetType = isDynRet( function, exprTypeVars );
     
    15211521
    15221522// --------------------------------------------------------------------------
     1523// TODO: Ideally, there would be no floating nodes at all.
    15231524/// Corrects the floating nodes created in CallAdapter.
    15241525struct RewireAdapters final : public ast::WithGuards {
     
    18361837
    18371838        // Not all members of a polymorphic type are themselves of a polymorphic
    1838         // type; in this case the member expression should be wrapped and
     1839        // type; in this cas the member expression should be wrapped and
    18391840        // dereferenced to form an lvalue.
    18401841        if ( !isPolyType( memberType, scopeTypeVars ) ) {
Note: See TracChangeset for help on using the changeset viewer.