diff --git a/cc_macro.c b/cc_macro.c index 35a1598..81a4a38 100644 --- a/cc_macro.c +++ b/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); } } } diff --git a/test/test.answers b/test/test.answers index 3a2152c..8864270 100644 --- a/test/test.answers +++ b/test/test.answers @@ -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 diff --git a/test/test1000/proof.answer b/test/test1000/proof.answer index 1d5860b..cdc7f22 100644 --- a/test/test1000/proof.answer +++ b/test/test1000/proof.answer @@ -1 +1 @@ -5717733f915e9c4251f773783e210ca4b25e6a3c2f78c182fd905209911c974e test/test1000/proof +61dde3b8a913296de7da40208428ff28ff741908ea9e98c7856626b19666288f test/test1000/proof