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.h
void 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);
#endif
F 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.c
case 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.h
struct 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);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#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
if(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 directive
default:
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.h
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_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.hh
PKW_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.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 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);