WONKY



LOG | FILES | OVERVIEW


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
append_to_last_line("CONSTANT",compile_data->lines);
break;
case KW_ID:
- append_to_last_line("ID",compile_data->lines);
+ append_to_last_line("ID ",compile_data->lines);
+ print_id(compile_data,((struct token_identifier*)token)->id);
break;
case KW_STRING:
case KW_WIDE_STRING:
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* preprocessing_lex_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)
{
- struct token_identifier *hold_token;
+ struct token *hold_token;
struct token *hold_hold_token;
+ struct identifier *hold_id;
struct token *ret;
- hold_token=(struct token_identifier*)preprocessing_extract_next_token(lexer_data);
+ hold_token=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;
- }
+ hold_id=((struct token_identifier*)hold_token)->id;
+ }else if(token_is_keyword(hold_token))
+ {
+ hold_id=((struct token_keyword*)hold_token)->id;
}else
{
preprocessing_goto_end_of_line(lexer_data);
delete_token((struct token*)hold_token);
+ /*NOTICE*/
return get_error_token("Id exprected after #define directive",where,lexer_data->previous_token_location,lexer_data->program);
}
+
+ 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_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_id,hold_hold_token);
+ delete_token((struct token*)hold_token);
+ delete_token(hold_hold_token);
+ return ret;
+ }
wonky_assert(SHOULD_NOT_REACH_HERE);
}
+ /*
+ * the first replacement token is the one the caller got
+ * when checking if the define directive is a function like
+ * on or a normal one.
+ * TODO: remove comment and make function less obscure
+ */
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);
+ ret=(struct token_normal_define_directive*)get_normal_define_directive_token(where,lexer_data->previous_token_location,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));
+ preprocessing_push_tokens_into_queue_until_eol(lexer_data,ret->define->replacement_tokens);
}
return (struct token*)ret;
}
+
+ /*
+ * [id,]* ) replacement-list
+ * the first '(' is chomped from caller
+ * TODO: remove comment and make function less obscure
+ */
struct token* preprocessing_lex_functionlike_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,struct identifier *id)
{
- #warning do this next!
+ struct token_functionlike_define_directive *ret;
+
+ ret=(struct token_functionlike_define_directive*)get_functionlike_define_directive_token(where,lexer_data->previous_token_location,id);
+
+ preprocessing_parse_functionlike_macro_id_list(lexer_data,ret);
+
+ preprocessing_push_functionlike_macro_substitution_tokens(lexer_data,where,ret->define);
+
+ return (struct token*)ret;
+ }
+ void preprocessing_push_tokens_into_queue_until_eol(struct Lexer_Data *lexer_data,struct Queue *queue)
+ {
+
+ while(!preprocessing_eol(lexer_data))
+ Queue_Push(queue,preprocessing_extract_next_token(lexer_data));
+ }
+ void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive)
+ {
+ struct token *hold_token;
+ while(!preprocessing_eol(lexer_data))
+ {
+ hold_token=preprocessing_extract_next_token(lexer_data);
+ if(hold_token->type==KW_ID && ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive==directive)
+ {
+
+ Queue_Push(directive->replacement_tokens,
+ get_functionlike_define_directive_argument_token(
+ where,
+ lexer_data->previous_token_location,
+ ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive_argument));
+ delete_token(hold_token);
+ }else if(token_is_keyword(hold_token) && ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive==directive)
+ {
+ Queue_Push(directive->replacement_tokens,
+ get_functionlike_define_directive_argument_token(
+ where,
+ lexer_data->previous_token_location,
+ ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive_argument));
+ delete_token(hold_token);
+ }else
+ {
+ Queue_Push(directive->replacement_tokens,hold_token);
+ }
+ }
+ }
+ void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *directive)
+ {
+ struct token *hold_token;
+ while(!preprocessing_eol(lexer_data))
+ {
+ hold_token=preprocessing_extract_next_token(lexer_data);
+ if(hold_token->type==KW_ELIPSIS)
+ {
+ directive->define->is_variadic=1;
+ delete_token(hold_token);
+ hold_token=preprocessing_extract_next_token(lexer_data);
+ if(hold_token->type==KW_OPEN_NORMAL)
+ {
+ delete_token(hold_token);
+ break;
+ }else
+ {
+ push_lexing_error("Expected ')' after '...' in functionlike macro",lexer_data);
+ break;
+ }
+ }else if(hold_token->type==KW_ID)
+ {
+ #warning make it check for duplicate ids here
+ struct functionlike_define_directive_argument *hold_argument;
+
+ hold_argument=get_functionlike_define_directive_argument(directive);
+
+ Queue_Push(directive->define->arguments,hold_argument);
+
+ ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive=directive->define;
+ ((struct token_identifier*)hold_token)->id->hold_functionlike_define_directive_argument=hold_argument;
+ delete_token(hold_token);
+ }else if(token_is_keyword(hold_token))
+ {
+ #warning make it check for duplicate ids here
+ Queue_Push(directive->define->arguments,
+ get_functionlike_define_directive_argument(directive));
+ ((struct token_keyword*)hold_token)->id->hold_functionlike_define_directive=directive->define;
+ delete_token(hold_token);
+ }else if(hold_token->type==KW_OPEN_NORMAL)
+ {
+ delete_token(hold_token);
+ break;
+ }
+ }
}
#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
#include <automata.h>
#include <token.h>
+ #include <macro.h>
#include <lexer.h>
#include <source_file.h>
struct token* preprocessing_lex_pragma_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
struct token* preprocessing_lex_defined_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where);
+ void preprocessing_push_tokens_into_queue_until_eol(struct Lexer_Data *lexer_data,struct Queue *queue);
+
+ void preprocessing_push_functionlike_macro_substitution_tokens(struct Lexer_Data *lexer_data,struct Source_Location *where,struct functionlike_define_directive *directive);
void preprocessing_goto_end_of_line(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,_Bool create_directive);
+ void preprocessing_parse_functionlike_macro_id_list(struct Lexer_Data *lexer_data,struct token_functionlike_define_directive *directive);
+
#endif
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
struct token *hold_token;
if(token_ptr_has_buffered_tokens(token_pointer))
return;
+
+
while(1)
{
- if(token_pointer->context->current_token_node==NULL)
+ if(token_pointer->context->number_of_remaining_tokens==0)
return;
hold_token=(struct token*)token_pointer->context->current_token_node->data;
- if(hold_token==NULL)
- return;
+ wonky_assert(hold_token!=NULL);
- switch(hold_token->preproc_type)
- {
- case PKW_DIRECTIVE:
- if(token_ptr_execute_preprocessing_directive(token_pointer,hold_token))
- return;
- break;
- case PKW_ID:
- if(token_ptr_possibly_execute_macro_expansion(token_pointer,hold_token))
- return;
- break;
- #error the split here was so that ids and keywords can be defined in a #define directive
- default:
- return;
-
- }
+ if(!token_ptr_do_preprocessing_stuff(token_pointer,hold_token))
+ return;
}
wonky_assert(SHOULD_NOT_REACH_HERE);
}
void token_ptr_goto_next_token(struct Token_Pointer *token_pointer)
{
if(token_ptr_has_remaining_tokens(token_pointer) && !token_ptr_has_buffered_tokens(token_pointer))
+ {
token_pointer->context->current_token_node=token_pointer->context->current_token_node->prev;
+ --token_pointer->context->number_of_remaining_tokens;
+ }
}
struct Token_Pointer* get_token_ptr(struct Preprocessing_Translation_Unit *unit,struct Program *program)
struct Token_Pointer *ret;
ret=wonky_malloc(sizeof(struct Token_Pointer));
- ret->context=get_token_ptr_context(unit->tokens->first);
+ ret->context=get_token_ptr_context(unit->tokens->first,unit->tokens->size);
ret->call_stack=wonky_malloc(sizeof(struct Stack));
ret->state=TOKEN_POINTER_STATE_NORMAL;
ret->program=program;
- ret->number_of_last_expanded_macro=1;
+ ret->macro_expansion_number=1;
return ret;
}
token_ptr_goto_next_token(ptr);
- token_ptr_jump_to(ptr,include_directive->tokens->first);
+ token_ptr_jump_to_first(ptr,include_directive->tokens);
ptr->state=TOKEN_POINTER_STATE_PREPROCESSING;
hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));
if(hold_unit->tokens->first)
- token_ptr_jump_to(ptr,hold_unit->tokens->first);
+ token_ptr_jump_to_first(ptr,hold_unit->tokens);
else
token_ptr_goto_next_token(ptr);
}else if(hold_token->type==KW_LESS)
hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));
if(hold_unit->tokens->first)
- token_ptr_jump_to(ptr,hold_unit->tokens->first);
+ token_ptr_jump_to_first(ptr,hold_unit->tokens);
else
token_ptr_goto_next_token(ptr);
}else if(hold_token->type==KW_LESS_EQ)
}
void token_ptr_execute_ifndef_directive(struct Token_Pointer *ptr,struct token_ifndef_directive *ifndef_directive)
{
- ++ptr->number_of_last_expanded_macro;
+ //++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)
}
void token_ptr_execute_functionlike_define_directive(struct Token_Pointer *ptr,struct token_functionlike_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_undef_directive(struct Token_Pointer *ptr,struct token_undef_directive *undef_directive)
}
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;
+ id->macro_expansion_number=ptr->macro_expansion_number;
+ /*the hack deepens*/
+ ++ptr->macro_expansion_number;
+
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);
+ token_ptr_execute_functionlike_macro(ptr,((struct token_functionlike_define_directive*)id->last_defined_macro_with_this_id)->define);
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);
+ token_ptr_jump_to_first(ptr,macro->replacement_tokens);
}
- void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct identifier *id)
+ void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct functionlike_define_directive *macro)
{
- #warning this still needs to be done
+ token_ptr_load_functionlike_macro_arguments_with_tokens(ptr,macro);
+ token_ptr_jump_to_first(ptr,macro->replacement_tokens);
+ }
+ void token_ptr_execute_functionlike_macro_argument(struct Token_Pointer *ptr,struct functionlike_define_directive_argument *argument)
+ {
+ if(argument->number_of_substitution_tokens==0)
+ token_ptr_goto_next_token(ptr);
+ else
+ token_ptr_jump_to(ptr,argument->first_in_argument_substitution_tokens,argument->number_of_substitution_tokens);
}
- _Bool token_ptr_execute_preprocessing_directive(struct Token_Pointer *ptr,struct token *token)
+ void token_ptr_load_functionlike_macro_arguments_with_tokens(struct Token_Pointer *ptr,struct functionlike_define_directive *macro)
+ {
+ #warning this is not done!
+
+ int open_bracket_count=1;
+ size_t number_of_tokens_in_argument;
+
+ struct token *hold_token;
+ struct Queue_Node *hold_argument_node;
+ struct Queue_Node *hold_leading_token_node;
+
+ hold_argument_node=macro->arguments->first;
+
+ hold_leading_token_node=token_ptr_get_token_under_pointer(ptr);
+
+
+
+ number_of_tokens_in_argument=0;
+
+ ptr->state=TOKEN_POINTER_STATE_DONT_EXPAND_MACROS;
+
+ while(open_bracket_count>=1 && token_ptr_has_buffered_tokens(ptr))
+ {
+ hold_token=token_ptr_get_token_under_pointer(ptr);
+ if(hold_token->type==KW_OPEN_NORMAL)
+ ++open_bracket_count;
+ else if(hold_token->type==KW_CLOSE_NORMAL)
+ --open_bracket_count;
+ else if(hold_token->type==KW_COMMA && open_bracket_count==1) /*if we are at the top level ()*/
+ {
+
+ }else
+ {
+ ++number_of_tokens_in_argument;
+ }
+ }
+
+ /*
+ * we assume that this was the state of the pointer before setting it
+ * to TOKEN_POINTER_STATE_DONT_EXPAND_MACROS
+ */
+ ptr->state=TOKEN_POINTER_STATE_NORMAL;
+
+ }
+ _Bool token_ptr_do_preprocessing_stuff(struct Token_Pointer *token_pointer,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;
+ return 1;
case PKW_IFDEF:
token_ptr_execute_ifdef_directive(token_pointer,(struct token_ifdef_directive*)token);
- break;
+ return 1;
case PKW_IFNDEF:
token_ptr_execute_ifndef_directive(token_pointer,(struct token_ifndef_directive*)token);
- break;
+ return 1;
case PKW_ELSE:
wonky_assert(SHOULD_NOT_REACH_HERE);
- break;
+ return 1;
case PKW_ENDIF:
wonky_assert(SHOULD_NOT_REACH_HERE);
- break;
+ return 1;
case PKW_INCLUDE:
token_ptr_execute_include_directive(token_pointer,(struct token_include_directive*)token);
- break;
+ return 1;
case PKW_DEFINE:
token_ptr_execute_normal_define_directive(token_pointer,(struct token_normal_define_directive*)token);
- break;
+ return 1;
case PKW_FUNCTIONLIKE_DEFINE:
token_ptr_execute_functionlike_define_directive(token_pointer,(struct token_functionlike_define_directive*)token);
- break;
+ return 1;
case PKW_UNDEF:
token_ptr_execute_undef_directive(token_pointer,(struct token_undef_directive*)token);
- break;
+ return 1;
case PKW_LINE:
token_ptr_execute_line_directive(token_pointer,(struct token_line_directive*)token);
- break;
+ return 1;
case PKW_ERROR:
token_ptr_execute_error_directive(token_pointer,(struct token_error_directive*)token);
- break;
+ return 1;
case PKW_PRAGMA:
token_ptr_execute_pragma_directive(token_pointer,(struct token_pragma_directive*)token);
- break;
+ return 1;
case PKW_FILE_MACRO:
token_ptr_execute_file_special_macro(token_pointer,token);
- return;/*NOTICE*/
+ return 1;/*NOTICE*/
case PKW_LINE_MACRO:
token_ptr_execute_line_special_macro(token_pointer,token);
- return;/*NOTICE*/
+ return 1;/*NOTICE*/
case PKW_STDC_MACRO:
token_ptr_execute_stdc_special_macro(token_pointer,token);
- return;/*NOTICE*/
+ return 1;/*NOTICE*/
case PKW_STDC_HOSTED_MACRO:
token_ptr_execute_stdc_hosted_special_macro(token_pointer,token);
- return;/*NOTICE*/
+ return 1;/*NOTICE*/
case PKW_STDC_VERSION_MACRO:
token_ptr_execute_stdc_version_special_macro(token_pointer,token);
- return;/*NOTICE*/
+ return 1;/*NOTICE*/
case LT_EOF:
if(token_pointer->call_stack->size>0)
{
token_pointer->context=Stack_Pop(token_pointer->call_stack);
+ return 1;
}else
{
token_pointer->context=NULL;
- return;
+ return 1;
}
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;
+ token_ptr_goto_next_token(token_pointer);
+ return 1;
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
- )
+ if( id_is_a_macro(
+ hold_id_token->id,
+ token_pointer->macro_expansion_number,
+ token_pointer->program->current_translation_unit_number
+ )
+ &&
+ token_pointer->state!=TOKEN_POINTER_STATE_DONT_EXPAND_MACROS)
{
token_ptr_execute_macro(token_pointer,hold_id_token->id);
+ return 1;
+ }else
+ {
+ return 0; /*NOTICE*/
+ }
+ break;
+ }
+ case KW_AUTO:
+ case KW_DO:
+ case KW_DOUBLE:
+ case KW_INT:
+ case KW_STRUCT:
+ case KW_BREAK:
+ case KW_ELSE:
+ case KW_LONG:
+ case KW_SWITCH:
+ case KW_CASE:
+ case KW_ENUM:
+ case KW_REGISTER:
+ case KW_TYPEDEF:
+ case KW_CHAR:
+ case KW_EXTERN:
+ case KW_RETURN:
+ case KW_UNION:
+ case KW_CONST:
+ case KW_FLOAT:
+ case KW_SHORT:
+ case KW_UNSIGNED:
+ case KW_CONTINUE:
+ case KW_FOR:
+ case KW_SIGNED:
+ case KW_VOID:
+ case KW_DEFAULT:
+ case KW_GOTO:
+ case KW_SIZEOF:
+ case KW_VOLATILE:
+ case KW_IF:
+ case KW_STATIC:
+ case KW_WHILE:
+ case KW_INLINE:
+ case KW_RESTRICT:
+ case KW_BOOL:
+ case KW_COMPLEX:
+ case KW_IMAGINARY:
+ {
+ struct token_keyword *hold_kw_token;
+ hold_kw_token=(struct token_keyword*)token;
+ if( id_is_a_macro(
+ hold_kw_token->id,
+ token_pointer->macro_expansion_number,
+ token_pointer->program->current_translation_unit_number
+ )
+ &&
+ token_pointer->state!=TOKEN_POINTER_STATE_DONT_EXPAND_MACROS
+ )
+ {
+ token_ptr_execute_macro(token_pointer,hold_kw_token->id);
+ return 1;
}else
{
- return; /*NOTICE*/
+ return 0; /*NOTICE*/
}
break;
}
+ case PKW_MACRO_ARGUMENT:
+ token_ptr_execute_functionlike_macro_argument(token_pointer,((struct token_functionlike_define_argument*)token)->argument);
+ return 1;
default:
- return;
+ return 0;
}
}
void token_ptr_execute_stdc_hosted_special_macro(struct Token_Pointer *ptr,struct token *directive)
{
wonky_free(ptr);
}
- struct Token_Pointer_Context* get_token_ptr_context(struct Queue_Node *start)
+ struct Token_Pointer_Context* get_token_ptr_context(struct Queue_Node *start,size_t number_of_remaining_tokens)
{
struct Token_Pointer_Context *ret;
struct Source_Location *hold_location;
ret=wonky_malloc(sizeof(struct Token_Pointer_Context));
+
ret->current_token_node=start;
+ ret->number_of_remaining_tokens=number_of_remaining_tokens;
+
ret->ungeted_tokens=wonky_malloc(sizeof(struct Queue));
hold_location=((struct token*)start->data)->delta->location;
ret->filename=hold_location->src_name->name;
ret->filename_size=hold_location->src_name->name_size;
+
Queue_Init(ret->ungeted_tokens);
return ret;
}
}else
{
- while(ptr->context->current_token_node==NULL &&
- ptr->state!=TOKEN_POINTER_STATE_PREPROCESSING &&
+ while(ptr->context->number_of_remaining_tokens==0 &&
+ //ptr->state!=TOKEN_POINTER_STATE_PREPROCESSING &&
ptr->call_stack->size>0)
{
delete_token_ptr_context(ptr->context);
ptr->context=Stack_Pop(ptr->call_stack);
}
- return ptr->context->current_token_node!=NULL;
+ return ptr->context->number_of_remaining_tokens!=0;
}
}
void token_ptr_unget_token(struct Token_Pointer *ptr,struct token *token)
else
return NULL;
}
- void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to)
+ void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to,size_t number_of_remaining_tokens)
{
struct Token_Pointer_Context *new_context;
- if(where_to!=NULL)
+ if(where_to!=NULL && number_of_remaining_tokens!=0)
{
if(ptr->call_stack->size>1000)
{
push_token_ptr_error("Preprocessing bounds exceeded",ptr);
return;
}
- new_context=get_token_ptr_context(where_to);
+ new_context=get_token_ptr_context(where_to,number_of_remaining_tokens);
Stack_Push(ptr->call_stack,ptr->context);
ptr->context=new_context;
}
}
+ void token_ptr_jump_to_first(struct Token_Pointer *ptr,struct Queue *queue)
+ {
+ token_ptr_jump_to(ptr,queue->first,queue->size);
+ }
void delete_token_ptr_context(struct Token_Pointer_Context *context)
{
wonky_free(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
struct Token_Pointer_Context
{
struct Queue_Node *current_token_node;
+ size_t number_of_remaining_tokens;
+
struct Queue *ungeted_tokens;
size_t line;
size_t column;
struct Program *program;
enum Token_Pointer_State state;
- size_t number_of_last_expanded_macro;
+
+ size_t macro_expansion_number;
};
+
struct Preprocessing_Translation_Unit* get_preprocessing_translation_unit(struct Source_File *source);
void delete_preprocessing_translation_unit(struct Preprocessing_Translation_Unit *unit);
struct Token_Pointer* get_token_ptr(struct Preprocessing_Translation_Unit *unit,struct Program *program);
void delete_token_ptr(struct Token_Pointer *ptr);
- struct Token_Pointer_Context* get_token_ptr_context(struct Queue_Node *start);
+ struct Token_Pointer_Context* get_token_ptr_context(struct Queue_Node *start,size_t number_of_remaining_tokens);
_Bool token_ptr_has_remaining_tokens(struct Token_Pointer *ptr);
+ size_t token_ptr_get_functionlike_macro_number(struct Token_Pointer *ptr);
void token_ptr_unget_token(struct Token_Pointer *ptr,struct token *token);
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);
- _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_execute_functionlike_macro(struct Token_Pointer *ptr,struct functionlike_define_directive *macro);
+ void token_ptr_execute_functionlike_macro_argument(struct Token_Pointer *ptr,struct functionlike_define_directive_argument *argument);
+ void token_ptr_load_functionlike_macro_arguments_with_tokens(struct Token_Pointer *ptr,struct functionlike_define_directive *macro);
+ _Bool token_ptr_do_preprocessing_stuff(struct Token_Pointer *ptr,struct token *token);
void token_ptr_assume_location_of_token(struct Token_Pointer *ptr,struct token *token);
struct token* token_ptr_get_buffered_token(struct Token_Pointer *ptr);
struct token* token_ptr_check_buffered_token(struct Token_Pointer *ptr);
- void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to);
+ void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to,size_t number_of_remaining_tokens);
+ void token_ptr_jump_to_first(struct Token_Pointer *ptr,struct Queue *queue);
void delete_token_ptr_context(struct Token_Pointer_Context *context);
#endif
F diff --git a/src/semantics/program/translation_unit.hh b/src/semantics/program/translation_unit.hh --- a/src/semantics/program/translation_unit.hh +++ b/src/semantics/program/translation_unit.hh
{
TOKEN_POINTER_STATE_NORMAL,
TOKEN_POINTER_STATE_PREPROCESSING,
+ TOKEN_POINTER_STATE_DONT_EXPAND_MACROS,
TOKEN_POINTER_STATE_ERROR,
TOKEN_POINTER_STATE_END
};
F diff --git a/src/syntax/automatas/automata.c b/src/syntax/automatas/automata.c --- a/src/syntax/automatas/automata.c +++ b/src/syntax/automatas/automata.c
.size=sizeof("defined"),
.data="defined",
.last_defined_macro_with_this_id=(struct token*)&(struct token_defined_unary_operator){.type=PKW_DEFINE},
- .last_use_as_a_macro_argument=NULL,
+ .number_of_translation_unit_where_id_was_last_defined_as_a_macro=0,
+ .macro_expansion_number=0,
};
enum Source_Chars get_ch(const char *str,size_t limit)
{
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.hh
PKW_ID,
PKW_PUNCTUATOR,
PKW_DIRECTIVE,
+ PKW_MACRO_ARGUMENT,
LT_EOF,
LT_ERROR,
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
gmemmove(ret->data,data,size);
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;
-
+ ret->macro_expansion_number=0;
+ ret->hold_functionlike_define_directive=NULL;
return ret;
}
+ _Bool id_is_a_macro(struct identifier *id,size_t macro_expansion_number,size_t translation_unit_number)
+ {
+ /*dark majick*/
+ return (id->number_of_translation_unit_where_id_was_last_defined_as_a_macro == translation_unit_number
+ &&
+ id->macro_expansion_number!=macro_expansion_number);
+ }
#endif
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
#define WONKY_IDENTIFIER_H WONKY_IDENTIFIER_H
#include <identifier.hh>
#include <token.h>
+ #include <macro.h>
struct identifier /*there is only one of these per id*/
{
size_t size;
char *data;
struct token *last_defined_macro_with_this_id;
- struct functionlike_define_directive_argument *last_use_as_a_macro_argument;
+
+ struct functionlike_define_directive *hold_functionlike_define_directive;
+ struct functionlike_define_directive_argument *hold_functionlike_define_directive_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;
+ size_t macro_expansion_number;
};
struct identifier* get_identifier(char *data,size_t size);
+ _Bool id_is_a_macro(struct identifier *id,size_t macro_expansion_number,size_t translation_unit_number);
+
#endif
F diff --git a/src/syntax/macro.c b/src/syntax/macro.c --- a/src/syntax/macro.c +++ b/src/syntax/macro.c
Queue_Init(ret->arguments);
ret->replacement_tokens=wonky_malloc(sizeof(struct Queue));
Queue_Init(ret->replacement_tokens);
+ ret->is_variadic=0;
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* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to)
{
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;
+ ret->first_in_argument_substitution_tokens=NULL;
+ ret->number_of_substitution_tokens=0;
return ret;
}
+ #warning there is no check for duplicate ids in function like macro id list
+ #warning functionlike macro '(' after the name of the macro should be glued to id, because otherwise we cant differentiate between '(' in the macro and the begining of the argument list. Currently this is not parsed correctly!
#endif
F diff --git a/src/syntax/macro.h b/src/syntax/macro.h --- a/src/syntax/macro.h +++ b/src/syntax/macro.h
#ifndef WONKY_MACRO_H
#define WONKY_MACRO_H WONKY_MACRO_H
#include <macro.hh>
+
#include <stddef.h>
#include <wonky_malloc.h>
+ #include <macro.h>
struct normal_define_directive
struct identifier *id;
struct Queue *arguments;
struct Queue *replacement_tokens;
+ _Bool is_variadic;
};
struct functionlike_define_directive_argument
{
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);
+ struct functionlike_define_directive_argument* get_functionlike_define_directive_argument(struct token_functionlike_define_directive *belongs_to);
+
+
+
+
#endif
+
F diff --git a/src/syntax/macro.hh b/src/syntax/macro.hh --- a/src/syntax/macro.hh +++ b/src/syntax/macro.hh
struct functionlike_define_directive_argument;
struct normal_define_directive;
- struct functionlike_define_directive_argument;
+ struct functionlike_define_directive;
#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
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;
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;
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->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;
{
wonky_free(token);
}
+ _Bool token_is_keyword(struct token *token)
+ {
+ switch(token->type)
+ {
+ case KW_AUTO:
+ case KW_DO:
+ case KW_DOUBLE:
+ case KW_INT:
+ case KW_STRUCT:
+ case KW_BREAK:
+ case KW_ELSE:
+ case KW_LONG:
+ case KW_SWITCH:
+ case KW_CASE:
+ case KW_ENUM:
+ case KW_REGISTER:
+ case KW_TYPEDEF:
+ case KW_CHAR:
+ case KW_EXTERN:
+ case KW_RETURN:
+ case KW_UNION:
+ case KW_CONST:
+ case KW_FLOAT:
+ case KW_SHORT:
+ case KW_UNSIGNED:
+ case KW_CONTINUE:
+ case KW_FOR:
+ case KW_SIGNED:
+ case KW_VOID:
+ case KW_DEFAULT:
+ case KW_GOTO:
+ case KW_SIZEOF:
+ case KW_VOLATILE:
+ case KW_IF:
+ case KW_STATIC:
+ case KW_WHILE:
+ case KW_INLINE:
+ case KW_RESTRICT:
+ case KW_BOOL:
+ case KW_COMPLEX:
+ case KW_IMAGINARY:
+ return 1;
+ default:
+ return 0;
+
+ }
+
+ }
+ struct token* get_normal_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id)
+ {
+ 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(previous_location,current_location);
+ ret->define=get_normal_define_directive(id);
+
+ return (struct token*)ret;
+ }
+ struct token* get_functionlike_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id)
+ {
+ struct token_functionlike_define_directive *ret;
+
+ ret->type=PKW_FUNCTIONLIKE_DEFINE;
+ ret->delta=get_source_location_delta(previous_location,current_location);
+ ret->define=get_functionlike_define_directive(id);
+
+ return (struct token*)ret;
+ }
+ struct token* get_functionlike_define_directive_argument_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct functionlike_define_directive_argument *argument)
+ {
+ struct token_functionlike_define_argument *ret;
+ ret=wonky_malloc(sizeof(struct token_functionlike_define_argument));
+ ret->type=PKW_MACRO_ARGUMENT;
+ ret->delta=get_source_location_delta(previous_location,current_location);
+ ret->argument=argument;
+
+
+ return (struct token*)ret;
+
+ }
#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
{
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 functionlike_define_directive *define;
+ };
+ struct token_functionlike_define_argument
+ {
+ enum LEXER_TYPE type;
+ struct Source_Location_Delta *delta;
+ struct functionlike_define_directive_argument *argument;
};
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* get_ifdef_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id,struct Queue_Node *if_true,struct Queue_Node *if_false,struct Queue_Node *end_of_if_directive);
- struct token* get_normal_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id,struct Queue *replacement_tokens);
+ struct token* get_normal_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id);
- struct token* get_functionlike_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id,struct Queue *argument_id_list_tokens,struct Queue *replacement_tokens);
+ struct token* get_functionlike_define_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id);
+ struct token* get_functionlike_define_directive_argument_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct functionlike_define_directive_argument *argument);
struct token* get_undef_directive_token(struct Source_Location *current_location,struct Source_Location *previous_location,struct identifier *id);
struct token* get_line_directive_token(struct Source_Location *current_location,struct Source_Location *new_location,struct Source_Location *previous_location);
char* get_string_from_token(struct token* token);
void delete_token(struct token* token);
+ _Bool token_is_keyword(struct token *token);
#endif
F diff --git a/src/syntax/token/token.hh b/src/syntax/token/token.hh --- a/src/syntax/token/token.hh +++ b/src/syntax/token/token.hh
struct token_ifndef_directive;
struct token_normal_define_directive;
struct token_functionlike_define_directive;
+ struct token_functionlike_define_argument;
struct token_undef_directive;
struct token_line_directive;
struct token_error_directive;