WONKY



LOG | FILES | OVERVIEW


F diff --git a/src/environment/error/gcc_error.c b/src/environment/error/gcc_error.c --- a/src/environment/error/gcc_error.c +++ b/src/environment/error/gcc_error.c
{
va_list args;
va_start(args,err_fmt);
- push_generic_note_vargs(program,err_fmt,args);
+ push_generic_error_vargs(program,err_fmt,args);
va_end(args);
}
void push_generic_error_vargs(struct Program *program,const char *err_fmt,va_list args)
Queue_Push(program->errors,error);
}
+ void push_token_pointer_error(struct Token_Pointer *ptr,const char *err_fmt,...)
+ {
+ va_list args;
+ va_start(args,err_fmt);
+ push_token_pointer_error_vargs(ptr,err_fmt,args);
+ va_end(args);
+ }
+ void push_token_pointer_error_vargs(struct Token_Pointer *ptr,const char *err_fmt,va_list args)
+ {
+ ssize_t line=-1;
+ ssize_t column=-1;
+ char *filename=NULL;
+ size_t filename_size=0;
+
+ struct Wonky_Message *hold;
+
+ if(ptr->context)
+ {
+ line=ptr->context->line;
+ column=ptr->context->column;
+ filename=ptr->context->filename;
+ filename_size=ptr->context->filename_size;
+ }
+
+ hold=get_wonky_message_vargs(WONKY_MESSAGE_TYPE_ERROR,
+ WONKY_MESSAGE_SOURCE_TRANSLATION,
+ line,column,filename,filename_size,err_fmt,args);
+ Queue_Push(ptr->program->errors,hold);
+ }
void push_translation_error(const char *fmt,struct Translation_Data *translation_data,...)
{
va_list args;
line,column,filename,filename_size,fmt,args);
s=wonky_string_stream(hold->message);
wonky_fseek(&s,0,SEEK_END);
- wonky_fprintf(&s,"\n%WIC",translation_data->token_pointer);
+ wonky_fprintf(&s,"%WIC",translation_data->token_pointer);
Queue_Push(translation_data->program->errors,hold);
wonky_string_stream_delete(&s);
}
WONKY_MESSAGE_SOURCE_TRANSLATION,
line,column,filename,filename_size,fmt,args);
s=wonky_string_stream(hold->message);
- wonky_fprintf(&s,"\n%WIC",translation_data->token_pointer);
+ wonky_fprintf(&s,"%WIC",translation_data->token_pointer);
Queue_Push(translation_data->program->errors,hold);
wonky_string_stream_delete(&s);
}
if(msg->filename && msg->filename_size)
wonky_write(out,msg->filename,msg->filename_size);
if(msg->line>0)
+ {
wonky_fprintf(out,"%s%zu:%zu ",(msg->filename?":":" "),(size_t)msg->line,(size_t)msg->column);
+ }
wonky_fprintf(out,"%s\n",msg->message->cs);
}
F diff --git a/src/environment/error/gcc_error.h b/src/environment/error/gcc_error.h --- a/src/environment/error/gcc_error.h +++ b/src/environment/error/gcc_error.h
void push_message_struct(struct Program *program,struct Wonky_Message *msg);
+ void push_token_pointer_error(struct Token_Pointer *ptr,const char *err_fmt,...);
+ void push_token_pointer_error_vargs(struct Token_Pointer *ptr,const char *err_fmt,va_list args);
+
void push_translation_error(const char *fmt,struct Translation_Data *translation_data,...);
void push_translation_error_vargs(const char *fmt,struct Translation_Data *translation_data,va_list args);
void push_translation_note(const char *fmt,struct Translation_Data *translation_data,...);
void print_message(struct wonky_stream *out,struct Wonky_Message *msg);
void delete_message(struct Program *program,struct Wonky_Message *msg);
+ void delete_error(struct Program *program,struct Wonky_Message *error);
#endif
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
{
/*the first '##' has been eaten by the caller*/
do{
+ /*first pass is not eol*/
hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where,directive);
Queue_Push(ret_q,hold_token);
}while(preprocessing_get_and_check_token(lexer_data,KW_HASHTAG_HASHTAG) && !preprocessing_eol(lexer_data));
return ret;
}
- do{
-
+ preprocessing_skip_white_space(lexer_data);
- preprocessing_skip_white_space(lexer_data);
+ where_does_the_token_start_in_the_source_file=lexer_data->where_in_src;
- where_does_the_token_start_in_the_source_file=lexer_data->where_in_src;
-
- if(preprocessing_eol(lexer_data))
- return NULL;
+ if(preprocessing_eol(lexer_data))
+ return NULL;
- hold_node=preprocessing_feed_automata_until_error(lexer_data);
+ hold_node=preprocessing_feed_automata_until_error(lexer_data);
- if(hold_node==NULL)
- return get_error_token("Unrecognised lexical element",get_source_location(
- lexer_data->which_column,
- lexer_data->which_row,
- where_does_the_token_start_in_the_source_file,
- lexer_data->where_in_src-where_does_the_token_start_in_the_source_file,
- lexer_data->src
- ),
- lexer_data->previous_token_location,
- lexer_data->program);
- }while(hold_node->keyword==KW_COMMENT);
+ if(hold_node==NULL)
+ return get_error_token("Unrecognised lexical element",get_source_location(
+ lexer_data->which_column,
+ lexer_data->which_row,
+ where_does_the_token_start_in_the_source_file,
+ lexer_data->where_in_src-where_does_the_token_start_in_the_source_file,
+ lexer_data->src
+ ),
+ lexer_data->previous_token_location,
+ lexer_data->program);
ret=preprocessing_make_token_finishing_on_node(lexer_data, hold_node, where_does_the_token_start_in_the_source_file,extract_directive,extract_defined_statement);
lexer_data->is_in_the_begining_of_line=0;
}
struct Automata_Node *preprocessing_feed_automata_next_char(struct Lexer_Data *lexer_data,struct Automata_Node *node)
{
- enum {
- UNKNOWN_CHAR,
- START_OF_POSSIBLE_LINE_SPLICE,
- KNOWN_CHAR
- } state;
size_t hold_where_in_src;
size_t hold_which_column;
size_t hold_which_row;
struct Automata_Node *ret;
enum Source_Chars ch;
- state=UNKNOWN_CHAR;
hold_where_in_src=lexer_data->where_in_src;
hold_which_column=lexer_data->which_column;
hold_which_row=lexer_data->which_row;
- do{
-
- if(lexer_eof(lexer_data))
- return NULL;
-
- switch(state)
- {
- case UNKNOWN_CHAR:
- if(lexer_data->src->src[lexer_data->where_in_src] == '\\')
- {
- state=START_OF_POSSIBLE_LINE_SPLICE;
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- }else
- {
- state=KNOWN_CHAR;
- }
- break;
- case START_OF_POSSIBLE_LINE_SPLICE:
- if(lexer_data->src->src[lexer_data->where_in_src] == '\n')
- {
- state=UNKNOWN_CHAR;
- ++lexer_data->where_in_src;
- lexer_data->which_column=0;
- ++lexer_data->which_row;
- }else
- {
- state=KNOWN_CHAR;
- }
- break;
- default:
- wonky_assert(SHOULD_NOT_REACH_HERE);
- }
-
- }while(state!=KNOWN_CHAR);
-
-
- ch=get_ch(& lexer_data->src->src[lexer_data->where_in_src],1);
-
- if(ch==CHAR_VERTICAL_TAB)
- return NULL;
+ ch=lexer_get_ch_accounting_for_linesplices_and_comments(lexer_data->program,lexer_data->src->src,
+ lexer_data->src->src_size,
+ &lexer_data->where_in_src,
+ &lexer_data->which_row,
+ &lexer_data->which_column);
- if(node->delta[ch]==id_node)
+ if(ch==CHAR_FORM_FEED_TAB)
+ {
+ ret=NULL;
+ }else if(node->delta[ch]==id_node)
{
ret=get_new_id_node(node,ch);
}else
{
ret=node->delta[ch];
}
+
if(ret==NULL)
{
lexer_data->where_in_src=hold_where_in_src;
return NULL;
}else
{
- ++lexer_data->which_column;
- ++lexer_data->where_in_src;
return ret;
}
}
void preprocessing_skip_white_space(struct Lexer_Data *lexer_data)
{
- enum White_Space_States
- {
- BLANK_SPACE,
- POSSIBLE_LINE_SPLICE,
- NON_WHITE_SPACE
- }state=BLANK_SPACE;
-
- while(state!=NON_WHITE_SPACE && (!preprocessing_eol(lexer_data) || state==POSSIBLE_LINE_SPLICE))
- {
- switch(lexer_data->src->src[lexer_data->where_in_src])
- {
- case '\n':
- if(state==POSSIBLE_LINE_SPLICE)
- {
- state=BLANK_SPACE;
- ++lexer_data->where_in_src;
- ++lexer_data->which_row;
- lexer_data->which_column=0;
- }else
- {
- return;
- }
- break;
- case ' ':
- case '\t':
- case '\v':
- if(state==POSSIBLE_LINE_SPLICE)
- state=NON_WHITE_SPACE;
- else
- {
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- }
-
- break;
- case '\\':
- if(state==POSSIBLE_LINE_SPLICE)
- {
- state=NON_WHITE_SPACE;
- }else
- {
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- state=POSSIBLE_LINE_SPLICE;
- }
- break;
- default:
- state=NON_WHITE_SPACE;
- }
+ preprocessing_skip_white_space_inner(lexer_data->program,
+ lexer_data->src->src,
+ lexer_data->src->src_size,
+ &lexer_data->where_in_src,
+ &lexer_data->which_row,
+ &lexer_data->which_column);
+ }
+ void preprocessing_skip_white_space_inner(struct Program *program,char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_col)
+ {
+
+ size_t wh_in_src=*where_in_src;
+ size_t wh_line=*which_line;
+ size_t wh_col=*which_col;
+ for(enum Source_Chars ch=CHAR_SPACE;
+ (ch==CHAR_SPACE || ch==CHAR_VERTICAL_TAB || ch==CHAR_HORISONTAL_TAB) && wh_in_src<src_size;
+ ch=lexer_get_ch_accounting_for_linesplices_and_comments(
+ program,
+ src,
+ src_size,
+ &wh_in_src,
+ &wh_line,
+ &wh_col)
+ )
+ {
+ *where_in_src=wh_in_src;
+ *which_line=wh_line;
+ *which_col=wh_col;
}
}
_Bool preprocessing_eol(struct Lexer_Data *lexer_data)
{
+ char *src=lexer_data->src->src;
+ size_t src_size=lexer_data->src->src_size;
+ size_t where_in_src;
+ size_t line;
+ size_t column;
+
+
if(lexer_data->buffer_token)
- return lexer_data->src->src[lexer_data->previous_token_location->starting_byte_index
- +lexer_data->previous_token_location->length]=='\n';
- else
- return lexer_data->src->src[lexer_data->where_in_src]=='\n' || lexer_eof(lexer_data);
+ {
+ return 0;
+ } else
+ {
+ where_in_src=lexer_data->where_in_src;
+ line=lexer_data->which_row;
+ column=lexer_data->which_column;
+ }
+
+ preprocessing_skip_white_space_inner(lexer_data->program,src,src_size,&where_in_src,&line,&column);
+
+
+
+ return lexer_get_ch_accounting_for_linesplices_and_comments(lexer_data->program,src,src_size,&where_in_src,&line,&column)==CHAR_FORM_FEED_TAB;
}
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,_Bool create_defined_statement)
{
wonky_assert(lexer_data->where_in_src > start_position);
wonky_assert(is_valid_automata_node(finishing_node));
+
token_location=get_source_location(
lexer_data->which_row,
lexer_data->which_column,
lexer_data->src
);
+
if(create_directive)
{
switch(finishing_node->preprocessing_keyword)
{
case PKW_IF:
- return preprocessing_lex_if_directive(lexer_data,token_location);
+ return preprocessing_lex_if_directive(lexer_data,token_location,PKW_IF);
case PKW_IFDEF:
return preprocessing_lex_ifdef_directive(lexer_data,token_location);
case PKW_IFNDEF:
return preprocessing_lex_ifndef_directive(lexer_data,token_location);
case PKW_ELIF:
- return preprocessing_lex_if_directive(lexer_data,token_location);
+ if(lexer_data->is_in_if_directive_body)
+ {
+ return preprocessing_lex_if_directive(lexer_data,token_location,PKW_ELIF);
+ }
+ else
+ return get_error_token("Stray #elif not participating in any #if",token_location,lexer_data->previous_token_location,lexer_data->program);
case PKW_ELSE:
- return preprocessing_return_else_token(lexer_data,token_location);
+ if(lexer_data->is_in_if_directive_body)
+ return preprocessing_return_else_token(lexer_data,token_location);
+ else
+ return get_error_token("Stray #else not participating in any #if",token_location,lexer_data->previous_token_location,lexer_data->program);
case PKW_ENDIF:
- return preprocessing_return_endif_token(lexer_data,token_location);
+ if(lexer_data->is_in_if_directive_body)
+ return preprocessing_return_endif_token(lexer_data,token_location);
+ else
+ return get_error_token("Stray #endif not participating in any #if",token_location,lexer_data->previous_token_location,lexer_data->program);
case PKW_INCLUDE:
return preprocessing_lex_include_directive(lexer_data,token_location);
case PKW_DEFINE:
ret->delta=get_source_location_delta(lexer_data->previous_token_location,where);
hold_error_size=lexer_data->where_in_src-hold_start_location;
- ret->error_message=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_TRANSLATION,where->line,where->column,where->src->src_name->name,where->src->src_name->name_size,"#error ");
+ ret->error_message=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_TRANSLATION,where->line,where->column,where->src->src_name->name,where->src->src_name->name_size,"#error");
string_stream=wonky_string_stream(ret->error_message->message);
+ wonky_fseek(&string_stream,0,SEEK_END);
wonky_write(&string_stream,lexer_data->src->src+hold_start_location,hold_error_size);
return (struct token*)ret;
}
- struct token* preprocessing_lex_if_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)
+ struct token* preprocessing_lex_if_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,enum LEXER_TYPE if_type)
{
struct token_if_directive *ret;
+ wonky_assert(if_type==PKW_IF || if_type==PKW_ELIF);
+
ret=wonky_malloc(sizeof(struct token_if_directive));
- ret->type=PKW_IF;
+ ret->type=if_type;
ret->delta=get_source_location_delta(lexer_data->previous_token_location,where);
ret->controlling_expression=wonky_malloc(sizeof(struct Queue));
Queue_Init(ret->if_true);
Queue_Init(ret->if_false);
- while(!preprocessing_eol(lexer_data))
- Queue_Push(ret->controlling_expression,
- preprocessing_extract_next_token_in_iflike_directive_control_statement(lexer_data));
+ preprocessing_lex_if_directive_control_statement(lexer_data,ret->controlling_expression);
preprocessing_lex_finish_iflike_directive(lexer_data,ret->if_true,ret->if_false);
+
return (struct token*)ret;
+
+ }
+ void preprocessing_lex_if_directive_control_statement(struct Lexer_Data *lexer_data,struct Queue *control_statement_tokens)
+ {
+ while(!preprocessing_eol(lexer_data))
+ Queue_Push(control_statement_tokens,
+ preprocessing_extract_next_token_in_iflike_directive_control_statement(lexer_data));
}
struct token* preprocessing_lex_ifdef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)
{
void preprocessing_lex_finish_iflike_directive(struct Lexer_Data *lexer_data,struct Queue *if_true,struct Queue *if_false)
{
struct token *hold_token;
+ struct token_if_directive *ret;
+ _Bool hold_lexerdata_state;
+
+ hold_lexerdata_state=lexer_data->is_in_if_directive_body; /*=(*/
+ lexer_data->is_in_if_directive_body=1;
+
+ /* За мен: тука може да му пуснеш типа на токена и да парсваш спрямо него.
+ * Не е супер сложното парсване тъй че може да го правиш линейно. (По-оптимално
+ * е спрямо стека така или иначе :Р
+ * НОВО: направо не давай типа, а направо си парсвай всичко в една фунцкия!
+ * */
+
while((hold_token=lexer_extract_next_token(lexer_data))!=NULL)
{
if(hold_token->type==PKW_ELSE)
{
- while((hold_token=lexer_extract_next_token(lexer_data))!=NULL)
+ while(!lexer_check(lexer_data,PKW_ENDIF) && (hold_token=lexer_extract_next_token(lexer_data))!=NULL)
{
- if(hold_token->type==PKW_ENDIF)
- break;
- else
- Queue_Push(if_false,hold_token);
+ Queue_Push(if_false,hold_token);
}
- if(hold_token==NULL)
+ if(lexer_check(lexer_data,PKW_ENDIF))
+ {
+ hold_token=lexer_extract_next_token(lexer_data);
+ }else if(lexer_eof(lexer_data))
+ {
push_generic_error(lexer_data->program,"Reached end of file before reaching a #endif");
+ }
- delete_token(hold_token);
+ if(hold_token)
+ delete_token(hold_token);
break;
}else if(hold_token->type==PKW_ELIF)
{
Queue_Push(if_true,hold_token);
}
}
+
+ lexer_data->is_in_if_directive_body=hold_lexerdata_state;
}
struct token* preprocessing_lex_define_directive(struct Lexer_Data *lexer_data,struct Source_Location *where)
{
/*returns NULL on eol*/
hold_token=preprocessing_extract_next_token(lexer_data);
-
+ //*(volatile char*)hold_token;
/*no eol tokens*/
wonky_assert(hold_token!=NULL);
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_include_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
- struct token* preprocessing_lex_if_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
+ struct token* preprocessing_lex_if_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,enum LEXER_TYPE if_type);
+ struct token* preprocessing_lex_elif_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
+ /*not chomping the ending #endif token is used for the #elif tokens*/
+ struct token* preprocessing_lex_iflike_directive_inner(struct Lexer_Data *lexer_data,struct Source_Location *where);
+ void preprocessing_lex_if_directive_control_statement(struct Lexer_Data *lexer_data,struct Queue *control_statement_tokens);
struct token* preprocessing_lex_ifdef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
struct token* preprocessing_lex_ifndef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
struct token* preprocessing_lex_ifdefndef_directive(struct Lexer_Data *lexer_data,struct Source_Location *where,enum LEXER_TYPE type);
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_in_iflike_directive_control_statement(struct Lexer_Data *lexer_data);
+ struct token* preprocessing_extract_next_directive_in_iflike_statement_body(struct Lexer_Data *lexer_data);
struct token* preprocessing_extract_next_token_inner(struct Lexer_Data *lexer_data,_Bool extract_directive,_Bool extract_defined_statement);
_Bool preprocessing_get_and_check_token(struct Lexer_Data *lexer_data,enum LEXER_TYPE token_type);
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);
+ void preprocessing_skip_white_space_inner(struct Program *program,char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_col);
+
_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,_Bool create_defined_statement);
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
ret->which_column=0;
ret->which_row=0;
ret->is_in_the_begining_of_line=1;
+ ret->is_in_if_directive_body=0;
ret->automata_view=AUTOMATA_VIEW_NORMAL;
ret->src=src;
ret->program=program;
void lexer_skip_white_space(struct Lexer_Data *lexer_data)
{
- enum White_Space_States
- {
- BLANK_SPACE,
- POSSIBLE_LINE_SPLICE,
- NON_WHITE_SPACE
- }state=BLANK_SPACE;
+ size_t where_in_src=lexer_data->where_in_src;
+ size_t which_line=lexer_data->which_row;
+ size_t which_column=lexer_data->which_column;
+ enum Source_Chars ch;
- while(state!=NON_WHITE_SPACE && !lexer_eof(lexer_data))
+ for(ch=CHAR_SPACE;
+ (ch==CHAR_SPACE || ch==CHAR_VERTICAL_TAB || ch==CHAR_HORISONTAL_TAB || ch==CHAR_FORM_FEED_TAB) && !lexer_eof(lexer_data);
+ ch=lexer_get_ch_accounting_for_linesplices_and_comments(
+ lexer_data->program,
+ lexer_data->src->src,
+ lexer_data->src->src_size,
+ &where_in_src,
+ &which_line,
+ &which_column)
+ )
{
- switch(lexer_data->src->src[lexer_data->where_in_src])
- {
- case '\n':
- state=BLANK_SPACE;
- ++lexer_data->where_in_src;
- ++lexer_data->which_row;
- lexer_data->which_column=0;
- lexer_data->is_in_the_begining_of_line=1;
- break;
- case ' ':
- case '\t':
- case '\v':
- if(state==POSSIBLE_LINE_SPLICE)
- state=NON_WHITE_SPACE;
- else
- {
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- }
- break;
- case '\\':
- if(state==POSSIBLE_LINE_SPLICE)
- {
- state=NON_WHITE_SPACE;
- }else
- {
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- state=POSSIBLE_LINE_SPLICE;
- }
- break;
- default:
- state=NON_WHITE_SPACE;
- }
+ if(ch==CHAR_FORM_FEED_TAB)
+ lexer_data->is_in_the_begining_of_line=1;
+ lexer_data->where_in_src=where_in_src;
+ lexer_data->which_row=which_line;
+ lexer_data->which_column=which_column;
}
+
+
}
inline _Bool lexer_eof(struct Lexer_Data *lexer_data)
{
- return lexer_data->where_in_src==lexer_data->src->src_size;
+ #warning might want a lexer_skip_white_space(lexer_data) here =)
+ return lexer_data->where_in_src>=lexer_data->src->src_size;
}
-
struct token* lexer_extract_next_token(struct Lexer_Data *lexer_data)
{
-
struct token *ret;
struct Automata_Node *hold_node;
size_t where_does_the_token_start_in_the_source_file;
return ret;
}
- do{
-
-
lexer_skip_white_space(lexer_data);
where_does_the_token_start_in_the_source_file=lexer_data->where_in_src;
),
lexer_data->previous_token_location,
lexer_data->program);
- }while(hold_node->keyword==KW_COMMENT);
-
ret=lexer_make_token_finishing_on_node(lexer_data, hold_node, where_does_the_token_start_in_the_source_file);
lexer_data->is_in_the_begining_of_line=0;
lexer_data->previous_token_location=ret->delta->location;
struct Automata_Node *lexer_feed_automata_next_char(struct Lexer_Data *lexer_data,struct Automata_Node *node)
{
- enum {
- UNKNOWN_CHAR,
- START_OF_POSSIBLE_LINE_SPLICE,
- KNOWN_CHAR
- } state;
size_t hold_where_in_src;
size_t hold_which_column;
size_t hold_which_row;
struct Automata_Node *ret;
enum Source_Chars ch;
- state=UNKNOWN_CHAR;
hold_where_in_src=lexer_data->where_in_src;
hold_which_column=lexer_data->which_column;
hold_which_row=lexer_data->which_row;
- do{
-
- if(lexer_eof(lexer_data))
- return NULL;
-
- switch(state)
- {
- case UNKNOWN_CHAR:
- if(lexer_data->src->src[lexer_data->where_in_src] == '\\')
- {
- state=START_OF_POSSIBLE_LINE_SPLICE;
- ++lexer_data->where_in_src;
- ++lexer_data->which_column;
- }else
- {
- state=KNOWN_CHAR;
- }
- break;
- case START_OF_POSSIBLE_LINE_SPLICE:
- if(lexer_data->src->src[lexer_data->where_in_src] == '\n')
- {
- state=UNKNOWN_CHAR;
- ++lexer_data->where_in_src;
- lexer_data->which_column=0;
- ++lexer_data->which_row;
- }else
- {
- state=KNOWN_CHAR;
- }
- break;
- default:
- wonky_assert(SHOULD_NOT_REACH_HERE);
- }
-
- }while(state!=KNOWN_CHAR);
-
+ ch=lexer_get_ch_accounting_for_linesplices_and_comments(lexer_data->program,lexer_data->src->src,
+ lexer_data->src->src_size,
+ &lexer_data->where_in_src,
+ &lexer_data->which_row,
+ &lexer_data->which_column);
- ch=get_ch(& lexer_data->src->src[lexer_data->where_in_src],1);
if(node->delta[ch]==id_node)
{
ret=get_new_id_node(node,ch);
return NULL;
}else
{
- switch(ch)
- {
- case CHAR_VERTICAL_TAB:
- case CHAR_FORM_FEED_TAB:
- ++lexer_data->which_row;
- ++lexer_data->where_in_src;
- lexer_data->which_column=0;
- break;
- default:
- ++lexer_data->which_column;
- ++lexer_data->where_in_src;
- }
return ret;
}
}
- struct token* lexer_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position)
+ struct token *lexer_make_token_finishing_on_node(struct Lexer_Data *lexer_data,struct Automata_Node *finishing_node,size_t start_position)
{
struct Source_Location *token_location;
lexer_data->src
);
+
switch(finishing_node->keyword)
{
case KW_HASHTAG_HASHTAG:
return preprocessing_lex_directive(lexer_data,where);
}
- _Bool lex_get_and_check(struct Lexer_Data *lexer_data,struct Source_Location *where,enum LEXER_TYPE token_type)
+ _Bool lexer_get_and_check(struct Lexer_Data *lexer_data,enum LEXER_TYPE token_type)
+ {
+ if(lexer_check(lexer_data,token_type))
+ {
+ delete_token(lexer_data->buffer_token);
+ return 1;
+ }else
+ {
+ return 0;
+ }
+ }
+ _Bool lexer_check(struct Lexer_Data *lexer_data,enum LEXER_TYPE token_type)
{
if(lexer_data->buffer_token==NULL)
lexer_data->buffer_token=lexer_extract_next_token(lexer_data);
if(lexer_data->buffer_token && lexer_data->buffer_token->type==token_type)
{
- lexer_data->buffer_token=NULL;
return 1;
}else
{
return 0;
}
}
+ enum Source_Chars lexer_get_ch_accounting_for_linesplices(struct Program *program,const char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_column)
+ {
+ enum {
+ UNKNOWN_CHAR,
+ START_OF_POSSIBLE_LINE_SPLICE,
+ KNOWN_CHAR
+ } state = UNKNOWN_CHAR;
+ enum Source_Chars ch;
+
+ while(state!=KNOWN_CHAR && *where_in_src<src_size)
+ {
+ ch=get_ch(src+*where_in_src,src_size-*where_in_src);
+ switch(state)
+ {
+ case UNKNOWN_CHAR:
+ if(ch==CHAR_BACKWARD_SLASH)
+ {
+ state=START_OF_POSSIBLE_LINE_SPLICE;
+ ++*where_in_src;
+ ++*which_column;
+ }else
+ {
+ state=KNOWN_CHAR;
+ }
+ break;
+ case START_OF_POSSIBLE_LINE_SPLICE:
+ if(ch==CHAR_FORM_FEED_TAB)
+ {
+ state=UNKNOWN_CHAR;
+ ++*where_in_src;
+ *which_column=0;
+ ++*which_line;
+ }else
+ {
+ state=KNOWN_CHAR;
+ }
+ break;
+ default:
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+ }
+ }
+
+ if(*where_in_src<src_size && state==KNOWN_CHAR)
+ {
+ ++*where_in_src;
+ if(ch==CHAR_FORM_FEED_TAB)
+ {
+ ++*which_line;
+ *which_column=0;
+ }else
+ {
+ ++*which_column;
+ }
+ return ch;
+ }else if(state==START_OF_POSSIBLE_LINE_SPLICE)
+ {
+ push_generic_error(program,"Can't linesplice into an end of file");
+ return CHAR_SPACE;
+ }else
+ {
+ return CHAR_SPACE;
+ }
+
+ }
+ enum Source_Chars lexer_get_ch_accounting_for_linesplices_and_comments(struct Program *program,const char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_column)
+ {
+ enum Source_Chars ch;
+
+ ch=lexer_get_ch_accounting_for_linesplices(program,src,src_size,where_in_src,which_line,which_column);
+ if(ch==CHAR_FORWARD_SLASH)
+ {
+ size_t wh_in_src=*where_in_src;
+ size_t wh_line=*which_line;
+ size_t wh_col=*which_column;
+
+ ch=lexer_get_ch_accounting_for_linesplices(program,src,src_size,&wh_in_src,&wh_line,&wh_col);
+
+ if(ch==CHAR_FORWARD_SLASH)
+ {
+ while(
+ lexer_get_ch_accounting_for_linesplices(
+ program,src,src_size,&wh_in_src,&wh_line,&wh_col)!=CHAR_FORM_FEED_TAB
+ &&
+ wh_in_src<src_size
+ );
+
+ *where_in_src=wh_in_src;
+ *which_line=wh_line;
+ *which_column=wh_col;
+ return CHAR_FORM_FEED_TAB;
+
+ }else if(ch==CHAR_STAR)
+ {
+ enum {
+ START,
+ STAR,
+ END
+ } state = START;
+
+ while(state!=END && wh_in_src<src_size)
+ {
+ ch=lexer_get_ch_accounting_for_linesplices(program,src,src_size,&wh_in_src,&wh_line,&wh_col);
+ if(state==START && ch==CHAR_STAR)
+ state=STAR;
+ else if(state==STAR && ch==CHAR_FORWARD_SLASH)
+ state=END;
+ else
+ state=START;
+ }
+ *where_in_src=wh_in_src;
+ *which_line=wh_line;
+ *which_column=wh_col;
+ return CHAR_SPACE;
+ }else
+ {
+ return CHAR_FORWARD_SLASH;
+ }
+ }else
+ {
+ return ch;
+ }
+
+
+ }
void delete_lexer_data(struct Lexer_Data *lexer_data)
{
wonky_free(lexer_data);
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
size_t which_row;
_Bool is_in_the_begining_of_line;
+ _Bool is_in_if_directive_body; /*hack*/
enum Automata_View automata_view;
_Bool lexer_eof(struct Lexer_Data *lexer_data);
struct token* lexer_extract_next_token(struct Lexer_Data *lexer_data);
+ struct token* lexer_extract_next_token_for_elif_directive_body(struct Lexer_Data *lexer_data);
+ struct token* lexer_extract_next_token_inner(struct Lexer_Data *lexer_data);
+
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 *lex_defined_unary_operator(struct Lexer_Data *lexer_data,struct Source_Location *where);
struct token *lex_preprocessing_directive(struct Lexer_Data *lexer_data,struct Source_Location *where);
- _Bool lex_get_and_check(struct Lexer_Data *lexer_data,struct Source_Location *where,enum LEXER_TYPE token_type);
+ _Bool lexer_get_and_check(struct Lexer_Data *lexer_data,enum LEXER_TYPE token_type);
+ _Bool lexer_check(struct Lexer_Data *lexer_data,enum LEXER_TYPE token_type);
+ enum Source_Chars lexer_get_ch_accounting_for_linesplices(struct Program *program,const char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_column);
+ enum Source_Chars lexer_get_ch_accounting_for_linesplices_and_comments(struct Program *program,const char *src,size_t src_size,size_t *where_in_src,size_t *which_line,size_t *which_column);
void delete_lexer_data(struct Lexer_Data *lexer_data);
F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c
struct Denoted *hold;
prototype=parse_declaration_specifiers(translation_data,scope);
+
while(!get_and_check(translation_data,KW_SEMICOLON))
{
hold=parse_declarator(translation_data,scope,prototype);
-
if(hold->denotation==DT_Function)
{
//Scope_Push(scope,hold,translation_data);
{
/*TODO error*/
Queue_Push(where_to_push_objects,get_declaration_error_tree(hold));
- push_generic_error(translation_data->program,"declaration expected");
+ push_translation_error("declaration expected",translation_data);
/*search for end of erronous declaration*/
break;
{
/*TODO error*/
Queue_Push(where_to_push_objects,get_declaration_error_tree(NULL));
- push_generic_error(translation_data->program,"Semicolon expected");
+ push_translation_error("Semicolon expected",translation_data);
break;
}
}
if(!get_and_check(translation_data,KW_CLOSE_NORMAL))
{
/*TODO error*/
- push_generic_error(translation_data->program,"expected a ')' finishing the parameter list");
+ push_translation_error("expected a ')' finishing the parameter list",translation_data);
Queue_Push(parameters,get_denoted_error(NULL));
}
F diff --git a/src/frontend/parse/parse_expression.c b/src/frontend/parse/parse_expression.c --- a/src/frontend/parse/parse_expression.c +++ b/src/frontend/parse/parse_expression.c
case KW_CONSTANT:
return (struct AST_Expression*)get_constant_tree(get_expression_value_constant(((struct token_constant*)hold_token)->constant));
case KW_ID:
- return (struct AST_Expression*)get_designator_tree(((struct token_identifier*)hold_token)->id,scope,translation_data);
+ return (struct AST_Expression*)get_designator_tree((struct token_identifier*)hold_token,scope,translation_data);
case KW_OPEN_NORMAL:
hold=(struct AST_Expression*)parse_expression(translation_data,scope);
if(get_and_check(translation_data,KW_CLOSE_NORMAL))
F diff --git a/src/misc/print.c b/src/misc/print.c --- a/src/misc/print.c +++ b/src/misc/print.c
void print_token(struct wonky_stream *out,struct token *token)
{
- wonky_fprintf(out,"[TOKEN: ");
- switch(token->type)
+ wonky_fprintf(out,"[TOKEN %WSl: ",token->delta->location);
+ print_token_text(out,token);
+ wonky_fprintf(out,"]\n");
+ }
+
+ char print_tokens_of_program(struct wonky_stream *out,char **base_source_names)
+ {
+
+ struct Source_File *src;
+ struct Program *program;
+ struct Token_Pointer *ptr;
+ struct Preprocessing_Translation_Unit *hold_unit;
+
+ char *this_directory[]={"./",NULL};
+ _Bool ret;
+
+ wonky_assert(base_source_names!=NULL);
+
+ if(*base_source_names==NULL)
{
- case KW_AUTO:
- wonky_fprintf(out,"AUTO");
- break;
- case KW_DO:
- wonky_fprintf(out,"DO");
- break;
- case KW_DOUBLE:
- wonky_fprintf(out,"DOUBLE");
- break;
- case KW_INT:
- wonky_fprintf(out,"INT");
- break;
- case KW_STRUCT:
- wonky_fprintf(out,"STRUCT");
- break;
- case KW_BREAK:
- wonky_fprintf(out,"BREAK");
- break;
- case KW_ELSE:
- wonky_fprintf(out,"ELSE");
- break;
- case KW_LONG:
- wonky_fprintf(out,"LONG");
- break;
- case KW_SWITCH:
- wonky_fprintf(out,"SWITCH");
- break;
- case KW_CASE:
- wonky_fprintf(out,"CASE");
- break;
- case KW_ENUM:
- wonky_fprintf(out,"ENUM");
- break;
- case KW_REGISTER:
- wonky_fprintf(out,"REGISTER");
- break;
- case KW_TYPEDEF:
- wonky_fprintf(out,"TYPEDEF");
- break;
- case KW_CHAR:
- wonky_fprintf(out,"CHAR");
- break;
- case KW_EXTERN:
- wonky_fprintf(out,"EXTERN");
- break;
- case KW_RETURN:
- wonky_fprintf(out,"RETURN");
- break;
- case KW_UNION:
- wonky_fprintf(out,"UNION");
- break;
- case KW_CONST:
- wonky_fprintf(out,"CONST");
- break;
- case KW_FLOAT:
- wonky_fprintf(out,"FLOAT");
- break;
- case KW_SHORT:
- wonky_fprintf(out,"SHORT");
- break;
- case KW_UNSIGNED:
- wonky_fprintf(out,"UNSIGNED");
- break;
- case KW_CONTINUE:
- wonky_fprintf(out,"CONTINUE");
- break;
- case KW_FOR:
- wonky_fprintf(out,"FOR");
- break;
- case KW_SIGNED:
- wonky_fprintf(out,"SIGNED");
- break;
- case KW_VOID:
- wonky_fprintf(out,"VOID");
- break;
- case KW_DEFAULT:
- wonky_fprintf(out,"DEFAULT");
- break;
- case KW_GOTO:
- wonky_fprintf(out,"GOTO");
- break;
- case KW_SIZEOF:
- wonky_fprintf(out,"SIZEOF");
- break;
- case KW_VOLATILE:
- wonky_fprintf(out,"VOLATILE");
- break;
- case KW_IF:
- wonky_fprintf(out,"IF");
- break;
- case KW_STATIC:
- wonky_fprintf(out,"STATIC");
- break;
- case KW_WHILE:
- wonky_fprintf(out,"WHILE");
- break;
- case KW_EXCLAMATION:
- wonky_fprintf(out,"!");
- break;
- case KW_PERCENT:
- wonky_fprintf(out,"%");
- break;
- case KW_AND:
- wonky_fprintf(out,"&");
- break;
- case KW_AND_AND:
- wonky_fprintf(out,"&&");
- break;
- case KW_OPEN_NORMAL:
- wonky_fprintf(out,"(");
- break;
- case KW_CLOSE_NORMAL:
- wonky_fprintf(out,")");
- break;
- case KW_STAR:
- wonky_fprintf(out,"*");
- break;
- case KW_PLUS:
- wonky_fprintf(out,"+");
- break;
- case KW_COMMA:
- wonky_fprintf(out,",");
- break;
- case KW_MINUS:
- wonky_fprintf(out,"-");
- break;
- case KW_DOT:
- wonky_fprintf(out,".");
- break;
- case KW_ARROW:
- wonky_fprintf(out,"->");
- break;
- case KW_COLUMN:
- wonky_fprintf(out,":");
- break;
- case KW_SEMICOLON:
- wonky_fprintf(out,";");
- break;
- case KW_LESS:
- wonky_fprintf(out,"<");
- break;
- case KW_EQ:
- wonky_fprintf(out,"=");
- break;
- case KW_EQEQ:
- wonky_fprintf(out,"==");
- break;
- case KW_MORE:
- wonky_fprintf(out,">");
- break;
- case KW_QUESTION:
- wonky_fprintf(out,"?");
- break;
- case KW_HAT:
- wonky_fprintf(out,"^");
- break;
- case KW_PIPE:
- wonky_fprintf(out,"|");
- break;
- case KW_PIPE_PIPE:
- wonky_fprintf(out,"||");
- break;
- case KW_TILDE:
- wonky_fprintf(out,"~");
- break;
- case KW_PLUSPLUS:
- wonky_fprintf(out,"++");
- break;
- case KW_MINUSMINUS:
- wonky_fprintf(out,"--");
- break;
- case KW_SHIFT_RIGHT:
- wonky_fprintf(out,">>");
- break;
- case KW_SHIFT_LEFT:
- wonky_fprintf(out,"<<");
- break;
- case KW_LESS_EQ:
- wonky_fprintf(out,"<=");
- break;
- case KW_MORE_EQ:
- wonky_fprintf(out,">=");
- break;
- case KW_NOT_EQ:
- wonky_fprintf(out,"!=");
- break;
- case KW_PLUS_EQ:
- wonky_fprintf(out,"+=");
- break;
- case KW_MINUS_EQ:
- wonky_fprintf(out,"-=");
- break;
- case KW_STAR_EQ:
- wonky_fprintf(out,"*=");
- break;
- case KW_PERCENT_EQ:
- wonky_fprintf(out,"%=");
- break;
- case KW_SHIFT_LEFT_EQ:
- wonky_fprintf(out,"<<=");
- break;
- case KW_SHIFT_RIGHT_EQ:
- wonky_fprintf(out,">>=");
- break;
- case KW_AND_EQ:
- wonky_fprintf(out,"&=");
- break;
- case KW_HAT_EQ:
- wonky_fprintf(out,"^=");
- break;
- case KW_PIPE_EQ:
- wonky_fprintf(out,"|=");
- break;
- case KW_HASHTAG:
- wonky_fprintf(out,"#");
- break;
- case KW_HASHTAG_HASHTAG:
- wonky_fprintf(out,"##");
- break;
- case KW_ELIPSIS:
- wonky_fprintf(out,"...");
- break;
- case KW_DIV:
- wonky_fprintf(out,"/");
- break;
- case KW_INLINE:
- wonky_fprintf(out,"INLINE");
- break;
- case KW_RESTRICT:
- wonky_fprintf(out,"RESTRICT");
- break;
- case KW_BOOL:
- wonky_fprintf(out,"_BOOL");
- break;
- case KW_COMPLEX:
- wonky_fprintf(out,"_COMPLEX");
- break;
- case KW_IMAGINARY:
- wonky_fprintf(out,"_IMAGINARY");
- break;
- case KW_OPEN_SQUARE:
- wonky_fprintf(out,"[");
- break;
- case KW_CLOSE_SQUARE:
- wonky_fprintf(out,"]");
- break;
- case KW_CLOSE_CURLY:
- wonky_fprintf(out,"}");
- break;
- case KW_OPEN_CURLY:
- wonky_fprintf(out,"{");
- break;
- case KW_DIV_EQ:
- wonky_fprintf(out,"/=");
- break;
- case KW_FORWARD_SLASH:
- wonky_fprintf(out,"/");
- break;
- case KW_NOTYPE:
- wonky_fprintf(out,"NOTYPE");
- break;
- case KW_HEXADECIMAL_CONSTANT:
- case KW_DECIMAL_CONSTANT:
- case KW_OCTAL_CONSTANT :
- case KW_UNSIGNED_DECIMAL_CONSTANT:
- case KW_UNSIGNED_OCTAL_CONSTANT:
- case KW_UNSIGNED_HEXADECIMAL_CONSTANT:
- case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:
- case KW_UNSIGNED_LONG_OCTAL_CONSTANT:
- case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:
- case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:
- case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:
- case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
- case KW_LONG_HEXADECIMAL_CONSTANT:
- case KW_LONG_OCTAL_CONSTANT:
- case KW_LONG_DECIMAL_CONSTANT:
- case KW_LONG_LONG_HEXADECIMAL_CONSTANT:
- case KW_LONG_LONG_OCTAL_CONSTANT:
- case KW_LONG_LONG_DECIMAL_CONSTANT:
- case KW_DOUBLE_DECIMAL_CONSTANT:
- case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
- case KW_FLOAT_DECIMAL_CONSTANT:
- case KW_DOUBLE_HEXADECIMAL_CONSTANT:
- case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:
- case KW_FLOAT_HEXADECIMAL_CONSTANT:
- case KW_CHAR_CONSTANT:
- case KW_WIDE_CHAR_CONSTANT:
- case KW_CONSTANT:
- wonky_fprintf(out,"CONSTANT");
- break;
- case KW_ID:
- wonky_fprintf(out,"ID ");
- print_id(out,((struct token_identifier*)token)->id);
- break;
- case KW_STRING:
- case KW_WIDE_STRING:
- wonky_fprintf(out,"STRING");
- break;
- case PKW_MACRO_ARGUMENT:
- wonky_fprintf(out,"MACRO ARGUMENT -_(:/)_-");
- break;
- case PKW_HASHTAG_UNARY_OP:
- wonky_fprintf(out,"#argument");
- break;
- case PKW_HASHTAG_HASHTAG_OP:
- {
- struct Queue_Node *it;
- it=((struct token_hashtag_hastag_operator*)token)->operands->first;
- if(it)
- print_token(out,(struct token*)it->data);
- it=it->prev;
- for(;it;it=it->prev)
- wonky_fprintf(out,"##%Wt",(struct token*)it->data);
- }
- break;
-
- default:
- wonky_fprintf(out,"NOTYPE");
-
- }
- wonky_fprintf(out,"]");
- }
-
- char print_tokens_of_program(struct wonky_stream *out,char **base_source_names)
- {
-
- struct Source_File *src;
- struct Program *program;
- struct Token_Pointer *ptr;
- struct Preprocessing_Translation_Unit *hold_unit;
-
- char *this_directory[]={"./",NULL};
- _Bool ret;
-
- wonky_assert(base_source_names!=NULL);
-
- if(*base_source_names==NULL)
- {
- return 0;
- }
-
- ret=0;
-
- program=get_program();
-
- do
- {
- src=get_source_file_from_string(*base_source_names,gstrnlen(*base_source_names,1000),program);
-
- hold_unit=lex(src,program);
- if(program->errors->size>0 || hold_unit==NULL)
- {
- ret=1;
- print_errors(out,program->errors);
+ return 0;
+ }
+
+ ret=0;
+
+ program=get_program();
+
+ do
+ {
+ src=get_source_file_from_string(*base_source_names,gstrnlen(*base_source_names,1000),program);
+
+ hold_unit=lex(src,program);
+ if(program->errors->size>0 || hold_unit==NULL)
+ {
+ ret=1;
+ print_errors(out,program->errors);
break;
}
wonky_fprintf(out,"denotation prototype");
return;
default:
- wonky_assert(SHOULD_NOT_REACH_HERE);
-
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+
+ }
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+ }
+ void print_list_of_denoted(struct wonky_stream *out,struct Queue *denoted)
+ {
+ struct Queue_Node *it;
+ for(it=denoted->first;it!=NULL;it=it->prev)
+ {
+ print_denoted(out,(struct Denoted*)it->data);
+ if(it->prev!=NULL)
+ wonky_fprintf(out,",");
+ }
+ }
+ void print_enumeration(struct wonky_stream *out,struct Enum *enumeration)
+ {
+ wonky_fprintf(out,"enum ");
+ print_list_of_denoted(out,enumeration->consts);
+ }
+ void print_struct_union(struct wonky_stream *out,struct Struct_Union *struct_union)
+ {
+ switch(struct_union->specifier)
+ {
+ case TS_UNION:
+ wonky_fprintf(out,"union ");
+ break;
+ case TS_STRUCT:
+ wonky_fprintf(out,"struct ");
+ break;
+ default:
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+ }
+ wonky_fprintf(out,"{");
+ print_list_of_denoted(out,struct_union->members);
+ wonky_fprintf(out,"}");
+
+ }
+ void print_object(struct wonky_stream *out,struct Object *object)
+ {
+ if(object->kind==OBJECT_KIND_NORMAL)
+ {
+ print_normal_object(out,object);
+ }else
+ {
+ print_bitfield_object(out,(struct Object_Bitfield*)object);
+ }
+ }
+ void print_normal_object(struct wonky_stream *out,struct Object *object)
+ {
+ wonky_fprintf(out," normal object that");
+ }
+ void print_bitfield_object(struct wonky_stream *out,struct Object_Bitfield *object)
+ {
+ wonky_fprintf(out,"bitfield object with %zu bits",object->number_of_bits);
+ }
+ void print_translation_unit_tree(struct wonky_stream *out,struct AST_Translation_Unit *unit,short indentation)
+ {
+ struct Queue_Node *it;
+ struct AST* hold;
+ for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
+ {
+ hold=(struct AST*)(it->data);
+ print_ast(out,hold,indentation);
+ if(hold->type!=ST_FUNCTION_DEFINITION)
+ wonky_fprintf(out,";\n");
+ }
+ }
+ void print_ast(struct wonky_stream *out,struct AST* tree,short indentation)
+ {
+ if(tree==NULL)
+ {
+ print_indentation(out,indentation);
+ wonky_fprintf(out,"NULLAST");
+ return;
+ }
+ switch(tree->type)
+ {
+ case OP_DESIGNATOR:
+ print_designator_expression_tree(out,(struct AST_Designator*)tree,indentation);
+ break;
+ case OP_MEMBER_TROUGH_PTR:
+ case OP_MEMBER:
+ case OP_BITWISE_AND:
+ case OP_BITWISE_XOR:
+ case OP_LOGICAL_AND:
+ case OP_LOGICAL_OR:
+ case OP_XOR_ASSIGN:
+ case OP_PIPE_ASSIGN:
+ case OP_SHIFT_RIGHT_ASSIGN:
+ case OP_ADD_ASSIGN:
+ case OP_SUBTRACT_ASSIGN:
+ case OP_MULTIPLY_ASSIGN:
+ case OP_REMAINDER_ASSIGN:
+ case OP_DIV_ASSIGN:
+ case OP_SUBTRACTION:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_REMAINDER:
+ case OP_EQUAL:
+ case OP_LESS:
+ case OP_LESS_EQ:
+ case OP_SHIFT_LEFT:
+ case OP_BITWISE_OR:
+ case OP_AND_ASSIGN:
+ case OP_ARR_SUBSCRIPT:
+ case OP_SHIFT_LEFT_ASSIGN:
+ case OP_ASSIGN:
+ case OP_ADDITION:
+ case OP_COMMA:
+ case OP_SHIFT_RIGHT:
+ case OP_GREATER_EQ:
+ case OP_GREATER:
+ case OP_NOT_EQUAL:
+ print_binary_expression_tree(out,(struct AST_Binary_Expression*)tree);
+ break;
+ case OP_COND:
+ print_conditional_expression_tree(out,(struct AST_Conditional_Expression*)tree);
+ break;
+ case OP_FUNCTION:
+ print_function_expression_tree(out,(struct AST_Function_Expression*)tree);
+ break;
+ case OP_LOGICAL_NOT:
+ case OP_UNARY_MINUS:
+ case OP_SIZEOF:
+ case OP_ADDR_OF:
+ case OP_DEREFERENCE:
+ case OP_POSTFIX_INC:
+ case OP_PREFIX_INC:
+ case OP_UNARY_PLUS:
+ case OP_POSTFIX_DEC:
+ case OP_PREFIX_DEC:
+ case OP_CAST:
+ case OP_BITWISE_NOT:
+ print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree);
+ break;
+ case OP_STRING_LITERAL:
+ print_string_literal(out,(struct AST_String_Literal*)tree);
+ break;
+ case OP_CONSTANT:
+ print_constant_tree(out,(struct AST_Constant*)tree);
+ break;
+ case OP_NOP:
+ wonky_fprintf(out,"NOP");
+ break;
+ case ST_SWITCH:
+ print_switch_statement_tree(out,(struct AST_Switch_Statement*)tree,indentation);
+ break;
+ case ST_IF:
+ print_if_statement_tree(out,(struct AST_If_Statement*)tree,indentation);
+ break;
+ case ST_WHILE:
+ print_while_statement_tree(out,(struct AST_While_Statement*)tree,indentation);
+ break;
+ case ST_DO_WHILE:
+ print_do_while_statement_tree(out,(struct AST_Do_While_Statement*)tree,indentation);
+ break;
+ case ST_GOTO:
+ print_goto_statement_tree(out,(struct AST_Goto_Statement*)tree,indentation);
+ break;
+ case ST_DEFAULT:
+ case ST_LABEL:
+ case ST_CASE:
+ print_labeled_statement_tree(out,(struct AST_Labeled_Statement*)tree,indentation);
+ break;
+ case ST_CONTINUE:
+ wonky_fprintf(out,"continue");
+ break;
+ case ST_BREAK:
+ wonky_fprintf(out,"break");
+ break;
+ case ST_RETURN:
+ print_return_statement_tree(out,(struct AST_Return_Statement*)tree,indentation);
+ break;
+ case ST_FOR:
+ print_for_statement_tree(out,(struct AST_For_Statement*)tree,indentation);
+ break;
+ case ST_COMPOUND:
+ print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree,indentation);
+ break;
+ case ST_OBJECT_DECLARATION:
+ print_indentation(out,indentation);
+ print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
+ break;
+ case ST_TYPE_DEFINITION:
+ print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);
+ break;
+ case ST_FUNCTION_DECLARATION:
+ print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);
+ break;
+ case ST_FUNCTION_DEFINITION:
+ print_function_definition(out,(struct AST_Function_Definition*)tree,indentation);
+ break;
+ case TRANSLATION_UNIT:
+ print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree,indentation);
+ break;
+ case ERROR:
+ print_error_tree(out,(struct AST_Error*)tree,indentation);
+ break;
+ default:
+ wonky_fprintf(out,"NOT POSSIBLE");
+ }
+
+ }
+
+ void print_function_definition(struct wonky_stream *out,struct AST_Function_Definition *function,short indentation)
+ {
+ print_indentation(out,indentation);
+ wonky_fprintf(out,"%WI is",function->function->id);
+ switch(function->function->linkage)
+ {
+ case LINKAGE_EXTERNAL:
+ wonky_fprintf(out," an externally linked ");
+ break;
+ case LINKAGE_INTERNAL:
+ wonky_fprintf(out," an internally linked ");
+ break;
+ default:
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+ }
+ wonky_fprintf(out,"%WT\n%Wi%WA",function->function->type,indentation,function->body);
+ }
+ void print_program_ast(struct wonky_stream *out,struct Program *program)
+ {
+ size_t i;
+ struct Queue_Node *it;
+
+ wonky_fprintf(out,"EXTERNALLY DEFINED {\n\tFUNCTIONS {\n");
+ for(it=program->functions_without_a_definition->first;it!=NULL;it=it->prev)
+ wonky_fprintf(out,"%Wi%WA\n",2,it->data);
+ wonky_fprintf(out,"\t}\n\tOBJECTS {\n");
+ for(it=program->external_objects_without_an_initialiser->first;it!=NULL;it=it->prev)
+ wonky_fprintf(out,"%Wi%WA\n",2,it->data);
+ wonky_fprintf(out,"\t}");
+ for(it=program->translation_units->first;it!=NULL;it=it->prev)
+ wonky_fprintf(out,"\n\tTRANSLATION_UNIT {\n%Wi%Wa\n\t} TRANSLATION_UNIT_END\n",2,it->data);
+ }
+ void print_keyword_enum(struct wonky_stream *out,enum LEXER_TYPE kw)
+ {
+ switch(kw)
+ {
+ case KW_AUTO:
+ wonky_fprintf(out,"KW_AUTO");
+ break;
+ case KW_DO:
+ wonky_fprintf(out,"KW_DO");
+ break;
+ case KW_DOUBLE:
+ wonky_fprintf(out,"KW_DOUBLE");
+ break;
+ case KW_INT:
+ wonky_fprintf(out,"KW_INT");
+ break;
+ case KW_STRUCT:
+ wonky_fprintf(out,"KW_STRUCT");
+ break;
+ case KW_BREAK:
+ wonky_fprintf(out,"KW_BREAK");
+ break;
+ case KW_ELSE:
+ wonky_fprintf(out,"KW_ELSE");
+ break;
+ case PKW_DEFINED:
+ wonky_fprintf(out,"KW_DEFINED");
+ break;
+ case KW_LONG:
+ wonky_fprintf(out,"KW_LONG");
+ break;
+ case KW_SWITCH:
+ wonky_fprintf(out,"KW_SWITCH");
+ break;
+ case KW_CASE:
+ wonky_fprintf(out,"KW_CASE");
+ break;
+ case KW_ENUM:
+ wonky_fprintf(out,"KW_ENUM");
+ break;
+ case KW_REGISTER:
+ wonky_fprintf(out,"KW_REGISTER");
+ break;
+ case KW_TYPEDEF:
+ wonky_fprintf(out,"KW_TYPEDEF");
+ break;
+ case KW_CHAR:
+ wonky_fprintf(out,"KW_CHAR");
+ break;
+ case KW_EXTERN:
+ wonky_fprintf(out,"KW_EXTERN");
+ break;
+ case KW_RETURN:
+ wonky_fprintf(out,"KW_RETURN");
+ break;
+ case KW_UNION:
+ wonky_fprintf(out,"KW_UNION");
+ break;
+ case KW_CONST:
+ wonky_fprintf(out,"KW_CONST");
+ break;
+ case KW_FLOAT:
+ wonky_fprintf(out,"KW_FLOAT");
+ break;
+ case KW_SHORT:
+ wonky_fprintf(out,"KW_SHORT");
+ break;
+ case KW_UNSIGNED:
+ wonky_fprintf(out,"KW_UNSIGNED");
+ break;
+ case KW_CONTINUE:
+ wonky_fprintf(out,"KW_CONTINUE");
+ break;
+ case KW_FOR:
+ wonky_fprintf(out,"KW_FOR");
+ break;
+ case KW_SIGNED:
+ wonky_fprintf(out,"KW_SIGNED");
+ break;
+ case KW_VOID:
+ wonky_fprintf(out,"KW_VOID");
+ break;
+ case KW_DEFAULT:
+ wonky_fprintf(out,"KW_DEFAULT");
+ break;
+ case KW_GOTO:
+ wonky_fprintf(out,"KW_GOTO");
+ break;
+ case KW_SIZEOF:
+ wonky_fprintf(out,"KW_SIZEOF");
+ break;
+ case KW_VOLATILE:
+ wonky_fprintf(out,"KW_VOLATILE");
+ break;
+ case KW_IF:
+ wonky_fprintf(out,"KW_IF");
+ break;
+ case KW_STATIC:
+ wonky_fprintf(out,"KW_STATIC");
+ break;
+ case KW_WHILE:
+ wonky_fprintf(out,"KW_WHILE");
+ break;
+ case KW_EXCLAMATION:
+ wonky_fprintf(out,"KW_EXCLAMATION");
+ break;
+ case KW_PERCENT:
+ wonky_fprintf(out,"KW_PERCENT");
+ break;
+ case KW_AND:
+ wonky_fprintf(out,"KW_AND");
+ break;
+ case KW_AND_AND:
+ wonky_fprintf(out,"KW_AND_AND");
+ break;
+ case KW_OPEN_NORMAL:
+ wonky_fprintf(out,"KW_OPEN_NORMAL");
+ break;
+ case KW_CLOSE_NORMAL:
+ wonky_fprintf(out,"KW_CLOSE_NORMAL");
+ break;
+ case KW_STAR:
+ wonky_fprintf(out,"KW_STAR");
+ break;
+ case KW_PLUS:
+ wonky_fprintf(out,"KW_PLUS");
+ break;
+ case KW_COMMA:
+ wonky_fprintf(out,"KW_COMMA");
+ break;
+ case KW_MINUS:
+ wonky_fprintf(out,"KW_MINUS");
+ break;
+ case KW_DOT:
+ wonky_fprintf(out,"KW_DOT");
+ break;
+ case KW_ARROW:
+ wonky_fprintf(out,"KW_ARROW");
+ break;
+ case KW_COLUMN:
+ wonky_fprintf(out,"KW_COLUMN");
+ break;
+ case KW_SEMICOLON:
+ wonky_fprintf(out,"KW_SEMICOLON");
+ break;
+ case KW_LESS:
+ wonky_fprintf(out,"KW_LESS");
+ break;
+ case KW_EQ:
+ wonky_fprintf(out,"KW_EQ");
+ break;
+ case KW_EQEQ:
+ wonky_fprintf(out,"KW_EQEQ");
+ break;
+ case KW_MORE:
+ wonky_fprintf(out,"KW_MORE");
+ break;
+ case KW_QUESTION:
+ wonky_fprintf(out,"KW_QUESTION");
+ break;
+ case KW_HAT:
+ wonky_fprintf(out,"KW_HAT");
+ break;
+ case KW_PIPE:
+ wonky_fprintf(out,"KW_PIPE");
+ break;
+ case KW_PIPE_PIPE:
+ wonky_fprintf(out,"KW_PIPE_PIPE");
+ break;
+ case KW_TILDE:
+ wonky_fprintf(out,"KW_TILDE");
+ break;
+ case KW_PLUSPLUS:
+ wonky_fprintf(out,"KW_PLUSPLUS");
+ break;
+ case KW_MINUSMINUS:
+ wonky_fprintf(out,"KW_MINUSMINUS");
+ break;
+ case KW_SHIFT_RIGHT:
+ wonky_fprintf(out,"KW_SHIFT_RIGHT");
+ break;
+ case KW_SHIFT_LEFT:
+ wonky_fprintf(out,"KW_SHIFT_LEFT");
+ break;
+ case KW_LESS_EQ:
+ wonky_fprintf(out,"KW_LESS_EQ");
+ break;
+ case KW_MORE_EQ:
+ wonky_fprintf(out,"KW_MORE_EQ");
+ break;
+ case KW_NOT_EQ:
+ wonky_fprintf(out,"KW_NOT_EQ");
+ break;
+ case KW_PLUS_EQ:
+ wonky_fprintf(out,"KW_PLUS_EQ");
+ break;
+ case KW_MINUS_EQ:
+ wonky_fprintf(out,"KW_MINUS_EQ");
+ break;
+ case KW_STAR_EQ:
+ wonky_fprintf(out,"KW_STAR_EQ");
+ break;
+ case KW_PERCENT_EQ:
+ wonky_fprintf(out,"KW_PERCENT_EQ");
+ break;
+ case KW_SHIFT_LEFT_EQ:
+ wonky_fprintf(out,"KW_SHIFT_LEFT_EQ");
+ break;
+ case KW_SHIFT_RIGHT_EQ:
+ wonky_fprintf(out,"KW_SHIFT_RIGHT_EQ");
+ break;
+ case KW_AND_EQ:
+ wonky_fprintf(out,"KW_AND_EQ");
+ break;
+ case KW_HAT_EQ:
+ wonky_fprintf(out,"KW_HAT_EQ");
+ break;
+ case KW_PIPE_EQ:
+ wonky_fprintf(out,"KW_PIPE_EQ");
+ break;
+ case KW_HASHTAG:
+ wonky_fprintf(out,"KW_HASHTAG");
+ break;
+ case KW_HASHTAG_HASHTAG:
+ wonky_fprintf(out,"KW_HASHTAG_HASHTAG");
+ break;
+ case KW_ELIPSIS:
+ wonky_fprintf(out,"KW_ELIPSIS");
+ break;
+ case KW_DIV:
+ wonky_fprintf(out,"KW_DIV");
+ break;
+ case KW_INLINE:
+ wonky_fprintf(out,"KW_INLINE");
+ break;
+ case KW_RESTRICT:
+ wonky_fprintf(out,"KW_RESTRICT");
+ break;
+ case KW_BOOL:
+ wonky_fprintf(out,"KW_BOOL");
+ break;
+ case KW_COMPLEX:
+ wonky_fprintf(out,"KW_COMPLEX");
+ break;
+ case KW_IMAGINARY:
+ wonky_fprintf(out,"KW_IMAGINARY");
+ break;
+ case KW_OPEN_SQUARE:
+ wonky_fprintf(out,"KW_OPEN_SQUARE");
+ break;
+ case KW_CLOSE_SQUARE:
+ wonky_fprintf(out,"KW_CLOSE_SQUARE");
+ break;
+ case KW_CLOSE_CURLY:
+ wonky_fprintf(out,"KW_CLOSE_CURLY");
+ break;
+ case KW_OPEN_CURLY:
+ wonky_fprintf(out,"KW_OPEN_CURLY");
+ break;
+ case KW_DIV_EQ:
+ wonky_fprintf(out,"KW_DIV_EQ");
+ break;
+ case KW_FORWARD_SLASH:
+ wonky_fprintf(out,"KW_FORWARD_SLASH");
+ break;
+ case KW_NOTYPE:
+ wonky_fprintf(out,"KW_NOTYPE");
+ break;
+ case KW_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_DECIMAL_CONSTANT");
+ break;
+ case KW_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_OCTAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_DECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_OCTAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_OCTAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_DECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT");
+ break;
+ case KW_LONG_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_LONG_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_OCTAL_CONSTANT");
+ break;
+ case KW_LONG_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_DECIMAL_CONSTANT");
+ break;
+ case KW_LONG_LONG_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_LONG_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_LONG_LONG_OCTAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_LONG_OCTAL_CONSTANT");
+ break;
+ case KW_LONG_LONG_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_LONG_DECIMAL_CONSTANT");
+ break;
+ case KW_DOUBLE_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_DOUBLE_DECIMAL_CONSTANT");
+ break;
+ case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_DOUBLE_DECIMAL_CONSTANT");
+ break;
+ case KW_FLOAT_DECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_FLOAT_DECIMAL_CONSTANT");
+ break;
+ case KW_DOUBLE_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_DOUBLE_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_FLOAT_HEXADECIMAL_CONSTANT:
+ wonky_fprintf(out,"KW_FLOAT_HEXADECIMAL_CONSTANT");
+ break;
+ case KW_COMMENT:
+ wonky_fprintf(out,"KW_COMMENT");
+ break;
+ case KW_ID:
+ wonky_fprintf(out,"KW_ID");
+ break;
+ case KW_CHAR_CONSTANT:
+ wonky_fprintf(out,"KW_CHAR_CONSTANT");
+ break;
+ case KW_WIDE_CHAR_CONSTANT:
+ wonky_fprintf(out,"KW_WIDE_CHAR_CONSTANT");
+ break;
+ case KW_STRING:
+ wonky_fprintf(out,"KW_STRING");
+ break;
+ case KW_WIDE_STRING:
+ wonky_fprintf(out,"KW_WIDE_STRING");
+ break;
+ case PKW_IF:
+ wonky_fprintf(out,"PKW_IF");
+ break;
+ case PKW_IFDEF:
+ wonky_fprintf(out,"PKW_IFDEF");
+ break;
+ case PKW_IFNDEF:
+ wonky_fprintf(out,"PKW_IFNDEF");
+ break;
+ case PKW_ELIF:
+ wonky_fprintf(out,"PKW_ELIF");
+ break;
+ case PKW_ELSE:
+ wonky_fprintf(out,"PKW_ELSE");
+ break;
+ case PKW_ENDIF:
+ wonky_fprintf(out,"PKW_ENDIF");
+ break;
+ case PKW_INCLUDE:
+ wonky_fprintf(out,"PKW_INCLUDE");
+ break;
+ case PKW_DEFINE:
+ wonky_fprintf(out,"PKW_DEFINE");
+ break;
+ case PKW_UNDEF:
+ wonky_fprintf(out,"PKW_UNDEF");
+ break;
+ case PKW_LINE:
+ wonky_fprintf(out,"PKW_LINE");
+ break;
+ case PKW_ERROR:
+ wonky_fprintf(out,"PKW_ERROR");
+ break;
+ case PKW_PRAGMA:
+ wonky_fprintf(out,"PKW_PRAGMA");
+ break;
+ case PKW_COMMENT:
+ wonky_fprintf(out,"PKW_COMMENT");
+ break;
+ case PKW_NOTYPE:
+ wonky_fprintf(out,"PKW_NOTYPE");
+ break;
+ default:
+ wonky_fprintf(out,"KW_ERROR");
}
- wonky_assert(SHOULD_NOT_REACH_HERE);
}
- void print_list_of_denoted(struct wonky_stream *out,struct Queue *denoted)
+ void print_errors(struct wonky_stream *out,struct Queue *errors)
{
struct Queue_Node *it;
- for(it=denoted->first;it!=NULL;it=it->prev)
- {
- print_denoted(out,(struct Denoted*)it->data);
- if(it->prev!=NULL)
- wonky_fprintf(out,",");
- }
+ for(it=errors->first;it!=NULL;it=it->prev)
+ print_message(out,(struct Wonky_Message*)it->data);
}
- void print_enumeration(struct wonky_stream *out,struct Enum *enumeration)
+ void print_function_args(struct wonky_stream *out,struct Type_Function *func)
{
- wonky_fprintf(out,"enum ");
- print_list_of_denoted(out,enumeration->consts);
+ size_t i;
+ if(func->number_of_arguments==0)
+ return;
+
+ print_denoted_argument(out,func->arguments[0]);
+ for(i=1;i<func->number_of_arguments;++i)
+ wonky_fprintf(out,", %Wd",func->arguments[i]);
}
- void print_struct_union(struct wonky_stream *out,struct Struct_Union *struct_union)
+ void print_denoted_argument(struct wonky_stream *out,struct Denoted_Object *denoted)
{
- switch(struct_union->specifier)
+ wonky_fprintf(out,"denoted object ");
+ if(denoted->id)
+ print_id(out,denoted->id);
+ wonky_fprintf(out,"%Wo is a %WT",denoted->object,denoted->object->type);
+ return;
+ }
+ void print_type_qualifier(struct wonky_stream *out,struct Type *type)
+ {
+ if(type_is_constant(type))
+ wonky_fprintf(out,"constant ");
+ if(type_is_volatile(type))
+ wonky_fprintf(out," volatile ");
+ }
+
+ void print_type_constraint_enum(struct wonky_stream *out,enum Type_Specifier specifier)
+ {
+ switch(specifier)
{
- case TS_UNION:
- wonky_fprintf(out,"union ");
+ case TC_LONG:
+ wonky_fprintf(out,"long ");
break;
- case TS_STRUCT:
- wonky_fprintf(out,"struct ");
+ case TC_LONG_LONG:
+ wonky_fprintf(out,"long long ");
+ break;
+ case TC_SHORT:
+ wonky_fprintf(out,"short");
break;
- default:
- wonky_assert(SHOULD_NOT_REACH_HERE);
}
- wonky_fprintf(out,"{");
- print_list_of_denoted(out,struct_union->members);
- wonky_fprintf(out,"}");
-
}
- void print_object(struct wonky_stream *out,struct Object *object)
+ void print_type_sign_enum(struct wonky_stream *out,enum Type_Signedness sign)
{
- if(object->kind==OBJECT_KIND_NORMAL)
+ if(sign==TSIGN_UNSIGNED)
+ wonky_fprintf(out,"unsigned ");
+ }
+
+ void print_type_constraint(struct wonky_stream *out,struct Type *type)
+ {
+ switch(type->specifier)
{
- print_normal_object(out,object);
- }else
+ case TS_VOID:
+ case TS_CHAR:
+ case TS_INT:
+ case TS_FLOAT:
+ case TS_DOUBLE:
+ print_type_constraint_enum(out,AS_BASIC_TYPE_PTR(type)->constraint);
+ }
+ }
+ void print_type_sign(struct wonky_stream *out,struct Type *type)
+ {
+ switch(type->specifier)
{
- print_bitfield_object(out,(struct Object_Bitfield*)object);
+ case TS_VOID:
+ case TS_CHAR:
+ case TS_INT:
+ case TS_FLOAT:
+ case TS_DOUBLE:
+ print_type_sign_enum(out,AS_BASIC_TYPE_PTR(type)->sign);
+ break;
}
}
- void print_normal_object(struct wonky_stream *out,struct Object *object)
+
+ void print_constant_tree(struct wonky_stream *out,struct AST_Constant *constant)
{
- wonky_fprintf(out," normal object that");
+ wonky_assert(constant && constant->value && constant->value->constant);
+ wonky_fprintf(out,"(const(%WT) %WC)",constant->value->constant->type,constant->value->constant);
}
- void print_bitfield_object(struct wonky_stream *out,struct Object_Bitfield *object)
+ void print_string_literal(struct wonky_stream *out,struct AST_String_Literal *string)
{
- wonky_fprintf(out,"bitfield object with %zu bits",object->number_of_bits);
+ wonky_fprintf(out,"%WC",string->value->constant);
}
- void print_translation_unit_tree(struct wonky_stream *out,struct AST_Translation_Unit *unit,short indentation)
+
+ void print_expression_value(struct wonky_stream *out,struct Expression_Value *value)
{
- struct Queue_Node *it;
- struct AST* hold;
- for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
- {
- hold=(struct AST*)(it->data);
- print_ast(out,hold,indentation);
- if(hold->type!=ST_FUNCTION_DEFINITION)
- wonky_fprintf(out,";\n");
- }
+ wonky_fprintf(out,"EXPRESSION VALUE of type");
}
- void print_ast(struct wonky_stream *out,struct AST* tree,short indentation)
+ void print_expression_value_type(struct wonky_stream *out,struct Expression_Value *expression_value)
{
- if(tree==NULL)
- {
- print_indentation(out,indentation);
- wonky_fprintf(out,"NULLAST");
- return;
- }
- switch(tree->type)
+ switch(expression_value->type)
{
- case OP_DESIGNATOR:
- print_designator_expression_tree(out,(struct AST_Designator*)tree,indentation);
- break;
- case OP_MEMBER_TROUGH_PTR:
- case OP_MEMBER:
- case OP_BITWISE_AND:
- case OP_BITWISE_XOR:
- case OP_LOGICAL_AND:
- case OP_LOGICAL_OR:
- case OP_XOR_ASSIGN:
- case OP_PIPE_ASSIGN:
- case OP_SHIFT_RIGHT_ASSIGN:
- case OP_ADD_ASSIGN:
- case OP_SUBTRACT_ASSIGN:
- case OP_MULTIPLY_ASSIGN:
- case OP_REMAINDER_ASSIGN:
- case OP_DIV_ASSIGN:
- case OP_SUBTRACTION:
- case OP_MUL:
- case OP_DIV:
- case OP_REMAINDER:
- case OP_EQUAL:
- case OP_LESS:
- case OP_LESS_EQ:
- case OP_SHIFT_LEFT:
- case OP_BITWISE_OR:
- case OP_AND_ASSIGN:
- case OP_ARR_SUBSCRIPT:
- case OP_SHIFT_LEFT_ASSIGN:
- case OP_ASSIGN:
- case OP_ADDITION:
- case OP_COMMA:
- case OP_SHIFT_RIGHT:
- case OP_GREATER_EQ:
- case OP_GREATER:
- case OP_NOT_EQUAL:
- print_binary_expression_tree(out,(struct AST_Binary_Expression*)tree);
- break;
- case OP_COND:
- print_conditional_expression_tree(out,(struct AST_Conditional_Expression*)tree);
- break;
- case OP_FUNCTION:
- print_function_expression_tree(out,(struct AST_Function_Expression*)tree);
- break;
- case OP_LOGICAL_NOT:
- case OP_UNARY_MINUS:
- case OP_SIZEOF:
- case OP_ADDR_OF:
- case OP_DEREFERENCE:
- case OP_POSTFIX_INC:
- case OP_PREFIX_INC:
- case OP_UNARY_PLUS:
- case OP_POSTFIX_DEC:
- case OP_PREFIX_DEC:
- case OP_CAST:
- case OP_BITWISE_NOT:
- print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree);
- break;
- case OP_STRING_LITERAL:
- print_string_literal(out,(struct AST_String_Literal*)tree);
- break;
- case OP_CONSTANT:
- print_constant_tree(out,(struct AST_Constant*)tree);
- break;
- case OP_NOP:
- wonky_fprintf(out,"NOP");
- break;
- case ST_SWITCH:
- print_switch_statement_tree(out,(struct AST_Switch_Statement*)tree,indentation);
- break;
- case ST_IF:
- print_if_statement_tree(out,(struct AST_If_Statement*)tree,indentation);
- break;
- case ST_WHILE:
- print_while_statement_tree(out,(struct AST_While_Statement*)tree,indentation);
- break;
- case ST_DO_WHILE:
- print_do_while_statement_tree(out,(struct AST_Do_While_Statement*)tree,indentation);
- break;
- case ST_GOTO:
- print_goto_statement_tree(out,(struct AST_Goto_Statement*)tree,indentation);
- break;
- case ST_DEFAULT:
- case ST_LABEL:
- case ST_CASE:
- print_labeled_statement_tree(out,(struct AST_Labeled_Statement*)tree,indentation);
+ case VALUE_LVALUE:
+ print_type(out, ((struct Expression_Value_LValue*)expression_value)->object->type,1);
+ return;
+ case VALUE_TEMP:
+ print_type(out,((struct Expression_Value_RValue*)expression_value)->temp_object->type,1);
+ return;
+ case VALUE_FUNCTION_DESIGNATOR:
+ print_type(out,((struct Expression_Value_Function_Designator*)expression_value)->function->type,1);
+ return;
+ case VALUE_CONSTANT:
+ print_type(out, ((struct Expression_Value_Constant*)expression_value)->constant->type,1);
+ return;
+ case VALUE_VOID:
+ wonky_fprintf(out,"void");
+ return;
+ }
+ wonky_assert(SHOULD_NOT_REACH_HERE);
+ }
+
+ void print_id(struct wonky_stream *out,struct identifier *id)
+ {
+ wonky_fprintf(out,"%s",id->data);
+ }
+ #undef TOK
+ #undef INDENT
+ void print_indentation(struct wonky_stream *out,short indentation)
+ {
+ for(short i=0;i<indentation;++i)
+ wonky_write(out,"\t",1);
+ }
+ void print_constant(struct wonky_stream *out,struct Constant *constant)
+ {
+ wonky_assert(constant->value);
+ switch(constant->type->specifier)
+ {
+ case TS_VOID:
+ wonky_fprintf(out,"void SHOULD NOT REACH HERE");
break;
- case ST_CONTINUE:
- wonky_fprintf(out,"continue");
+ case TS_CHAR:
+ wonky_fprintf(out,"%c",*(char*)constant->value);
break;
- case ST_BREAK:
- wonky_fprintf(out,"break");
+ case TS_INT:
+ wonky_fprintf(out,"%d",*(int*)constant->value);
break;
- case ST_RETURN:
- print_return_statement_tree(out,(struct AST_Return_Statement*)tree,indentation);
+ case TS_FLOAT:
+ wonky_fprintf(out,"%f",*(float*)constant->value);
break;
- case ST_FOR:
- print_for_statement_tree(out,(struct AST_For_Statement*)tree,indentation);
+ case TS_DOUBLE:
+ wonky_fprintf(out,"%f",*(double*)constant->value);
break;
- case ST_COMPOUND:
- print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree,indentation);
+ case TS_STRUCT:
+ wonky_fprintf(out,"%WT",constant->type);
break;
- case ST_OBJECT_DECLARATION:
- print_indentation(out,indentation);
- print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
+ case TS_ENUM:
+ wonky_fprintf(out,"%WT",constant->type);
break;
- case ST_TYPE_DEFINITION:
- print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);
+ case TS_UNION:
+ wonky_fprintf(out,"%WT",constant->type);
break;
- case ST_FUNCTION_DECLARATION:
- print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);
+ case TS_POINTER:
+ wonky_fprintf(out,"%p",*(void**)constant->value);
break;
- case ST_FUNCTION_DEFINITION:
- print_function_definition(out,(struct AST_Function_Definition*)tree,indentation);
+ case TS_ARRAY:
+ wonky_fprintf(out,"%WT",constant->type);
break;
- case TRANSLATION_UNIT:
- print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree,indentation);
+ case TS_VARIABLE_LENGTH_ARRAY:
+ wonky_fprintf(out,"var length array %WT",constant->type);
break;
- case ERROR:
- print_error_tree(out,(struct AST_Error*)tree,indentation);
+ case TS_FUNC:
+ wonky_fprintf(out,"FUNCTION %WT",constant->type);
break;
- default:
- wonky_fprintf(out,"NOT POSSIBLE");
- }
-
- }
-
- void print_function_definition(struct wonky_stream *out,struct AST_Function_Definition *function,short indentation)
- {
- print_indentation(out,indentation);
- wonky_fprintf(out,"%WI is",function->function->id);
- switch(function->function->linkage)
- {
- case LINKAGE_EXTERNAL:
- wonky_fprintf(out," an externally linked ");
+ case TS_NONE:
+ wonky_fprintf(out,"NONE CONSTANT");
break;
- case LINKAGE_INTERNAL:
- wonky_fprintf(out," an internally linked ");
+ case TS_ERROR:
+ wonky_fprintf(out,"ERROR CONSTANT");
break;
- default:
- wonky_assert(SHOULD_NOT_REACH_HERE);
}
- wonky_fprintf(out,"%WT\n%Wi%WA",function->function->type,indentation,function->body);
- }
- void print_program_ast(struct wonky_stream *out,struct Program *program)
- {
- size_t i;
- struct Queue_Node *it;
-
- wonky_fprintf(out,"EXTERNALLY DEFINED {\n\tFUNCTIONS {\n");
- for(it=program->functions_without_a_definition->first;it!=NULL;it=it->prev)
- wonky_fprintf(out,"%Wi%WA\n",2,it->data);
- wonky_fprintf(out,"\t}\n\tOBJECTS {\n");
- for(it=program->external_objects_without_an_initialiser->first;it!=NULL;it=it->prev)
- wonky_fprintf(out,"%Wi%WA\n",2,it->data);
- wonky_fprintf(out,"\t}");
- for(it=program->translation_units->first;it!=NULL;it=it->prev)
- wonky_fprintf(out,"\n\tTRANSLATION_UNIT {\n%Wi%Wa\n\t} TRANSLATION_UNIT_END\n",2,it->data);
}
- void print_keyword_enum(struct wonky_stream *out,enum LEXER_TYPE kw)
+ void print_token_text(struct wonky_stream *out,struct token *token)
{
- switch(kw)
+ switch(token->type)
{
case KW_AUTO:
- wonky_fprintf(out,"KW_AUTO");
+ wonky_fprintf(out,"auto");
break;
case KW_DO:
- wonky_fprintf(out,"KW_DO");
+ wonky_fprintf(out,"do");
break;
case KW_DOUBLE:
- wonky_fprintf(out,"KW_DOUBLE");
+ wonky_fprintf(out,"double");
break;
case KW_INT:
- wonky_fprintf(out,"KW_INT");
+ wonky_fprintf(out,"int");
break;
case KW_STRUCT:
- wonky_fprintf(out,"KW_STRUCT");
+ wonky_fprintf(out,"struct");
break;
case KW_BREAK:
- wonky_fprintf(out,"KW_BREAK");
+ wonky_fprintf(out,"break");
break;
case KW_ELSE:
- wonky_fprintf(out,"KW_ELSE");
- break;
- case PKW_DEFINED:
- wonky_fprintf(out,"KW_DEFINED");
+ wonky_fprintf(out,"else");
break;
case KW_LONG:
- wonky_fprintf(out,"KW_LONG");
+ wonky_fprintf(out,"long");
break;
case KW_SWITCH:
- wonky_fprintf(out,"KW_SWITCH");
+ wonky_fprintf(out,"switch");
break;
case KW_CASE:
- wonky_fprintf(out,"KW_CASE");
+ wonky_fprintf(out,"case");
break;
case KW_ENUM:
- wonky_fprintf(out,"KW_ENUM");
+ wonky_fprintf(out,"enum");
break;
case KW_REGISTER:
- wonky_fprintf(out,"KW_REGISTER");
+ wonky_fprintf(out,"register");
break;
case KW_TYPEDEF:
- wonky_fprintf(out,"KW_TYPEDEF");
+ wonky_fprintf(out,"typedef");
break;
case KW_CHAR:
- wonky_fprintf(out,"KW_CHAR");
+ wonky_fprintf(out,"char");
break;
case KW_EXTERN:
- wonky_fprintf(out,"KW_EXTERN");
+ wonky_fprintf(out,"extern");
break;
case KW_RETURN:
- wonky_fprintf(out,"KW_RETURN");
+ wonky_fprintf(out,"return");
break;
case KW_UNION:
- wonky_fprintf(out,"KW_UNION");
+ wonky_fprintf(out,"union");
break;
case KW_CONST:
- wonky_fprintf(out,"KW_CONST");
+ wonky_fprintf(out,"const");
break;
case KW_FLOAT:
- wonky_fprintf(out,"KW_FLOAT");
+ wonky_fprintf(out,"float");
break;
case KW_SHORT:
- wonky_fprintf(out,"KW_SHORT");
+ wonky_fprintf(out,"short");
break;
case KW_UNSIGNED:
- wonky_fprintf(out,"KW_UNSIGNED");
+ wonky_fprintf(out,"unsigned");
break;
case KW_CONTINUE:
- wonky_fprintf(out,"KW_CONTINUE");
+ wonky_fprintf(out,"continue");
break;
case KW_FOR:
- wonky_fprintf(out,"KW_FOR");
+ wonky_fprintf(out,"for");
break;
case KW_SIGNED:
- wonky_fprintf(out,"KW_SIGNED");
+ wonky_fprintf(out,"signed");
break;
case KW_VOID:
- wonky_fprintf(out,"KW_VOID");
+ wonky_fprintf(out,"void");
break;
case KW_DEFAULT:
- wonky_fprintf(out,"KW_DEFAULT");
+ wonky_fprintf(out,"default");
break;
case KW_GOTO:
- wonky_fprintf(out,"KW_GOTO");
+ wonky_fprintf(out,"goto");
break;
case KW_SIZEOF:
- wonky_fprintf(out,"KW_SIZEOF");
+ wonky_fprintf(out,"sizeof");
break;
case KW_VOLATILE:
- wonky_fprintf(out,"KW_VOLATILE");
+ wonky_fprintf(out,"volatile");
break;
case KW_IF:
- wonky_fprintf(out,"KW_IF");
+ wonky_fprintf(out,"if");
break;
case KW_STATIC:
- wonky_fprintf(out,"KW_STATIC");
+ wonky_fprintf(out,"static");
break;
case KW_WHILE:
- wonky_fprintf(out,"KW_WHILE");
+ wonky_fprintf(out,"while");
break;
case KW_EXCLAMATION:
- wonky_fprintf(out,"KW_EXCLAMATION");
+ wonky_fprintf(out,"!");
break;
case KW_PERCENT:
- wonky_fprintf(out,"KW_PERCENT");
+ wonky_fprintf(out,"%");
break;
case KW_AND:
- wonky_fprintf(out,"KW_AND");
+ wonky_fprintf(out,"&");
break;
case KW_AND_AND:
- wonky_fprintf(out,"KW_AND_AND");
+ wonky_fprintf(out,"&&");
break;
case KW_OPEN_NORMAL:
- wonky_fprintf(out,"KW_OPEN_NORMAL");
+ wonky_fprintf(out,"(");
break;
case KW_CLOSE_NORMAL:
- wonky_fprintf(out,"KW_CLOSE_NORMAL");
+ wonky_fprintf(out,")");
break;
case KW_STAR:
- wonky_fprintf(out,"KW_STAR");
+ wonky_fprintf(out,"*");
break;
case KW_PLUS:
- wonky_fprintf(out,"KW_PLUS");
+ wonky_fprintf(out,"+");
break;
case KW_COMMA:
- wonky_fprintf(out,"KW_COMMA");
+ wonky_fprintf(out,",");
break;
case KW_MINUS:
- wonky_fprintf(out,"KW_MINUS");
+ wonky_fprintf(out,"-");
break;
case KW_DOT:
- wonky_fprintf(out,"KW_DOT");
+ wonky_fprintf(out,".");
break;
case KW_ARROW:
- wonky_fprintf(out,"KW_ARROW");
+ wonky_fprintf(out,"->");
break;
case KW_COLUMN:
- wonky_fprintf(out,"KW_COLUMN");
+ wonky_fprintf(out,":");
break;
case KW_SEMICOLON:
- wonky_fprintf(out,"KW_SEMICOLON");
+ wonky_fprintf(out,";");
break;
case KW_LESS:
- wonky_fprintf(out,"KW_LESS");
+ wonky_fprintf(out,"<");
break;
case KW_EQ:
- wonky_fprintf(out,"KW_EQ");
+ wonky_fprintf(out,"=");
break;
case KW_EQEQ:
- wonky_fprintf(out,"KW_EQEQ");
+ wonky_fprintf(out,"==");
break;
case KW_MORE:
- wonky_fprintf(out,"KW_MORE");
+ wonky_fprintf(out,">");
break;
case KW_QUESTION:
- wonky_fprintf(out,"KW_QUESTION");
+ wonky_fprintf(out,"?");
break;
case KW_HAT:
- wonky_fprintf(out,"KW_HAT");
+ wonky_fprintf(out,"^");
break;
case KW_PIPE:
- wonky_fprintf(out,"KW_PIPE");
+ wonky_fprintf(out,"|");
break;
case KW_PIPE_PIPE:
- wonky_fprintf(out,"KW_PIPE_PIPE");
+ wonky_fprintf(out,"||");
break;
case KW_TILDE:
- wonky_fprintf(out,"KW_TILDE");
+ wonky_fprintf(out,"~");
break;
case KW_PLUSPLUS:
- wonky_fprintf(out,"KW_PLUSPLUS");
+ wonky_fprintf(out,"++");
break;
case KW_MINUSMINUS:
- wonky_fprintf(out,"KW_MINUSMINUS");
+ wonky_fprintf(out,"--");
break;
case KW_SHIFT_RIGHT:
- wonky_fprintf(out,"KW_SHIFT_RIGHT");
+ wonky_fprintf(out,">>");
break;
case KW_SHIFT_LEFT:
- wonky_fprintf(out,"KW_SHIFT_LEFT");
+ wonky_fprintf(out,"<<");
break;
case KW_LESS_EQ:
- wonky_fprintf(out,"KW_LESS_EQ");
+ wonky_fprintf(out,"<=");
break;
case KW_MORE_EQ:
- wonky_fprintf(out,"KW_MORE_EQ");
+ wonky_fprintf(out,">=");
break;
case KW_NOT_EQ:
- wonky_fprintf(out,"KW_NOT_EQ");
+ wonky_fprintf(out,"!=");
break;
case KW_PLUS_EQ:
- wonky_fprintf(out,"KW_PLUS_EQ");
+ wonky_fprintf(out,"+=");
break;
case KW_MINUS_EQ:
- wonky_fprintf(out,"KW_MINUS_EQ");
+ wonky_fprintf(out,"-=");
break;
case KW_STAR_EQ:
- wonky_fprintf(out,"KW_STAR_EQ");
+ wonky_fprintf(out,"*=");
break;
case KW_PERCENT_EQ:
- wonky_fprintf(out,"KW_PERCENT_EQ");
+ wonky_fprintf(out,"%=");
break;
case KW_SHIFT_LEFT_EQ:
- wonky_fprintf(out,"KW_SHIFT_LEFT_EQ");
+ wonky_fprintf(out,"<<=");
break;
case KW_SHIFT_RIGHT_EQ:
- wonky_fprintf(out,"KW_SHIFT_RIGHT_EQ");
+ wonky_fprintf(out,">>=");
break;
case KW_AND_EQ:
- wonky_fprintf(out,"KW_AND_EQ");
+ wonky_fprintf(out,"&=");
break;
case KW_HAT_EQ:
- wonky_fprintf(out,"KW_HAT_EQ");
+ wonky_fprintf(out,"^=");
break;
case KW_PIPE_EQ:
- wonky_fprintf(out,"KW_PIPE_EQ");
+ wonky_fprintf(out,"|=");
break;
case KW_HASHTAG:
- wonky_fprintf(out,"KW_HASHTAG");
+ wonky_fprintf(out,"#");
break;
case KW_HASHTAG_HASHTAG:
- wonky_fprintf(out,"KW_HASHTAG_HASHTAG");
+ wonky_fprintf(out,"##");
break;
case KW_ELIPSIS:
- wonky_fprintf(out,"KW_ELIPSIS");
+ wonky_fprintf(out,"...");
break;
case KW_DIV:
- wonky_fprintf(out,"KW_DIV");
+ wonky_fprintf(out,"/");
break;
case KW_INLINE:
- wonky_fprintf(out,"KW_INLINE");
+ wonky_fprintf(out,"inline");
break;
case KW_RESTRICT:
- wonky_fprintf(out,"KW_RESTRICT");
+ wonky_fprintf(out,"restrict");
break;
case KW_BOOL:
- wonky_fprintf(out,"KW_BOOL");
+ wonky_fprintf(out,"_Bool");
break;
case KW_COMPLEX:
- wonky_fprintf(out,"KW_COMPLEX");
+ wonky_fprintf(out,"_Complex");
break;
case KW_IMAGINARY:
- wonky_fprintf(out,"KW_IMAGINARY");
+ wonky_fprintf(out,"_Imaginary");
break;
case KW_OPEN_SQUARE:
- wonky_fprintf(out,"KW_OPEN_SQUARE");
+ wonky_fprintf(out,"[");
break;
case KW_CLOSE_SQUARE:
- wonky_fprintf(out,"KW_CLOSE_SQUARE");
+ wonky_fprintf(out,"]");
break;
case KW_CLOSE_CURLY:
- wonky_fprintf(out,"KW_CLOSE_CURLY");
+ wonky_fprintf(out,"}");
break;
case KW_OPEN_CURLY:
- wonky_fprintf(out,"KW_OPEN_CURLY");
+ wonky_fprintf(out,"{");
break;
case KW_DIV_EQ:
- wonky_fprintf(out,"KW_DIV_EQ");
+ wonky_fprintf(out,"/=");
break;
case KW_FORWARD_SLASH:
- wonky_fprintf(out,"KW_FORWARD_SLASH");
+ wonky_fprintf(out,"/");
break;
case KW_NOTYPE:
- wonky_fprintf(out,"KW_NOTYPE");
- break;
- case KW_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_HEXADECIMAL_CONSTANT");
- break;
- case KW_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_DECIMAL_CONSTANT");
- break;
- case KW_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_OCTAL_CONSTANT");
+ wonky_fprintf(out,"NOTYPE");
break;
+ case KW_HEXADECIMAL_CONSTANT:
+ case KW_DECIMAL_CONSTANT:
+ case KW_OCTAL_CONSTANT :
case KW_UNSIGNED_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_DECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_OCTAL_CONSTANT");
- break;
case KW_UNSIGNED_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_HEXADECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_OCTAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_DECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT");
- break;
case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT");
- break;
case KW_LONG_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_HEXADECIMAL_CONSTANT");
- break;
case KW_LONG_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_OCTAL_CONSTANT");
- break;
case KW_LONG_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_DECIMAL_CONSTANT");
- break;
case KW_LONG_LONG_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_LONG_HEXADECIMAL_CONSTANT");
- break;
case KW_LONG_LONG_OCTAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_LONG_OCTAL_CONSTANT");
- break;
case KW_LONG_LONG_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_LONG_DECIMAL_CONSTANT");
- break;
case KW_DOUBLE_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_DOUBLE_DECIMAL_CONSTANT");
- break;
case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_DOUBLE_DECIMAL_CONSTANT");
- break;
case KW_FLOAT_DECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_FLOAT_DECIMAL_CONSTANT");
- break;
case KW_DOUBLE_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_DOUBLE_HEXADECIMAL_CONSTANT");
- break;
case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT");
- break;
case KW_FLOAT_HEXADECIMAL_CONSTANT:
- wonky_fprintf(out,"KW_FLOAT_HEXADECIMAL_CONSTANT");
- break;
- case KW_COMMENT:
- wonky_fprintf(out,"KW_COMMENT");
+ case KW_CHAR_CONSTANT:
+ case KW_WIDE_CHAR_CONSTANT:
+ case KW_CONSTANT:
+ print_constant(out,((struct token_constant*)token)->constant);
break;
case KW_ID:
- wonky_fprintf(out,"KW_ID");
+ print_id(out,((struct token_identifier*)token)->id);
break;
- case KW_CHAR_CONSTANT:
- wonky_fprintf(out,"KW_CHAR_CONSTANT");
+ case KW_STRING:
+ case KW_WIDE_STRING:
+ wonky_fprintf(out,"%s",((struct token_string*)token)->constant->value);
break;
- case KW_WIDE_CHAR_CONSTANT:
- wonky_fprintf(out,"KW_WIDE_CHAR_CONSTANT");
+ case PKW_MACRO_ARGUMENT:
+ wonky_fprintf(out,"MACRO ARGUMENT -_(:/)_-");
break;
- case KW_STRING:
- wonky_fprintf(out,"KW_STRING");
+ case PKW_HASHTAG_UNARY_OP:
+ wonky_fprintf(out,"#argument");
break;
- case KW_WIDE_STRING:
- wonky_fprintf(out,"KW_WIDE_STRING");
+ case PKW_HASHTAG_HASHTAG_OP:
+ {
+ struct Queue_Node *it;
+ it=((struct token_hashtag_hastag_operator*)token)->operands->first;
+ if(it)
+ print_token(out,(struct token*)it->data);
+ it=it->prev;
+ for(;it;it=it->prev)
+ wonky_fprintf(out,"##%Wt",(struct token*)it->data);
+ }
+ break;
+ case PKW_DEFINED:
+ wonky_fprintf(out,"defined(...)");
break;
case PKW_IF:
wonky_fprintf(out,"PKW_IF");
case PKW_COMMENT:
wonky_fprintf(out,"PKW_COMMENT");
break;
- case PKW_NOTYPE:
- wonky_fprintf(out,"PKW_NOTYPE");
- break;
- default:
- wonky_fprintf(out,"KW_ERROR");
- }
- }
- void print_errors(struct wonky_stream *out,struct Queue *errors)
- {
- struct Queue_Node *it;
- for(it=errors->first;it!=NULL;it=it->prev)
- print_message(out,(struct Wonky_Message*)it->data);
- }
- void print_function_args(struct wonky_stream *out,struct Type_Function *func)
- {
- size_t i;
- if(func->number_of_arguments==0)
- return;
-
- print_denoted_argument(out,func->arguments[0]);
- for(i=1;i<func->number_of_arguments;++i)
- wonky_fprintf(out,", %Wd",func->arguments[i]);
- }
- void print_denoted_argument(struct wonky_stream *out,struct Denoted_Object *denoted)
- {
- wonky_fprintf(out,"denoted object ");
- if(denoted->id)
- print_id(out,denoted->id);
- wonky_fprintf(out,"%Wo is a %WT",denoted->object,denoted->object->type);
- return;
- }
- void print_type_qualifier(struct wonky_stream *out,struct Type *type)
- {
- if(type_is_constant(type))
- wonky_fprintf(out,"constant ");
- if(type_is_volatile(type))
- wonky_fprintf(out," volatile ");
- }
- void print_type_constraint_enum(struct wonky_stream *out,enum Type_Specifier specifier)
- {
- switch(specifier)
- {
- case TC_LONG:
- wonky_fprintf(out,"long ");
- break;
- case TC_LONG_LONG:
- wonky_fprintf(out,"long long ");
- break;
- case TC_SHORT:
- wonky_fprintf(out,"short");
- break;
- }
- }
- void print_type_sign_enum(struct wonky_stream *out,enum Type_Signedness sign)
- {
- if(sign==TSIGN_UNSIGNED)
- wonky_fprintf(out,"unsigned ");
- }
+ default:
+ wonky_fprintf(out,"NOTYPE:%d",token->type);
- void print_type_constraint(struct wonky_stream *out,struct Type *type)
- {
- switch(type->specifier)
- {
- case TS_VOID:
- case TS_CHAR:
- case TS_INT:
- case TS_FLOAT:
- case TS_DOUBLE:
- print_type_constraint_enum(out,AS_BASIC_TYPE_PTR(type)->constraint);
- }
- }
- void print_type_sign(struct wonky_stream *out,struct Type *type)
- {
- switch(type->specifier)
- {
- case TS_VOID:
- case TS_CHAR:
- case TS_INT:
- case TS_FLOAT:
- case TS_DOUBLE:
- print_type_sign_enum(out,AS_BASIC_TYPE_PTR(type)->sign);
- break;
}
}
-
- void print_constant_tree(struct wonky_stream *out,struct AST_Constant *constant)
- {
- wonky_assert(constant && constant->value && constant->value->constant);
- wonky_fprintf(out,"(const(%WT) %WC)",constant->value->constant->type,constant->value->constant);
- }
- void print_string_literal(struct wonky_stream *out,struct AST_String_Literal *string)
- {
- wonky_fprintf(out,"%WC",string->value->constant);
- }
-
- void print_expression_value(struct wonky_stream *out,struct Expression_Value *value)
- {
- wonky_fprintf(out,"EXPRESSION VALUE of type");
- }
- void print_expression_value_type(struct wonky_stream *out,struct Expression_Value *expression_value)
+ void print_raw_token_text(struct wonky_stream *out,struct token *token)
{
- switch(expression_value->type)
- {
- case VALUE_LVALUE:
- print_type(out, ((struct Expression_Value_LValue*)expression_value)->object->type,1);
- return;
- case VALUE_TEMP:
- print_type(out,((struct Expression_Value_RValue*)expression_value)->temp_object->type,1);
- return;
- case VALUE_FUNCTION_DESIGNATOR:
- print_type(out,((struct Expression_Value_Function_Designator*)expression_value)->function->type,1);
- return;
- case VALUE_CONSTANT:
- print_type(out, ((struct Expression_Value_Constant*)expression_value)->constant->type,1);
- return;
- case VALUE_VOID:
- wonky_fprintf(out,"void");
- return;
- }
- wonky_assert(SHOULD_NOT_REACH_HERE);
- }
+ wonky_write(out,
+ token->delta->location->src->src
+ +
+ token->delta->location->starting_byte_index
+ ,
+ token->delta->location->length);
- void print_id(struct wonky_stream *out,struct identifier *id)
- {
- wonky_fprintf(out,"%s",id->data);
- }
- #undef TOK
- #undef INDENT
- void print_indentation(struct wonky_stream *out,short indentation)
- {
- for(short i=0;i<indentation;++i)
- wonky_write(out,"\t",1);
- }
- void print_constant(struct wonky_stream *out,struct Constant *constant)
- {
- wonky_assert(constant->value);
- switch(constant->type->specifier)
- {
- case TS_VOID:
- wonky_fprintf(out,"void SHOULD NOT REACH HERE");
- break;
- case TS_CHAR:
- wonky_fprintf(out,"%c",*(char*)constant->value);
- break;
- case TS_INT:
- wonky_fprintf(out,"%d",*(int*)constant->value);
- break;
- case TS_FLOAT:
- wonky_fprintf(out,"%f",*(float*)constant->value);
- break;
- case TS_DOUBLE:
- wonky_fprintf(out,"%f",*(double*)constant->value);
- break;
- case TS_STRUCT:
- wonky_fprintf(out,"%WT",constant->type);
- break;
- case TS_ENUM:
- wonky_fprintf(out,"%WT",constant->type);
- break;
- case TS_UNION:
- wonky_fprintf(out,"%WT",constant->type);
- break;
- case TS_POINTER:
- wonky_fprintf(out,"%p",*(void**)constant->value);
- break;
- case TS_ARRAY:
- wonky_fprintf(out,"%WT",constant->type);
- break;
- case TS_VARIABLE_LENGTH_ARRAY:
- wonky_fprintf(out,"var length array %WT",constant->type);
- break;
- case TS_FUNC:
- wonky_fprintf(out,"FUNCTION %WT",constant->type);
- break;
- case TS_NONE:
- wonky_fprintf(out,"NONE CONSTANT");
- break;
- case TS_ERROR:
- wonky_fprintf(out,"ERROR CONSTANT");
- break;
- }
}
#endif
F diff --git a/src/misc/print.h b/src/misc/print.h --- a/src/misc/print.h +++ b/src/misc/print.h
void print_id(struct wonky_stream *out,struct identifier *id);
void print_indentation(struct wonky_stream *out,short indentation);
void print_constant(struct wonky_stream *out,struct Constant *constant);
+ void print_token_text(struct wonky_stream *out,struct token *token);
+ void print_raw_token_text(struct wonky_stream *out,struct token *token);
#endif
F diff --git a/src/misc/wonky_stream.c b/src/misc/wonky_stream.c --- a/src/misc/wonky_stream.c +++ b/src/misc/wonky_stream.c
}
- for(d=1;d*10<a;d*=10);
+ for(d=1;d*10<=a;d*=10);
for(d;d>0;d/=10)
{
hold[0]=a/d+'0';
if(a==0)
return wonky_write(s,"0",1);
- for(d=1;d*10<a;d*=10);
+ for(d=1;d*10<=a;d*=10);
for(d;d>0;d/=10)
{
hold[0]=a/d+'0';
if(a==0)
return wonky_write(s,"0",1);
- for(d=1;d*16<a;d*=16);
+ for(d=1;d*16<=a;d*=16);
for(d;d>0;d/=16)
{
if(a/d<10)
if(a==0)
return wonky_write(s,"0",1);
- for(d=1;d*8<a;d*=8);
+ for(d=1;d*8<=a;d*=8);
for(d;d>0;d/=8)
{
hold[0]=a/d+'0';
struct Token_Pointer_Context *hold;
_Bool print_line=0;
wonky_assert(tp!=NULL);
- for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
+ if(tp->call_stack->size>2)
{
- hold=(struct Token_Pointer_Context*)it->data;
- wonky_assert(hold);
- if(hold->is_file_inclusion)
+ wonky_write(s,"\n",1);
+ for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
{
- if(print_line)
- wonky_write(s,"\n",1);
- wonky_write(s,"\tIncluded in ",sizeof("\tIncluded in ")-1);
- wonky_write(s,hold->filename,hold->filename_size);
- wonky_fprintf(s,":%zu",hold->line+1);
- print_line=1;
- }
+ hold=(struct Token_Pointer_Context*)it->data;
+ wonky_assert(hold);
+ if(hold->is_file_inclusion)
+ {
+ if(print_line)
+ wonky_write(s,"\n",1);
+ wonky_write(s,"\tIncluded in ",sizeof("\tIncluded in ")-1);
+ wonky_write(s,hold->filename,hold->filename_size);
+ wonky_fprintf(s,":%zu",hold->line+1);
+ print_line=1;
+ }
+ }
}
}
{
struct Token_Pointer_Context *hold=va_arg(args,struct Token_Pointer_Context*);
wonky_assert(hold);
- wonky_fprintf(s,"ctx=%p : {\n\tcurrent_token_node = %p\n\tnum_remain_toks = %zu\n\tline = %zu\n\tcolumn = %zu\n\tbarier=%d\n\tfilename = \"",hold,hold->current_token_node,hold->number_of_remaining_tokens,hold->line,hold->column,hold->barrier);
+ wonky_fprintf(s,"ctx=%p",hold);
+ if(hold->current_token_node)
+ {
+ wonky_assert(hold->current_token_node->data!=NULL);
+ wonky_fprintf(s,": {\n\tcurrent_token_node = %Wt",hold->current_token_node->data);
+ }else
+ {
+ wonky_fprintf(s,": {\n\tcurrent_token_node = NULL");
+ }
+ wonky_fprintf(s,"\n\tnum_remain_toks = %zu\n\tline = %zu\n\tcolumn = %zu\n\tbarier=%d\n\tfilename = \"",hold->number_of_remaining_tokens,hold->line,hold->column,hold->barrier);
wonky_write(s,hold->filename,hold->filename_size);
wonky_write(s,"\"",sizeof("\"")-1);
if(hold->executed_macro_id)
wonky_fprintf(s,"\n}\n");
}
break;
+ case WONKY__CONVERSION_WONKY_TOKEN_LINE:
+ {
+ struct token *token=va_arg(args,struct token*);
+ size_t begining_of_real_line=token->delta->location->starting_byte_index;
+ size_t ending_of_real_line=token->delta->location->starting_byte_index;
+ for(begining_of_real_line ;begining_of_real_line && token->delta->location->src->src[begining_of_real_line]!='\n' ;--begining_of_real_line);
+ for(ending_of_real_line ;ending_of_real_line<token->delta->location->src->src_size && token->delta->location->src->src[ending_of_real_line]!='\n' ;++ending_of_real_line);
+ begining_of_real_line+=!!(begining_of_real_line);
+ wonky_assert(begining_of_real_line<ending_of_real_line);
+ wonky_write(s,token->delta->location->src->src+begining_of_real_line,ending_of_real_line-begining_of_real_line);
+ }
+ break;
+ case WONKY__CONVERSION_WONKY_SOURCE_LOCATION:
+ {
+ struct Source_Location *loc=va_arg(args,struct Source_Location*);
+ wonky_write(s,"[ ",2);
+ if(loc->src->src_name)
+ wonky_write(s,loc->src->src_name->name,loc->src->src_name->name_size);
+ else
+ wonky_write(s,"null",sizeof("null")-1);
+ wonky_fprintf(s," %zu:%zu]",loc->line+1,loc->column);
+ }
+ break;
+ case WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT:
+ {
+ struct token *token=va_arg(args,struct token*);
+ print_raw_token_text(s,token);
+ }
+ break;
}
}
/*
%WE - message
- %Wt - token
- %Wi - indentation (short)
- %WI - id
- %Wd - denoted
- %WA - ast
- %WT - type
+ %Wt - token
+ %Wi - indentation (short)
+ %WI - id
+ %Wd - denoted
+ %WA - ast
+ %WT - type
%WAE - ast enum
- %Wo - object
- %WC - constant
- %WS - source name
+ %Wo - object
+ %WC - constant
+ %WS - source name
+ %WSl - source location
%WIC - inclusion chain (takes Token_Pointer )
%WPC - token pointer context call stack ( takes Token_Pointer *)
%WPc - token pointer context ( takes Token_Pointer_Context *)
%WMA - macro argument
- %WMf - functionlike macro
+ %WMf - functionlike macro
+ %Wtl - print line containing token ( takes token*)
+ %Wtr - print raw token text ( takes token *)
*/
void wonky__parse_scan_format(const char *begining, struct wonky__scanformat *destination)
{
++destination->forward_crawl;
if(destination->wonky_form)
{
- destination->conversion=WONKY__CONVERSION_WONKY_TOKEN;
+ if(begining[destination->forward_crawl]=='l')
+ {
+ ++destination->forward_crawl;
+ destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_LINE;
+ } else if(begining[destination->forward_crawl]=='r')
+ {
+ ++destination->forward_crawl;
+ destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT;
+ } else
+ {
+ destination->conversion=WONKY__CONVERSION_WONKY_TOKEN;
+ }
/*WARNING EARLY RETURN*/
return;
}else
case 'S':
++destination->forward_crawl;
if(destination->wonky_form)
- destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_NAME;
+ {
+ if(begining[destination->forward_crawl]=='l')
+ {
+ destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_LOCATION;
+ ++destination->forward_crawl;
+ }else
+ {
+ destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_NAME;
+ }
+ }
break;
case 'P':
++destination->forward_crawl;
F diff --git a/src/misc/wonky_stream.hh b/src/misc/wonky_stream.hh --- a/src/misc/wonky_stream.hh +++ b/src/misc/wonky_stream.hh
WONKY__CONVERSION_WONKY_MACRO_ARGUMENT,
WONKY__CONVERSION_WONKY_TOKEN_POINTER_CONTEXT,
WONKY__CONVERSION_WONKY_FUNCTIONLIKE_MACRO,
+ WONKY__CONVERSION_WONKY_TOKEN_LINE,
+ WONKY__CONVERSION_WONKY_SOURCE_LOCATION,
+ WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT,
WONKY__CONVERSION_END
};
enum wonky__scanformat_modifier
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.c
return ret;
}
- struct AST_Expression* get_designator_tree(struct identifier *id,struct Scope* scope,struct Translation_Data *translation_data)
+ struct AST_Expression* get_designator_tree(struct token_identifier *id,struct Scope* scope,struct Translation_Data *translation_data)
{
struct AST_Designator *ret;
struct Denoted *hold_denoted;
ret->type=OP_DESIGNATOR;
- hold_denoted=check_ordinary(scope,id);
+ hold_denoted=check_ordinary(scope,id->id);
if(hold_denoted==NULL)
{
- push_translation_error("using undeclared id - %WI, in expression",translation_data,id);
+ push_translation_error("using undeclared id - %WI\n%WSl \"%Wtl\"",translation_data,id->id,id->delta->location,id);
wonky_free(ret);
return (struct AST_Expression*)get_error_tree(NULL);
}else
break;
case DT_Function:
ret->value=get_expression_value_function_designator((struct Denoted_Function*)hold_denoted);
- ret->id=id;
+ ret->id=id->id;
return (struct AST_Expression*)get_address_expression_tree((struct AST_Expression*)ret,translation_data);/*BEWARE*/
}
}
- ret->id=id;
+ ret->id=id->id;
return (struct AST_Expression*)ret;
}
F diff --git a/src/semantics/ast.h b/src/semantics/ast.h --- a/src/semantics/ast.h +++ b/src/semantics/ast.h
struct AST_Constant* get_constant_tree(struct Expression_Value_Constant *value);
struct AST_String_Literal* get_string_literal_tree(struct Expression_Value_Constant *value);
- struct AST_Expression* get_designator_tree(struct identifier *id,struct Scope* scope,struct Translation_Data *translation_data);
+ struct AST_Expression* get_designator_tree(struct token_identifier *id,struct Scope* scope,struct Translation_Data *translation_data);
struct AST_Designator* get_designator_tree_from_denoted_object(struct Denoted_Object *object,struct Translation_Data *translation_data);
struct AST_Designator* get_struct_union_member_tree_designator(struct identifier *id,struct Normal_Scope *inner_scope,struct Translation_Data *translation_data);
F diff --git a/src/semantics/identifiers/denoted.c b/src/semantics/identifiers/denoted.c --- a/src/semantics/identifiers/denoted.c +++ b/src/semantics/identifiers/denoted.c
ret=wonky_malloc(sizeof(struct Denoted_Base));
ret->denotation=prototype->denotation;
ret->id=NULL;
- ret->type=prototype->type;
+ ret->type=get_type_error(prototype->type);
wonky_assert(is_valid_denoted_base(ret));
return ret;
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
do
{
base_file=get_source_file_from_string(*base_source_names,gstrnlen(*base_source_names,1000),program);
+ if(base_file==NULL)
+ break;
Queue_Push(program->preprocessing_translation_units_to_be_compiled,lex(base_file,program));
}while(*(++base_source_names) != NULL);
if(ret==NULL)
{
hold_src=get_source_file_from_string(filename,filename_size,program);
+ if(hold_src==NULL)
+ return NULL;
ret=lex(hold_src,program);
if(ret==NULL)
return NULL;
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;
struct Preprocessing_Translation_Unit *hold_unit;
- char *include_name;
wonky_assert(include_directive->tokens->first);
if(hold_token->type==KW_STRING)
{
+ char *include_name;
if(ptr->context->current_token_node!=NULL)
{
- push_generic_error(ptr->program,"Unexpected token at end of include directive");
+ push_token_pointer_error(ptr,"Unexpected token at end of include directive");
return;
}
include_name=((struct token_string*)hold_token)->constant->value;
hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));
if(hold_unit==NULL)
+ {
+
+ token_ptr_pop_context(ptr);
+ push_token_pointer_error(ptr,"Failed to execute include directive %Wtl",include_directive);
+ if(ptr->call_stack->size)
+ push_generic_note(ptr->program,"%WIC",ptr);
return;
+ }
if(hold_unit->tokens->first)
token_ptr_jump_to_first(ptr,hold_unit->tokens,1);
else
- token_ptr_goto_next_token(ptr);
+ token_ptr_pop_context(ptr);
}else if(hold_token->type==KW_LESS)
{
+ struct wonky_str include_name;
+ struct wonky_stream strs;
+
+ include_name=wonky_string_make();
+
+ strs=wonky_string_stream(&include_name);
token_ptr_set_barrier(ptr);
ptr->state=TOKEN_POINTER_STATE_PREPROCESSING;
- include_name=gstrncpy("",2);
hold_token=token_ptr_get_token_under_pointer(ptr);
while(hold_token->type!=KW_MORE && hold_token->type!=KW_MORE_EQ)
{
- switch(hold_token->type)
- {
- case KW_ID:
- include_name=gstrn_append(include_name,((struct token_identifier*)hold_token)->id->data,100);
- break;
- case KW_DIV:
- include_name=gstrn_append(include_name,"/",100);
- break;
- case KW_DOT:
- include_name=gstrn_append(include_name,".",100);
- break;
- case KW_MINUS:
- include_name=gstrn_append(include_name,"-",100);
- break;
- default:
- if(token_is_keyword(hold_token))
- {
- include_name=gstrn_append(include_name,((struct token_keyword*)hold_token)->id->data,100);
- }else
- {
- push_generic_error(ptr->program,"Unsupported symbol found inside filename in include directive with angular brackets and macro expansion");
- return;/*NOTICE*/
- }
- }
+
+ print_raw_token_text(&strs,hold_token);
hold_token=token_ptr_get_token_under_pointer(ptr);
}
ptr->state=TOKEN_POINTER_STATE_NORMAL;
token_ptr_clear_barrier(ptr);
+ wonky_stream_delete(&strs);
if(ptr->context->current_token_node!=NULL)
{
- push_generic_error(ptr->program,"Unexpected token at end of include directive");
+ push_token_pointer_error(ptr,"Unexpected token at end of include directive");
return;
}
- hold_unit=program_get_translation_unit(ptr->program,include_name,gstrnlen(include_name,100));
+ hold_unit=program_get_translation_unit(ptr->program,include_name.cs,wonky_string_length(include_name));
if(hold_unit==NULL)
+ {
+ token_ptr_pop_context(ptr);
+ push_token_pointer_error(ptr,"Failed to execute include directive %Wtl",include_directive);
+ if(ptr->call_stack->size)
+ push_generic_note(ptr->program,"%WIC",ptr);
return;
+ }
if(hold_unit->tokens->first)
token_ptr_jump_to_first(ptr,hold_unit->tokens,1);
else
- token_ptr_goto_next_token(ptr);
+ token_ptr_pop_context(ptr);
}else if(hold_token->type==KW_LESS_EQ) /*implementation defined*/
{
- push_generic_error(ptr->program,"'=' is not supported inside filename in include directive with angular brackets and macro expansion");
+ push_token_pointer_error(ptr,"'=' is not supported inside filename in include directive with angular brackets and macro expansion");
return;
}
ptr->is_in_conditional_directive=0;
ptr->state=TOKEN_POINTER_STATE_NORMAL;
+ if(token_ptr_has_remaining_tokens_in_current_context(ptr))
+ {
+ push_token_pointer_error(ptr,"Remaining tokens in #if directive after control expression\n");
+ token_ptr_pop_context(ptr);
+ }
+
if(evaluate_const_expression_integer(control,dummy_data)!=0)
{
- token_ptr_jump_to_first(ptr,if_directive->if_true,0);
+ if(if_directive->if_true->size!=0)
+ token_ptr_jump_to_first(ptr,if_directive->if_true,0);
}else
{
if(if_directive->if_false!=NULL)
hold_token=token_ptr_get_token_under_pointer(ptr);
if(hold_token->type!=KW_OPEN_NORMAL)
{
- push_generic_error(ptr->program,"Expected '(' after functionlike macro id");
+ push_token_pointer_error(ptr,"Expected '(' after functionlike macro id");
return;
}
{
if(hold_argument_node==NULL)
{
- push_generic_error(ptr->program,"Too many arguments given to functionlike macro");
+ push_token_pointer_error(ptr,"Too many arguments given to functionlike macro");
return;
}
if(number_of_tokens_in_argument==0)
{
- push_generic_error(ptr->program,"No tokens in functionlike macro");
+ push_token_pointer_error(ptr,"No tokens in functionlike macro");
return;
}
hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;
if(hold_argument_node==NULL || hold_argument_node->prev!=NULL)
{
- push_generic_error(ptr->program,"Too few arguments given to functionlike macro");
+ push_token_pointer_error(ptr,"Too few arguments given to functionlike macro");
return;
}
hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;
{
token_ptr_execute_macro(token_pointer,hold_id_token->id);
return 1;
+ }else if(token_pointer->is_in_conditional_directive)
+ {
+ token_ptr_goto_next_token(token_pointer);
+ /*all undefined id tokens in control expression are replaced with 0*/
+ Queue_Push(token_pointer->context->ungeted_tokens,get_constant_token(
+ KW_DECIMAL_CONSTANT,
+ hold_id_token->delta->location,
+ hold_id_token->delta->location,
+ "0",
+ 1));
+ return 0;
}else
{
return 0; /*NOTICE*/
{
token_ptr_execute_macro(token_pointer,hold_kw_token->id);
return 1;
+ }else if(token_pointer->is_in_conditional_directive)
+ {
+
+ token_ptr_goto_next_token(token_pointer);
+ /*all undefined id tokens in control expression are replaced with 0*/
+ Queue_Push(token_pointer->context->ungeted_tokens,get_constant_token(
+ KW_DECIMAL_CONSTANT,
+ hold_kw_token->delta->location,
+ hold_kw_token->delta->location,
+ "0",
+ 1));
+ return 0;
}else
{
return 0; /*NOTICE*/
ret->ungeted_tokens=wonky_malloc(sizeof(struct Queue));
hold_location=((struct token*)start->data)->delta->location;
- ret->line=hold_location->line;
- ret->column=hold_location->column;
+ //ret->line=hold_location->line;
+ //ret->column=hold_location->column;
+
+ ret->line=0;
+ ret->column=0;
ret->filename=hold_location->src->src_name->name;
ret->filename_size=hold_location->src->src_name->name_size;
ret->executed_macro_id=NULL;
{
if(ptr->call_stack->size>1000)
{
- push_generic_error(ptr->program,"Preprocessing bounds exceeded");
+ push_token_pointer_error(ptr,"Preprocessing bounds exceeded");
return;
}
new_context=get_token_ptr_context(where_to,number_of_remaining_tokens,is_file_inclusion);
{
if(ptr->call_stack->size>1000)
{
- push_generic_error(ptr->program,"Preprocessing bounds exceeded");
+ push_token_pointer_error(ptr,"Preprocessing bounds exceeded");
return;
}
new_context=get_token_ptr_context(arg->first_in_argument_substitution_tokens,arg->number_of_substitution_tokens,0);
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
[' ']=CHAR_SPACE,
['\t']=CHAR_HORISONTAL_TAB,
['\v']=CHAR_VERTICAL_TAB,
- ['\n']=CHAR_FORM_FEED_TAB,
+ ['\n']=CHAR_FORM_FEED_TAB, // this name is retarded
};
struct identifier defined_special_identifier
F diff --git a/src/syntax/source_file.c b/src/syntax/source_file.c --- a/src/syntax/source_file.c +++ b/src/syntax/source_file.c
if(file==NULL)
{
push_generic_error(program,"Could not open file %s",filename);
- ret->src_name=get_source_name("");
- return ret;
+ wonky_free(ret);
+
+ return NULL;
}
}
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
ret=wonky_malloc(sizeof(struct token_error));
ret->type=LT_ERROR;
ret->delta=get_source_location_delta(previous_location,current_location);
- ret->error=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_PREPROCESSING,current_location->line,current_location->column,current_location->src->src_name->name,current_location->src->src_name->name_size,"%s:%zu:%zu %s",hold_err.cs);
+ ret->error=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_PREPROCESSING,current_location->line,current_location->column,current_location->src->src_name->name,current_location->src->src_name->name_size,"%s",hold_err.cs);
return (struct token*)ret;
}