Implement simple macro expansion
- no longer generate CONSTANT lines for #defined constants - "#define FOO 1" turns "return FOO;" into "return 1;" - Macros expanding into a macro is not supported: #define FOO 1 #define BAR FOO will expand BAR to FOO, not to 1 - Expansion inside #if conditions is not supported. - Function-like macros are not supported.
This commit is contained in:
parent
a8551f2fcd
commit
09acd6253d
90
cc_macro.c
90
cc_macro.c
|
@ -33,6 +33,7 @@ struct macro_list
|
|||
{
|
||||
struct macro_list* next;
|
||||
char* symbol;
|
||||
struct token_list* expansion;
|
||||
};
|
||||
|
||||
struct macro_list* macro_env;
|
||||
|
@ -72,6 +73,44 @@ void eat_newline_tokens()
|
|||
}
|
||||
}
|
||||
|
||||
/* returns the first token inserted; inserts *before* point */
|
||||
struct token_list* insert_tokens(struct token_list* point, struct token_list* token)
|
||||
{
|
||||
struct token_list* copy;
|
||||
struct token_list* first = NULL;
|
||||
|
||||
while (NULL != token)
|
||||
{
|
||||
copy = calloc(1, sizeof(struct token_list));
|
||||
copy->s = token->s;
|
||||
copy->filename = token->filename;
|
||||
copy->linenumber = token->linenumber;
|
||||
|
||||
if(NULL == first)
|
||||
{
|
||||
first = copy;
|
||||
}
|
||||
|
||||
copy->next = point;
|
||||
|
||||
if (NULL != point)
|
||||
{
|
||||
copy->prev = point->prev;
|
||||
|
||||
if(NULL != point->prev)
|
||||
{
|
||||
point->prev->next = copy;
|
||||
}
|
||||
|
||||
point->prev = copy;
|
||||
}
|
||||
|
||||
token = token->next;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
struct macro_list* lookup_macro(struct token_list* token)
|
||||
{
|
||||
struct macro_list* hold = macro_env;
|
||||
|
@ -307,18 +346,10 @@ int macro_expression()
|
|||
|
||||
void handle_define()
|
||||
{
|
||||
int replace_with_constant = TRUE;
|
||||
struct macro_list* hold;
|
||||
struct token_list* expansion_end;
|
||||
|
||||
if (replace_with_constant)
|
||||
{
|
||||
macro_token->s = "CONSTANT";
|
||||
macro_token = macro_token->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
eat_current_token();
|
||||
}
|
||||
eat_current_token();
|
||||
|
||||
require(NULL != macro_token, "got an EOF terminated #define\n");
|
||||
require('\n' != macro_token->s[0], "unexpected newline after #define\n");
|
||||
|
@ -329,24 +360,31 @@ void handle_define()
|
|||
hold->next = macro_env;
|
||||
macro_env = hold;
|
||||
|
||||
/* discard the macro name */
|
||||
eat_current_token();
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
require(NULL != macro_token, "got an EOF terminated #define\n");
|
||||
|
||||
if ('\n' == macro_token->s[0])
|
||||
{
|
||||
expansion_end->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (replace_with_constant)
|
||||
expansion_end = macro_token;
|
||||
|
||||
/* in the first iteration, we set the first token of the expansion, if
|
||||
it exists */
|
||||
if (NULL == hold->expansion)
|
||||
{
|
||||
macro_token = macro_token->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
eat_current_token();
|
||||
hold->expansion = macro_token;
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void macro_directive()
|
||||
|
@ -427,6 +465,21 @@ void macro_directive()
|
|||
}
|
||||
}
|
||||
|
||||
struct token_list* maybe_expand(struct token_list* token)
|
||||
{
|
||||
struct macro_list* hold = lookup_macro(token);
|
||||
struct token_list* hold2;
|
||||
if (NULL == hold)
|
||||
{
|
||||
return token->next;
|
||||
}
|
||||
|
||||
token = eat_token(token);
|
||||
hold2 = insert_tokens(token, hold->expansion);
|
||||
|
||||
return hold2->next;
|
||||
}
|
||||
|
||||
void preprocess()
|
||||
{
|
||||
int start_of_line = TRUE;
|
||||
|
@ -459,10 +512,9 @@ void preprocess()
|
|||
else
|
||||
{
|
||||
start_of_line = FALSE;
|
||||
|
||||
if(NULL == conditional_inclusion_top)
|
||||
{
|
||||
macro_token = macro_token->next;
|
||||
macro_token = maybe_expand(macro_token);
|
||||
}
|
||||
else if(!conditional_inclusion_top->include)
|
||||
{
|
||||
|
@ -471,7 +523,7 @@ void preprocess()
|
|||
}
|
||||
else
|
||||
{
|
||||
macro_token = macro_token->next;
|
||||
macro_token = maybe_expand(macro_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -175,8 +175,8 @@ a2a83f42119e646b389b98647cf6cf2aa9597185997c9453db746178c8c4c0bf test/results/t
|
|||
698853b79efb30865a663c4863c050639eb21c7400008f7840830503928973d4 test/results/test0106-knight-native-binary
|
||||
45c2ba61dc209d7ffa39de9ff0f0a7f8f3ea4d7e38598c72f982fcaf9a05c84a test/results/test0106-knight-posix-binary
|
||||
944580ff4aae38aafac139faf6eed5bfe4ff68b01a7a3adfa346de8803101182 test/results/test0106-x86-binary
|
||||
d4ea011b32eabe55d30d9872fb62472a7941845cf2c9198bd84378fce9098505 test/results/test1000-aarch64-binary
|
||||
0c21df6c75998ef0d2e4188e591759b147d1d3011675c2243b9d5d90f93745c9 test/results/test1000-amd64-binary
|
||||
b97927188f7683005fb97d82f88a232284a7b472446f4afb2c5ccdef59f335f8 test/results/test1000-armv7l-binary
|
||||
d67c1c38a4d3e8b4461df71754a7d0ae556e549a7718fd190964e0a3c1835ecf test/results/test1000-knight-posix-binary
|
||||
42dd021d8a0c8979a8796b1f459f29adca28b293b73530d17f34753b5a17d016 test/results/test1000-x86-binary
|
||||
26e9a6dd65d2cd9f7ad45b0dc145239b9317c77029c6b69faf922a9af65a0678 test/results/test1000-aarch64-binary
|
||||
421f97cb2c0ea0fbdc6ac366a340657682bf1ed9f36f7edad9972f61eb9ec2a8 test/results/test1000-amd64-binary
|
||||
7486674615d8165e5e0365070a1e20142c12d334db7393fbeafa46d14c5c74c5 test/results/test1000-armv7l-binary
|
||||
8e7f3f18441a8f5762741f1362d6789098fbb8c9f7ac722b7036416e7e602b25 test/results/test1000-knight-posix-binary
|
||||
02f26abda516b431ea6e01cfd135e45cd387fa71470495aba005bc121e23c425 test/results/test1000-x86-binary
|
||||
|
|
|
@ -1 +1 @@
|
|||
5717733f915e9c4251f773783e210ca4b25e6a3c2f78c182fd905209911c974e test/test1000/proof
|
||||
61dde3b8a913296de7da40208428ff28ff741908ea9e98c7856626b19666288f test/test1000/proof
|
||||
|
|
Loading…
Reference in New Issue