Earlier I was fixing a lexer for my parser; now I have to create a validater for it. My idea was to convert the enumeration constants to strings by using the following preprocessor macro: #define MACRO_STRINGIFY(x) #x
.
Then I made a function to compare various token values lactually, I made three, but they are all the same with a few minor changes):
unsigned int compare_keyword( enum script_keywords keyword, char *token ) {
char *temporary = MACRO_STRINGIFY( keyword );
unsigned int i = 0;
for (; i < (strlen( "KEYWORD_" ) + 1); i++) {
++temporary;
}
// 0 on match, 1 on no match
return strcmp( temporary, token ) ? 1 : 0;
}
Now, this function works absolutely fine... when keyword is the enumeration constant:
void test() {
printf( "\nIF is " );
// Finish the sentence based on the return value
compare_keyword( KEYWORD_IF, "IF" ) ? printf( "not a keyword.\n" ) : printf( "a keyword.\n" );
}
test(); //--> Outputs 'IF is a keyword' like expected.
On the other hand, the function does not work as intended if I pass a value like 1 (the value which the symbolic enumeration constant KEYWORD_IF resolves to.):
// Same as last time with one edit:
void test() {
/* See above code with following change on line 4 */
compare_keyword( 1, "IF" ) /* etc... */
/* Rest of code from previous test */
}
test(); //--> Outputs 'IF is not a keyword' even if KEYWORD_IF resolves to the value 1.
The point I'm getting across here is that the preproccessor is very literal, and I would much prefer using a for loop to loop through the constants efficiently without bloating the code size (which is what would happen if I end up using enumeration constants). Therefore, the question is how can I convert plain integer values to their symbolic names without using switch…case…
or if…else…
?
Edit: Enumeration Details:
enum script_keywords {
KEYWORD_IF = 1,
KEYWORD_THEN = 2,
KEYWORD_ELSEIF = 3,
KEYWORD_ELSE = 4,
KEYWORD_ENDIF = 5,
KEYWORD_FOR = 6,
KEYWORD_TO = 7,
KEYWORD_STEP = 8,
KEYWORD_EXITFOR = 9,
KEYWORD_NEXT = 10,
KEYWORD_LOOP = 11,
KEYWORD_WHILE = 12,
KEYWORD_EXITLOOP = 13,
KEYWORD_ENDLOOP = 14,
KEYWORD_DO = 15,
KEYWORD_EXITDO = 16,
KEYWORD_UNTIL = 17,
KEYWORD_ON = 18,
KEYWORD_GOTO = 19,
KEYWORD_CALL = 20,
KEYWORD_LET = 21,
KEYWORD_DIM = 22,
KEYWORD_AS = 23
};