From 4550eec19e074506fae3707b45dd67d004686caa Mon Sep 17 00:00:00 2001 From: Sanne Wouda Date: Fri, 8 Jan 2021 21:25:34 +0000 Subject: [PATCH] Extend macro #define support - now supports #if defined(FOO) - translation of #define FOO 1 to CONSTANT FOO 1 is still supported --- cc_macro.c | 113 ++++++++++++++++++++++++++++++++++--- test/test.answers | 10 ++-- test/test1000/proof.answer | 2 +- 3 files changed, 110 insertions(+), 15 deletions(-) diff --git a/cc_macro.c b/cc_macro.c index d039ff4..0365e90 100644 --- a/cc_macro.c +++ b/cc_macro.c @@ -28,6 +28,13 @@ struct conditional_inclusion int previous_condition_matched; /* 1 == all subsequent conditions treated as FALSE */ }; +struct macro_list +{ + struct macro_list* next; + char* symbol; +}; + +struct macro_list* macro_env; struct conditional_inclusion* conditional_inclusion_top; /* point where we are currently modifying the global_token list */ @@ -76,6 +83,25 @@ void eat_newline_tokens() } } +struct macro_list* lookup_macro(struct token_list* token) +{ + struct macro_list* hold = macro_env; + + while (NULL != hold) + { + if (match(token->s, hold->symbol)) + { + /* found! */ + return hold; + } + + hold = hold->next; + } + + /* not found! */ + return NULL; +} + int macro_expression(); int macro_variable() { @@ -91,7 +117,9 @@ int macro_number() int macro_primary_expr() { - require(NULL != macro_token, "got an EOF terminated macro expression\n"); + int defined_has_paren = FALSE; + int hold; + require(NULL != macro_token, "got an EOF terminated macro primary expression\n"); if('-' == macro_token->s[0]) { @@ -108,6 +136,36 @@ int macro_primary_expr() eat_current_token(); return macro_expression(); } + else if(match("defined", macro_token->s)) + { + eat_current_token(); + + require(NULL != macro_token, "got an EOF terminated macro defined expression\n"); + + if('(' == macro_token->s[0]) + { + defined_has_paren = TRUE; + eat_current_token(); + } + + if (NULL != lookup_macro(macro_token)) + { + hold = TRUE; + } + else + { + hold = FALSE; + } + eat_current_token(); + + if(TRUE == defined_has_paren) + { + require(')' == macro_token->s[0], "missing close parenthesis for defined()\n"); + eat_current_token(); + } + + return hold; + } else if(in_set(macro_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_")) { return macro_variable(); @@ -127,7 +185,7 @@ int macro_additive_expr() int lhs = macro_primary_expr(); int hold; - require(NULL != macro_token, "got an EOF terminated macro expression\n"); + require(NULL != macro_token, "got an EOF terminated macro additive expression\n"); if(match("+", macro_token->s)) { eat_current_token(); @@ -258,6 +316,49 @@ int macro_expression() return macro_bitwise_expr(); } +void handle_define() +{ + int replace_with_constant = TRUE; + struct macro_list* hold; + + if (replace_with_constant) + { + macro_token->s = "CONSTANT"; + macro_token = macro_token->next; + } + else + { + eat_current_token(); + } + + require(NULL != macro_token, "got an EOF terminated #define\n"); + require('\n' != macro_token->s[0], "unexpected newline after #define\n"); + + /* insert new macro */ + hold = calloc(1, sizeof(struct macro_list)); + hold->symbol = macro_token->s; + hold->next = macro_env; + macro_env = hold; + + while (TRUE) + { + require(NULL != macro_token, "got an EOF terminated #define\n"); + + if ('\n' == macro_token->s[0]) + { + return; + } + + if (replace_with_constant) + { + macro_token = macro_token->next; + } + else + { + eat_current_token(); + } + } +} void macro_directive() { @@ -315,13 +416,7 @@ void macro_directive() } else if(match("#define", macro_token->s)) { - macro_token->s = "CONSTANT"; - while('\n' != macro_token->s[0]) - { - macro_token = macro_token->next; - require(NULL != macro_token, "Ran off the end of a #define\n"); - } - return; + handle_define(); } else { diff --git a/test/test.answers b/test/test.answers index 8029161..38aa940 100644 --- a/test/test.answers +++ b/test/test.answers @@ -169,8 +169,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 -9a87d68e52780cb33b58f8b39fecb67063ee4921745e6b31afa1d38d34bb1142 test/results/test1000-aarch64-binary -9450e369831274bd30115fdfe76c17778a9f0f73c2f804acce6096d9e7c38e4b test/results/test1000-amd64-binary -42890f9ab2895f65adccd9b129fb54b022d21f79a9647e174712c96b5081c679 test/results/test1000-armv7l-binary -58af5b8989b6e05a7434326ebca7f523892a31af3d7460c5658e64c31a47663f test/results/test1000-knight-posix-binary -1d8ad9ce8db6c7910292dbc39f909b0cf4154cba4e4701762f6f0e2793a5effc test/results/test1000-x86-binary +770ff703d257edfe01563649b14f73aa8cc844460d7e1dbc27420f407c7e8b2f test/results/test1000-aarch64-binary +057b66ec17170ec1e13a457bc2064d13b6b57e6b6f0abb7aa260f1fa1099edc9 test/results/test1000-amd64-binary +63d09ed177486cb7fe23f541d5e4f753359b05ad3bc61703efde555ec5793a03 test/results/test1000-armv7l-binary +b14e247056af6c0f0a8b983444a8a04b4c9221f0a66b8d89b218c6cfeed55cf1 test/results/test1000-knight-posix-binary +e2944312b3a46b9dc5111b078655436b731f8f841b3d0aeb8fe43a6d85ca3ae1 test/results/test1000-x86-binary diff --git a/test/test1000/proof.answer b/test/test1000/proof.answer index 70368c1..6ebc1ac 100644 --- a/test/test1000/proof.answer +++ b/test/test1000/proof.answer @@ -1 +1 @@ -390acadbb8394a5a8621174ae55e063e70221b60eb1e96549bb97c950a807a99 test/test1000/proof +58da283d4215ba779d3f5de527f6d918cfae5dc2a3c999fc92fb76dfc7cb97ad test/test1000/proof