diff --git a/preprocess.c b/preprocess.c index 5cb740028e1998b66ef9b0be1bd98d8504a0f514..82a0ef383333f46c6c964944f47c116869bae9f6 100644 --- a/preprocess.c +++ b/preprocess.c @@ -5,6 +5,7 @@ struct Macro { Macro *next; char *name; Token *body; + bool deleted; }; // `#if` can be nested, so we use a stack to manage nested `#if`s. @@ -150,7 +151,7 @@ static Macro *find_macro(Token *tok) { for (Macro *m = macros; m; m = m->next) if (strlen(m->name) == tok->len && !strncmp(m->name, tok->loc, tok->len)) - return m; + return m->deleted ? NULL : m; return NULL; } @@ -223,6 +224,18 @@ static Token *preprocess2(Token *tok) { continue; } + if (equal(tok, "undef")) { + tok = tok->next; + if (tok->kind != TK_IDENT) + error_tok(tok, "macro name must be an identifier"); + char *name = strndup(tok->loc, tok->len); + tok = skip_line(tok->next); + + Macro *m = add_macro(name, NULL); + m->deleted = true; + continue; + } + if (equal(tok, "if")) { long val = eval_const_expr(&tok, tok); push_cond_incl(start, val); diff --git a/test/macro.c b/test/macro.c index c26008087a994ba722e8f1f2223f902c2b07d010..6481464a2438eace6bc5138f4b2598a20231d2bf 100644 --- a/test/macro.c +++ b/test/macro.c @@ -121,6 +121,13 @@ int main() { #define END ) ASSERT_ 5, if, five END; +#undef ASSERT_ +#undef if +#undef five +#undef END + + if (0); + printf("OK\n"); return 0; }