Sunday, August 17, 2014

More Enumeration Classes

Several more enumerations were changed to enumeration classes.  While more of these included a size of enumerator, they were not being used.  This included the translator test mode, translator reference type, dictionary entry type, error list type, program model operation type, and the table multiple enumerations.  Two instances where the enum keyword was in front of the enumeration name were removed (this is something required for C but not C++).

This leaves several enumerations that are not as easy as adding the class keyword and renaming the enumerators like those changed above.  These include the code (auto-generated), token status (auto-generated), sub-code (bit masks), table flag (bit masks), table search type, token type, and test option enumerations.

The auto-generated enumerations need a good C++ solution and not the current kludgy C solution using an external awk script.  The bit mask enumerations will need operator functions implemented (bit-wise OR and AND), which will require using type casting.  For the others, the size of enumerators are used for either dimensioning arrays or for looping over the enumerators.

[branch cpp11 commit e71fe6f0fe]

Data Type As Enumeration Class

Now that the number of and size of enumerators of the data type enumeration have been removed, there was one more enumerator left that needed to be removed if possible, specifically the No_DataType enumerator that was assigned to a -1, which was used to indicate an unset data type.  If this enumerator was left in place, then switch statements would need to have a case for it or would need a blank default.

C++11 allows a default enumerator in the form EnumName{} just like for any other type.  For user types, it calls the default constructor (if there is one, else a compile error is reported).  For built in types, the value is assigned a zero.  And so is the case for a default enumerator, which also has the equivalent value of zero.  For unscoped enumerations, the value is zero, but for an enumeration class, the value can't be used as an integer without a cast.

Therefore, the No_DataType enumerator was replaced with the default enumerator DataType{}.  In addition, the first enumerator can't have the default value of zero, so was assigned to the value of one.  This is not an issue since data type enumerators are no longer used as indexes to array (only as keys to maps).  All of the Xx_DataType enumerators were changed to just Xx in the class enumeration definition and to DataType::Xx for all uses in the code since the enumerators are now scoped.

There was one remaining issue.  The test names awk script scanned the header file for the data type enumeration and created an array of C style strings with the names of the enumerator. As the string  This awk script generates the test names header file used in the test source file for converting enumerators to strings for test output.  The awk script was modified to instead look for the enumeration class and to generate an unordered map.  This code was put into a new function in the script.  This script also generates C style string arrays for the code and token type enumerations.  These will also be changed at some point.

[branch cpp11 commit 06ef6f17c5]

Size of Data Types Enumerator

The size of enumerator was removed but it was used for the dimension of two arrays.  Both of these arrays were two dimensional, so some sort of compound map would have been needed.  Instead, simple switch statements and conditional operators were used.  This should be nearly as efficient as an array as the compiler may generate a lookup table for a switch and this is not in highly critical code so absolute efficiency is not required.

The first array was used to obtain a conversion code needed to convert the data type in a token to the desired data type.  The conversion code obtained could be a null code representing no conversion needed or an invalid code representing a data type that can't be converted.

This array was used by the convert code and find code functions in the Table class.  The convert code function was modified to process the two data types directly using compound switch statements (the first on the token data type, and the second on the needed data type).  The find code function used the array for a data type in a token with the needed data type and so was changed to simply call the convert code function instead.

The second used of the size of enumerator was to dimension the an array used in the expected error status function of the Translator class.  This array was dimensioned for the number of data types and the number of reference types (none, variable, variable or defined function, or all) and used to obtain a token error status when a reference is expected but not found.  This function was changed to use a compound switch statement (the first on the data type, and the second on the reference type or the tertiary operator was used where a second switch was overkill).  The size of enumerator for the reference enumerator was only used for this array and was also removed.

[branch cpp11 commit 4183a87f74]