F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txtinclude_directories(src/frontend/lex)include_directories(src/frontend/lex/automatas)include_directories(src/frontend/parse)+include_directories(src/semantics)include_directories(src/semantics/identifiers)include_directories(src/semantics/memory)include_directories(src/semantics/value)include_directories(src/semantics/constraints)+ include_directories(src/semantics/program)+include_directories(src/debug)include_directories(src/debug/wobler)include_directories(src/misc)- include_directories(src/program)+ include_directories(src/environment)+ include_directories(src/environment/command_arguments)+ include_directories(src/environment/error)set(SOURCESsrc/misc/map.csrc/misc/queue.csrc/misc/stack.c- src/program/gcc_arguments.c- src/program/gcc_error.c- src/program/program.c+ src/environment/command_arguments/gcc_arguments.c+ src/environment/error/gcc_error.c+ src/semantics/program/program.csrc/semantics/ast.csrc/semantics/constraints/expression_constraints.csrc/semantics/constraints/initialiser_constraints.cF diff --git a/README b/README deleted file mode 100644 --- a/README +++ /dev/null- How to build:- Use cmake out of the repository, for example /tmp/build-- You can compile wonky with make and run tests with make test-- Wonky C99 compiler command line arguments-- --print-tokens- prints the tokens after preprocessing- --print-ast- prints 'ast' of the program after parsingF diff --git a/README.txt b/README.txt new file mode 100644 --- /dev/null +++ b/README.txt+ What is Wonky:+ Wonky is supposed to be a c99 compiler. Sadly at the moment it does not compile to machine code, or asm.++ What can I do with it?+ Nothing interesting at the moment.++ How to build it:+ Use cmake out of the repository, for example /tmp/build+ You can compile wonky with make and run tests with make test++ How to contibute:+ If you have added code or documentation you can send it to me+ via email gts@volconst.com++ Wonky C99 compiler command line arguments+ --print-tokens+ prints the tokens after preprocessing+ --print-ast+ prints 'ast' of the program after parsing+ --compile-asm or -asm+ outputs asm to stdout. Mostly NOPs and segfaults at the moment.F diff --git a/doc/arch.txt b/doc/arch.txt new file mode 100644 --- /dev/null +++ b/doc/arch.txt+ Wonky follows the standart architecture+ of a parsing and lexing frontend followed by a+ code generation backend.++ Currently there is no middle end -+ the intermideate representation and+ optimisations done on it. It is a goal+ to make one.+++ Parsing and semantics are separated.++ Constraint checks are separated from whatever+ has constraint checks in the hope of preserving+ code readability. ( Not fully implemented )+++ ASTs are a very fragile part of the design.+ Adding node types is very difficult, because+ their use is scattered accross the whole program.+ This was done to simplify code organisation, but+ did not work out. Will refactor them so that+ the functions that use them are in them ( very+ C++ like ). This or rely on IR to serve as a+ mask to the asts.F diff --git a/doc/build.txt b/doc/build.txt new file mode 100644 --- /dev/null +++ b/doc/build.txt+ Wonky is currently build using cmake+ It defaults to building with debug symbols and+ no optimisations.++ If you want to add a source file for+ compiling you must add it to the SOURCE+ var, and if it's located in new directory+ you must run include_directories on it.++ The only complex thing the cmake script+ compiling a different object for the+ normal assert and the debug assert that+ the wobler uses and linking them to+ wonky and wobler correctly.F diff --git a/doc/hier.txt b/doc/hier.txt new file mode 100644 --- /dev/null +++ b/doc/hier.txt+ The source of Wonky is scattered many different+ directories with the hope of preserving tidiness.+ They should be self explanatory, but here is a+ list ( that is probabbly incomplete and out of date )+ so you know how to interpret the names++ doc - documentation dir+ tests - test .c files dir+ src - root source dir+ src/backend - source proccessing code dir+ src/frontend - code generation code dir+ src/debug - functions for asserts and wobler dir+ src/misc - non compiler specific data structures dir+ src/environment - deals with the host system, I/O and command line args+ src/semantics - data structures specific to the compiler and code that+ deals with them+F diff --git a/doc/tests.txt b/doc/tests.txt new file mode 100644 --- /dev/null +++ b/doc/tests.txt+ make test++ Tests are mainly done with asserts in the source code.+ Wonky uses wonky_assert. There asserts are triggered+ by lexing and parsing the .c files in the tests directory++ There is an in house testing system named+ the wobler. It's currently located in src/debug/wobler.++ It links to a different assert function implementation+ that lets it continue on with tests after an assertion+ fail.++ If you want to add tests you need to put them into+ the tests tld, the you must add it to the tests array+ ( currently in src/debug/wobler/wobler_tests.h )F diff --git a/doc/todo.txt b/doc/todo.txt new file mode 100644 --- /dev/null +++ b/doc/todo.txt+ Add #pragma, #line and whatever preprocessing directives+ are still undone.+ Create a custom allocation system.+ Implement the const expression evaluation stuff+ Add asm compilation stuff.F diff --git a/src/environment/command_arguments/gcc_arguments.c b/src/environment/command_arguments/gcc_arguments.c new file mode 100644 --- /dev/null +++ b/src/environment/command_arguments/gcc_arguments.c+ #ifndef WONKY_ARGUMENTS_C+ #define WONKY_ARGUMENTS_C WONKY_ARGUMENTS_C+ #include <gcc_arguments.h>++++ struct Command_Arguments* parse_command_arguments(char **argv)+ {+ struct Command_Arguments *ret;+ struct Queue *source_names;++ ret=malloc(sizeof(struct Command_Arguments));+ ret->print_ast=ret->print_tokens=ret->transpile_to_js=ret->is_quiet=ret->compile_to_intel_asm=0;+ ret->output_file=ret->javascript_extern_file=NULL;++ source_names=malloc(sizeof(struct Queue));+ Queue_Init(source_names);++ ret->error_message=NULL;++ /*we skip the first element(the program name)*/+ for(++argv;*argv;++argv)+ {+ if(gstr_cmp(*argv,"--print-tokens"))+ {+ ret->print_tokens=1;+ }else if(gstr_cmp(*argv,"--print-ast"))+ {+ ret->print_ast=1;+ }else if(gstr_cmp(*argv,"--quiet") || gstr_cmp(*argv,"-q"))+ {+ ret->is_quiet=1;+ if(ret->print_ast || ret->print_tokens)+ {+ ret->error_message="print and quiet conflict. Aborting";+ break;+ }+ }else if(gstr_cmp(*argv,"--transpile_to_js") || gstr_cmp(*argv,"-js"))+ {+ ret->transpile_to_js=1;+ }else if(gstr_cmp(*argv,"--compile-asm") || gstr_cmp(*argv,"-asm"))+ {+ ret->compile_to_intel_asm=1;+ }else if(gstr_cmp(*argv,"-o"))+ {+ ++argv;+ if(*argv==NULL)+ {+ ret->error_message="expected a filename after -o. Aborting";+ break;+ }else+ {+ ret->output_file=fopen(*argv,"w");+ if(ret->output_file==NULL)+ {+ ret->error_message="Couldn't open file for output. Aborting";+ break;+ }+ }+ }else if(gstr_cmp(*argv,"--make-extern-file"))+ {+ ret->javascript_extern_file=fopen(*argv,"w");+ if(ret->javascript_extern_file==NULL)+ {+ ret->error_message="Couldn't open file for extern dump. Aborting";+ break;+ }+ }else if(gstr_cmp(*argv,"--add-html"))+ {+ ret->insert_html=1;+ }else+ {+ Queue_Push(source_names,*argv);+ }+ }++ ret->source_names=malloc((source_names->size+1)*sizeof(char*) );+ ret->source_names[source_names->size]=NULL;+ while(source_names->size)+ {+ ret->source_names[source_names->size-1]=(char*)source_names->first->data;+ Queue_Pop(source_names);+ }+ free(source_names);+ if(ret->transpile_to_js && ret->output_file==NULL)+ {+ ret->output_file=fopen("a.js","w");+ if(ret==NULL)+ ret->error_message="Couldn't open file for output. Aborting";+ }+ return ret;+ }+++ void delete_command_arguments(struct Command_Arguments *args)+ {+ if(args->output_file!=NULL)+ fclose(args->output_file);+ if(args->javascript_extern_file!=NULL)+ fclose(args->javascript_extern_file);++ free(args->source_names);+ free(args);+ }++ #endifF diff --git a/src/environment/command_arguments/gcc_arguments.h b/src/environment/command_arguments/gcc_arguments.h new file mode 100644 --- /dev/null +++ b/src/environment/command_arguments/gcc_arguments.h+ #ifndef WONKY_ARGUMENTS_H+ #define WONKY_ARGUMENTS_H WONKY_ARGUMENTS_H+ #include <gcc_arguments.hh>+ #include <queue.h>+ #include <gcc_string.h>+ #include <stdio.h>+ #include <common.h>+++ struct Command_Arguments+ {+ char **source_names;+ char print_tokens:1;+ char print_ast:1;+ char is_quiet:1;+ char transpile_to_js:1;+ char insert_html:1;+ char compile_to_intel_asm:1;+++ FILE* output_file;+ FILE* javascript_extern_file;+++ char *error_message;+ };++ struct Command_Arguments* parse_command_arguments(char **argv);+ void delete_command_arguments(struct Command_Arguments *args);++ #endifF diff --git a/src/environment/command_arguments/gcc_arguments.hh b/src/environment/command_arguments/gcc_arguments.hh new file mode 100644 --- /dev/null +++ b/src/environment/command_arguments/gcc_arguments.hh+ #ifndef WONKY_ARGUMENTS_HH+ #define WONKY_ARGUMENTS_HH WONKY_ARGUMENTS_HH+++ struct Command_Arguments;+++ #endifF diff --git a/src/environment/error/gcc_error.c b/src/environment/error/gcc_error.c new file mode 100644 --- /dev/null +++ b/src/environment/error/gcc_error.c+ #ifndef WONKY_ERROR_C+ #define WONKY_ERROR_C WONKY_ERROR_C+ #include <gcc_error.h>+++ /*+ %T - type+ %D - denoted+ %t - 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)+ {++ 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;++ }+ }++ 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;+ }++ void push_translation_message_inner(const char *prefix,const char *message_format,struct Translation_Data *translation_data,va_list args)+ {+ struct Translation_Message *hold_message;+ char *filename=NULL;+ size_t line=0;+ size_t row=0;++ if(translation_data->tokens->size>0)+ {+ 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, ...)+ {+ wonky_assert(SHOULD_NOT_REACH_HERE);+ }+ void push_lexing_note(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...)+ {++ wonky_assert(SHOULD_NOT_REACH_HERE);+ }+ void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_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);++ }+ void push_compile_error(const char *message,struct Compile_Data *compile_data)+ {+ Queue_Push(compile_data->errors,gstr_to_heap(message));+ }+ void push_compile_note(const char *message,struct Compile_Data *compile_data)+ {+ Queue_Push(compile_data->errors,gstr_to_heap(message));+ }+ char* get_string_for_type_error(struct Type *type,struct Translation_Data *translation_data)+ {+ char *ret;+ struct Type *current;++ ret=gstr_to_heap("");++ current=type;++ while(type_is_derivative(current))+ {+ switch(current->specifier)+ {++ case TS_POINTER:+ ret=gstr_append_and_consume(gstr_to_heap("*"),ret);+ current=((struct Type_Pointer*)current)->points_to;+ break;+ case TS_ARRAY:+ ret=gstr_append_and_consume(gstr_to_heap("("),ret);+ ret=gstr_append_and_consume(ret,gstr_to_heap(")[]"));+ current=((struct Type_Array*)current)->is_array_of;+ break;+ case TS_FUNC: /*TODO*/+ goto hack;+ default:+ wonky_assert(SHOULD_NOT_REACH_HERE);+ }+ }+ hack:+ switch(current->specifier)+ {+ case TS_DOUBLE:+ ret=gstr_append_and_consume(gstr_to_heap("double"),ret);+ break;+ case TS_FLOAT:+ ret=gstr_append_and_consume(gstr_to_heap("float"),ret);+ break;+ case TS_INT:+ ret=gstr_append_and_consume(gstr_to_heap("int"),ret);+ break;+ case TS_CHAR:+ ret=gstr_append_and_consume(gstr_to_heap("char"),ret);+ break;+ case TS_STRUCT:+ ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);+ goto hack2;+ case TS_UNION:+ ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);+ hack2:+ {+ struct token *id;+ id=((struct Type_Struct_Union*)current)->struct_union->id;++ ret=gstr_append_and_consume(ret,gstr_dup(id->data,id->data+id->data_size,id->data_size+1));+ }+ break;+ default:+ ret=gstr_append_and_consume(gstr_to_heap("type"),ret);+ }+ return ret;+ }+ char* get_string_for_denoted_error(struct Denoted *denoted,struct Translation_Data *translation_data)+ {+ char *ret;++ ret=gstr_to_heap("denoted");++ return ret;+ }+ char* get_string_for_token_error(struct token *token,struct Translation_Data *translation_data)+ {+ 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;++ if(filename!=NULL)+ filename_length=gstrlen(filename);+ else+ filename_length=sizeof("NULL")+100;++ ret=calloc(filename_length+64,1);++ sprintf(ret,"%s %zu:%zu ",filename,line,column);+ return ret;+ }++ 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);+ }+ void print_compile_errors(FILE *out,struct Queue *errors)+ {+ while(errors->size>0)+ fputs(Queue_Pop(errors),out);+ }+ #endifF diff --git a/src/environment/error/gcc_error.h b/src/environment/error/gcc_error.h new file mode 100644 --- /dev/null +++ b/src/environment/error/gcc_error.h+ #ifndef WONKY_ERROR_H+ #define WONKY_ERROR_H WONKY_ERROR_H+ #include <gcc_error.hh>+ #include <lexer.h>+ #include <stdio.h>+ #include <stdarg.h>+ #include <queue.h>+ #include <gcc_string.h>+ #include <common.h>+ #include <compile.h>+++ struct Translation_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);+++ void push_compile_error(const char *message,struct Compile_Data *compile_data);+ void push_compile_note(const char *message,struct Compile_Data *compile_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);+++ void print_compile_errors(FILE *out,struct Queue *errors);++++ /*++ =====================================================================================================================+ 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++ [Error] file line:column - Usage of undeclared identifier a at file:line+ =====================================================================================================================+ push_translation_error("Addition between incompatible types %T and %T",...);++ |+ V++ [Error] file line:column - Addition between incomptatible types int and struct kek+ =====================================================================================================================+ */+ #endifF diff --git a/src/environment/error/gcc_error.hh b/src/environment/error/gcc_error.hh new file mode 100644 --- /dev/null +++ b/src/environment/error/gcc_error.hh+ #ifndef WONKY_ERROR_H+ #define WONKY_ERROR_H WONKY_ERROR_H+++ struct Translation_Error;+ struct Output_Message;+++ #endifF diff --git a/src/program/gcc_arguments.c b/src/program/gcc_arguments.c deleted file mode 100644 --- a/src/program/gcc_arguments.c +++ /dev/null- #ifndef WONKY_ARGUMENTS_C- #define WONKY_ARGUMENTS_C WONKY_ARGUMENTS_C- #include <gcc_arguments.h>---- struct Command_Arguments* parse_command_arguments(char **argv)- {- struct Command_Arguments *ret;- struct Queue *source_names;-- ret=malloc(sizeof(struct Command_Arguments));- ret->print_ast=ret->print_tokens=ret->transpile_to_js=ret->is_quiet=ret->compile_to_intel_asm=0;- ret->output_file=ret->javascript_extern_file=NULL;-- source_names=malloc(sizeof(struct Queue));- Queue_Init(source_names);-- ret->error_message=NULL;-- /*we skip the first element(the program name)*/- for(++argv;*argv;++argv)- {- if(gstr_cmp(*argv,"--print-tokens"))- {- ret->print_tokens=1;- }else if(gstr_cmp(*argv,"--print-ast"))- {- ret->print_ast=1;- }else if(gstr_cmp(*argv,"--quiet") || gstr_cmp(*argv,"-q"))- {- ret->is_quiet=1;- if(ret->print_ast || ret->print_tokens)- {- ret->error_message="print and quiet conflict. Aborting";- break;- }- }else if(gstr_cmp(*argv,"--transpile_to_js") || gstr_cmp(*argv,"-js"))- {- ret->transpile_to_js=1;- }else if(gstr_cmp(*argv,"--compile-asm") || gstr_cmp(*argv,"-asm"))- {- ret->compile_to_intel_asm=1;- }else if(gstr_cmp(*argv,"-o"))- {- ++argv;- if(*argv==NULL)- {- ret->error_message="expected a filename after -o. Aborting";- break;- }else- {- ret->output_file=fopen(*argv,"w");- if(ret->output_file==NULL)- {- ret->error_message="Couldn't open file for output. Aborting";- break;- }- }- }else if(gstr_cmp(*argv,"--make-extern-file"))- {- ret->javascript_extern_file=fopen(*argv,"w");- if(ret->javascript_extern_file==NULL)- {- ret->error_message="Couldn't open file for extern dump. Aborting";- break;- }- }else if(gstr_cmp(*argv,"--add-html"))- {- ret->insert_html=1;- }else- {- Queue_Push(source_names,*argv);- }- }-- ret->source_names=malloc((source_names->size+1)*sizeof(char*) );- ret->source_names[source_names->size]=NULL;- while(source_names->size)- {- ret->source_names[source_names->size-1]=(char*)source_names->first->data;- Queue_Pop(source_names);- }- free(source_names);- if(ret->transpile_to_js && ret->output_file==NULL)- {- ret->output_file=fopen("a.js","w");- if(ret==NULL)- ret->error_message="Couldn't open file for output. Aborting";- }- return ret;- }--- void delete_command_arguments(struct Command_Arguments *args)- {- if(args->output_file!=NULL)- fclose(args->output_file);- if(args->javascript_extern_file!=NULL)- fclose(args->javascript_extern_file);-- free(args->source_names);- free(args);- }-- #endifF diff --git a/src/program/gcc_arguments.h b/src/program/gcc_arguments.h deleted file mode 100644 --- a/src/program/gcc_arguments.h +++ /dev/null- #ifndef WONKY_ARGUMENTS_H- #define WONKY_ARGUMENTS_H WONKY_ARGUMENTS_H- #include <gcc_arguments.hh>- #include <queue.h>- #include <gcc_string.h>- #include <stdio.h>- #include <common.h>--- struct Command_Arguments- {- char **source_names;- char print_tokens:1;- char print_ast:1;- char is_quiet:1;- char transpile_to_js:1;- char insert_html:1;- char compile_to_intel_asm:1;--- FILE* output_file;- FILE* javascript_extern_file;--- char *error_message;- };-- struct Command_Arguments* parse_command_arguments(char **argv);- void delete_command_arguments(struct Command_Arguments *args);-- #endifF diff --git a/src/program/gcc_arguments.hh b/src/program/gcc_arguments.hh deleted file mode 100644 --- a/src/program/gcc_arguments.hh +++ /dev/null- #ifndef WONKY_ARGUMENTS_HH- #define WONKY_ARGUMENTS_HH WONKY_ARGUMENTS_HH--- struct Command_Arguments;--- #endifF diff --git a/src/program/gcc_error.c b/src/program/gcc_error.c deleted file mode 100644 --- a/src/program/gcc_error.c +++ /dev/null- #ifndef WONKY_ERROR_C- #define WONKY_ERROR_C WONKY_ERROR_C- #include <gcc_error.h>--- /*- %T - type- %D - denoted- %t - 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)- {-- 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;-- }- }-- 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;- }-- void push_translation_message_inner(const char *prefix,const char *message_format,struct Translation_Data *translation_data,va_list args)- {- struct Translation_Message *hold_message;- char *filename=NULL;- size_t line=0;- size_t row=0;-- if(translation_data->tokens->size>0)- {- 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, ...)- {- wonky_assert(SHOULD_NOT_REACH_HERE);- }- void push_lexing_note(const char *error_message,struct Source_File *src,struct Translation_Data *translation_data, ...)- {-- wonky_assert(SHOULD_NOT_REACH_HERE);- }- void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_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);-- }- void push_compile_error(const char *message,struct Compile_Data *compile_data)- {- Queue_Push(compile_data->errors,gstr_to_heap(message));- }- void push_compile_note(const char *message,struct Compile_Data *compile_data)- {- Queue_Push(compile_data->errors,gstr_to_heap(message));- }- char* get_string_for_type_error(struct Type *type,struct Translation_Data *translation_data)- {- char *ret;- struct Type *current;-- ret=gstr_to_heap("");-- current=type;-- while(type_is_derivative(current))- {- switch(current->specifier)- {-- case TS_POINTER:- ret=gstr_append_and_consume(gstr_to_heap("*"),ret);- current=((struct Type_Pointer*)current)->points_to;- break;- case TS_ARRAY:- ret=gstr_append_and_consume(gstr_to_heap("("),ret);- ret=gstr_append_and_consume(ret,gstr_to_heap(")[]"));- current=((struct Type_Array*)current)->is_array_of;- break;- case TS_FUNC: /*TODO*/- goto hack;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }- }- hack:- switch(current->specifier)- {- case TS_DOUBLE:- ret=gstr_append_and_consume(gstr_to_heap("double"),ret);- break;- case TS_FLOAT:- ret=gstr_append_and_consume(gstr_to_heap("float"),ret);- break;- case TS_INT:- ret=gstr_append_and_consume(gstr_to_heap("int"),ret);- break;- case TS_CHAR:- ret=gstr_append_and_consume(gstr_to_heap("char"),ret);- break;- case TS_STRUCT:- ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);- goto hack2;- case TS_UNION:- ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);- hack2:- {- struct token *id;- id=((struct Type_Struct_Union*)current)->struct_union->id;-- ret=gstr_append_and_consume(ret,gstr_dup(id->data,id->data+id->data_size,id->data_size+1));- }- break;- default:- ret=gstr_append_and_consume(gstr_to_heap("type"),ret);- }- return ret;- }- char* get_string_for_denoted_error(struct Denoted *denoted,struct Translation_Data *translation_data)- {- char *ret;-- ret=gstr_to_heap("denoted");-- return ret;- }- char* get_string_for_token_error(struct token *token,struct Translation_Data *translation_data)- {- 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;-- if(filename!=NULL)- filename_length=gstrlen(filename);- else- filename_length=sizeof("NULL")+100;-- ret=calloc(filename_length+64,1);-- sprintf(ret,"%s %zu:%zu ",filename,line,column);- return ret;- }-- 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);- }- void print_compile_errors(FILE *out,struct Queue *errors)- {- while(errors->size>0)- fputs(Queue_Pop(errors),out);- }- #endifF diff --git a/src/program/gcc_error.h b/src/program/gcc_error.h deleted file mode 100644 --- a/src/program/gcc_error.h +++ /dev/null- #ifndef WONKY_ERROR_H- #define WONKY_ERROR_H WONKY_ERROR_H- #include <gcc_error.hh>- #include <lexer.h>- #include <stdio.h>- #include <stdarg.h>- #include <queue.h>- #include <gcc_string.h>- #include <common.h>- #include <compile.h>--- struct Translation_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);--- void push_compile_error(const char *message,struct Compile_Data *compile_data);- void push_compile_note(const char *message,struct Compile_Data *compile_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);--- void print_compile_errors(FILE *out,struct Queue *errors);---- /*-- =====================================================================================================================- 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-- [Error] file line:column - Usage of undeclared identifier a at file:line- =====================================================================================================================- push_translation_error("Addition between incompatible types %T and %T",...);-- |- V-- [Error] file line:column - Addition between incomptatible types int and struct kek- =====================================================================================================================- */- #endifF diff --git a/src/program/gcc_error.hh b/src/program/gcc_error.hh deleted file mode 100644 --- a/src/program/gcc_error.hh +++ /dev/null- #ifndef WONKY_ERROR_H- #define WONKY_ERROR_H WONKY_ERROR_H--- struct Translation_Error;- struct Output_Message;--- #endifF diff --git a/src/program/program.c b/src/program/program.c deleted file mode 100644 --- a/src/program/program.c +++ /dev/null- #ifndef WONKY_PROGRAM_C- #define WONKY_PROGRAM_C WONKY_PROGRAM_C- #/*Don't mind me*/include/*When I grow up I want to be a new line*/ <program.h>--- struct Program* get_program()- {- struct Program *ret;- ret=malloc(sizeof(struct Program));- ret->translation_units=malloc(sizeof(struct Queue));- ret->source_files=malloc(sizeof(struct Queue));- ret->errors=malloc(sizeof(struct Queue));- ret->types=malloc(sizeof(struct Map));- ret->external_linkage=get_linkage();-- Queue_Init(ret->translation_units);- Queue_Init(ret->source_files);- Queue_Init(ret->errors);---- Map_Init(ret->types);-- return ret;- }- struct Source_File* extract_source_file(FILE *in,struct Source_Name *name)- {- long file_size;- struct Source_File *src;--- if(fseek(in,0,SEEK_END)==-1)- return NULL;- if((file_size=ftell(in))==-1)- return NULL;- if(fseek(in,0,SEEK_SET)==-1)- return NULL;-- src=malloc(sizeof(struct Source_File));-- src->src_name=name;-- src->src=malloc(file_size+1);- src->src_size=file_size;-- src->where_in_src=0;-- src->which_column=0;- src->which_row=0;- src->is_in_the_begining_of_line=1;-- src->src[file_size]='\0';-- fread(src->src,1,file_size,in);- fclose(in);- return src;- }- struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage)- {- struct Translation_Data *ret;- ret=malloc(sizeof(struct Translation_Data));- ret->tokens=malloc(sizeof(struct Queue));- ret->errors=malloc(sizeof(struct Queue));- ret->source_files=malloc(sizeof(struct Queue));- Queue_Init(ret->tokens);- Queue_Init(ret->errors);- Queue_Init(ret->source_files);-- ret->macros=malloc(sizeof(struct Map));- Map_Init(ret->macros);-- ret->types=types;-- ret->number_of_errors_when_last_checked=0;-- ret->external_linkage=external_linkage;- ret->internal_linkage=internal_linkage;-- return ret;- }- struct Source_Name* get_source_name(char *filename,char *base)- {- struct Source_Name *ret;- ret=malloc(sizeof(struct Source_Name));- ret->base=gstrcpy(base);- ret->filename=gstrcpy(filename);- normalise_source_name(ret);- return ret;- }- /*where_to_search ends in a NULL pointer*/- struct Source_File* get_source_file(char *filename,char **where_to_search)- {- FILE *in;- char *temp_name;- char is_directory=0;- struct Source_Name *name;- struct Source_File *file;-- wonky_assert(where_to_search!=NULL);- wonky_assert(*where_to_search!=NULL);- do- {- temp_name=gstr_append(*where_to_search,filename);- in=fopen(temp_name,"r");- free(temp_name);- if(in==NULL)- continue;-- name=get_source_name(filename,*where_to_search);- file=extract_source_file(in,name);- if(file!=NULL)- {- return file;- }else- {- delete_source_name(name);- }- }while(*(++where_to_search));- return NULL;- }-- /*this might cause compatability issues TODO*/- void normalise_source_name(struct Source_Name *name)- {- size_t offset;- size_t i;- size_t last_slash;- char *hold_base;-- for(last_slash=offset=0;name->filename[offset];++offset)- {- if(name->filename[offset]=='/')- {- last_slash=offset;- }- }-- if(last_slash==0)- return;-- if(name->base==NULL)- {- offset=0;- name->base=malloc(last_slash+1);- name->base[last_slash]='\0';- name->base[last_slash-1]='/';-- }else- {- offset=gstrlen((char*)name->base);- hold_base=malloc(offset+last_slash+2);- strmv(hold_base,(char*)name->base);-- hold_base[last_slash+offset]='/';- hold_base[last_slash+offset+1]='\0';- free((void*)name->base);-- name->base=hold_base;- }-- for(i=0;i<last_slash;++i)- name->base[offset+i]=name->filename[i];--- ++i;- /*prune the filename*/- offset=gstrlen(name->filename+i);- hold_base=malloc(offset+1);- strmv(hold_base,name->filename+i);- free(name->filename);- name->filename=hold_base;--- }-- struct Program* parse_program(char **base_source_names)- {- struct Source_File *base_file;- struct Program *program;- struct Translation_Data *hold_translation_data;- char *this_directory[]={"./","",NULL};-- wonky_assert(base_source_names!=NULL);-- if(*base_source_names==NULL)- {- return NULL;- }-- program=get_program();- hold_translation_data=get_translation_data(program->types,get_linkage(),program->external_linkage);- do- {- base_file=get_source_file(*base_source_names,this_directory);- if(base_file==NULL)- {- /*TODO error*/- free(base_file);- continue;- }else- {- Queue_Push(hold_translation_data->source_files,base_file);- lex(base_file,hold_translation_data);- if(!has_new_errors(hold_translation_data))- {- Queue_Push(program->translation_units,parse_translation_unit(hold_translation_data));- }else- {- flush_tokens(hold_translation_data->tokens);- }- assimilate_translation_data(program,hold_translation_data);- }- }while(*(++base_source_names));-- delete_translation_data(hold_translation_data);- return program;- }-- void lex_program(struct Translation_Data *hold,struct Source_File *file)- {- Queue_Push(hold->source_files,file);- lex(file,hold);- }--- _Bool has_new_errors(struct Translation_Data *translation_data)- {- if(translation_data->errors->size != translation_data->number_of_errors_when_last_checked)- {- translation_data->number_of_errors_when_last_checked=translation_data->errors->size;- return 1;- }else- {- return 0;- }- }-- void delete_program(struct Program *program)- {- while(program->translation_units->size>0)- delete_ast(Queue_Pop(program->translation_units));- free(program->translation_units);---- while(program->source_files->size>0)- delete_source_file(Queue_Pop(program->source_files));- free(program->source_files);--- while(program->errors->size>0)- delete_translation_error(Queue_Pop(program->errors));- free(program->errors);--- delete_linkage(program->external_linkage);-- /*BEWARE*/- Map_Map(program->types,delete_type);- Map_Destroy(program->types);- free(program->types);-- free(program);-- }- void delete_translation_data(struct Translation_Data *translation_data)- {- wonky_assert(translation_data->tokens->size==0 &&- translation_data->errors->size==0 &&- translation_data->source_files->size==0);- free(translation_data->tokens);- free(translation_data->errors);- free(translation_data->source_files);-- Map_Map(translation_data->macros,delete_macro);- Map_Destroy(translation_data->macros);- free(translation_data->macros);-- free(translation_data);-- }- void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data)- {- Queue_Append(program->errors,translation_data->errors);- Queue_Append(program->source_files,translation_data->source_files);-- flush_tokens(translation_data->tokens);-- Queue_Init(translation_data->errors);- Queue_Init(translation_data->source_files);-- translation_data->number_of_errors_when_last_checked=0;--- }- _Bool has_no_tokens(struct Translation_Data *translation_data)- {- return (translation_data->tokens->size)==0;- }- #endifF diff --git a/src/program/program.h b/src/program/program.h deleted file mode 100644 --- a/src/program/program.h +++ /dev/null- #ifndef WONKY_PROGRAM_H- #define WONKY_PROGRAM_H WONKY_PROGRAM_H--- #include <program.hh>- #include <queue.h>- #include <scope.h>- #include <lexer.h>- #include <gcc_string.h>- #include <gcc_arguments.h>- #include <parse_translation_unit.h>- #include <common.h>- #include <ast.h>--- struct Program- {- struct Queue *translation_units;- struct Queue *source_files;- struct Queue *errors;-- /*- the type node structures from- all the translation units are stored here- */- struct Map *types;-- struct Linkage *external_linkage;- };- struct Translation_Data- {- struct Queue *tokens;--- struct Queue *errors;- size_t number_of_errors_when_last_checked;--- struct Queue *source_files;-- struct Map *macros;-- /*passed from program struct*/- struct Map *types;- struct Linkage *external_linkage;- struct Linkage *internal_linkage;- /*end of passed from program struct*/- };-- struct Program* get_program();- struct Source_Name* get_source_name(char *filename,char *base);-- struct Source_File* extract_source_file(FILE *in,struct Source_Name *name);- struct Source_File* get_source_file(char *filename,char **where_to_search);- void normalise_source_name(struct Source_Name *name);-- struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage);--- struct Program* parse_program(char **base_source_names);- void lex_program(struct Translation_Data *hold,struct Source_File *file);- void entype_program(struct Program *program);--- _Bool has_new_errors(struct Translation_Data *translation_data);- _Bool has_no_tokens(struct Translation_Data *translation_data);-- void delete_program(struct Program *program);- void delete_translation_data(struct Translation_Data *translation_data);- void destroy_translation_data(struct Translation_Data *translation_data);- void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data);-- #endifF diff --git a/src/program/program.hh b/src/program/program.hh deleted file mode 100644 --- a/src/program/program.hh +++ /dev/null- #ifndef WONKY_PROGRAM_HH- #define WONKY_PROGRAM_HH WONKY_PROGRAM_HH-- struct Program;- struct Translation_Data;--- #endifF diff --git a/src/semantics/program/program.c b/src/semantics/program/program.c new file mode 100644 --- /dev/null +++ b/src/semantics/program/program.c+ #ifndef WONKY_PROGRAM_C+ #define WONKY_PROGRAM_C WONKY_PROGRAM_C+ #/*Don't mind me*/include/*When I grow up I want to be a new line*/ <program.h>+++ struct Program* get_program()+ {+ struct Program *ret;+ ret=malloc(sizeof(struct Program));+ ret->translation_units=malloc(sizeof(struct Queue));+ ret->source_files=malloc(sizeof(struct Queue));+ ret->errors=malloc(sizeof(struct Queue));+ ret->types=malloc(sizeof(struct Map));+ ret->external_linkage=get_linkage();++ Queue_Init(ret->translation_units);+ Queue_Init(ret->source_files);+ Queue_Init(ret->errors);++++ Map_Init(ret->types);++ return ret;+ }+ struct Source_File* extract_source_file(FILE *in,struct Source_Name *name)+ {+ long file_size;+ struct Source_File *src;+++ if(fseek(in,0,SEEK_END)==-1)+ return NULL;+ if((file_size=ftell(in))==-1)+ return NULL;+ if(fseek(in,0,SEEK_SET)==-1)+ return NULL;++ src=malloc(sizeof(struct Source_File));++ src->src_name=name;++ src->src=malloc(file_size+1);+ src->src_size=file_size;++ src->where_in_src=0;++ src->which_column=0;+ src->which_row=0;+ src->is_in_the_begining_of_line=1;++ src->src[file_size]='\0';++ fread(src->src,1,file_size,in);+ fclose(in);+ return src;+ }+ struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage)+ {+ struct Translation_Data *ret;+ ret=malloc(sizeof(struct Translation_Data));+ ret->tokens=malloc(sizeof(struct Queue));+ ret->errors=malloc(sizeof(struct Queue));+ ret->source_files=malloc(sizeof(struct Queue));+ Queue_Init(ret->tokens);+ Queue_Init(ret->errors);+ Queue_Init(ret->source_files);++ ret->macros=malloc(sizeof(struct Map));+ Map_Init(ret->macros);++ ret->types=types;++ ret->number_of_errors_when_last_checked=0;++ ret->external_linkage=external_linkage;+ ret->internal_linkage=internal_linkage;++ return ret;+ }+ struct Source_Name* get_source_name(char *filename,char *base)+ {+ struct Source_Name *ret;+ ret=malloc(sizeof(struct Source_Name));+ ret->base=gstrcpy(base);+ ret->filename=gstrcpy(filename);+ normalise_source_name(ret);+ return ret;+ }+ /*where_to_search ends in a NULL pointer*/+ struct Source_File* get_source_file(char *filename,char **where_to_search)+ {+ FILE *in;+ char *temp_name;+ char is_directory=0;+ struct Source_Name *name;+ struct Source_File *file;++ wonky_assert(where_to_search!=NULL);+ wonky_assert(*where_to_search!=NULL);+ do+ {+ temp_name=gstr_append(*where_to_search,filename);+ in=fopen(temp_name,"r");+ free(temp_name);+ if(in==NULL)+ continue;++ name=get_source_name(filename,*where_to_search);+ file=extract_source_file(in,name);+ if(file!=NULL)+ {+ return file;+ }else+ {+ delete_source_name(name);+ }+ }while(*(++where_to_search));+ return NULL;+ }++ /*this might cause compatability issues TODO*/+ void normalise_source_name(struct Source_Name *name)+ {+ size_t offset;+ size_t i;+ size_t last_slash;+ char *hold_base;++ for(last_slash=offset=0;name->filename[offset];++offset)+ {+ if(name->filename[offset]=='/')+ {+ last_slash=offset;+ }+ }++ if(last_slash==0)+ return;++ if(name->base==NULL)+ {+ offset=0;+ name->base=malloc(last_slash+1);+ name->base[last_slash]='\0';+ name->base[last_slash-1]='/';++ }else+ {+ offset=gstrlen((char*)name->base);+ hold_base=malloc(offset+last_slash+2);+ strmv(hold_base,(char*)name->base);++ hold_base[last_slash+offset]='/';+ hold_base[last_slash+offset+1]='\0';+ free((void*)name->base);++ name->base=hold_base;+ }++ for(i=0;i<last_slash;++i)+ name->base[offset+i]=name->filename[i];+++ ++i;+ /*prune the filename*/+ offset=gstrlen(name->filename+i);+ hold_base=malloc(offset+1);+ strmv(hold_base,name->filename+i);+ free(name->filename);+ name->filename=hold_base;+++ }++ struct Program* parse_program(char **base_source_names)+ {+ struct Source_File *base_file;+ struct Program *program;+ struct Translation_Data *hold_translation_data;+ char *this_directory[]={"./","",NULL};++ wonky_assert(base_source_names!=NULL);++ if(*base_source_names==NULL)+ {+ return NULL;+ }++ program=get_program();+ hold_translation_data=get_translation_data(program->types,get_linkage(),program->external_linkage);+ do+ {+ base_file=get_source_file(*base_source_names,this_directory);+ if(base_file==NULL)+ {+ /*TODO error*/+ free(base_file);+ continue;+ }else+ {+ Queue_Push(hold_translation_data->source_files,base_file);+ lex(base_file,hold_translation_data);+ if(!has_new_errors(hold_translation_data))+ {+ Queue_Push(program->translation_units,parse_translation_unit(hold_translation_data));+ }else+ {+ flush_tokens(hold_translation_data->tokens);+ }+ assimilate_translation_data(program,hold_translation_data);+ }+ }while(*(++base_source_names));++ delete_translation_data(hold_translation_data);+ return program;+ }++ void lex_program(struct Translation_Data *hold,struct Source_File *file)+ {+ Queue_Push(hold->source_files,file);+ lex(file,hold);+ }+++ _Bool has_new_errors(struct Translation_Data *translation_data)+ {+ if(translation_data->errors->size != translation_data->number_of_errors_when_last_checked)+ {+ translation_data->number_of_errors_when_last_checked=translation_data->errors->size;+ return 1;+ }else+ {+ return 0;+ }+ }++ void delete_program(struct Program *program)+ {+ while(program->translation_units->size>0)+ delete_ast(Queue_Pop(program->translation_units));+ free(program->translation_units);++++ while(program->source_files->size>0)+ delete_source_file(Queue_Pop(program->source_files));+ free(program->source_files);+++ while(program->errors->size>0)+ delete_translation_error(Queue_Pop(program->errors));+ free(program->errors);+++ delete_linkage(program->external_linkage);++ /*BEWARE*/+ Map_Map(program->types,delete_type);+ Map_Destroy(program->types);+ free(program->types);++ free(program);++ }+ void delete_translation_data(struct Translation_Data *translation_data)+ {+ wonky_assert(translation_data->tokens->size==0 &&+ translation_data->errors->size==0 &&+ translation_data->source_files->size==0);+ free(translation_data->tokens);+ free(translation_data->errors);+ free(translation_data->source_files);++ Map_Map(translation_data->macros,delete_macro);+ Map_Destroy(translation_data->macros);+ free(translation_data->macros);++ free(translation_data);++ }+ void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data)+ {+ Queue_Append(program->errors,translation_data->errors);+ Queue_Append(program->source_files,translation_data->source_files);++ flush_tokens(translation_data->tokens);++ Queue_Init(translation_data->errors);+ Queue_Init(translation_data->source_files);++ translation_data->number_of_errors_when_last_checked=0;+++ }+ _Bool has_no_tokens(struct Translation_Data *translation_data)+ {+ return (translation_data->tokens->size)==0;+ }+ #endifF diff --git a/src/semantics/program/program.h b/src/semantics/program/program.h new file mode 100644 --- /dev/null +++ b/src/semantics/program/program.h+ #ifndef WONKY_PROGRAM_H+ #define WONKY_PROGRAM_H WONKY_PROGRAM_H+++ #include <program.hh>+ #include <queue.h>+ #include <scope.h>+ #include <lexer.h>+ #include <gcc_string.h>+ #include <gcc_arguments.h>+ #include <parse_translation_unit.h>+ #include <common.h>+ #include <ast.h>+++ struct Program+ {+ struct Queue *translation_units;+ struct Queue *source_files;+ struct Queue *errors;++ /*+ the type node structures from+ all the translation units are stored here+ */+ struct Map *types;++ struct Linkage *external_linkage;+ };+ struct Translation_Data+ {+ struct Queue *tokens;+++ struct Queue *errors;+ size_t number_of_errors_when_last_checked;+++ struct Queue *source_files;++ struct Map *macros;++ /*passed from program struct*/+ struct Map *types;+ struct Linkage *external_linkage;+ struct Linkage *internal_linkage;+ /*end of passed from program struct*/+ };++ struct Program* get_program();+ struct Source_Name* get_source_name(char *filename,char *base);++ struct Source_File* extract_source_file(FILE *in,struct Source_Name *name);+ struct Source_File* get_source_file(char *filename,char **where_to_search);+ void normalise_source_name(struct Source_Name *name);++ struct Translation_Data* get_translation_data(struct Map *types,struct Linkage *internal_linkage,struct Linkage *external_linkage);+++ struct Program* parse_program(char **base_source_names);+ void lex_program(struct Translation_Data *hold,struct Source_File *file);+ void entype_program(struct Program *program);+++ _Bool has_new_errors(struct Translation_Data *translation_data);+ _Bool has_no_tokens(struct Translation_Data *translation_data);++ void delete_program(struct Program *program);+ void delete_translation_data(struct Translation_Data *translation_data);+ void destroy_translation_data(struct Translation_Data *translation_data);+ void assimilate_translation_data(struct Program *program,struct Translation_Data *translation_data);++ #endifF diff --git a/src/semantics/program/program.hh b/src/semantics/program/program.hh new file mode 100644 --- /dev/null +++ b/src/semantics/program/program.hh+ #ifndef WONKY_PROGRAM_HH+ #define WONKY_PROGRAM_HH WONKY_PROGRAM_HH++ struct Program;+ struct Translation_Data;+++ #endif