F diff --git a/src/backend/print/print.c b/src/backend/print/print.c
--- a/src/backend/print/print.c
+++ b/src/backend/print/print.c
struct Queue_Node *it;
for(it=errors->first;it!=NULL;it=it->prev)
{
- print_translation_error(out,(struct Translation_Error*)it->data);
+ print_translation_error(out,(struct Translation_Message*)it->data);
}
}
void print_function_args(FILE *out,struct Type_Function *func)
F diff --git a/src/frontend/lex/preprocessing.c b/src/frontend/lex/preprocessing.c
--- a/src/frontend/lex/preprocessing.c
+++ b/src/frontend/lex/preprocessing.c
goto_new_line(src,translation_data);
src->src[src->where_in_src-1]='\0';
- Queue_Push(translation_data->errors,get_translation_error(error,line,column,src->src_name->filename));
+ push_raw_translation_error(error,line,column,src->src_name->filename,translation_data);
}
void parse_preproc_line_line(struct Source_File *src,struct Translation_Data *translation_data)
F diff --git a/src/misc/gcc_string.c b/src/misc/gcc_string.c
--- a/src/misc/gcc_string.c
+++ b/src/misc/gcc_string.c
#include <gcc_string.h>
- size_t gstrlen(char *str)
+ size_t gstrlen(const char *str)
{
size_t i;
for(i=0;str[i]!='\0';++i);
return i;
}
- char* gstr_append(char *lead,char *follower)
+ char* gstr_append(const char *lead,const char *follower)
{
char *ret,*hold;
hold=ret=malloc(gstrlen(lead) + gstrlen(follower)+1);
{
while(*(target++)=*(source++));
}
- char* gstrcpy(char *str)
+ char* gstrcpy(const char *str)
{
char *temp=malloc(gstrlen(str)+1);
for(size_t i=0;(temp[i]=str[i])!='\0';++i);
return temp;
}
- char* gstrncpy(char *str,size_t size)
+ char* gstrncpy(const char *str,size_t size)
{
size_t i;
char *temp=malloc(size+1);
return 0;
return 1;
}
+ char *gstr_append_and_consume(const char *lead,const char *follower)
+ {
+ char *ret;
+
+ ret=gstr_append(lead,follower);
+
+ free((void*)lead),free((void*)follower);
+
+ return ret;
+ }
+ char* gstr_dup(const char *first,const char *last,size_t limit)
+ {
+ char *ret;
+ ptrdiff_t diff;
+ size_t i;
+
+ assert(first!=NULL && last!=NULL);
+
+ diff=last-first;
+
+ if((ssize_t)diff<0 || (size_t)diff>=limit)
+ {
+ ret=malloc(1);
+ ret[0]='\0';
+ return ret;
+ }else
+ {
+ ret=malloc((size_t)diff+1);
+ ret[(size_t)diff]='\0';
+
+ for(i=0;first+i!=last;++i)
+ ret[i]=first[i];
+
+ return ret;
+ }
+
+ assert(0);
+ }
+ char* gstr_to_heap(const char *literal)
+ {
+ size_t i;
+ size_t literal_length;
+ char *ret;
+
+ literal_length=gstrlen(literal);
+
+ ret=malloc(literal_length+1);
+
+ for(i=0;i<=literal_length;++i)
+ ret[i]=literal[i];
+
+ return ret;
+
+ }
#endif
F diff --git a/src/misc/gcc_string.h b/src/misc/gcc_string.h
--- a/src/misc/gcc_string.h
+++ b/src/misc/gcc_string.h
#ifndef GSTRING_H
#define GSTRING_H GSTRING_H
#include <stdlib.h>
+ #include <stddef.h>
+ #include <assert.h>
- size_t gstrlen(char *str);
- char* gstr_append(char *lead,char *follower);
- char* gstrcpy(char *str);
- char* gstrncpy(char *str,size_t size);
+ size_t gstrlen(const char *str);
+ char* gstr_append(const char *lead,const char *follower);
+ char* gstrcpy(const char *str);
+ char* gstrncpy(const char *str,size_t size);
char gstr_cmp(const char *a,const char *b);
char gstrn_cmp(const char *a,const char *b,size_t size);
void strmv(char *target,char *source);
-
+ char *gstr_append_and_consume(const char *lead,const char *follower);
+ char* gstr_dup(const char *first,const char *last,size_t limit);
+ char* gstr_to_heap(const char *literal);
#endif
F diff --git a/src/program/gcc_error.c b/src/program/gcc_error.c
--- a/src/program/gcc_error.c
+++ b/src/program/gcc_error.c
#include <gcc_error.h>
-
- struct Translation_Error* get_translation_error(const char *error_message,size_t line,size_t column,const char *filename)
+ /*
+ %T - type
+ %D - denoted
+ /bin/bash: line 1: src/program/gcc_error.h: Permission denied
+ /bin/bash: line 1: =: No such file or directory
+ */
+ struct Translation_Message* get_translation_message(const char *message_format,struct Translation_Data *translation_data,char *filename,size_t line,size_t column,va_list args)
{
- struct Translation_Error *ret;
- ret=malloc(sizeof(struct Translation_Error));
- ret->error_message=error_message;
- ret->column=column;
+
+ size_t i;
+ const char *where_in_return_message=message_format;
+ const char *hold_return_string;
+ const char *hold_return_substring;
+
+ struct Translation_Message *ret;
+
+ hold_return_string=get_translation_message_location_prefix(filename,line,column);
+
+
+ for(i=0;i<1000 && message_format[i]!='\0';++i)
+ {
+ if(message_format[i]=='%')
+ {
+ switch(message_format[i+1])
+ {
+ case 't':
+ hold_return_substring=get_string_for_token_error(va_arg(args,struct token*),translation_data);
+ break;
+ case 'T':
+ hold_return_substring=get_string_for_type_error(va_arg(args,struct Type*),translation_data);
+ break;
+ case 'D':
+ hold_return_substring=get_string_for_denoted_error(va_arg(args,struct Denoted*),translation_data);
+ break;
+ default:
+ continue; /*goes to top for loop*/
+ }
+
+ hold_return_substring=gstr_append_and_consume(
+ gstr_dup(where_in_return_message,message_format+i,i+1),
+ hold_return_substring);
+ hold_return_string=gstr_append_and_consume(hold_return_string,hold_return_substring);
+
+ where_in_return_message=message_format+i+2;
+ i+=2;
+
+ }
+ }
+
+ hold_return_string=gstr_append_and_consume(
+ hold_return_string,
+ gstr_dup(where_in_return_message,message_format+i,i+1)
+ );
+
+ ret=malloc(sizeof(struct Translation_Message));
+ ret->message=hold_return_string;
ret->line=line;
+ ret->column=column;
ret->filename=filename;
+
+ return ret;
}
- struct Translation_Error* get_translation_error_by_token(const char *error_message,struct token *error_token)
+ void push_translation_message_inner(const char *prefix,const char *message_format,struct Translation_Data *translation_data,va_list args)
{
- if(error_token==NULL)
- {
- return get_translation_error(error_message,0,0,"");
- }else
+ struct Translation_Message *hold_message;
+ char *filename=NULL;
+ size_t line=0;
+ size_t row=0;
+
+ if(translation_data->tokens->size>0)
{
- return get_translation_error(error_message,error_token->line+1,error_token->column+1,error_token->filename);
+ struct token *hold_token;
+ hold_token=translation_data->tokens->first->data;
+ filename=(char*)hold_token->filename;
+ line=hold_token->line;
+ row=hold_token->column;
}
+
+ hold_message=get_translation_message(message_format,translation_data,filename,line,row,args);
+ hold_message->message=gstr_append_and_consume(gstr_to_heap(prefix),hold_message->message);
+ Queue_Push(translation_data->errors,hold_message);
+ }
+ void push_translation_error(const char *message_format,struct Translation_Data *translation_data, ...)
+ {
+ va_list args;
+ va_start(args,translation_data);
+ push_translation_message_inner("[Error] ",message_format,translation_data,args);
+ va_end(args);
+ }
+ void push_translation_note(const char *note_message,struct Translation_Data *translation_data, ...)
+ {
+ va_list args;
+ va_start(args,translation_data);
+ push_translation_message_inner("[Note] ",note_message,translation_data,args);
+ va_end(args);
}
+ void push_lexing_error(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...)
+ {
+ assert(0);
+ }
+ void push_lexing_note(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...)
+ {
- void push_translation_error(const char *error_message,struct Translation_Data *translation_data)
+ assert(0);
+ }
+ void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_data)
{
- if(translation_data->tokens->size==0)
- {
- get_translation_error(error_message,0,0,"");
- }else
- {
- Queue_Push(translation_data->errors,get_translation_error_by_token(error_message,(struct token*)translation_data->tokens->first->data));
- }
+ struct Translation_Message *hold_message;
+ hold_message=malloc(sizeof(struct Translation_Message));
+ hold_message->message=gstr_to_heap(error_message);
+ hold_message->filename=filename;
+ hold_message->line=line;
+ hold_message->column=column;
+
+ Queue_Push(translation_data->errors,hold_message);
+
}
+ char* get_string_for_type_error(struct Type *type,struct Translation_Data *translation_data)
+ {
+ char *ret;
- void push_lexing_error(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data)
+ ret=gstr_to_heap("type");
+
+ return ret;
+ }
+ char* get_string_for_denoted_error(struct Denoted *denoted,struct Translation_Data *translation_data)
{
- Queue_Push(translation_data->errors,get_translation_error(error_message,src->which_row+1,src->which_column+1,src->src_name->filename));
+ char *ret;
+
+ ret=gstr_to_heap("denoted");
+
+ return ret;
}
- void print_translation_error(FILE *out,struct Translation_Error *error)
+ char* get_string_for_token_error(struct token *token,struct Translation_Data *translation_data)
{
- fprintf(out,"Error ");
- if(error->filename!=NULL)
- {
- fprintf(out,"(line %i column %i) ",error->line,error->column);
- fprintf(out,"in %s ",error->filename);
- }
- fprintf(out,": %s\n",error->error_message);
+ char *ret;
+
+ ret=gstr_dup(token->data,token->data+token->data_size,token->data_size+1);
+
+ return ret;
}
+ char* get_translation_message_location_prefix(char *filename,size_t line,size_t column)
+ {
+ char *ret;
+ size_t filename_length;
+
+ filename_length=gstrlen(filename);
+ ret=calloc(filename_length+64,1);
+ sprintf(ret,"%s %zu:%zu ",filename,line,column);
+ return ret;
+ }
- void delete_translation_error(struct Translation_Error *translation_error)
+ void print_translation_error(FILE *out,struct Translation_Message *error)
+ {
+ fprintf(out,"%s\n",error->message);
+ }
+ void delete_translation_error(struct Translation_Message *translation_error)
{
free(translation_error);
}
F diff --git a/src/program/gcc_error.h b/src/program/gcc_error.h
--- a/src/program/gcc_error.h
+++ b/src/program/gcc_error.h
#include <gcc_error.hh>
#include <lexer.h>
#include <stdio.h>
+ #include <stdarg.h>
+ #include <queue.h>
+ #include <gcc_string.h>
-
- struct Translation_Error
+ struct Translation_Message
{
- const char *error_message;
+ const char *message;
size_t line,column;
const char *filename;
-
};
+ /*
+ %T print type - takes pointer to Type
+ %D denoted - takes pointer to Denoted
+ %t token - takes pointer to a token
+ */
+ struct Translation_Message* get_translation_message(const char *message_format,struct Translation_Data *translation_data,char *filename,size_t line,size_t column,va_list args);
+
+
+ void push_translation_message_inner(const char *prefix,const char *message_format,struct Translation_Data *translation_data,va_list args);
+ void push_translation_error(const char *message_format,struct Translation_Data *translation_data, ...);
+ void push_translation_note(const char *note_message,struct Translation_Data *translation_data, ...);
+
+ void push_lexing_error(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...);
+ void push_lexing_note(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...);
+
+ void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_data);
+
+
+ char* get_string_for_type_error(struct Type *type,struct Translation_Data *translation_data);
+ char* get_string_for_denoted_error(struct Denoted *denoted,struct Translation_Data *translation_data);
+ char* get_string_for_token_error(struct token *token,struct Translation_Data *translation_data);
+ char* get_translation_message_location_prefix(char *filename,size_t line,size_t column);
+
+ void print_translation_error(FILE *out,struct Translation_Message *message);
+ void delete_translation_error(struct Translation_Message *message);
+
+ /*
+
+ =====================================================================================================================
+ push_translation_error("Redeclaration of identifier %t",idptr);
+ push_translation_note("First declared here %L as %T",denoted->id->filename,denoted->id->line,denoted->type);
+
+ |
+ V
+
+ [Error] file line:column - Redeclaration of identifier a
+ [Note] file line:column - First declared as Type
+ =====================================================================================================================
+ push_translation_error("Usage of undeclared identifier %t at %L",idptr,idptr);
+
+ |
+ V
- struct Translation_Error* get_translation_error(const char *error_message,size_t line,size_t column,const char *filename);
- struct Translation_Error* get_translation_error_by_token(const char *error_message,struct token *error_token);
- void push_translation_error(const char *error_message,struct Translation_Data *translation_data);
- void push_lexing_error(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data);
- void print_translation_error(FILE *out,struct Translation_Error *error);
+ [Error] file line:column - Usage of undeclared identifier a at file:line
+ =====================================================================================================================
+ push_translation_error("Addition between incompatible types %T and %T",...);
+
+ |
+ V
- void delete_translation_error(struct Translation_Error *translation_error);
+ [Error] file line:column - Addition between incomptatible types int and struct kek
+ =====================================================================================================================
+ */
#endif
F diff --git a/src/program/gcc_error.hh b/src/program/gcc_error.hh
--- a/src/program/gcc_error.hh
+++ b/src/program/gcc_error.hh
struct Translation_Error;
+ struct Output_Message;
#endif
F diff --git a/src/semantics/identifiers/scope.c b/src/semantics/identifiers/scope.c
--- a/src/semantics/identifiers/scope.c
+++ b/src/semantics/identifiers/scope.c
void push_object(struct Scope *current,struct Translation_Data *translation_data,struct Denoted_Object *denoted_object)
{
- #define PO_ERROR(msg) delete_denoted_object(denoted_object);push_translation_error(msg,translation_data);return;
+ #define PO_ERROR(msg) push_translation_error(msg,translation_data,denoted_object->id);delete_denoted_object(denoted_object);return;
struct Denoted_Object *hold_object;
struct Linkage *linkage;
hold_object=CHECK_AND_PUSH(denoted_object,&AS_NORMAL_SCOPE(current)->ordinary);
if(hold_object!=NULL && hold_object->linkage==LINKAGE_NONE)
- {PO_ERROR("redeclaration of identifier");}
+ {PO_ERROR("redeclaration of identifier %t ");}
if(denoted_object->linkage==LINKAGE_NONE)
{
F diff --git a/src/semantics/memory/object.c b/src/semantics/memory/object.c
--- a/src/semantics/memory/object.c
+++ b/src/semantics/memory/object.c
ret=malloc(sizeof(struct Object));
ret->kind=OBJECT_KIND_NORMAL;
ret->type=type;
- ret->storage_class=storage_class;
+ if(storage_class==SCS_EXTERN || storage_class==SCS_STATIC)
+ ret->storage_class=SCS_STATIC;
+ else if(storage_class==SCS_REGISTER)
+ ret->storage_class=storage_class;
+ else
+ ret->storage_class=SCS_NONE;
+
ret->location=NULL;
return ret;
}