F diff --git a/src/frontend/lex/lex_preprocessing_directive.c b/src/frontend/lex/lex_preprocessing_directive.c --- a/src/frontend/lex/lex_preprocessing_directive.c +++ b/src/frontend/lex/lex_preprocessing_directive.ccase PKW_DEFINE:return preprocessing_lex_define_directive(lexer_data,token_location);case PKW_UNDEF:- return get_error_token("PREPROCESSING UNDEF NOT DONE",token_location,lexer_data->previous_token_location,lexer_data->program);+ return preprocessing_lex_undef_directive(lexer_data,token_location);case PKW_LINE:return preprocessing_lex_line_directive(lexer_data,token_location);case PKW_ERROR:return (struct token*)ret;}+ struct token* preprocessing_lex_undef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)+ {+ struct token_undef_directive *ret;+ struct token *hold_token;+ ret=wonky_malloc(sizeof(struct token_undef_directive));+ ret->type=PKW_UNDEF;+ ret->delta=get_source_location_delta(lexer_data->previous_token_location,where);+ ret->id=NULL;++ hold_token=preprocessing_extract_next_token(lexer_data);++ if(hold_token==NULL || !token_is_identifier_in_preprocessing(hold_token))+ {+ push_lexing_error("Expected id in #undef directive",lexer_data);+ }else+ {+ if(token_is_a_special_macro(hold_token))+ {+ push_lexing_error("Special macro id in #undef directive is not allowed",lexer_data);+ }else+ {+ ret->id=hold_token;+ }+ }+ return (struct token*)ret;+ }void preprocessing_push_tokens_into_queue_until_eol(struct Lexer_Data *lexer_data,struct Queue *queue){F diff --git a/src/semantics/program/translation_unit.c b/src/semantics/program/translation_unit.c --- a/src/semantics/program/translation_unit.c +++ b/src/semantics/program/translation_unit.c}void token_ptr_execute_undef_directive(struct Token_Pointer *ptr,struct token_undef_directive *undef_directive){+ struct identifier *id;token_ptr_goto_next_token(ptr);+ if(undef_directive->id->type==KW_ID)+ {+ id=((struct token_identifier*)undef_directive->id)->id;+ }else if(token_is_keyword(undef_directive->id))+ {+ id=((struct token_keyword*)undef_directive->id)->id;+ }else+ {+ wonky_assert(SHOULD_NOT_REACH_HERE);+ }+ if(id!=NULL)+ {+ id->number_of_translation_unit_where_id_was_last_defined_as_a_macro=0;+ }}void token_ptr_execute_line_directive(struct Token_Pointer *ptr,struct token_line_directive *line_directive){F diff --git a/src/syntax/token/token.c b/src/syntax/token/token.c --- a/src/syntax/token/token.c +++ b/src/syntax/token/token.cif(token->type==KW_ID)return id_is_a_macro(((struct token_identifier*)token)->id,macro_expansion_number,translation_unit_number);+ else if(token_is_keyword(token))+ return id_is_a_macro(((struct token_keyword*)token)->id,macro_expansion_number,translation_unit_number);elsereturn token_is_a_special_macro(token) || token_is_keyword(token);}F diff --git a/src/syntax/token/token.h b/src/syntax/token/token.h --- a/src/syntax/token/token.h +++ b/src/syntax/token/token.h{enum LEXER_TYPE type;struct Source_Location_Delta *delta;- struct identifier *id;+ struct token *id; /*keywords are also identifiers in preprocessing*/};struct token_line_directive{