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.c
save_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.c
case 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!
+ }
#endif
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.h
struct 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.c
Map_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.h
struct 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.c
hold_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.c
case 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.c
ret->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.h
char *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;
+ }
#endif
F 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);
#endif
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
}
char* get_string_from_token(struct token* token)
{
-
+ return "asdfasdf";
+ }
+ void delete_token(struct token* token)
+ {
+ wonky_free(token);
}
#endif
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
struct 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