Changes in / [5c27b6a:c5c123f]
- Files:
-
- 5 edited
-
doc/theses/jiada_liang_MMath/CFAenum.tex (modified) (10 diffs)
-
doc/theses/jiada_liang_MMath/background.tex (modified) (5 diffs)
-
doc/theses/jiada_liang_MMath/intro.tex (modified) (1 diff)
-
doc/theses/jiada_liang_MMath/relatedwork.tex (modified) (6 diffs)
-
src/Parser/parser.yy (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r5c27b6a rc5c123f 4 4 \CFA supports C enumeration using the same syntax and semantics for backwards compatibility. 5 5 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 6 Any enumeration extensions must be intuitive to C programmers both in syntax and semantics. 7 The following sections detail all of my new contributions to enumerations in \CFA. 8 9 10 \section{Aliasing} 11 12 C already provides @const@-style aliasing using the unnamed enumerator \see{\VRef{s:TypeName}}, even if the name @enum@ is misleading (@const@ would be better). 13 Given the existence of this form, it is straightforward to extend it with types other than integers. 14 \begin{cfa} 15 enum E { Size = 20u, PI = 3.14159L, Jack = L"John" }; 16 \end{cfa} 17 which matches with @const@ aliasing in other programming languages. 18 Here, the type of the enumerator is the type of the initialization constant, \eg @typeof(20u)@ for @Size@ implies @unsigned int@. 19 Auto-initialization is restricted to the case where all constants are @int@, matching with C. 20 As seen in \VRef{s:EnumeratorTyping}, this feature is just a shorthand for multiple typed-enumeration declarations. 21 22 23 \section{Enumerator Unscoping} 24 \label{s:EnumeratorUnscoping} 25 26 In C, unscoped enumerators presents a \Newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names. 27 There is no mechanism in C to resolve these naming conflicts other than renaming one of the duplicates, which may be impossible. 6 7 8 \section{Enumerator Name Resolution} 9 \label{s:EnumeratorNameResolution} 10 11 In C, unscoping of enumerators presents a \Newterm{naming problem} when multiple enumeration types appear in the same scope with duplicate enumerator names. 12 There is no mechanism in C to resolve these naming conflicts other than renaming of one of the duplicates, which may be impossible. 28 13 29 14 The \CFA type-system allows extensive overloading, including enumerators. 30 15 Furthermore, \CFA uses the left-hand of assignment in type resolution to pinpoint the best overloaded name. 31 Finally, qualification and casting areprovided to disambiguate any ambiguous situations.16 Finally, qualification is provided to disambiguate any ambiguous situations. 32 17 \begin{cfa} 33 18 enum E1 { First, Second, Third, Fourth }; 34 enum E2 { @Fourth@, @Third@, @Second@, @First@ }; $\C{// same enumerator names}$19 enum E2 { @Fourth@, @Third@, @Second@, @First@ }; 35 20 E1 p() { return Third; } $\C{// correctly resolved duplicate names}$ 36 21 E2 p() { return Fourth; } 37 22 void foo() { 38 E1 e1 = First; E2 e2 = First; $\C{// initialization}$39 e1 = Second; e2 = Second; $\C{// assignment}$40 e1 = p(); e2 = p(); $\C{// function call}$23 E1 e1 = First; E2 e2 = First; 24 e1 = Second; e2 = Second; 25 e1 = p(); e2 = p(); $\C{// correctly resolved function call}$ 41 26 int i = @E1.@First + @E2.@First; $\C{// disambiguate with qualification}$ 42 27 int j = @(E1)@First + @(E2)@First; $\C{// disambiguate with cast}$ … … 44 29 \end{cfa} 45 30 \CFA overloading allows programmers to use the most meaningful names without fear of name clashes from include files. 46 In most cases, the type system implicitly disambiguates, otherwisethe programmer explicitly disambiguates using qualification or casting.31 Either the type system implicitly disambiguates or the programmer explicitly disambiguates using qualification or casting. 47 32 48 33 49 34 \section{Enumerator Scoping} 50 35 51 An enumeration can be scoped, using @'!'@, so the enumerator constants are not projected into the enclosing scope.52 \begin{cfa} 53 enum Week @!@ { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun };36 An enumeration can be scoped, so the enumerator constants are not projected into the enclosing scope, using @'!'@. 37 \begin{cfa} 38 enum Weekday @!@ { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun }; 54 39 enum RGB @!@ { Red, Green, Blue }; 55 40 \end{cfa} 56 41 Now the enumerators \emph{must} be qualified with the associated enumeration. 57 42 \begin{cfa} 58 Week week = @Week.@Mon;59 week = @Week.@Sat;60 RGB rgb = @RGB.@Red;61 rgb = @RGB.@Blue;43 Weekday weekday = @Weekday@.Mon; 44 weekday = @Weekday@.Sat; 45 RGB rgb = RGB.Red; 46 rgb = RGB.Blue; 62 47 \end{cfa} 63 48 It is possible to toggle back to unscoping using the \CFA @with@ clause/statement (see also \CC \lstinline[language=c++]{using enum} in Section~\ref{s:C++RelatedWork}). 64 49 \begin{cfa} 65 with ( @Week @, @RGB@ ) { $\C{// type names}$66 week = @Sun@;$\C{// no qualification}$50 with ( @Weekday@, @RGB@ ) { $\C{// type names}$ 51 weekday = @Sun@; $\C{// no qualification}$ 67 52 rgb = @Green@; 68 53 } 69 54 \end{cfa} 70 As in Section~\ref{s:EnumeratorUnscoping}, opening multiple scoped enumerations in a @with@ can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handles ambiguities. 71 72 73 \section{Enumeration Pseudo-functions} 74 75 Pseudo-functions are function-like operators that do not result in any run-time computations, \ie like @sizeof@, @alignof@, @typeof@. 76 A pseudo-function call is often substituted with information extracted from the compilation symbol-table, like storage size or alignment associated with the underlying architecture. 77 78 The attributes of an enumerator are accessed by pseudo-functions @posE@, @valueE@, and @labelE@. 79 \begin{cfa} 80 int jane_pos = @posE@( Names.Jane ); $\C{// 2}$ 81 char * jane_value = @valueE@( Names.Jane ); $\C{// "JANE"}$ 82 char * jane_label = @labelE@( Names.Jane ); $\C{// "Jane"}$ 83 sout | posE( Names.Jane) | labelE( Names.Jane ) | valueE( Names.Jane ); 84 \end{cfa} 85 Note the ability to print all of an enumerator's properties. 86 55 As in Section~\ref{s:EnumeratorNameResolution}, opening multiple unscoped enumerations can result in duplicate enumeration names, but \CFA implicit type resolution and explicit qualification/casting handles name resolution. 87 56 88 57 \section{Enumerator Typing} 89 \label{s:EnumeratorTyping}90 58 91 59 \CFA extends the enumeration declaration by parameterizing with a type (like a generic type), allowing enumerators to be assigned any values from the declared type. 92 60 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 enumerator constants. 93 61 Note, the synonyms @Liz@ and @Beth@ in the last declaration. 94 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 96 C has an implicit type conversion from an enumerator to its base type @int@. 97 Correspondingly, \CFA has an implicit (safe) conversion from a typed enumerator to its base type. 62 63 Because enumerators are constants, the enumeration type is implicitly @const@, so all the enumerator types in Figure~\ref{f:EumeratorTyping} are rewritten with @const@. 64 A typed enumeration has an implicit (safe) conversion to its base type. 98 65 \begin{cfa} 99 66 char currency = Dollar; … … 133 100 struct Person { char * name; int age, height; }; 134 101 @***@enum( @Person@ ) friends { @Liz@ = { "ELIZABETH", 22, 170 }, @Beth@ = Liz, 135 Jon = { "JONATHAN", 35, 190 } };102 Jon = { "JONATHAN", 35, 190 } }; 136 103 \end{cfa} 137 104 \caption{Enumerator Typing} … … 139 106 \end{figure} 140 107 141 An advantage of the typed enumerations is eliminating the \emph{harmonizing} problem between an enumeration and companion data \see{\VRef{s:Usage}}: 108 Typed enumerations deals with the \emph{harmonizing} problem between an enumeration and any companion data. 109 The following example is from the \CFA compiler, written in \CC. 110 \begin{cfa} 111 enum integral_types { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 112 char * integral_names[NO_OF_ITYPES] = { 113 "char", "signed char", "unsigned char", 114 "signed short int", "unsigned short int", 115 "signed int", "unsigned int", 116 ... 117 }; 118 \end{cfa} 119 The \emph{harmonizing} problem occurs because the enumeration declaration is in one header file and the names are declared in another translation unit. 120 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). 121 The typed enumeration largely solves this problem by combining and managing the two data types. 142 122 \begin{cfa} 143 123 enum( char * ) integral_types { … … 155 135 156 136 137 \section{Pure Enumerators} 138 139 An empty enumerator type, @enum()@, implies the enumerators are opaque symbols without values but set properties; 140 hence, there is no default conversion to @int@. 141 142 \begin{cfa} 143 enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND }; 144 Mode iomode = O_RDONLY; 145 bool b = iomode == O_RDONLY || iomode < O_APPEND; $\C{// ordering}$ 146 @***@@int i = iomode;@ $\C{// disallow conversion to int}$ 147 \end{cfa} 148 149 \section{Enumerator Subset} 150 151 If follows from enumerator typing that the enumerator type can be another enumerator. 152 \begin{cfa} 153 enum( @char@ ) Currency { Dollar = '$\textdollar$', Cent = '$\textcent$', Yen = '$\textyen$', Pound = '$\textsterling$', Euro = 'E' }; 154 enum( Currency ) Europe { Euro = Currency.Euro, Pound = Currency.Pound }; 155 enum( char ) Letter { A = 'A', B = 'B', C = 'C', ..., Z = 'Z' }; 156 enum( @Letter@ ) Greek { Alph = A, Beta = B, ..., Zeta = Z }; // intersection 157 \end{cfa} 158 Subset enumerations may have more or less enumerators than their typed enumeration, but the enumerator values must be from the typed enumeration. 159 For example, @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@. 160 \begin{cfa} 161 Letter letter = A; 162 Greak greek = Beta; 163 letter = Beta; $\C{// allowed, greek == B}$ 164 @greek = A;@ $\C{// disallowed}$ 165 \end{cfa} 166 167 157 168 \section{Enumeration Inheritance} 158 169 … … 187 198 g( Fred ); g( Jill ); 188 199 h( Fred ); h( Jill ); h( Sue ); 189 j( Fred ); j( Jill ); j( Sue );j( "WILL" );200 j( Fred ); j( Jill ); j( Sue ); j( "WILL" ); 190 201 \end{cfa} 191 202 \end{tabular} … … 194 205 195 206 196 \section{Enumerator Control Structures} 207 \section{Enumeration Pseudo-functions} 208 209 Pseudo-functions are function-like operators that do not result in any run-time computations, \ie like @sizeof@, @offsetof@, @typeof@. 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 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 213 \begin{cfa} 214 @***@int jane_pos = @position@( Names.Jane ); $\C{// 2}$ 215 @***@char * jane_value = @value@( Names.Jane ); $\C{// "JANE"}$ 216 @***@char * jane_label = @label@( Names.Jane ); $\C{// "Jane"}$ 217 sout | @label@( Names.Jane ) | @value@( Names.Jane ); 218 \end{cfa} 219 Note the ability to print both enumerator label and value. 220 221 222 \section{Enumerator Position or Value} 197 223 198 224 Enumerators can be used in multiple contexts. … … 255 281 256 282 257 @if@ statement258 259 @switch@ statement260 261 looping statements262 263 264 283 \section{Planet Example} 265 284 266 \VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating mostof the \CFA enumeration features.285 \VRef[Figure]{f:PlanetExample} shows an archetypal enumeration example illustrating all of the \CFA enumeration features. 267 286 Enumeration @Planet@ is a typed enumeration of type @MR@. 268 287 Each of the planet enumerators is initialized to a specific mass/radius, @MR@, value. … … 274 293 struct MR { double mass, radius; }; 275 294 enum( MR ) Planet { 276 // mass (kg) radius (km)277 MERCURY = { 0.330_E24, 2.4397_E6 },278 VENUS = { 4.869_E24, 6.0518_E6 },295 // mass radius 296 MERCURY = { 3.303_E23, 2.4397_E6 }, 297 VENUS = { 4.869_E24, 6.0518_E6 }, 279 298 EARTH = { 5.976_E24, 6.3781_E6 }, 280 MOON = { 7.346_E22, 1.7380_E6 }, $\C{// not a planet}$ 281 MARS = { 0.642_E24, 3.3972_E6 }, 282 JUPITER = { 1898._E24, 71.492_E6 }, 283 SATURN = { 568.8_E24, 60.268_E6 }, 284 URANUS = { 86.86_E24, 25.559_E6 }, 285 NEPTUNE = { 102.4_E24, 24.746_E6 }, 299 MARS = { 6.421_E23, 3.3972_E6 }, 300 JUPITER = { 1.898_E27, 7.1492_E7 }, 301 SATURN = { 5.688_E26, 6.0268_E7 }, 302 URANUS = { 8.686_E25, 2.5559_E7 }, 303 NEPTUNE = { 1.024_E26, 2.4746_E7 }, 286 304 }; 287 enum( double ) { G = 6.6743E-11 }; $\C{// universal gravitational constant (m3 kg-1 s-2)}$305 enum( double ) { G = 6.6743E-11 }; // universal gravitational constant (m3 kg-1 s-2) 288 306 289 307 static double surfaceGravity( Planet p ) with( p ) { … … 298 316 double mass = earthWeight / surfaceGravity( EARTH ); 299 317 for ( p; Planet ) { 300 sout | "Your weight on" | labelE(p) | "is" | wd(1,1, surfaceWeight( p, mass )) | "kg";318 sout | "Your weight on" | labelE(p) | "is" | surfaceWeight( p, mass ); 301 319 } 302 320 } 303 304 $\$$ planet 100305 Your weight on MERCURY is 37.7 kg306 Your weight on VENUS is 90.5 kg307 Your weight on EARTH is 100.0 kg308 Your weight on MOON is 16.6 kg309 Your weight on MARS is 37.9 kg310 Your weight on JUPITER is 252.8 kg311 Your weight on SATURN is 106.6 kg312 Your weight on URANUS is 90.5 kg313 Your weight on NEPTUNE is 113.8 kg314 321 \end{cfa} 315 322 \caption{Planet Example} -
doc/theses/jiada_liang_MMath/background.tex
r5c27b6a rc5c123f 1 1 \chapter{Background} 2 2 3 \CFA is a backwards-compatible extension of the C programming language , therefore, it must support C-style enumerations.4 The following covers C enumerations.3 \CFA is a backwards-compatible extension of the C programming language. 4 Therefore, it must support C-style enumerations and any enumeration extensions must be intuitive to C programmers both in syntax and semantics. 5 5 6 As discussed in \VRef{s:Aliasing}, it is common for C programmers to ``believe'' there are three equivalent forms of named constants.6 It is common for C programmers to ``believe'' there are three equivalent forms of named constants. 7 7 \begin{clang} 8 8 #define Mon 0 … … 13 13 \item 14 14 For @#define@, the programmer has to explicitly manage the constant name and value. 15 Furthermore, these C preprocessor macro names are outside of the C type-system and can incorrectly change random text in a program.15 Furthermore, these C preprocessor macro names are outside of the C type-system, and hence cannot be overloaded, and can incorrectly change random text in a program. 16 16 \item 17 17 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{ … … 22 22 \end{clang} 23 23 \item 24 Only the @enum@ form is managed by the compiler, is part of the language type-system, works in all C constant-expression locations, and might not occupy storage..24 Only the @enum@ form is managed by the compiler, is part of the language type-system, and works in all C constant-expression locations. 25 25 \end{enumerate} 26 26 27 27 28 28 \section{C \lstinline{const}} 29 \label{s:Cconst}30 29 31 C can simulate the aliasing @const@ declarations \see{\VRef{s:Aliasing}}, with static and dynamic initialization.30 As noted, C has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization. 32 31 \begin{clang} 33 static const int one = 0 + 1; $\C{// static in itialization}$32 static const int one = 0 + 1; $\C{// static intialization}$ 34 33 static const void * NIL = NULL; 35 34 static const double PI = 3.14159; … … 39 38 Sat = Fri + 1, Sun = Sat + 1; 40 39 void foo() { 41 const int r = random() % 100;$\C{// dynamic intialization}$42 int va[r]; $\C{// VLA, autoscope only}$40 const int r = random(); $\C{// dynamic intialization}$ 41 int sa[Sun]; $\C{// VLA, local scope only}$ 43 42 } 44 43 \end{clang} 45 44 Statically initialized identifiers may appear in any constant-expression context, \eg @case@. 46 Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays on the stack. 47 Again, this form of aliasing to primary constant is not an enumeration. 45 Dynamically initialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays. 48 46 49 47 … … 65 63 \end{clang} 66 64 The terms \emph{enumeration} and \emph{enumerator} used in this work \see{\VRef{s:Terminology}} come from the grammar. 67 The C enumeration semantics arediscussed using examples.65 The C enumeration semantics is discussed using examples. 68 66 67 An unnamed enumeration is used to provide secondary renaming, like a @const@ declaration in other languages. 68 \begin{clang} 69 enum { Size = 20, Pi = 3.14159 }; // unnamed enumeration $\(\Rightarrow\)$ no ordering 70 \end{clang} 71 This declaration form is not an enumeration even though it is declared using an @enum@ because it has none of the following enumeration properties. 69 72 70 \subsection{Type Name} 71 \label{s:TypeName} 73 A \emph{named} enumeration type is an actual enumeration. 74 \begin{clang} 75 enum Weekday { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun, }; 76 \end{clang} 77 Enumerators without an explicitly designated constant value are \Newterm{auto-initialized} by the compiler: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 78 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@. 79 Initialization may occur in any order. 80 \begin{clang} 81 enum Weekday { Thu@ = 10@, Fri, Sat, Sun, Mon@ = 0@, Tue, Wed }; 82 \end{clang} 83 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma. 84 \begin{clang} 85 enum Weekday { 86 Thu = 10, Fri, Sat, Sun, 87 Mon = 0, Tue, Wed@,@ // terminating comma 88 }; 89 \end{clang} 90 This feature allow enumerator lines to be interchanged without moving a comma.\footnote{ 91 A terminating comma appears in other C syntax, \eg the initializer list.} 92 Finally, C enumerators are \Newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type. 72 93 73 An \emph{unnamed} enumeration is used to provide aliasing \see{\VRef{s:Aliasing}} exactly like a @const@ declaration in other languages. 74 However, it is restricted to integral values. 94 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerated values. 95 In practice, since integral constants are used, which have type @int@ (unless qualified with a size suffix), C uses @int@ as the underlying type for enumeration variables. 96 Finally, there is an implicit bidirectional conversion between an enumeration and its integral type. 75 97 \begin{clang} 76 enum { Size = 20, Max = 10, MaxPlus10 = Max + 10, Max10Plus1, Fred = -7 }; 98 { 99 enum Weekday { /* as above */ }; $\C{// enumerators implicitly projected into local scope}$ 100 Weekday weekday = Mon; $\C{// weekday == 0}$ 101 weekday = Fri; $\C{// weekday == 11}$ 102 int i = Sun; $\C{// implicit conversion to int, i == 13}$ 103 weekday = 10000; $\C{// UNDEFINED! implicit conversion to Weekday}$ 104 } 105 int j = Wed; $\C{// ERROR! Wed is not declared in this scope}$ 77 106 \end{clang} 78 Here, the aliased constants are: 20, 10, 20, 21, and -7. 79 Direct initialization is by a compile-time expression generating a constant value. 80 An enumerator without initialization is \Newterm{auto-initialized}: from left to right, starting at zero or the next explicitly initialized constant, incrementing by @1@. 81 Because multiple independent enumerators can be combined, enumerators with the same values can occur. 82 The enumerators are rvalues, so assignment is disallowed. 83 Finally, enumerators are \Newterm{unscoped}, \ie enumerators declared inside of an @enum@ are visible (projected) into the enclosing scope of the @enum@ type. 84 For unnamed enumeration this semantic is required because there is no type name for scoped qualification. 85 86 As noted, this kind of aliasing declaration is not an enumeration, even though it is declared using an @enum@ in C. 87 While the semantics is misleading, this enumeration form matches with aggregate types: 88 \begin{cfa} 89 typedef struct /* unnamed */ { ... } S; 90 struct /* unnamed */ { ... } x, y, z; $\C{// questionable}$ 91 struct S { 92 union /* unnamed */ { $\C{// unscoped fields}$ 93 int i; double d ; char ch; 94 }; 95 }; 96 \end{cfa} 97 Hence, C programmers would expect this enumeration form to exist in harmony with the aggregate form. 98 99 A \emph{named} enumeration is an enumeration: 100 \begin{clang} 101 enum @Week@ { Mon, Tue, Wed, Thu@ = 10@, Fri, Sat, Sun }; 102 \end{clang} 103 and adopts the same semantics with respect to direct and auto intialization. 104 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@. 105 As well, initialization may occur in any order. 106 \begin{clang} 107 enum Week { 108 Thu@ = 10@, Fri, Sat, Sun, 109 Mon@ = 0@, Tue, Wed@,@ }; // terminating comma 110 \end{clang} 111 Note, the comma in the enumerator list can be a terminator or a separator, allowing the list to end with a dangling comma.\footnote{ 112 A terminating comma appears in other C syntax, \eg the initializer list.} 113 This feature allow enumerator lines to be interchanged without moving a comma. 114 Named enumerators are also unscoped. 115 116 117 \subsection{Implementation} 118 119 In theory, a C enumeration \emph{variable} is an implementation-defined integral type large enough to hold all enumerator values. 120 In practice, C uses @int@ as the underlying type for enumeration variables, because of the restriction to integral constants, which have type @int@ (unless qualified with a size suffix). 121 122 123 \subsection{Usage} 124 \label{s:Usage} 125 126 C proves an implicit \emph{bidirectional} conversion between an enumeration and its integral type. 127 \begin{clang} 128 enum Week week = Mon; $\C{// week == 0}$ 129 week = Fri; $\C{// week == 11}$ 130 int i = Sun; $\C{// implicit conversion to int, i == 13}$ 131 @week = 10000;@ $\C{// UNDEFINED! implicit conversion to Week}$ 132 \end{clang} 133 While converting an enumerator to underlying type is useful, the implicit conversion from the base type to an enumeration type is a common source of error. 134 135 Enumerators can appear in @switch@ and looping statements. 136 \begin{cfa} 137 enum Week { Mon, Tue, Wed, Thu, Fri, Sat, Sun }; 138 switch ( week ) { 139 case Mon: case Tue: case Wed: case Thu: case Fri: 140 printf( "weekday\n" ); 141 case Sat: case Sun: 142 printf( "weekend\n" ); 143 } 144 for ( enum Week day = Mon; day <= Sun; day += 1 ) { 145 printf( "day %d\n", day ); // 0-6 146 } 147 \end{cfa} 148 For iterating, the enumerator values \emph{must} have a consecutive ordering with a fixed step between values. 149 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@. 150 For safety, \CC does not support the bidirectional conversion, and hence, an unsafe cast is necessary to increment @day@: @day = (Week)(day + 1)@. 151 152 There is a C idiom to automatically know the number of enumerators in an enumeration. 153 \begin{cfa} 154 enum E { A, B, C, D, @N@ }; // N == 4 155 for ( enum E e = A; e < @N@; e += 1 ) ... 156 \end{cfa} 157 Here, the auto-incrementing counts the number of enumerators and puts the total into the last enumerator @N@. 158 @N@ is often used as the dimension for an array assocated with the enumeration. 159 \begin{cfa} 160 E array[@N@]; 161 for ( enum E e = A; e < N; e += 1 ) { 162 array[e] = e; 163 } 164 \end{cfa} 165 However, for typed enumerations, \see{\VRef{f:EumeratorTyping}}, this idiom fails. 166 167 This idiom leads to another C idiom using an enumeration with matching companion information. 168 For example, an enumeration is linked with a companion array of printable strings. 169 \begin{cfa} 170 enum Integral_Type { chr, schar, uschar, sshort, ushort, sint, usint, ..., NO_OF_ITYPES }; 171 char * Integral_Name[@NO_OF_ITYPES@] = { 172 "char", "signed char", "unsigned char", 173 "signed short int", "unsigned short int", 174 "signed int", "unsigned int", ... 175 }; 176 enum Integral_Type integral_type = ... 177 printf( "%s\n", Integral_Name[@integral_type@] ); // human readable type name 178 \end{cfa} 179 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}. 180 The need to harmonize is at best indicated by a comment before the enumeration. 181 This issue is exacerbated if enumeration and companion array are in different translation units. 182 183 \bigskip 184 While C provides a true enumeration, it is restricted, has unsafe semantics, and does provide enumeration features in other programming languages. 107 The implicit conversion from @int@ to an enumeration type is an unnecessary source of error. -
doc/theses/jiada_liang_MMath/intro.tex
r5c27b6a rc5c123f 99 99 100 100 \subsection{Aliasing} 101 \label{s:Aliasing}102 101 103 102 Some languages provide simple secondary aliasing (renaming), \eg: -
doc/theses/jiada_liang_MMath/relatedwork.tex
r5c27b6a rc5c123f 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}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}.20 Enumeration types 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}, Java~\cite{Java}, Modula-3~\cite{Modula-3}, Rust~\cite{Rust}, Swift~\cite{Swift}, Python~\cite{Python}. 21 21 Among theses languages, there are a large set of overlapping features, but each language has its own unique extensions and restrictions. 22 22 … … 24 24 \label{s:Pascal} 25 25 26 Classic Pascal has the \lstinline[language= Pascal]{const} aliasingdeclaration binding a name to a constant literal/expression.26 Classic Pascal has the \lstinline[language=pascal]{const} declaration binding a name to a constant literal/expression. 27 27 \begin{pascal} 28 28 const one = 0 + 1; Vowels = set of (A,E,I,O,U); NULL = NIL; 29 29 PI = 3.14159; Plus = '+'; Fred = 'Fred'; 30 30 \end{pascal} 31 As stated, this mechanism is not an enumeration because there is no specific type (pseudo enumeration).31 This mechanism is not an enumeration because there is no specific type (pseudo enumeration). 32 32 Hence, there is no notion of a (possibly ordered) set, modulo the \lstinline[language=pascal]{set of} type. 33 33 The type of each constant name (enumerator) is inferred from the constant-expression type. … … 139 139 Ops : array( 0..3 ) of Operator; 140 140 Ops := @"+-*/"@; -- string assignment to array elements 141 Ops := "+-" @&@ "*/"; -- string concatenation and assignment141 Ops := @"+-" & "*/"@; -- string concatenation and assignment 142 142 \end{ada} 143 143 Ada's @Character@ type is defined as a character enumeration across all Latin-1 characters. … … 215 215 \label{s:C++RelatedWork} 216 216 217 \CC enumeration is largely backwards compatible with C, so it inherited C's enumerations with some modifications and additions. 218 219 \CC has aliasing using @const@ declarations, like C \see{\VRef{s:Cconst}}, with type inferencing, plus static/dynamic initialization. 220 (Note, a \CC @constexpr@ declaration is the same @const@ with the restriction that the initialization is a compile-time expression.) 217 \CC has the equivalent of Pascal typed @const@ declarations \see{\VRef{s:Pascal}}, with static and dynamic initialization. 221 218 \begin{c++} 222 const @auto@ one = 0 + 1;$\C{// static initialization}$223 const @auto@ NIL = nullptr;224 const @auto@PI = 3.14159;225 const @auto@Plus = '+';226 const @auto@Fred = "Fred";227 const @auto@Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1,219 const auto one = 0 + 1; $\C{// static initialization}$ 220 const auto NULL = nullptr; 221 const auto PI = 3.14159; 222 const auto Plus = '+'; 223 const auto Fred = "Fred"; 224 const auto Mon = 0, Tue = Mon + 1, Wed = Tue + 1, Thu = Wed + 1, Fri = Thu + 1, 228 225 Sat = Fri + 1, Sun = Sat + 1; 229 void foo() { 230 const @auto@ r = random(); $\C{// dynamic initialization}$ 231 int va[r]; $\C{// VLA, auto scope only}$ 232 } 226 int sa[Sun]; 227 const auto r = random(); $\C{// dynamic initialization}$ 228 int da[r]; $\C{// VLA}$ 233 229 \end{c++} 234 230 Statically initialized identifiers may appear in any constant-expression context, \eg @case@. 235 Dynamically in itialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays.236 Interestingly, global \CC @const@ declarations are implicitly marked @static@ (@r@ , read-only local, rather than @R@, read-only external)231 Dynamically intialized identifiers may appear as array dimensions in @g++@, which allows variable-sized arrays. 232 Interestingly, global \CC @const@ declarations are implicitly marked @static@ (@r@ rather than @R@). 237 233 \begin{c++} 238 234 $\$$ nm test.o 239 235 0000000000000018 @r@ Mon 240 236 \end{c++} 241 whereas C @const@ declarations without @static@ are marked @R@. 242 243 The following non-backwards compatible changes are made \see{\cite[\S~7.2]{ANSI98:C++}}. 237 238 \CC enumeration is largely backwards compatible with C, so it inherited C's enumerations. 239 However, the following non-backwards compatible changes are made. 240 244 241 \begin{cquote} 245 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type.242 7.2 Change: \CC objects of enumeration type can only be assigned values of the same enumeration type. 246 243 In C, objects of enumeration type can be assigned values of any integral type. \\ 247 244 Example: … … 257 254 258 255 \begin{cquote} 259 Change: In \CC, the type of an enumerator is its enumeration.256 7.2 Change: In \CC, the type of an enumerator is its enumeration. 260 257 In C, the type of an enumerator is @int@. \\ 261 258 Example: … … 272 269 Taking the size of an enumerator is not a common C coding practice. 273 270 \end{cquote} 271 274 272 Hence, the values in a \CC enumeration can only be its enumerators (without a cast). 275 273 While the storage size of an enumerator is up to the compiler, there is still an implicit cast to @int@. -
src/Parser/parser.yy
r5c27b6a rc5c123f 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Apr 27 16:23:14202413 // Update Count : 662 512 // Last Modified On : Tue Apr 23 15:39:29 2024 13 // Update Count : 6620 14 14 // 15 15 … … 1698 1698 1699 1699 with_statement: 1700 WITH '(' t ype_list ')' statement // support scoped enumeration1700 WITH '(' tuple_expression_list ')' statement 1701 1701 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); } 1702 1702 ; … … 3359 3359 // empty 3360 3360 { $$ = nullptr; forall = false; } 3361 | WITH '(' t ype_list ')' attribute_list_opt // support scoped enumeration3361 | WITH '(' tuple_expression_list ')' attribute_list_opt 3362 3362 { 3363 3363 $$ = $3; forall = false;
Note:
See TracChangeset
for help on using the changeset viewer.