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.c{struct token *ret;- ret=preprocessing_extract_next_token(lexer_data);+ ret=preprocessing_extract_next_directive(lexer_data);if(ret==NULL)return get_error_token("PREPROCESSING EMPTY DIRECTIVE NOT SUPPORTED",where,lexer_data->previous_token_location,lexer_data->program);{return get_error_token("PREPROCESSING DIRECTIVES NOT DONE",where,lexer_data->previous_token_location,lexer_data->program);}+ struct token* preprocessing_extract_next_directive(struct Lexer_Data *lexer_data)+ {+ return preprocessing_extract_next_token_inner(lexer_data,1);+ }struct token* preprocessing_extract_next_token(struct Lexer_Data *lexer_data){+ return preprocessing_extract_next_token_inner(lexer_data,0);+ }+ struct token* preprocessing_extract_next_token_inner(struct Lexer_Data *lexer_data,_Bool extract_directive)+ {struct token *ret;struct Automata_Node *hold_node;lexer_data->program);}while(hold_node->keyword==KW_COMMENT);- ret=preprocessing_make_token_finishing_on_node(lexer_data, hold_node, where_does_the_token_start_in_the_source_file);+ ret=preprocessing_make_token_finishing_on_node(lexer_data, hold_node, where_does_the_token_start_in_the_source_file,extract_directive);lexer_data->is_in_the_begining_of_line=0;return ret;}return lexer_data->src->src[lexer_data->where_in_src]=='\n' || lexer_eof(lexer_data);}#warning a hashtag include "asdfadf" [ space ] makes the first assert fail. This is probably due to an empty token after the string one- struct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position)+ struct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position,_Bool create_directive){struct Source_Location *token_location;F diff --git a/src/frontend/lex/lex_preprocessing_directive.h b/src/frontend/lex/lex_preprocessing_directive.h --- a/src/frontend/lex/lex_preprocessing_directive.h +++ b/src/frontend/lex/lex_preprocessing_directive.hvoid preprocessing_goto_end_of_line(struct Lexer_Data *lexer_data);+struct token* preprocessing_extract_next_token(struct Lexer_Data *lexer_data);+ struct token* preprocessing_extract_next_directive(struct Lexer_Data *lexer_data);+ struct token* preprocessing_extract_next_token_inner(struct Lexer_Data *lexer_data,_Bool extract_directive);+struct Automata_Node* preprocessing_feed_automata_until_error(struct Lexer_Data *lexer_data);struct Automata_Node* preprocessing_feed_automata_next_char(struct Lexer_Data *lexer_data,struct Automata_Node *node);void preprocessing_skip_white_space(struct Lexer_Data *lexer_data);_Bool preprocessing_eol(struct Lexer_Data *lexer_data);- struct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position);+ struct token *preprocessing_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position,_Bool create_directive);#endifF diff --git a/src/frontend/lex/lexer.c b/src/frontend/lex/lexer.c --- a/src/frontend/lex/lexer.c +++ b/src/frontend/lex/lexer.ccase KW_BOOL:case KW_COMPLEX:case KW_IMAGINARY:- return get_keyword_token(finishing_node->keyword,token_location,lexer_data->previous_token_location);+ if(finishing_node->data==NULL)+ {+ struct identifier *id;++ id=get_identifier(lexer_data->src->src+start_position,lexer_data->where_in_src-start_position);+ finishing_node->data=id;+ }+ return get_keyword_token(finishing_node->keyword,token_location,lexer_data->previous_token_location,finishing_node->data);case KW_EXCLAMATION:case KW_PERCENT:F diff --git a/src/frontend/lex/lexer.h b/src/frontend/lex/lexer.h --- a/src/frontend/lex/lexer.h +++ b/src/frontend/lex/lexer.hstruct Automata_Node* lexer_feed_automata_until_error(struct Lexer_Data *lexer_data);struct Automata_Node *lexer_feed_automata_next_char(struct Lexer_Data *lexer_data,struct Automata_Node *node);+struct token *lexer_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position);void delete_lexer_data(struct Lexer_Data *lexer_data);---------------#endifF 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.cif(hold_token==NULL)return;- switch(hold_token->type)+ switch(hold_token->preproc_type){- case PKW_IF:- case PKW_ELIF:- token_ptr_execute_if_directive(token_pointer,(struct token_if_directive*)hold_token);- break;- case PKW_IFDEF:- token_ptr_execute_ifdef_directive(token_pointer,(struct token_ifdef_directive*)hold_token);- break;- case PKW_IFNDEF:- token_ptr_execute_ifndef_directive(token_pointer,(struct token_ifndef_directive*)hold_token);- break;- case PKW_ELSE:- wonky_assert(SHOULD_NOT_REACH_HERE);- break;- case PKW_ENDIF:- wonky_assert(SHOULD_NOT_REACH_HERE);- break;- case PKW_INCLUDE:- token_ptr_execute_include_directive(token_pointer,(struct token_include_directive*)hold_token);- break;- case PKW_DEFINE:- token_ptr_execute_normal_define_directive(token_pointer,(struct token_normal_define_directive*)hold_token);- break;- case PKW_FUNCTIONLIKE_DEFINE:- token_ptr_execute_functionlike_define_directive(token_pointer,(struct token_functionlike_define_directive*)hold_token);- break;- case PKW_UNDEF:- token_ptr_execute_undef_directive(token_pointer,(struct token_undef_directive*)hold_token);- break;- case PKW_LINE:- token_ptr_execute_line_directive(token_pointer,(struct token_line_directive*)hold_token);- break;- case PKW_ERROR:- token_ptr_execute_error_directive(token_pointer,(struct token_error_directive*)hold_token);- break;- case PKW_PRAGMA:- token_ptr_execute_pragma_directive(token_pointer,(struct token_pragma_directive*)hold_token);- break;- case PKW_FILE_MACRO:- token_ptr_execute_file_special_macro(token_pointer,hold_token);- return;/*NOTICE*/- case PKW_LINE_MACRO:- token_ptr_execute_line_special_macro(token_pointer,hold_token);- return;/*NOTICE*/- case PKW_STDC_MACRO:- token_ptr_execute_stdc_special_macro(token_pointer,hold_token);- return;/*NOTICE*/- case PKW_STDC_HOSTED_MACRO:- token_ptr_execute_stdc_hosted_special_macro(token_pointer,hold_token);- return;/*NOTICE*/- case PKW_STDC_VERSION_MACRO:- token_ptr_execute_stdc_version_special_macro(token_pointer,hold_token);- return;/*NOTICE*/- case LT_EOF:- if(token_pointer->call_stack->size>0)- {- token_pointer->context=Stack_Pop(token_pointer->call_stack);- }else- {- token_pointer->context=NULL;+ case PKW_DIRECTIVE:+ if(token_ptr_execute_preprocessing_directive(token_pointer,hold_token))return;- }break;- case LT_ERROR:- push_translation_message_into_program_as_error(((struct token_error*)hold_token)->error,token_pointer->program);- token_pointer->context->current_token_node=token_pointer->context->current_token_node->prev;+ case PKW_ID:+ if(token_ptr_possibly_execute_macro_expansion(token_pointer,hold_token))+ return;break;- case KW_ID:- {- struct token_identifier *hold_id_token;- hold_id_token=(struct token_identifier*)hold_token;- if( hold_id_token->id->number_of_translation_unit_where_id_was_last_defined_as_a_macro- ==- token_pointer->program->current_translation_unit_number- &&- hold_id_token->id->number_of_macro_that_last_expanded_this_id!=token_pointer->number_of_last_expanded_macro- )- {- token_ptr_execute_macro(token_pointer,hold_id_token->id);- }else- {- return; /*NOTICE*/- }- break;- }+ #error the split here was so that ids and keywords can be defined in a #define directivedefault:return;+}}wonky_assert(SHOULD_NOT_REACH_HERE);}void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct identifier *id){-+ #warning this still needs to be done+ }+ _Bool token_ptr_execute_preprocessing_directive(struct Token_Pointer *ptr,struct token *token)+ {+ switch(token->type)+ {+ case PKW_IF:+ case PKW_ELIF:+ token_ptr_execute_if_directive(token_pointer,(struct token_if_directive*)token);+ break;+ case PKW_IFDEF:+ token_ptr_execute_ifdef_directive(token_pointer,(struct token_ifdef_directive*)token);+ break;+ case PKW_IFNDEF:+ token_ptr_execute_ifndef_directive(token_pointer,(struct token_ifndef_directive*)token);+ break;+ case PKW_ELSE:+ wonky_assert(SHOULD_NOT_REACH_HERE);+ break;+ case PKW_ENDIF:+ wonky_assert(SHOULD_NOT_REACH_HERE);+ break;+ case PKW_INCLUDE:+ token_ptr_execute_include_directive(token_pointer,(struct token_include_directive*)token);+ break;+ case PKW_DEFINE:+ token_ptr_execute_normal_define_directive(token_pointer,(struct token_normal_define_directive*)token);+ break;+ case PKW_FUNCTIONLIKE_DEFINE:+ token_ptr_execute_functionlike_define_directive(token_pointer,(struct token_functionlike_define_directive*)token);+ break;+ case PKW_UNDEF:+ token_ptr_execute_undef_directive(token_pointer,(struct token_undef_directive*)token);+ break;+ case PKW_LINE:+ token_ptr_execute_line_directive(token_pointer,(struct token_line_directive*)token);+ break;+ case PKW_ERROR:+ token_ptr_execute_error_directive(token_pointer,(struct token_error_directive*)token);+ break;+ case PKW_PRAGMA:+ token_ptr_execute_pragma_directive(token_pointer,(struct token_pragma_directive*)token);+ break;+ case PKW_FILE_MACRO:+ token_ptr_execute_file_special_macro(token_pointer,token);+ return;/*NOTICE*/+ case PKW_LINE_MACRO:+ token_ptr_execute_line_special_macro(token_pointer,token);+ return;/*NOTICE*/+ case PKW_STDC_MACRO:+ token_ptr_execute_stdc_special_macro(token_pointer,token);+ return;/*NOTICE*/+ case PKW_STDC_HOSTED_MACRO:+ token_ptr_execute_stdc_hosted_special_macro(token_pointer,token);+ return;/*NOTICE*/+ case PKW_STDC_VERSION_MACRO:+ token_ptr_execute_stdc_version_special_macro(token_pointer,token);+ return;/*NOTICE*/+ case LT_EOF:+ if(token_pointer->call_stack->size>0)+ {+ token_pointer->context=Stack_Pop(token_pointer->call_stack);+ }else+ {+ token_pointer->context=NULL;+ return;+ }+ break;+ case LT_ERROR:+ push_translation_message_into_program_as_error(((struct token_error*)token)->error,token_pointer->program);+ token_pointer->context->current_token_node=token_pointer->context->current_token_node->prev;+ break;+ case KW_ID:+ {+ struct token_identifier *hold_id_token;+ hold_id_token=(struct token_identifier*)token;+ if( hold_id_token->id->number_of_translation_unit_where_id_was_last_defined_as_a_macro+ ==+ token_pointer->program->current_translation_unit_number+ &&+ hold_id_token->id->number_of_macro_that_last_expanded_this_id!=token_pointer->number_of_last_expanded_macro+ )+ {+ token_ptr_execute_macro(token_pointer,hold_id_token->id);+ }else+ {+ return; /*NOTICE*/+ }+ break;+ }+ default:+ return;+ }}void token_ptr_execute_stdc_hosted_special_macro(struct Token_Pointer *ptr,struct token *directive){F diff --git a/src/semantics/program/translation_unit.h b/src/semantics/program/translation_unit.h --- a/src/semantics/program/translation_unit.h +++ b/src/semantics/program/translation_unit.hvoid token_ptr_execute_macro(struct Token_Pointer *ptr,struct identifier *id);void token_ptr_execute_normal_macro(struct Token_Pointer *ptr,struct normal_define_directive *macro);void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct identifier *id);+ _Bool token_ptr_execute_preprocessing_directive(struct Token_Pointer *ptr,struct token *token);+ _Bool token_ptr_possibly_execute_macro_expansion(struct Token_Pointer *ptr,struct token *token);void token_ptr_assume_location_of_token(struct Token_Pointer *ptr,struct token *token);F diff --git a/src/syntax/automatas/automata.hh b/src/syntax/automatas/automata.hh --- a/src/syntax/automatas/automata.hh +++ b/src/syntax/automatas/automata.hhPKW_STDC_VERSION_MACRO,PKW_TIME_MACRO,PKW_ANGULAR_BRACKET_INCLUDE_NAME,+ PKW_CONSTANT,+ PKW_ID,+ PKW_PUNCTUATOR,+ PKW_DIRECTIVE,LT_EOF,LT_ERROR,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.c#define WONKY_TOKEN_C WONKY_TOKEN_C#include <token.h>- struct token* copy_token(struct token *src)- {- struct token *cpy;- cpy=wonky_malloc(sizeof(struct token));- *cpy=*src;- return cpy;- }struct token* get_id_token(struct identifier *id,struct Source_Location *current_location,struct Source_Location *previous_location){struct token_identifier *ret;ret=wonky_malloc(sizeof(struct token_identifier));ret->type=KW_ID;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);ret->id=id;return (struct token*)ret;}- struct token* get_keyword_token(enum LEXER_TYPE type,struct Source_Location *current_location,struct Source_Location *previous_location)+ struct token* get_keyword_token(enum LEXER_TYPE type,struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id){struct token_keyword *ret;ret=wonky_malloc(sizeof(struct token_keyword));ret->type=type;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);+ ret->id=id;return (struct token*)ret;}struct token_punctuator *ret;ret=wonky_malloc(sizeof(struct token_punctuator));ret->type=type;+ ret->preproc_type=PKW_CONSTANT;ret->delta=get_source_location_delta(previous_location,current_location);ret->punctuator_type=PUNCTUATOR_NORMAL;/*TODO*/ret=wonky_malloc(sizeof(struct token_constant));ret->delta=get_source_location_delta(previous_location,current_location);ret->type=KW_CONSTANT;+ ret->preproc_type=PKW_CONSTANT;switch(bare_type){ret=wonky_malloc(sizeof(struct token_constant));ret->delta=get_source_location_delta(previous_location,current_location);ret->type=KW_CONSTANT;+ ret->preproc_type=PKW_CONSTANT;ret->constant=get_long_long_int_constant(number);return (struct token*)ret;}struct token_string *ret;ret=wonky_malloc(sizeof(struct token_string));ret->type=bare_type;+ ret->preproc_type=PKW_CONSTANT;ret->delta=get_source_location_delta(previous_location,current_location);if(bare_type==KW_STRING)ret=wonky_malloc(sizeof(struct token_string));ret->delta=get_source_location_delta(previous_location,current_location);ret->tokens=tokens;+ ret->type=PKW_INCLUDE;+ ret->preproc_type=PKW_DIRECTIVE;return (struct token*)ret;}struct token* get_error_token(const char *msg,struct Source_Location *current_location,struct Source_Location *previous_location,struct Program *program,...)ret=wonky_malloc(sizeof(struct token_error));ret->type=LT_ERROR;+ ret->preproc_type=LT_ERROR;ret->delta=get_source_location_delta(previous_location,current_location);ret->error=get_translation_message(msg,struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=LT_EOF;+ ret->preproc_type=LT_EOF;ret->delta=NULL;return ret;struct token_string *ret;ret=wonky_malloc(sizeof(struct token_string));ret->type=KW_STRING;+ ret->preproc_type=PKW_CONSTANT;ret->delta=first->delta;ret->constant=concatenate_string_literals(first->constant,second->constant);struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=PKW_FILE_MACRO;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);return ret;struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=PKW_LINE_MACRO;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);;return ret;struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=PKW_STDC_MACRO;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);;return ret;struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=PKW_STDC_HOSTED_MACRO;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);;return ret;struct token *ret;ret=wonky_malloc(sizeof(struct token));ret->type=PKW_STDC_VERSION_MACRO;+ ret->preproc_type=PKW_ID;ret->delta=get_source_location_delta(previous_location,current_location);;return ret;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.hstruct token{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;};struct token_identifier{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct identifier *id;};struct token_keyword{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;+ struct identifier *id;};struct token_punctuator{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;enum Punctuator_Token_Type punctuator_type;};struct token_constant{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Constant *constant;};struct token_string{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Constant *constant;};struct token_include_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Queue *tokens;};struct token_if_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Queue *controlling_expression;struct Queue_Node *if_true;struct token_ifdef_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct identifier *id;struct Queue_Node *if_defined;struct token_ifndef_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct identifier *id;struct Queue_Node *if_undefined;struct token_normal_define_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct normal_define_directive *define;};struct token_functionlike_define_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct functionlike_define_directive_argument *define;};struct token_undef_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct identifier *id;};struct token_line_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *directive_delta;size_t line;struct token_error_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;char *error_message;};struct token_pragma_directive{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;enum Pragma_Type pragma_type;};struct token_defined_unary_operator{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct identifier *id;};struct token_hashtag_unary_operator{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct token_functionlike_define_directive *operand;};struct token_hashtag_hastag_unary_operator{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Queue *operands;};struct token_error{enum LEXER_TYPE type;+ enum LEXER_TYPE preproc_type;struct Source_Location_Delta *delta;struct Translation_Message *error;};- struct token* copy_token(struct token *src);void handle_splicing(struct token *word);char compare_tokens(struct token *a,struct token *b);struct token* get_id_token(struct identifier *id,struct Source_Location *current_location,struct Source_Location *previous_location);- struct token* get_keyword_token(enum LEXER_TYPE type,struct Source_Location *current_location,struct Source_Location *previous_location);+ struct token* get_keyword_token(enum LEXER_TYPE type,struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id);struct token* get_punctuator_token(enum LEXER_TYPE type,struct Source_Location *current_location,struct Source_Location *previous_location);struct token* get_constant_token(enum LEXER_TYPE bare_type,struct Source_Location *current_location,struct Source_Location *previous_location,char *data,size_t size);struct token* get_constant_long_long_int_token(struct Source_Location *current_location,struct Source_Location *previous_location,long long int number);