F diff --git a/src/backend/text/print/print.c b/src/backend/text/print/print.c --- a/src/backend/text/print/print.c +++ b/src/backend/text/print/print.csave_compiled_object_for_print(obj,out);fprintf(out,"\n} END OF TOKENS\n");-+ ++program->current_translation_unit_number;}while(*(++base_source_names));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_INCLUDE:return preprocessing_lex_include_directive(lexer_data,token_location);case PKW_DEFINE:- return get_error_token("PREPROCESSING DEFINE NOT DONE",token_location,lexer_data->previous_token_location,lexer_data->program);+ 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);case PKW_LINE:return (struct token*)ret;}+ struct token* preprocessing_lex_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)+ {+ struct token_identifier *hold_token;+ struct token *hold_hold_token;+ struct token *ret;++ hold_token=(struct token_identifier*)preprocessing_extract_next_token(lexer_data);++ if(hold_token->type==KW_ID)+ {+ hold_hold_token=preprocessing_extract_next_token(lexer_data);+ if(hold_hold_token->type==KW_OPEN_NORMAL)+ {+ ret=preprocessing_lex_functionlike_define_directive(lexer_data,where,hold_token->id);+ delete_token((struct token*)hold_token);+ delete_token(hold_hold_token);+ return ret;+ }else+ {+ ret=preprocessing_lex_normal_define_directive(lexer_data,where,hold_token->id,hold_hold_token);+ delete_token((struct token*)hold_token);+ delete_token(hold_hold_token);+ return ret;+ }+ }else+ {+ preprocessing_goto_end_of_line(lexer_data);+ delete_token((struct token*)hold_token);+ return get_error_token("Id exprected after #define directive",where,lexer_data->previous_token_location,lexer_data->program);+ }+ wonky_assert(SHOULD_NOT_REACH_HERE);+ }+ struct token* preprocessing_lex_normal_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,struct identifier *id,struct token *first_replacement_token)+ {+ struct token_normal_define_directive *ret;++ ret=wonky_malloc(sizeof(struct token_normal_define_directive));+ ret->type=PKW_DEFINE;+ ret->delta=get_source_location_delta(lexer_data->previous_token_location,where);+ ret->define=get_normal_define_directive(id);++ if(first_replacement_token)+ {+ Queue_Push(ret->define->replacement_tokens,first_replacement_token);++ while(!preprocessing_eol(lexer_data))+ Queue_Push(ret->define->replacement_tokens,preprocessing_extract_next_token(lexer_data));+ }++ return (struct token*)ret;+ }+ struct token* preprocessing_lex_functionlike_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,struct identifier *id)+ {+ #warning do this next!+ }#endifF 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.hstruct token* preprocessing_lex_ifndef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);struct token* preprocessing_lex_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);- struct token* preprocessing_lex_normal_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);- struct token* preprocessing_lex_functionlike_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);+ struct token* preprocessing_lex_normal_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,struct identifier *id,struct token *first_replacement_token);+ struct token* preprocessing_lex_functionlike_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,struct identifier *id);struct token* preprocessing_lex_undef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);void preprocessing_goto_end_of_line(struct Lexer_Data *lexer_data);struct token* preprocessing_extract_next_token(struct Lexer_Data *lexer_data);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);+ 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);F diff --git a/src/semantics/program/program.c b/src/semantics/program/program.c --- a/src/semantics/program/program.c +++ b/src/semantics/program/program.cMap_Init(ret->types);Map_Init(ret->preprocessing_translation_units);+ ret->current_translation_unit_number=1;+return ret;}program->translation_units,parse_translation_unit(hold_translation_data));+ ++program->current_translation_unit_number;}F diff --git a/src/semantics/program/program.h b/src/semantics/program/program.h --- a/src/semantics/program/program.h +++ b/src/semantics/program/program.hstruct Queue *functions_without_a_definition;struct Queue *external_objects_without_an_initialiser;++ size_t current_translation_unit_number;};struct Translation_Data{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.chold_token=(struct token*)token_pointer->context->current_token_node->data;+token_ptr_goto_next_token(token_pointer);token_ptr_assume_location_of_token(token_pointer,hold_token);+return hold_token;}void token_ptr_goto_next_normal_token(struct Token_Pointer *token_pointer)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;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;+ }default:return;}ret->program=program;+ ret->number_of_last_expanded_macro=1;+return ret;}}void token_ptr_execute_ifndef_directive(struct Token_Pointer *ptr,struct token_ifndef_directive *ifndef_directive){+ ++ptr->number_of_last_expanded_macro;token_ptr_goto_next_token(ptr);}void token_ptr_execute_normal_define_directive(struct Token_Pointer *ptr,struct token_normal_define_directive *define_directive){+ define_directive->define->id->number_of_translation_unit_where_id_was_last_defined_as_a_macro+ =+ ptr->program->current_translation_unit_number;++ define_directive->define->id->last_defined_macro_with_this_id=(struct token*)define_directive;+token_ptr_goto_next_token(ptr);}void token_ptr_execute_functionlike_define_directive(struct Token_Pointer *ptr,struct token_functionlike_define_directive *define_directive)1);Queue_Push(ptr->context->ungeted_tokens,line);}+ void token_ptr_execute_macro(struct Token_Pointer *ptr,struct identifier *id)+ {+ id->number_of_macro_that_last_expanded_this_id=ptr->number_of_last_expanded_macro;+ token_ptr_goto_next_token(ptr);++ if(id->last_defined_macro_with_this_id->type==PKW_DEFINE)+ token_ptr_execute_normal_macro(ptr,((struct token_normal_define_directive*)id->last_defined_macro_with_this_id)->define);+ else if(id->last_defined_macro_with_this_id->type==PKW_FUNCTIONLIKE_DEFINE)+ token_ptr_execute_functionlike_macro(ptr,id);+ else+ wonky_assert(SHOULD_NOT_REACH_HERE);++ }+ void token_ptr_execute_normal_macro(struct Token_Pointer *ptr,struct normal_define_directive *macro)+ {+ token_ptr_jump_to(ptr,macro->replacement_tokens->first);+ }+ void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct identifier *id)+ {++ }void token_ptr_execute_stdc_hosted_special_macro(struct Token_Pointer *ptr,struct token *directive){struct token_constant *line;{struct Token_Pointer_Context *new_context;- if(ptr->call_stack->size>1000)+ if(where_to!=NULL){- push_token_ptr_error("Preprocessing bounds exceeded",ptr);- return;+ if(ptr->call_stack->size>1000)+ {+ push_token_ptr_error("Preprocessing bounds exceeded",ptr);+ return;+ }+ new_context=get_token_ptr_context(where_to);+ Stack_Push(ptr->call_stack,ptr->context);+ ptr->context=new_context;}- new_context=get_token_ptr_context(where_to);- Stack_Push(ptr->call_stack,ptr->context);- ptr->context=new_context;}void delete_token_ptr_context(struct Token_Pointer_Context *context){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.h#include <wonky_assert.h>#include <queue.h>#include <source_file.h>+ #include <macro.h>struct Preprocessing_Translation_Unit{struct Program *program;enum Token_Pointer_State state;+ size_t number_of_last_expanded_macro;};struct Preprocessing_Translation_Unit* get_preprocessing_translation_unit(struct Source_File *source);void delete_preprocessing_translation_unit(struct Preprocessing_Translation_Unit *unit);void token_ptr_execute_stdc_special_macro(struct Token_Pointer *ptr,struct token *directive);void token_ptr_execute_stdc_hosted_special_macro(struct Token_Pointer *ptr,struct token *directive);void token_ptr_execute_stdc_version_special_macro(struct Token_Pointer *ptr,struct token *directive);+ void 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);void token_ptr_assume_location_of_token(struct Token_Pointer *ptr,struct token *token);F diff --git a/src/semantics/value/value.c b/src/semantics/value/value.c --- a/src/semantics/value/value.c +++ b/src/semantics/value/value.ccase VALUE_VOID:return ((struct Expression_Value_Void*)expression_value)->void_type;}+ #warning reaches here on int main() { return; }wonky_assert(SHOULD_NOT_REACH_HERE);}F diff --git a/src/syntax/automatas/generator/keyword_list.c b/src/syntax/automatas/generator/keyword_list.c --- a/src/syntax/automatas/generator/keyword_list.c +++ b/src/syntax/automatas/generator/keyword_list.c.data_string="NULL"},{- .keyword="defined",- .preprocessing_kw_string="PKW_DEFINED",- .kw_string="KW_ID",- .action_string="AUTOMATA_ACTION_DISPENSE_TOKEN",- .data_string="&defined_special_identifier"- },- {.keyword="ifdef",.preprocessing_kw_string="PKW_IFDEF",.kw_string="KW_ID",.data_string="NULL"},{+ .keyword="defined",+ .preprocessing_kw_string="PKW_DEFINED",+ .kw_string="KW_ID",+ .action_string="AUTOMATA_ACTION_DISPENSE_TOKEN",+ .data_string="&defined_special_identifier"+ },+ {.keyword="undef",.preprocessing_kw_string="PKW_UNDEF",.kw_string="KW_ID",F diff --git a/src/syntax/identifier/identifier.c b/src/syntax/identifier/identifier.c --- a/src/syntax/identifier/identifier.c +++ b/src/syntax/identifier/identifier.cret->data[size]='\0';ret->last_defined_macro_with_this_id=NULL;ret->last_use_as_a_macro_argument=NULL;+ ret->number_of_translation_unit_where_id_was_last_defined_as_a_macro=0;+ ret->number_of_macro_that_last_expanded_this_id=0;return ret;}F diff --git a/src/syntax/identifier/identifier.h b/src/syntax/identifier/identifier.h --- a/src/syntax/identifier/identifier.h +++ b/src/syntax/identifier/identifier.hchar *data;struct token *last_defined_macro_with_this_id;struct functionlike_define_directive_argument *last_use_as_a_macro_argument;+ size_t number_of_translation_unit_where_id_was_last_defined_as_a_macro;+ size_t number_of_macro_that_last_expanded_this_id;};F diff --git a/src/syntax/macro.c b/src/syntax/macro.c --- a/src/syntax/macro.c +++ b/src/syntax/macro.c#define WONKY_MACRO_C WONKY_MACRO_C#include <macro.h>+ struct normal_define_directive* get_normal_define_directive(struct identifier *id)+ {+ struct normal_define_directive *ret;+ ret=wonky_malloc(sizeof(struct normal_define_directive));+ ret->id=id;+ ret->replacement_tokens=wonky_malloc(sizeof(struct Queue));+ Queue_Init(ret->replacement_tokens);+ return ret;+ }+ struct functionlike_define_directive* get_functionlike_define_directive(struct identifier *id)+ {+ struct functionlike_define_directive *ret;+ ret=wonky_malloc(sizeof(struct functionlike_define_directive));+ ret->id=id;+ ret->arguments=wonky_malloc(sizeof(struct Queue));+ Queue_Init(ret->arguments);+ ret->replacement_tokens=wonky_malloc(sizeof(struct Queue));+ Queue_Init(ret->replacement_tokens);+ return ret;+ }+ struct functionlike_define_directive_argument* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to,struct Queue_Node *first_in_argument_substitution_tokens,size_t number_of_substitution_tokens)+ {+ struct functionlike_define_directive_argument *ret;+ ret=wonky_malloc(sizeof(struct functionlike_define_directive_argument));+ ret->belongs_to=belongs_to;+ ret->first_in_argument_substitution_tokens=first_in_argument_substitution_tokens;+ ret->number_of_substitution_tokens=number_of_substitution_tokens;++ return ret;+ }#endifF diff --git a/src/syntax/macro.h b/src/syntax/macro.h --- a/src/syntax/macro.h +++ b/src/syntax/macro.h#define WONKY_MACRO_H WONKY_MACRO_H#include <macro.hh>#include <stddef.h>+ #include <wonky_malloc.h>struct normal_define_directive{struct identifier *id;struct Queue *replacement_tokens;- struct Translation_Unit *the_last_place_this_macro_was_defined;};struct functionlike_define_directive{struct identifier *id;struct Queue *arguments;struct Queue *replacement_tokens;- struct Translation_Unit *the_last_place_this_macro_was_defined;};struct functionlike_define_directive_argument{struct Queue_Node *first_in_argument_substitution_tokens;size_t number_of_substitution_tokens;};+++ struct normal_define_directive* get_normal_define_directive(struct identifier *id);+ struct functionlike_define_directive* get_functionlike_define_directive(struct identifier *id);+ struct functionlike_define_directive_argument* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to,struct Queue_Node *first_in_argument_substitution_tokens,size_t number_of_substitution_tokens);#endifF 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}char* get_string_from_token(struct token* token){-+ return "asdfasdf";+ }+ void delete_token(struct token* token)+ {+ wonky_free(token);}#endifF 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* get_stdc_version_macro_token(struct Source_Location *current_location,struct Source_Location *previous_location);struct token* get_time_macro_token(struct Source_Location *current_location,struct Source_Location *previous_location);char* get_string_from_token(struct token* token);+ void delete_token(struct token* token);#endif