F diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txtmisc/queue.cmisc/stack.cmisc/print.c+ misc/gcc_string.c+ misc/gcc_arguments.clex/chonky.clex/chonky_jr.clex/lexer.csemantics/program.csemantics/scope.csemantics/semantics.c+ semantics/gcc_error.c)add_executable(wonky ${SOURCES})F diff --git a/lex/lexer.c b/lex/lexer.c --- a/lex/lexer.c +++ b/lex/lexer.c#ifndef LEXER_C#define LEXER_C LEXER_C- #include "lexer.h"+ /*asdf*/#include <lexer.h>- struct Queue* lex(struct Source_File *src,struct Program *prog)+ char *well_known_locations_base[]={"./",NULL};+ void lex(struct Source_File *src,struct Translation_Data *translation_data){struct token *current_token;- struct Queue *tokens;- tokens=malloc(sizeof(struct Queue));- Queue_Init(tokens);while(src->src[src->where_in_src]!='\0'){- if(src->which_column==0 && src->src[src->where_in_src]=='#')+ if(src->which_column==0){- /*todo preprocesing*/- ++src->where_in_src;- ++src->which_column;- do_preproc_stuff(src,prog);- }else- {- current_token=get_next_token(src,prog,&chonky[0]);- if(current_token->type!=KW_NOTYPE)- Queue_Push(tokens,current_token);- else- free(current_token);+ skip_white_space(src);+ if(src->src[src->where_in_src]=='#')+ {+ /*todo preprocesing*/+ ++src->where_in_src;+ ++src->which_column;+ parse_preproc_line(src,translation_data);+ continue;+ }}- }--- return tokens;-- }-- /*we have skipped the leading #*/- /*- #include string- #include <qchar>- #define [ id(list) replacement- #line number [string]- #if- #ifdef- #ifndef- #pragma- #error- #-- these should be seperated from the ifs- #elif- #else- #endif--- */- void do_preproc_stuff(struct Source_File *src,struct Program *prog)- {- struct token *hold;- hold=get_next_token(src,prog,&chonky_jr[0]);- switch(hold->type)- {- case PKW_INCLUDE:- free(hold);- do_include_stuff(src,prog);- return;- case PKW_DEFINE:- free(hold);- do_define_stuff(src,prog);--- default:- return;- /*TODO error*/-- }- }- void do_include_stuff(struct Source_File *src,struct Program *prog)- {- struct token *hold;- hold=get_next_token(src,prog,&chonky[0]);- if(hold->type==KW_STRING)- {- hold->data[hold->data_size-1]='\0';- hold->data_size-=2;- ++hold->data;- handle_splicing(hold);- lex_program(hold->data,prog);- free(hold);- }else if(hold->type==KW_LESS)/*hack*/- {- ++hold->data;- while(src->src[src->where_in_src]!='>')+ current_token=get_next_token(src,&chonky[0]);+ if(current_token->type!=KW_NOTYPE){- ++src->where_in_src;- ++hold->data_size;+ Queue_Push(translation_data->tokens,current_token);+ }else+ {+ if(src->where_in_src!=src->src_size)+ push_lexing_error("unexpected character",src,translation_data);+ free(current_token);+ return;}- /*skip the >*/- ++src->where_in_src;- hold->data[hold->data_size-1]='\0';- handle_splicing(hold);-- lex_program(hold->data,prog);- free(hold);-- }else- {- /*TODO error*/- return;}- }- struct define_directive* get_define_directive(struct token* macro_name)- {- struct define_directive* ret;- ret=malloc(sizeof(struct define_directive));- ret->macro_name=macro_name;- Queue_Init(&ret->replacement_list);- Queue_Init(&ret->id_list);- ret->number_of_arguments=0;- Map_Init(&ret->arguments);- return ret;- }- /*- id[(list)] tokens \n- */- void do_define_stuff(struct Source_File *src,struct Program *prog)- {- struct token *hold;- struct define_directive *macro;- hold=get_next_token(src,prog,&chonky[0]);- if(hold->type==KW_ID)- {- macro=get_define_directive(hold);- Map_Push(&prog->defines,hold->data,hold->data_size,macro);- hold=get_next_token(src,prog,&chonky[0]);- }else- {- /*TODO error*/- return;- }}{size_t back;size_t front;+ if(word->data_size==0)+ return;front=0;for(front;front<word->data_size-1;++front){}word->data[back]=word->data[front];}+ void chase_new_line(struct Source_File *src,struct Translation_Data *translation_data)+ {+ while(src->src[src->where_in_src]!='\n' && src->src[src->where_in_src]!='\0')+ {+ if(src->src[src->where_in_src]!=' ' && src->src[src->where_in_src]!='\t')+ {+ push_lexing_error("expected a new line",src,translation_data);+ }else+ {+ ++src->which_column;+ }+ ++src->where_in_src;+ }+ src->which_column=0;+ ++src->which_row;+ }+ void skip_white_space(struct Source_File *src)+ {+ while(src->src[src->where_in_src]==' ' || src->src[src->where_in_src]=='\n' || src->src[src->where_in_src]=='\t')+ {+ if(src->src[src->where_in_src]=='\n')+ {+ src->which_column=0;+ ++src->which_row;+ }else+ {+ ++src->which_column;+ }+ ++src->where_in_src;+ }+ }struct token_vector Lex_Queue_Condense(struct Queue *tokens){size_t i;return ret;}- char check(struct Queue *tokens,enum KEYWORDS kw,size_t ahead)+ char check(struct Translation_Data *translation_data,enum KEYWORDS kw,size_t ahead){size_t i;struct Queue_Node *current;- if(tokens->size<=ahead)+ if(translation_data->tokens->size<=ahead){return 0;}else{- for(i=0,current=tokens->first;i<ahead;++i,current=current->prev);+ for(i=0,current=translation_data->tokens->first;i<ahead;++i,current=current->prev);if( ((struct token*)(current->data))->type == kw ){}}}- char get_and_check(struct Queue *tokens,enum KEYWORDS kw)+ char get_and_check(struct Translation_Data *translation_data,enum KEYWORDS kw){struct token *hold_token;- if(tokens->size==0)+ if(translation_data->tokens->size==0){return 0;}else{- hold_token=tokens->first->data;+ hold_token=translation_data->tokens->first->data;if(hold_token->type!=kw){return 0;}else{- hold_token=Queue_Pop(tokens);+ hold_token=Queue_Pop(translation_data->tokens);free(hold_token);return 1;}}}- char get_and_check_unsafe(struct Queue *tokens,enum KEYWORDS kw)+ char get_and_check_unsafe(struct Translation_Data *translation_data,enum KEYWORDS kw){struct token *hold_token;- hold_token=tokens->first->data;+ hold_token=translation_data->tokens->first->data;if(hold_token->type!=kw){return 0;}else{- hold_token=Queue_Pop(tokens);+ hold_token=Queue_Pop(translation_data->tokens);free(hold_token);return 1;}}- void chomp(struct Queue *tokens)+ void chomp(struct Translation_Data *translation_data){- free(Queue_Pop(tokens));+ free(Queue_Pop(translation_data->tokens));}- enum KEYWORDS kw_get(struct Queue *tokens)+ enum KEYWORDS kw_get(struct Translation_Data *translation_data){- if(tokens->size==0)+ if(translation_data->tokens->size==0)return KW_NOTYPE;- return ((struct token*)(tokens->first->data))->type;+ return ((struct token*)(translation_data->tokens->first->data))->type;}- struct token* get_next_token(struct Source_File *src,struct Program *prog,struct automata_entry *start_state)+ struct token* get_next_token(struct Source_File *src,struct automata_entry *start_state){int temp;size_t current_size;{ret=malloc(sizeof(struct token));ret->type=KW_COMMENT;+ ret->filename=src->src_name->filename;ret->data=src->src + src->where_in_src;src->where_in_src+=2;while(src->where_in_src!=src->src_size && src->src[src->where_in_src]!='\n')++src->where_in_src;}}-- }- /*ignore leading spaces and tabs and check for double slash comment*/- while(src->src[src->where_in_src]==' ' || src->src[src->where_in_src]=='\n' || src->src[src->where_in_src]=='\t')- {- if(src->src[src->where_in_src]=='\n')- {- src->which_column=0;- ++src->which_row;- }else if(src->src[src->where_in_src]=='\t')- {- src->which_row+=5;- }- ++src->where_in_src;+ ++src->which_row;+ src->which_column=0;}+ /*ignore leading spaces,tabs and newlines*/+ skip_white_space(src);while(src->src[src->where_in_src]!='\0'){ret->column=src->which_column;ret->line=src->which_row;ret->data=src->src+(src->where_in_src-current_size);+ ret->filename=src->src_name->filename;handle_splicing(ret);return ret;}ret=malloc(sizeof(struct token));ret->type=KW_NOTYPE;ret->data_size=0;+ ret->filename=src->src_name->filename;return ret;}F diff --git a/lex/lexer.h b/lex/lexer.h --- a/lex/lexer.h +++ b/lex/lexer.h#include <queue.h>#include <program.h>#include <preprocessing.h>++ extern char *well_known_locations_base[];struct token{enum KEYWORDS type;size_t data_size;char *data;size_t line,column;+ /*:X*/+ const char *filename;};struct token_vector+ struct Source_Name+ {+ char *filename;+ char *base;+ };++ struct Source_File+ {+ struct Source_Name *src_name;++ char *src;+ size_t src_size;+ size_t where_in_src;+ size_t which_column;+ size_t which_row;+ };+- struct Queue* lex(struct Source_File *src,struct Program *prog);- struct token* get_next_token(struct Source_File *src,struct Program *prog,struct automata_entry *start_state);++ void lex(struct Source_File *src,struct Translation_Data *translation_data);+ struct token* get_next_token(struct Source_File *src,struct automata_entry *start_state);struct token_vector Lex_Queue_Condense(struct Queue *tokens);- char check(struct Queue *tokens,enum KEYWORDS kw,size_t ahead);- char get_and_check(struct Queue *tokens,enum KEYWORDS kw);- char get_and_check_unsafe(struct Queue *tokens,enum KEYWORDS kw);- void chomp(struct Queue *tokens);- enum KEYWORDS kw_get(struct Queue *tokens);+ void handle_splicing(struct token *word);+ void chase_new_line(struct Source_File *src,struct Translation_Data *translation_data);+ void skip_white_space(struct Source_File *src);++ char check(struct Translation_Data *translation_data,enum KEYWORDS kw,size_t ahead);+ char get_and_check(struct Translation_Data *translation_data,enum KEYWORDS kw);+ char get_and_check_unsafe(struct Translation_Data *translation_data,enum KEYWORDS kw);+ void chomp(struct Translation_Data *translation_data);+ enum KEYWORDS kw_get(struct Translation_Data *translation_data);#endifF diff --git a/lex/lexer.hh b/lex/lexer.hh --- a/lex/lexer.hh +++ b/lex/lexer.hh#define LEXER_HH LEXER_HH/*struct declarations. Definitions are in .h*/+struct token;struct token_vector;struct define_directive;+ struct Source_Name;+ struct Source_File;#endifF diff --git a/lex/preprocessing.c b/lex/preprocessing.c --- a/lex/preprocessing.c +++ b/lex/preprocessing.c#ifndef GCC_PREPROCESSING_C#define GCC_PREPROCESSING_C GCC_PREPROCESSING_C- #include "preprocessing.h"+ #include <preprocessing.h>- struct define_directive++ /*we have skipped the leading #*/+ /*+ #include string+ #include <qchar>+ #define [ id(list) replacement+ #line number [string]+ #if+ #ifdef+ #ifndef+ #pragma+ #error+ #++ these should be seperated from the ifs+ #elif+ #else+ #endif+++ */+ void parse_preproc_line(struct Source_File *src,struct Translation_Data *translation_data)+ {+ struct token *hold;+ hold=get_next_token(src,&chonky_jr[0]);+ switch(hold->type)+ {+ case PKW_INCLUDE:+ free(hold);+ parse_include_line(src,translation_data);+ return;+ case PKW_DEFINE:+ free(hold);+ parse_define_line(src,translation_data);+ default:+ return;+ /*TODO error*/++ }+ }+ void parse_include_line(struct Source_File *src,struct Translation_Data *translation_data)+ {+ struct token *hold;+ hold=get_next_token(src,&chonky[0]);+ if(hold->type==KW_STRING)+ {+ char *where_to_search[]={src->src_name->base,NULL};+ struct Source_File *hold_file;++ hold->data[hold->data_size-1]='\0';+ hold->data_size-=2;+ ++hold->data;+ handle_splicing(hold);+++ /*search in the directory of the file from which we include*/+ hold_file=get_source_file(hold->data,where_to_search);+ /*fallback to well known locations == <>*/+ if(hold_file==NULL)+ {+ hold_file=get_source_file(hold->data,well_known_locations_base);+ if(hold_file==NULL)+ {+ /*TODO error*/+ push_translation_error("include error",translation_data);+ return;+ }+ }+ lex_program(translation_data,hold_file);+ free(hold);+ }else if(hold->type==KW_LESS)/*hack*/+ {+ struct Source_File *hold_file;+ ++hold->data;+ while(src->src[src->where_in_src]!='>' && src->where_in_src<src->src_size)+ {+ ++src->where_in_src;+ ++hold->data_size;+ }+ if(src->where_in_src==src->src_size)+ {+ /*TODO error*/+ return;+ }+ /*skip the >*/+ ++src->where_in_src;+ hold->data[hold->data_size-1]='\0';+ handle_splicing(hold);++ hold_file=get_source_file(hold->data,well_known_locations_base);+ if(hold_file==NULL)+ {+ /*TODO error*/+ push_translation_error("include error",translation_data);+ return;+ }++ lex_program(translation_data,hold_file);+ free(hold);++ }else+ {+ /*TODO error*/+ push_translation_error("include error",translation_data);+ return;+ }+++ chase_new_line(src,translation_data);+ }+ void parse_define_line(struct Source_File *src,struct Translation_Data *translation_data)+ {+ }+ /*+ id[(list)] tokens \n+ */+ struct define_directive* get_define_directive(struct token* macro_name){- struct token *macro_name;- struct Queue replacement_list;- /*the tokens of the macro (contains a special token)*/- struct Queue id_list;-- struct Map arguments;- size_t number_of_arguments;- /*put arguments here*/- struct token **argument_list;- };+ }#endifF diff --git a/lex/preprocessing.h b/lex/preprocessing.h --- a/lex/preprocessing.h +++ b/lex/preprocessing.h#ifndef GCC_PREPROCESSING_H#define GCC_PREPROCESSING_H GCC_PREPROCESSING_H+ #include <preprocessing.hh>+ #include <program.h>+ #include <lexer.h>+ #include <gcc_error.h>- void do_preproc_stuff(struct Source_File *src,struct Program *prog);- void do_include_stuff(struct Source_File *src,struct Program *prog);- void do_define_stuff(struct Source_File *src,struct Program *prog);- void handle_splicing(struct token *word);+ struct define_directive+ {+ struct token *macro_name;+ struct Queue replacement_list;+ /*the tokens of the macro (contains a special token)*/+ struct Queue id_list;++ struct Map arguments;+ size_t number_of_arguments;+ /*put arguments here*/+ struct token **argument_list;+ };++ void parse_preproc_line(struct Source_File *src,struct Translation_Data *translation_data);+ void parse_include_line(struct Source_File *src,struct Translation_Data *translation_data);+ void parse_define_line(struct Source_File *src,struct Translation_Data *translation_data);struct define_directive* get_define_directive(struct token* macro_name);F diff --git a/lex/preprocessing.hh b/lex/preprocessing.hh new file mode 100644 --- /dev/null +++ b/lex/preprocessing.hh+ #ifndef GCC_PREPROCESSING_H+ #define GCC_PREPROCESSING_H GCC_PREPROCESSING_H++ struct define_directive;++ #endifF diff --git a/main.c b/main.c --- a/main.c +++ b/main.c// print_expression(test_expression,stdout,0);*/- if(argv[1]==NULL)+ struct Command_Arguments *command_arguments;+ struct Program *program;++ command_arguments=parse_command_arguments(argv);+ if(command_arguments->print_tokens && !command_arguments->is_quiet){- printf("Give me a file!\n");- return -1;+ return print_tokens_of_program(stdout,command_arguments->source_names);+ }else+ {+ program=parse_program(command_arguments->source_names);+ if(program->errors->size>0)+ {+ if(!command_arguments->is_quiet)+ {+ print_errors(stdout,program->errors);+ }+ return 1;+ }else if(command_arguments->print_ast && !command_arguments->is_quiet)+ {+ print_program_ast(stdout,program);+ }}- struct Program *program;+++ /*program=get_program();lex_program(argv[1],program);print_program_tokens(stdout,program);parse_program(program);print_program_ast(stdout,program);+ */F diff --git a/misc/all.h b/misc/all.h --- a/misc/all.h +++ b/misc/all.h#define GCC_ALL GCC_ALL+ #include <gcc_arguments.h>#include <ast.h>#include <denoted.h>F diff --git a/misc/gcc_arguments.c b/misc/gcc_arguments.c new file mode 100644 --- /dev/null +++ b/misc/gcc_arguments.c+ #ifndef GCC_ARGUMENTS_C+ #define GCC_ARGUMENTS_C GCC_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=0;++ source_names=malloc(sizeof(struct Queue));+ Queue_Init(source_names);+++ /*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;+ }else+ {+ Queue_Push(source_names,*argv);+ }+ }++ ret->source_names=malloc(source_names->size+1);+ 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);+ return ret;+ }+++ #endifF diff --git a/misc/gcc_arguments.h b/misc/gcc_arguments.h new file mode 100644 --- /dev/null +++ b/misc/gcc_arguments.h+ #ifndef GCC_ARGUMENTS_H+ #define GCC_ARGUMENTS_H GCC_ARGUMENTS_H+ #include <gcc_arguments.hh>+ #include <queue.h>+ #include <gcc_string.h>+++ struct Command_Arguments+ {+ char **source_names;+ char print_tokens:1;+ char print_ast:1;+ char is_quiet:1;+ };++ struct Command_Arguments* parse_command_arguments(char **argv);++ #endifF diff --git a/misc/gcc_arguments.hh b/misc/gcc_arguments.hh new file mode 100644 --- /dev/null +++ b/misc/gcc_arguments.hh+ #ifndef GCC_ARGUMENTS_HH+ #define GCC_ARGUMENTS_HH GCC_ARGUMENTS_HH+++ struct Command_Arguments;+++ #endifF diff --git a/misc/gcc_string.c b/misc/gcc_string.c new file mode 100644 --- /dev/null +++ b/misc/gcc_string.c+ #ifndef GSTRING_C+ #define GSTRING_C GSTRING_C+ #include <gcc_string.h>+++ size_t gstrlen(char *str)+ {+ size_t i;+ for(i=0;str[i]!='\0';++i);+ return i;+ }++ char* gstr_append(char *lead,char *follower)+ {+ char *ret,*hold;+ hold=ret=malloc(gstrlen(lead) + gstrlen(follower));+ while(*(hold++)=*(lead++));+ hold--;+ while(*(hold++)=*(follower++));+ return ret;+ }++ void strmv(char *target,char *source)+ {+ while(*(target++)=*(source++));+ }+ char* gstrcpy(char *str)+ {+ char *temp=malloc(gstrlen(str)+1);+ for(size_t i=0;(temp[i]=str[i])!='\0';++i);+ return temp;+ }+ char gstr_cmp(const char *a,const char *b)+ {+ while(*a==*b && *a)+ ++a,++b;+ if(*a==*b)+ return 1;+ else+ return 0;+ }+ #endifF diff --git a/misc/gcc_string.h b/misc/gcc_string.h new file mode 100644 --- /dev/null +++ b/misc/gcc_string.h+ #ifndef GSTRING_H+ #define GSTRING_H GSTRING_H+ #include <stdlib.h>+++ size_t gstrlen(char *str);+ char* gstr_append(char *lead,char *follower);+ char* gstrcpy(char *str);+ char gstr_cmp(const char *a,const char *b);+ void strmv(char *target,char *source);++++ #endifF diff --git a/misc/print.c b/misc/print.c --- a/misc/print.c +++ b/misc/print.c// fprintf(out,"]");}+ char print_tokens_of_program(FILE *out,char **base_source_names)+ {++ struct Source_File *base_file;+ struct Translation_Data *hold_translation_data;+ char *this_directory[]={"./",NULL};+ char ret;++ assert(base_source_names!=NULL);++ if(*base_source_names==NULL)+ {+ return 0;+ }+ ret=0;++ hold_translation_data=get_translation_data();+ do+ {+ base_file=get_source_file(*base_source_names,this_directory);+ if(base_file==NULL)+ {+ /*TODO error*/+ continue;+ }else+ {+ lex(base_file,hold_translation_data);+ if(hold_translation_data->errors->size>0)+ {+ ret=1;+ /*if we are here then the is_quiet flag has not been set*/+ print_errors(out,hold_translation_data->errors);+ free(base_file->src);+ free(base_file->src_name);+ free(base_file);+ break;+ }+ fprintf(out,"\nTOKENS OF %s {\n",base_file->src_name->filename);+ print_tokens(out,hold_translation_data->tokens);+ fprintf(out,"\n} END OF TOKENS\n");++ while(hold_translation_data->tokens->size!=0)+ {+ free(Queue_Pop(hold_translation_data->tokens));+ }+ free(base_file->src);+ free(base_file->src_name);+ free(base_file);+ }+ }while(*(++base_source_names));+++ while(hold_translation_data->errors->size>0)+ free(Queue_Pop(hold_translation_data->errors));++ free(hold_translation_data->errors);+++ free(hold_translation_data->tokens);++ free(hold_translation_data->source_files);+ free(hold_translation_data);+ return ret;+ }void print_tokens(FILE *out,struct Queue *tokens){struct Queue_Node *it;print_type(out,function->type,1);print_ast(out,(struct AST*)function->body);}- void print_program_tokens(FILE *out,struct Program *program)- {- struct Queue_Node *it;- struct Queue_Node *it2;- it=program->source_files.first;- it2=program->translation_units_tokens.first;- for(;it!=NULL && it2!=NULL;it=it->prev,it2=it2->prev)- {- fprintf(out,"TOKENS for %s\n{\n",((struct Source_File*)(it->data))->src_name);- print_tokens(out,it2->data);- fprintf(out,"TOKENS_END for %s\n}\n",((struct Source_File*)(it->data))->src_name);- }- }void print_program_ast(FILE *out,struct Program *program){size_t i;struct Queue_Node *it;- it=program->source_files.first;- for( i=0; (i<program->number_of_translation_units) && it!=NULL;++i,it=it->prev)+ for(it=program->translation_units->first;it!=NULL;it=it->prev){- fprintf(out,"TRANSLATION_UNIT for %s\n{\n",((struct Source_File*)(it->data))->src_name);- print_ast(out,program->translation_units[i]);- fprintf(out,"TRANSLATION_UNIT_END for %s\n}\n",((struct Source_File*)(it->data))->src_name);+ fprintf(out,"TRANSLATION_UNIT {\n");+ print_ast(out,(struct AST*)it->data);+ fprintf(out,"\n} TRANSLATION_UNIT_END\n");}}void print_keyword_enum(FILE *out,enum KEYWORDS kw)fprintf(out," KW_STRING ");break;}}+ void print_errors(FILE *out,struct Queue *errors)+ {+ struct Queue_Node *it;+ for(it=errors->first;it!=NULL;it=it->prev)+ {+ print_translation_error(out,(struct Translation_Error*)it->data);+ }+ }#undef TOK#undef INDENTF diff --git a/misc/print.h b/misc/print.h --- a/misc/print.h +++ b/misc/print.hvoid print_token(FILE *out,struct token *token);void print_tokens(FILE *out,struct Queue *tokens);+ char print_tokens_of_program(FILE *out,char **base_names);void print_ast_enum(FILE *out,enum AST_Type op);void print_error_tree(FILE *out,struct AST_Error *error);void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin);void print_program_ast(FILE *out,struct Program *program);void print_keyword_enum(FILE *out,enum KEYWORDS kw);void print_function_definition(FILE *out,struct Denoted_Function *function);+ void print_errors(FILE *out,struct Queue *errors);#endifF diff --git a/misc/queue.c b/misc/queue.c --- a/misc/queue.c +++ b/misc/queue.cvoid Queue_Append(struct Queue *lead,struct Queue *follower){assert(lead!=NULL);- lead->last->prev=follower->first;- lead->last=follower->last;-- lead->size+=follower->size;+ assert(follower!=NULL);+ if(lead->last==NULL)+ {+ lead->last=follower->last;+ lead->first=follower->first;+ lead->size=follower->size;+ }else+ {+ lead->last->prev=follower->first;+ lead->last=follower->last;+ lead->size+=follower->size;+ }}void Queue_Destroy(Queue *q)F diff --git a/parse/parse_declaration.c b/parse/parse_declaration.c --- a/parse/parse_declaration.c +++ b/parse/parse_declaration.c/*declaration-specifiers init-declarator (,init-declarator)* ;*//* init-declarator: declarator [ = initializer ] */- void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions)+ void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions){struct Denotation_Prototype *prototype;struct Denoted *hold;- prototype=parse_declaration_specifiers(tokens,scope);+ prototype=parse_declaration_specifiers(translation_data,scope);while(1){- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN))return;- hold=parse_declarator(tokens,scope,prototype);++ hold=parse_declarator(translation_data,scope,prototype);+++if(hold->denotation==DT_Function && parse_function_definitions==1){- if(get_and_check(tokens,KW_OPEN_CURLY))+ if(get_and_check(translation_data,KW_OPEN_CURLY)){- ((struct Denoted_Function*)hold)->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(tokens,scope);+ ((struct Denoted_Function*)hold)->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,scope);Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));Scope_Push(scope,hold);free(prototype);{/*TODO error*/Queue_Push(where_to_push,get_declaration_error_tree(hold));+ push_translation_error("declaration expected",translation_data);free(prototype);+ /*search for end of erronous declaration*/+ while(!get_and_check(translation_data,KW_SEMI_COLUMN))+ {+ free(Queue_Pop(translation_data->tokens));+ }return;}Scope_Push(scope,hold);parse_function_definitions=0;- if(!get_and_check(tokens,KW_COMMA))+ if(!get_and_check(translation_data,KW_COMMA)){- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return;}else{/*TODO error*/Queue_Push(where_to_push,get_declaration_error_tree(NULL));+ push_translation_error("semi column expected",translation_data);return;}}}- struct Denotation_Prototype* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope)+ struct Denotation_Prototype* parse_specifier_qualifier_list(struct Translation_Data *translation_data,struct Scope *scope){- return parse_declaration_specifiers_inner(tokens,scope,0);+ return parse_declaration_specifiers_inner(translation_data,scope,0);}- struct Denotation_Prototype* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope)+ struct Denotation_Prototype* parse_declaration_specifiers(struct Translation_Data *translation_data,struct Scope *scope){- return parse_declaration_specifiers_inner(tokens,scope,1);+ return parse_declaration_specifiers_inner(translation_data,scope,1);}/*declaration-specifiers:( storage-class-specifier type-specifier type-qualifier function-specifier)* */- struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Queue *tokens,struct Scope *scope,char parse_storage_class)+ struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Translation_Data *translation_data,struct Scope *scope,char parse_storage_class){enum KEYWORDS hold_kw;struct Denotation_Prototype *ret;while(1){- hold_kw=kw_get(tokens);+ hold_kw=kw_get(translation_data);switch(hold_kw){case KW_CONST:- chomp(tokens);+ chomp(translation_data);ret->is_const=1;break;case KW_VOLATILE:- chomp(tokens);+ chomp(translation_data);ret->is_volatile=1;break;case KW_INT:- chomp(tokens);+ chomp(translation_data);if(ret->specifier!=TS_NONE){+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_INT;break;case KW_VOID:- chomp(tokens);+ chomp(translation_data);if(ret->specifier!=TS_NONE){+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_VOID;break;case KW_CHAR:- chomp(tokens);+ chomp(translation_data);if(ret->specifier!=TS_NONE){+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_CHAR;break;case KW_DOUBLE:- chomp(tokens);+ chomp(translation_data);if(ret->specifier!=TS_NONE){+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_DOUBLE;break;case KW_FLOAT:- chomp(tokens);+ chomp(translation_data);if(ret->specifier!=TS_NONE){+ push_translation_error("more than one type specifier given",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_FLOAT;break;case KW_LONG:- chomp(tokens);+ chomp(translation_data);if(ret->constraint!=TC_NONE){- return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);+ if(ret->constraint==TC_LONG)+ {+ ret->constraint=TC_LONG_LONG;+ break;+ }else+ {+ if(ret->constraint==TC_LONG_LONG)+ push_translation_error("yeah ... it's big",translation_data);+ else if(ret->constraint==TC_SHORT)+ push_translation_error("long and short constraints contradict",translation_data);+ else+ assert(0);+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);+ }}ret->constraint=TC_LONG;break;case KW_SHORT:- chomp(tokens);+ chomp(translation_data);if(ret->constraint!=TC_NONE){+ switch(ret->constraint)+ {+ case TC_LONG:+ push_translation_error("long and short constraints contradict",translation_data);+ break;+ case TC_SHORT:+ push_translation_error("it's not about the size, it's about how you use it",translation_data);+ break;+ case TC_LONG_LONG:+ push_translation_error("long long and short constraints contradict",translation_data);+ break;+ default:+ /*should not be able to enter here*/+ assert(0);+ }return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->constraint=TC_SHORT;case KW_EXTERN:if(!parse_storage_class)goto exit;- chomp(tokens);+ chomp(translation_data);if(ret->storage_class!=SC_NONE){+ switch(ret->storage_class)+ {+ case SC_EXTERN:+ push_translation_error("only one extern allowed >:|",translation_data);+ break;++ case SC_TYPEDEF:+ case SC_STATIC:+ push_translation_error("only one storage class allowed >:|",translation_data);+ break;+ default:+ assert(0);+ }+return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->storage_class=SC_EXTERN;case KW_STATIC:if(!parse_storage_class)goto exit;- chomp(tokens);+ chomp(translation_data);if(ret->storage_class!=SC_NONE){+ switch(ret->storage_class)+ {+ case SC_STATIC:+ push_translation_error("only one static allowed >:|",translation_data);+ break;++ case SC_EXTERN:+ case SC_TYPEDEF:+ push_translation_error("only one storage class allowed >:|",translation_data);+ break;+ default:+ assert(0);+ }return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->storage_class=SC_STATIC;case KW_TYPEDEF:if(!parse_storage_class)goto exit;- chomp(tokens);+ chomp(translation_data);if(ret->storage_class!=SC_NONE){+ switch(ret->storage_class)+ {+ case SC_STATIC:+ case SC_EXTERN:+ case SC_TYPEDEF:+ push_translation_error("only one storage class allowed >:|",translation_data);+ break;+ default:+ assert(0);+ }return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->storage_class=SC_TYPEDEF;case KW_UNION:ret->specifier=TS_UNION;hack:- chomp(tokens);- if(check(tokens,KW_ID,0))+ chomp(translation_data);+ if(check(translation_data,KW_ID,0)){struct token *id;struct Denoted_Struct_Union *tag;- id=Queue_Pop(tokens);+ id=Queue_Pop(translation_data->tokens);tag=(struct Denoted_Struct_Union*)check_tag(scope,id);if(tag==NULL)body=get_struct_union_base(scope,ret->specifier);Scope_Push(scope,get_denoted_struct_union(id,body));- parse_struct_union_specifier_finish(tokens,scope,body);+ parse_struct_union_specifier_finish(translation_data,scope,body);ret->struct_union=body;}else{ret->struct_union=tag->struct_union;if(ret->struct_union->specifier!=ret->specifier){+ push_translation_error("more than one type specifier",translation_data);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}if(ret->struct_union->is_finished==0){/*then this could be a definition*/- parse_struct_union_specifier_finish(tokens,scope,ret->struct_union);+ parse_struct_union_specifier_finish(translation_data,scope,ret->struct_union);}}}else{ret->struct_union=get_struct_union_base(scope,ret->specifier);- parse_struct_union_specifier_finish(tokens,scope,ret->struct_union);+ parse_struct_union_specifier_finish(translation_data,scope,ret->struct_union);+ if(ret->struct_union->is_finished==0)+ {+ push_translation_error("expected a struct tag or a struct definition",translation_data);+ return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);+ }}break;case KW_ENUM:- chomp(tokens);+ chomp(translation_data);ret->specifier=TS_ENUM;- if(check(tokens,KW_ID,0))+ if(check(translation_data,KW_ID,0)){struct token *id;struct Denoted_Enum *enumerator;- id=Queue_Pop(tokens);+ id=Queue_Pop(translation_data->tokens);enumerator=(struct Denoted_Enum*)check_tag(scope,id);if(enumerator==NULL){struct Enum *body;body=get_enum_base();Scope_Push(scope,get_denoted_enum(id,body));- parse_enum_specifier_finish(tokens,scope,body);+ parse_enum_specifier_finish(translation_data,scope,body);ret->enumerator=body;}else{if(ret->enumerator->is_finished==0){/*this could be an enum definition*/- parse_enum_specifier_finish(tokens,scope,ret->enumerator);+ parse_enum_specifier_finish(translation_data,scope,ret->enumerator);}}}else{- parse_enum_specifier_finish(tokens,scope,ret->enumerator);+ parse_enum_specifier_finish(translation_data,scope,ret->enumerator);}break;case KW_ID:if(ret->specifier==TS_NONE){struct Denoted *hold;- hold=check_ordinary(scope,(struct token*)tokens->first->data);+ hold=check_ordinary(scope,(struct token*)translation_data->tokens->first->data);if(hold!=NULL && hold->denotation==DT_Typedef){ret->type=((struct Denoted_Typedef*)hold)->type;- chomp(tokens);+ chomp(translation_data);break;}/*falltrough - this has not been typedefed*/declarator:( pointer ( type-qualifier )* )* direct-declarator*/- struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype)+ struct Denoted* parse_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denotation_Prototype *prototype){struct Denoted_Base temp;temp.id=NULL;temp.denotation=DT_Prototype;temp.type=prototype->type;- parse_declarator_inner(tokens,scope,&temp);+ parse_declarator_inner(translation_data,scope,&temp);return extract_denoted(&temp,prototype,0);}- void parse_declarator_inner(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base)+ void parse_declarator_inner(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base){enum KEYWORDS hold;- while(get_and_check(tokens,KW_STAR))+ while(get_and_check(translation_data,KW_STAR)){base->type=get_pointer_type(base->type);- hold=kw_get(tokens);+ hold=kw_get(translation_data);while(1){if(hold==KW_CONST)}}}- parse_direct_declarator(tokens,scope,base);+ parse_direct_declarator(translation_data,scope,base);}/*id direct-declarator-finish( declarator ) direct-declarator-finish*/- void parse_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base)+ void parse_direct_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base){- if(check(tokens,KW_ID,0))+ if(check(translation_data,KW_ID,0)){- base->id=Queue_Pop(tokens);- parse_direct_declarator_finish(tokens,scope,base);+ base->id=Queue_Pop(translation_data->tokens);+ parse_direct_declarator_finish(translation_data,scope,base);- }else if(get_and_check(tokens,KW_OPEN_NORMAL))+ }else if(get_and_check(translation_data,KW_OPEN_NORMAL)){struct Queue *hack;+ struct Queue *hold;hack=malloc(sizeof(struct Queue));Queue_Init(hack);- while(!check(tokens,KW_CLOSE_NORMAL,0))++ while(!check(translation_data,KW_CLOSE_NORMAL,0)){- Queue_Push(hack,Queue_Pop(tokens));+ Queue_Push(hack,Queue_Pop(translation_data->tokens));}/*remove closing )*/- chomp(tokens);- parse_direct_declarator_finish(tokens,scope,base);- parse_declarator_inner(hack,scope,base);+ chomp(translation_data);+ parse_direct_declarator_finish(translation_data,scope,base);++++ hold=translation_data->tokens;+ translation_data->tokens=hack;+ parse_declarator_inner(translation_data,scope,base);+ translation_data->tokens=hold;if(hack->size!=0){/*TODO error*/free(Queue_Pop(hack));}free(hack);+ push_translation_error("declarator error",translation_data);return;}free(hack);}else{/*this might be an abstract declarator*/- parse_direct_declarator_finish(tokens,scope,base);+ parse_direct_declarator_finish(translation_data,scope,base);}}direct-declarator-finish:( [ constant-expression ] | (parameter-list) | ( [id-list] ) )**/- void parse_direct_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base)+ void parse_direct_declarator_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base){while(1){- if(get_and_check(tokens,KW_OPEN_SQUARE))+ if(get_and_check(translation_data,KW_OPEN_SQUARE)){- base->type=get_array_type(base->type,parse_expression(tokens,scope));- if(!get_and_check(tokens,KW_CLOSE_NORMAL))+ base->type=get_array_type(base->type,parse_expression(translation_data,scope));+ if(!get_and_check(translation_data,KW_CLOSE_NORMAL)){base->type=get_type_error(base->type);base->denotation=DT_Error;return;}- }else if(get_and_check(tokens,KW_OPEN_NORMAL))+ }else if(get_and_check(translation_data,KW_OPEN_NORMAL)){struct Queue *parameters;struct Scope *function_prototype_scope;parameters=malloc(sizeof(struct Queue));Queue_Init(parameters);- parse_paramenter_list(tokens,function_prototype_scope,parameters);+ parse_paramenter_list(translation_data,function_prototype_scope,parameters);base->type=get_function_type(base->type,parameters,function_prototype_scope);}elsestruct-union-specifier-finish:{ ( struct-declaration )* }*/- void parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Struct_Union *base)+ void parse_struct_union_specifier_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Struct_Union *base){- if(get_and_check(tokens,KW_OPEN_CURLY))+ if(get_and_check(translation_data,KW_OPEN_CURLY)){base->is_finished=1;- while(parse_struct_declaration(tokens,base->inner_namespace,base->members))+ while(parse_struct_declaration(translation_data,base->inner_namespace,base->members)){- if(get_and_check(tokens,KW_CLOSE_CURLY))+ if(get_and_check(translation_data,KW_CLOSE_CURLY)){return ;}}/*TODO error*/+ push_translation_error("expected closing curly bracket from struct declaration",translation_data);return ;struct-declaration:specifier-qualifier-list ( struct-declarator )* ;*/- char parse_struct_declaration(struct Queue *tokens,struct Scope *struct_scope,struct Queue* members)+ char parse_struct_declaration(struct Translation_Data *translation_data,struct Scope *struct_scope,struct Queue* members){struct Denotation_Prototype *prototype;struct Denoted *hold;- prototype=parse_specifier_qualifier_list(tokens,struct_scope);+ prototype=parse_specifier_qualifier_list(translation_data,struct_scope);while(1){- hold=parse_struct_declarator(tokens,struct_scope,prototype);+ hold=parse_struct_declarator(translation_data,struct_scope,prototype);if(hold!=NULL && hold->denotation!=DT_Error){Scope_Push(struct_scope,hold);{free(prototype);/*todo error*/+ push_translation_error("there is a problem with the declarator",translation_data);return 0;}- if(!get_and_check(tokens,KW_COMMA))+ if(!get_and_check(translation_data,KW_COMMA)){- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){break;}else{free(prototype);+ push_translation_error("semi column expected in struct declaration",translation_data);/*todo error*/return 0;}declarator[ declarator ] : constant-expression*/- struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype)+ struct Denoted* parse_struct_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denotation_Prototype *prototype){struct Denoted *hold;- if(get_and_check(tokens,KW_COLUMN))+ if(get_and_check(translation_data,KW_COLUMN)){/*unnamed bitfields are possible*/struct Denoted_Object *obj;obj=(struct Denoted_Object*)get_denoted_object(NULL,SC_NONE,prototype->type);- obj->object->type=get_type_bitfield(prototype->type,parse_expression(tokens,scope));+ obj->object->type=get_type_bitfield(prototype->type,parse_expression(translation_data,scope));return (struct Denoted*)obj;}else{- hold=parse_declarator(tokens,scope,prototype);- if(get_and_check(tokens,KW_COLUMN))+ hold=parse_declarator(translation_data,scope,prototype);+ if(get_and_check(translation_data,KW_COLUMN)){if(hold->denotation==DT_Object){- ((struct Denoted_Object*)hold)->object->type=get_type_bitfield(((struct Denoted_Object*)hold)->object->type,parse_expression(tokens,scope));+ ((struct Denoted_Object*)hold)->object->type=get_type_bitfield(((struct Denoted_Object*)hold)->object->type,parse_expression(translation_data,scope));return hold;}else{/*TODO error*/+ push_translation_error("bitfield must be ",translation_data);return get_denoted_error(hold);}}elseenum-specifier-finish{ ( enumeration-constant [ = constant-expression ] , )* }*/- void parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Enum *enumeration)+ void parse_enum_specifier_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Enum *enumeration){struct token *id;struct Denoted_Enum_Const *hold;int where_in_enumeration=0;- if(get_and_check(tokens,KW_OPEN_CURLY))+ if(get_and_check(translation_data,KW_OPEN_CURLY)){enumeration->is_finished=1;do{- if(check(tokens,KW_ID,0))+ if(check(translation_data,KW_ID,0)){- id=Queue_Pop(tokens);- if(get_and_check(tokens,KW_EQ))+ id=Queue_Pop(translation_data->tokens);+ if(get_and_check(translation_data,KW_EQ)){- hold=(struct Denoted_Enum_Const*)get_denoted_enum_const_expr(id,enumeration,parse_expression(tokens,scope));+ hold=(struct Denoted_Enum_Const*)get_denoted_enum_const_expr(id,enumeration,parse_expression(translation_data,scope));Queue_Push(enumeration->consts,hold);where_in_enumeration=hold->value+1;}elseQueue_Push(enumeration->consts,get_denoted_enum_const_num(id,enumeration,where_in_enumeration));++where_in_enumeration;}- if(!get_and_check(tokens,KW_COMMA) && get_and_check(tokens,KW_CLOSE_CURLY))+ if(!get_and_check(translation_data,KW_COMMA) && get_and_check(translation_data,KW_CLOSE_CURLY)){return;}else{/*TODO error*/+ push_translation_error("enum definition error",translation_data);Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}}else{/*TODO error*/+ push_translation_error("enum definition error, expected an id",translation_data);Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}- }while(!get_and_check(tokens,KW_CLOSE_CURLY));+ }while(!get_and_check(translation_data,KW_CLOSE_CURLY));}}parameter-list:(declaratoion-specifiers (declarator | abstract-declarator),)+*/- void parse_paramenter_list(struct Queue *tokens,struct Scope *function_prototype_scope,struct Queue *parameters)+ void parse_paramenter_list(struct Translation_Data *translation_data,struct Scope *function_prototype_scope,struct Queue *parameters){- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ if(get_and_check(translation_data,KW_CLOSE_NORMAL))return;struct Denotation_Prototype *prototype;temp.denotation=DT_Prototype;do{- prototype=parse_declaration_specifiers(tokens,function_prototype_scope);+ prototype=parse_declaration_specifiers(translation_data,function_prototype_scope);temp.id=NULL;temp.type=prototype->type;- parse_declarator_inner(tokens,function_prototype_scope,&temp);+ parse_declarator_inner(translation_data,function_prototype_scope,&temp);hold=extract_denoted(&temp,prototype,1);Queue_Push(parameters,hold);free(prototype);- }while(get_and_check(tokens,KW_COMMA));- if(!get_and_check(tokens,KW_CLOSE_NORMAL))+ }while(get_and_check(translation_data,KW_COMMA));+ if(!get_and_check(translation_data,KW_CLOSE_NORMAL)){/*TODO error*/+ push_translation_error("expected a ')' finishing the parameter list",translation_data);Queue_Push(parameters,get_denoted_error(NULL));return;}type-name:specifier-qualifier-list [abstract-declarator]*/- struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope)+ struct Type* parse_type_name(struct Translation_Data *translation_data,struct Scope *scope){struct Denotation_Prototype *prototype;struct Type *ret;- prototype=parse_specifier_qualifier_list(tokens,scope);- ret=parse_abstract_declarator(tokens,scope,prototype->type);+ prototype=parse_specifier_qualifier_list(translation_data,scope);+ ret=parse_abstract_declarator(translation_data,scope,prototype->type);free(prototype);return ret;}abstract-declarator:( pointer )* abstract-direct-declarator*/- struct Type* parse_abstract_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base)+ struct Type* parse_abstract_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Type *base){struct Denoted_Base hold;hold.denotation=DT_Prototype;hold.id=NULL;hold.type=base;- parse_declarator_inner(tokens,scope,&hold);+ parse_declarator_inner(translation_data,scope,&hold);if(hold.denotation==DT_Error || hold.id!=NULL){/*TODO error*/+ push_translation_error("unexpedted id in abstract declarator",translation_data);return get_type_error(hold.type);}return hold.type;assignment-expression{ initializer , ... [,] }*/- struct AST* parse_initializer(struct Queue *tokens,struct Scope *scope,struct Denoted_Object *base)+ struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base){}F diff --git a/parse/parse_declaration.h b/parse/parse_declaration.h --- a/parse/parse_declaration.h +++ b/parse/parse_declaration.hstruct Enum;- void parse_declaration(struct Queue *tokens,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions);- struct Denotation_Prototype* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope);- struct Denotation_Prototype* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope);- struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Queue *tokens,struct Scope *scope,char parse_storage_class);- struct Denoted* parse_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype);- void parse_declarator_inner(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);- void parse_direct_declarator(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);- void parse_direct_declarator_finish(struct Queue *tokens,struct Scope *scope,struct Denoted_Base *base);- void parse_struct_union_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Struct_Union *base);- char parse_struct_declaration(struct Queue *tokens,struct Scope *struct_scope,struct Queue* members);- struct Denoted* parse_struct_declarator(struct Queue *tokens,struct Scope *scope,struct Denotation_Prototype *prototype);- void parse_enum_specifier_finish(struct Queue *tokens,struct Scope *scope,struct Enum *enumeration);- void parse_paramenter_list(struct Queue *tokens,struct Scope *function_prototype_scope,struct Queue *parameters);- struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope);- struct Type* parse_abstract_declarator(struct Queue *tokens,struct Scope *scope,struct Type *base);- struct AST* parse_initializer(struct Queue *tokens,struct Scope *scope,struct Denoted_Object *base);+ void parse_declaration(struct Translation_Data *translation_data,struct Scope *scope,struct Queue *where_to_push,char parse_function_definitions);+ struct Denotation_Prototype* parse_specifier_qualifier_list(struct Translation_Data *translation_data,struct Scope *scope);+ struct Denotation_Prototype* parse_declaration_specifiers(struct Translation_Data *translation_data,struct Scope *scope);+ struct Denotation_Prototype* parse_declaration_specifiers_inner(struct Translation_Data *translation_data,struct Scope *scope,char parse_storage_class);+ struct Denoted* parse_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denotation_Prototype *prototype);+ void parse_declarator_inner(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base);+ void parse_direct_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base);+ void parse_direct_declarator_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Base *base);+ void parse_struct_union_specifier_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Struct_Union *base);+ char parse_struct_declaration(struct Translation_Data *translation_data,struct Scope *struct_scope,struct Queue* members);+ struct Denoted* parse_struct_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Denotation_Prototype *prototype);+ void parse_enum_specifier_finish(struct Translation_Data *translation_data,struct Scope *scope,struct Enum *enumeration);+ void parse_paramenter_list(struct Translation_Data *translation_data,struct Scope *function_prototype_scope,struct Queue *parameters);+ struct Type* parse_type_name(struct Translation_Data *translation_data,struct Scope *scope);+ struct Type* parse_abstract_declarator(struct Translation_Data *translation_data,struct Scope *scope,struct Type *base);+ struct AST* parse_initializer(struct Translation_Data *translation_data,struct Scope *scope,struct Denoted_Object *base);#endifF diff --git a/parse/parse_expression.c b/parse/parse_expression.c --- a/parse/parse_expression.c +++ b/parse/parse_expression.c- struct AST* parse_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_expression(struct Translation_Data *translation_data,struct Scope *scope){- return parse_comma_expression(tokens,scope);+ return parse_comma_expression(translation_data,scope);}- struct AST* parse_const_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_const_expression(struct Translation_Data *translation_data,struct Scope *scope){- return parse_comma_expression(tokens,scope);+ return parse_comma_expression(translation_data,scope);}/*primary-expression:generic-selection*/- struct AST* parse_primary_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_primary_expression(struct Translation_Data *translation_data,struct Scope *scope){struct token *hold_token;struct AST *hold;- if(tokens->size==0)+ if(translation_data->tokens->size==0){/*TODO error*/return (struct AST*)get_error_tree(NULL);}- hold_token=Queue_Pop(tokens);+ hold_token=Queue_Pop(translation_data->tokens);switch(hold_token->type){case KW_NUMBER:case KW_ID:return (struct AST*)get_lvalue_expression_tree(hold_token,scope);case KW_OPEN_NORMAL:- hold=parse_expression(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ hold=parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){return (struct AST*)hold;}else(e)*\)*/- struct AST_Function_Expression* parse_arglist(struct Queue *tokens,struct Scope *scope,struct AST* id)+ struct AST_Function_Expression* parse_arglist(struct Translation_Data *translation_data,struct Scope *scope,struct AST* id){struct AST_Function_Expression *ret;ret=get_function_expression_tree(id,scope);ret->id=id;- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){return ret;}do{- Queue_Push(&ret->arguments,parse_assignment_expression(tokens,scope));- } while(get_and_check(tokens,KW_COMMA));- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ Queue_Push(&ret->arguments,parse_assignment_expression(translation_data,scope));+ } while(get_and_check(translation_data,KW_COMMA));+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){return ret;}elseprimary_expression ( ++ | -- | \[ expression \] | .id | ->id | \( arglist \) )**/- struct AST* parse_postfix_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_postfix_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;struct AST *hold_expr;- hold=parse_primary_expression(tokens,scope);+ hold=parse_primary_expression(translation_data,scope);- while(tokens->size!=0)+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_PLUSPLUS:- chomp(tokens);+ chomp(translation_data);hold=(struct AST*)get_unary_expression_tree(hold,OP_POSTFIX_INC);break;case KW_MINUSMINUS:- chomp(tokens);+ chomp(translation_data);hold=(struct AST*)get_unary_expression_tree(hold,OP_POSTFIX_DEC);break;case KW_DOT:- chomp(tokens);- if(check(tokens,KW_ID,0))+ chomp(translation_data);+ if(check(translation_data,KW_ID,0)){- hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(tokens),scope),OP_MEMBER);+ hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(translation_data->tokens),scope),OP_MEMBER);}break;case KW_ARROW:- chomp(tokens);- if(check(tokens,KW_ID,0))+ chomp(translation_data);+ if(check(translation_data,KW_ID,0)){- hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(tokens),scope),OP_MEMBER_TROUGH_PTR);+ hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(translation_data->tokens),scope),OP_MEMBER_TROUGH_PTR);}break;case KW_OPEN_SQUARE:- chomp(tokens);- if(get_and_check(tokens,KW_CLOSE_SQUARE))+ chomp(translation_data);+ if(get_and_check(translation_data,KW_CLOSE_SQUARE)){hold=(struct AST*)get_binary_expression_tree(hold,NULL,OP_ARR_SUBSCRIPT);}else{- hold_expr=parse_expression(tokens,scope);+ hold_expr=parse_expression(translation_data,scope);hold=(struct AST*)get_binary_expression_tree(hold,hold_expr,OP_ARR_SUBSCRIPT);- if(!get_and_check(tokens,KW_CLOSE_SQUARE))+ if(!get_and_check(translation_data,KW_CLOSE_SQUARE)){return (struct AST*)get_error_tree(hold);}}break;case KW_OPEN_NORMAL:- chomp(tokens);- return (struct AST*)parse_arglist(tokens,scope,hold);+ chomp(translation_data);+ return (struct AST*)parse_arglist(translation_data,scope,hold);break;default:unary-expression(type)cast-expression*/- struct AST* parse_cast_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_cast_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST_Unary_Expression *ret;- if(get_and_check(tokens,KW_OPEN_NORMAL))+ if(get_and_check(translation_data,KW_OPEN_NORMAL)){- if(is_type(tokens,scope))+ if(is_type(translation_data,scope)){ret=get_unary_expression_tree(NULL,OP_CAST);- ret->value_type=parse_type_name(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ ret->value_type=parse_type_name(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- ret->operand=parse_cast_expression(tokens,scope);+ ret->operand=parse_cast_expression(translation_data,scope);return (struct AST*)ret;}else{}else{- return (struct AST*)parse_unary_expression(tokens,scope);+ return (struct AST*)parse_unary_expression(translation_data,scope);}}else{- return parse_unary_expression(tokens,scope);+ return parse_unary_expression(translation_data,scope);}}/**/- struct AST* parse_unary_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_unary_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST_Unary_Expression *hold;- if(tokens->size==0)+ if(translation_data->tokens->size==0){/*TODO error*/return (struct AST*)get_error_tree(NULL);}/*TODO make it iterative*/- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_PLUSPLUS:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_PREFIX_INC);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_PREFIX_INC);case KW_MINUSMINUS:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_PREFIX_DEC);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_PREFIX_DEC);case KW_PLUS:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_UNARY_PLUS);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_UNARY_PLUS);case KW_MINUS:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_UNARY_MINUS);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_UNARY_MINUS);case KW_EXCLAMATION:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_LOGICAL_NOT);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_LOGICAL_NOT);case KW_TILDE:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_BITWISE_NOT);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_BITWISE_NOT);case KW_STAR:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_DEREFERENCE);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_DEREFERENCE);case KW_AND:- chomp(tokens);- return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_ADDR_OF);+ chomp(translation_data);+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(translation_data,scope),OP_ADDR_OF);case KW_SIZEOF:- chomp(tokens);- if(get_and_check(tokens,KW_OPEN_NORMAL))+ chomp(translation_data);+ if(get_and_check(translation_data,KW_OPEN_NORMAL)){hold=get_unary_expression_tree(NULL,OP_CAST);- hold->value_type=parse_type_name(tokens,scope);- hold->operand=parse_unary_expression(tokens,scope);+ hold->value_type=parse_type_name(translation_data,scope);+ hold->operand=parse_unary_expression(translation_data,scope);return (struct AST*)hold;}else{- return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_SIZEOF);+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(translation_data,scope),OP_SIZEOF);}default:- return parse_postfix_expression(tokens,scope);+ return parse_postfix_expression(translation_data,scope);}}multiplicative-expression:cast-expression ( ( * | / | % ) cast-expression )**/- struct AST* parse_multiplicative_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_multiplicative_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_cast_expression(tokens,scope);- while(tokens->size!=0)+ hold=parse_cast_expression(translation_data,scope);+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_STAR:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_MUL);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_MUL);break;case KW_FORWARD_SLASH:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_DIV);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_DIV);break;case KW_PERCENT:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_REMAINDER);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(translation_data,scope),OP_REMAINDER);break;default:return hold;additive-expression:multiplicative-expression ( ( + | - ) multiplicative )**/- struct AST* parse_additive_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_additive_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_multiplicative_expression(tokens,scope);+ hold=parse_multiplicative_expression(translation_data,scope);- while(tokens->size!=0)+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_PLUS:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(tokens,scope),OP_ADDITION);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(translation_data,scope),OP_ADDITION);break;case KW_MINUS:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(tokens,scope),OP_SUBTRACTION);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(translation_data,scope),OP_SUBTRACTION);break;default:return hold;bitwise-shift:additive-expression ( ( << | >> ) additive-expression)**/- struct AST* parse_shift_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_shift_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_additive_expression(tokens,scope);+ hold=parse_additive_expression(translation_data,scope);- while(tokens->size!=0)+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_SHIFT_LEFT:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(tokens,scope),OP_SHIFT_LEFT);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(translation_data,scope),OP_SHIFT_LEFT);break;case KW_SHIFT_RIGHT:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(tokens,scope),OP_SHIFT_RIGHT);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(translation_data,scope),OP_SHIFT_RIGHT);break;default:return hold;shift-expression ( ( < | > | <= | >= ) shift-expression )**/- struct AST* parse_relational_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_relational_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_shift_expression(tokens,scope);+ hold=parse_shift_expression(translation_data,scope);- while(tokens->size!=0)+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_LESS:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_LESS);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_LESS);break;case KW_LESS_EQ:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_LESS_EQ);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_LESS_EQ);break;case KW_MORE:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_GREATER);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_GREATER);break;case KW_MORE_EQ:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_GREATER_EQ);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(translation_data,scope),OP_GREATER_EQ);break;default:return hold;equality-expression:realtional-expression ( ( == | != ) relational-expression )**/- struct AST* parse_equality_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_equality_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_relational_expression(tokens,scope);+ hold=parse_relational_expression(translation_data,scope);- while(tokens->size!=0)+ while(translation_data->tokens->size!=0){- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_EQEQ:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(tokens,scope),OP_EQUAL);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(translation_data,scope),OP_EQUAL);break;case KW_NOT_EQ:- chomp(tokens);- hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(tokens,scope),OP_NOT_EQUAL);+ chomp(translation_data);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(translation_data,scope),OP_NOT_EQUAL);break;default:return hold;and-expression:equality-expression ( & equality-expression ) **/- struct AST* parse_and_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_and_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_equality_expression(tokens,scope);- while(get_and_check(tokens,KW_AND))+ hold=parse_equality_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_AND)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_equality_expression(tokens,scope),OP_BITWISE_AND);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_equality_expression(translation_data,scope),OP_BITWISE_AND);}return hold;}and-expression (^ and-expression)**/- struct AST* parse_exclusive_or_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_exclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_and_expression(tokens,scope);- while(get_and_check(tokens,KW_HAT))+ hold=parse_and_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_HAT)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_and_expression(tokens,scope),OP_BITWISE_XOR);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_and_expression(translation_data,scope),OP_BITWISE_XOR);}return hold;inclusive-or-expression:exclusive-or-expression (|exclusive-or-expression)**/- struct AST* parse_inclusive_or_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_inclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_exclusive_or_expression(tokens,scope);- while(get_and_check(tokens,KW_PIPE))+ hold=parse_exclusive_or_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_PIPE)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_exclusive_or_expression(tokens,scope),OP_BITWISE_OR);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_exclusive_or_expression(translation_data,scope),OP_BITWISE_OR);}return hold;}logical-and-expression:inclusive-or-expression(&&inclusive-or-expression)**/- struct AST* parse_logical_and_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_logical_and_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_inclusive_or_expression(tokens,scope);- while(get_and_check(tokens,KW_AND_AND))+ hold=parse_inclusive_or_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_AND_AND)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_inclusive_or_expression(tokens,scope),OP_LOGICAL_AND);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_inclusive_or_expression(translation_data,scope),OP_LOGICAL_AND);}return hold;}logical-or-expression:logical-and-expression ( || logical-and-expression )**/- struct AST* parse_logical_or_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_logical_or_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_logical_and_expression(tokens,scope);- while(get_and_check(tokens,KW_AND_AND))+ hold=parse_logical_and_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_AND_AND)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_logical_and_expression(tokens,scope),OP_LOGICAL_OR);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_logical_and_expression(translation_data,scope),OP_LOGICAL_OR);}return hold;}logical-or-expressionlogical-or-expression?expression:conditional-expression*/- struct AST* parse_conditional_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_conditional_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_logical_or_expression(tokens,scope);- if(get_and_check(tokens,KW_QUESTION))+ hold=parse_logical_or_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_QUESTION)){- hold=(struct AST*)get_conditional_expression_tree(hold,parse_expression(tokens,scope),NULL);- if(get_and_check(tokens,KW_COLUMN))+ hold=(struct AST*)get_conditional_expression_tree(hold,parse_expression(translation_data,scope),NULL);+ if(get_and_check(translation_data,KW_COLUMN)){- ((struct AST_Conditional_Expression*)hold)->right=parse_conditional_expression(tokens,scope);+ ((struct AST_Conditional_Expression*)hold)->right=parse_conditional_expression(translation_data,scope);return hold;}else{conditional-expressionunary-expression ( ( = | += | -= | %= | /= | *= | >>= | <<= | &= | |= | ^= ) assignment-expression*/- struct AST* parse_assignment_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_assignment_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- if(tokens->size==0)+ if(translation_data->tokens->size==0){/*TODO error*/return (struct AST*)get_error_tree(NULL);}- hold=parse_conditional_expression(tokens,scope);- if(tokens->size==0)+ hold=parse_conditional_expression(translation_data,scope);+ if(translation_data->tokens->size==0)return hold;/*TODO make it iterative*/- switch(((struct token*)tokens->first->data)->type)+ switch(((struct token*)translation_data->tokens->first->data)->type){case KW_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_ASSIGN);case KW_PLUS_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_ADD_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_ADD_ASSIGN);case KW_MINUS_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SUBTRACT_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SUBTRACT_ASSIGN);case KW_PERCENT_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_REMAINDER_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_REMAINDER_ASSIGN);case KW_DIV_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_DIV_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_DIV_ASSIGN);case KW_STAR_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_MULTIPLY_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_MULTIPLY_ASSIGN);case KW_SHIFT_RIGHT_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SHIFT_RIGHT_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SHIFT_RIGHT_ASSIGN);case KW_SHIFT_LEFT_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SHIFT_LEFT_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_SHIFT_LEFT_ASSIGN);case KW_AND_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_AND_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_AND_ASSIGN);case KW_PIPE_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_PIPE_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_PIPE_ASSIGN);case KW_HAT_EQ:- chomp(tokens);- return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_XOR_ASSIGN);+ chomp(translation_data);+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_XOR_ASSIGN);default:return hold;}comma-expression:assignment-expression(,assignment-expression)**/- struct AST* parse_comma_expression(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_comma_expression(struct Translation_Data *translation_data,struct Scope *scope){struct AST *hold;- hold=parse_assignment_expression(tokens,scope);- while(get_and_check(tokens,KW_COMMA))+ hold=parse_assignment_expression(translation_data,scope);+ while(get_and_check(translation_data,KW_COMMA)){- hold=(struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_COMMA);+ hold=(struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(translation_data,scope),OP_COMMA);}return hold;}F diff --git a/parse/parse_expression.h b/parse/parse_expression.h --- a/parse/parse_expression.h +++ b/parse/parse_expression.h#include <lexer.h>#include <parse_declaration.h>#include <ast.h>- #include<limits.h>+ #include <limits.h>- struct AST* parse_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_const_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_primary_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_const_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_primary_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST_Function_Expression* parse_arglist(struct Queue *tokens,struct Scope *scope,struct AST* id);- struct AST* parse_postfix_expression(struct Queue *tokens,struct Scope *scope);+ struct AST_Function_Expression* parse_arglist(struct Translation_Data *translation_data,struct Scope *scope,struct AST* id);+ struct AST* parse_postfix_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST* parse_cast_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_unary_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_cast_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_unary_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST* parse_multiplicative_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_multiplicative_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST* parse_additive_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_additive_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST* parse_shift_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_shift_expression(struct Translation_Data *translation_data,struct Scope *scope);- struct AST* parse_relational_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_equality_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_and_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_exclusive_or_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_inclusive_or_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_logical_and_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_logical_or_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_conditional_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_assignment_expression(struct Queue *tokens,struct Scope *scope);- struct AST* parse_comma_expression(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_relational_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_equality_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_and_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_exclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_inclusive_or_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_logical_and_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_logical_or_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_conditional_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_assignment_expression(struct Translation_Data *translation_data,struct Scope *scope);+ struct AST* parse_comma_expression(struct Translation_Data *translation_data,struct Scope *scope);F diff --git a/parse/parse_statement.c b/parse/parse_statement.c --- a/parse/parse_statement.c +++ b/parse/parse_statement.c#ifndef PARSE_GCC_STATEMENT_C#define PARSE_GCC_STATEMENT_C PARSE_GCC_STATEMENT_C#include "parse_statement.h"- #include "parse_declaration.h"- struct AST* parse_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_statement(struct Translation_Data* translation_data,struct Scope *scope){- if(tokens->size==0)+ if(translation_data->tokens->size==0)return NULL;- switch(kw_get(tokens))+ switch(kw_get(translation_data)){case KW_NOTYPE:return (struct AST*)get_error_tree(NULL);case KW_OPEN_CURLY:- chomp(tokens);- return parse_finish_compound_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_compound_statement(translation_data,scope);case KW_IF:- chomp(tokens);- return parse_finish_if_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_if_statement(translation_data,scope);case KW_SWITCH:- chomp(tokens);- return parse_finish_switch_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_switch_statement(translation_data,scope);case KW_WHILE:- chomp(tokens);- return parse_finish_while_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_while_statement(translation_data,scope);case KW_DO:- chomp(tokens);- return parse_finish_do_while_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_do_while_statement(translation_data,scope);case KW_FOR:- chomp(tokens);- return parse_finish_for_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_for_statement(translation_data,scope);case KW_GOTO:- chomp(tokens);- return parse_finish_goto_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_goto_statement(translation_data,scope);case KW_CASE:- chomp(tokens);- return parse_finish_labeled_statement(tokens,scope,ST_CASE);+ chomp(translation_data);+ return parse_finish_labeled_statement(translation_data,scope,ST_CASE);case KW_DEFAULT:- chomp(tokens);- return parse_finish_default_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_default_statement(translation_data,scope);case KW_ID:/*TODO check if id is in function scope*/if(0){- return parse_finish_labeled_statement(tokens,scope,ST_LABEL);+ return parse_finish_labeled_statement(translation_data,scope,ST_LABEL);}else{- return parse_expression_statement(tokens,scope);+ return parse_expression_statement(translation_data,scope);}case KW_CONTINUE:- chomp(tokens);- return parse_finish_continue_statement(tokens);+ chomp(translation_data);+ return parse_finish_continue_statement(translation_data);case KW_BREAK:- chomp(tokens);- return parse_finish_break_statement(tokens);+ chomp(translation_data);+ return parse_finish_break_statement(translation_data);case KW_RETURN:- chomp(tokens);- return parse_finish_return_statement(tokens,scope);+ chomp(translation_data);+ return parse_finish_return_statement(translation_data,scope);default:- return parse_expression_statement(tokens,scope);+ return parse_expression_statement(translation_data,scope);}/*( declaration | statement )* }*/- struct AST* parse_finish_compound_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_Compound_Statement *hold;hold=get_compound_statement_tree(scope);- while(!get_and_check(tokens,KW_CLOSE_CURLY))+ while(!get_and_check(translation_data,KW_CLOSE_CURLY)){- if(is_type(tokens,hold->scope))+ if(is_type(translation_data,hold->scope)){- parse_declaration(tokens,hold->scope,&hold->components,0);+ parse_declaration(translation_data,hold->scope,&hold->components,0);}else{- Queue_Push(&hold->components,parse_statement(tokens,hold->scope));+ Queue_Push(&hold->components,parse_statement(translation_data,hold->scope));}}( expression ) statement( expression ) statement else statement*/- struct AST* parse_finish_if_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_If_Statement *hold;hold=get_if_statement_tree();- if(get_and_check(tokens,KW_OPEN_NORMAL))+ if(get_and_check(translation_data,KW_OPEN_NORMAL)){- hold->condition=parse_expression(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ hold->condition=parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(tokens,scope);+ hold->body_statement=parse_statement(translation_data,scope);}else{return (struct AST*)get_error_tree((struct AST*)hold);}- if(get_and_check(tokens,KW_ELSE))+ if(get_and_check(translation_data,KW_ELSE)){- hold->else_statement=parse_statement(tokens,scope);+ hold->else_statement=parse_statement(translation_data,scope);return (struct AST*)hold;}else{/*( expression ) statement*/- struct AST* parse_finish_switch_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_Switch_Statement *hold;hold=get_switch_statement_tree();- if(get_and_check(tokens,KW_OPEN_NORMAL))+ if(get_and_check(translation_data,KW_OPEN_NORMAL)){- hold->condition=parse_expression(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ hold->condition=parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(tokens,scope);+ hold->body_statement=parse_statement(translation_data,scope);}else{return (struct AST*)get_error_tree((struct AST*)hold);( expression ) statement*/- struct AST* parse_finish_while_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_While_Statement *hold;hold=get_while_statement_tree();- if(get_and_check(tokens,KW_OPEN_NORMAL))+ if(get_and_check(translation_data,KW_OPEN_NORMAL)){- hold->condition=parse_expression(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ hold->condition=parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){- hold->body_statement=parse_statement(tokens,scope);+ hold->body_statement=parse_statement(translation_data,scope);}else{return (struct AST*)get_error_tree((struct AST*)hold);/*statement while ( expression ) ;*/- struct AST* parse_finish_do_while_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_Do_While_Statement *hold;hold=get_do_while_statement_tree();- hold->body_statement=parse_statement(tokens,scope);- if(get_and_check(tokens,KW_WHILE) && get_and_check(tokens,KW_OPEN_NORMAL))+ hold->body_statement=parse_statement(translation_data,scope);+ if(get_and_check(translation_data,KW_WHILE) && get_and_check(translation_data,KW_OPEN_NORMAL)){- hold->condition=parse_expression(tokens,scope);+ hold->condition=parse_expression(translation_data,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL) && get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_CLOSE_NORMAL) && get_and_check(translation_data,KW_SEMI_COLUMN)){return (struct AST*)hold;}else/*( [ expression ] ; [ expression ] ; [ expression ] ) statement*/- struct AST* parse_finish_for_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_For_Statement *hold;hold=get_for_statement_tree();- if(!get_and_check(tokens,KW_OPEN_NORMAL))+ if(!get_and_check(translation_data,KW_OPEN_NORMAL))return (struct AST*)get_error_tree((struct AST*)hold);- hold->initialisation=parse_expression_statement(tokens,scope);- hold->condition=parse_expression_statement(tokens,scope);- if(get_and_check(tokens,KW_CLOSE_NORMAL))+ hold->initialisation=parse_expression_statement(translation_data,scope);+ hold->condition=parse_expression_statement(translation_data,scope);+ if(get_and_check(translation_data,KW_CLOSE_NORMAL)){hold->update=get_nop_tree();}else{- hold->update=parse_expression(tokens,scope);- if(!get_and_check(tokens,KW_CLOSE_NORMAL))+ hold->update=parse_expression(translation_data,scope);+ if(!get_and_check(translation_data,KW_CLOSE_NORMAL))return (struct AST*)get_error_tree((struct AST*)hold);}- hold->body_statement=parse_statement(tokens,scope);+ hold->body_statement=parse_statement(translation_data,scope);return (struct AST*)hold;}/*id ;*/- struct AST* parse_finish_goto_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST* ret;- if(check(tokens,KW_ID,0))+ if(check(translation_data,KW_ID,0)){- ret=(struct AST*)get_goto_statement_tree(Queue_Pop(tokens),scope);- if(get_and_check(tokens,KW_SEMI_COLUMN))+ ret=(struct AST*)get_goto_statement_tree(Queue_Pop(translation_data->tokens),scope);+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return ret;}else/*;*/- struct AST* parse_finish_continue_statement(struct Queue* tokens)+ struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data){struct AST *hold;hold=malloc(sizeof(struct AST));hold->type=ST_CONTINUE;- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return hold;}else/*;*/- struct AST* parse_finish_break_statement(struct Queue* tokens)+ struct AST* parse_finish_break_statement(struct Translation_Data* translation_data){struct AST *hold;hold=malloc(sizeof(struct AST));hold->type=ST_BREAK;- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return hold;}elseid:statement*/- struct AST* parse_finish_labeled_statement(struct Queue* tokens,struct Scope *scope,enum AST_Type type)+ struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,enum AST_Type type){struct AST_Labeled_Statement *ret;- if(check(tokens,KW_ID,0))+ if(check(translation_data,KW_ID,0)){- ret=get_labeled_statement_tree(Queue_Pop(tokens),NULL,scope,type);- if(get_and_check(tokens,KW_COLUMN))+ ret=get_labeled_statement_tree(Queue_Pop(translation_data->tokens),NULL,scope,type);+ if(get_and_check(translation_data,KW_COLUMN)){- ret->statement=parse_statement(tokens,scope);+ ret->statement=parse_statement(translation_data,scope);return (struct AST*)ret;}else{:statement*/- struct AST* parse_finish_default_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_Labeled_Statement *ret;ret=get_labeled_statement_tree(NULL,NULL,scope,ST_DEFAULT);- if(get_and_check(tokens,KW_COLUMN))+ if(get_and_check(translation_data,KW_COLUMN)){- ret->statement=parse_statement(tokens,scope);+ ret->statement=parse_statement(translation_data,scope);return (struct AST*)ret;}else{[ expression ] ;*/- struct AST* parse_finish_return_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_finish_return_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST_Return_Statement *hold;- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){hold=get_return_statement_tree(get_nop_tree());return (struct AST*)hold;}- hold=get_return_statement_tree(parse_expression(tokens,scope));- if(get_and_check(tokens,KW_SEMI_COLUMN))+ hold=get_return_statement_tree(parse_expression(translation_data,scope));+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return (struct AST*)hold;}else[ expression ] ;*/- struct AST* parse_expression_statement(struct Queue* tokens,struct Scope *scope)+ struct AST* parse_expression_statement(struct Translation_Data* translation_data,struct Scope *scope){struct AST *hold;- if(get_and_check(tokens,KW_SEMI_COLUMN))+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){hold=get_nop_tree();return (struct AST*)hold;}- hold=parse_expression(tokens,scope);- if(get_and_check(tokens,KW_SEMI_COLUMN))+ hold=parse_expression(translation_data,scope);+ if(get_and_check(translation_data,KW_SEMI_COLUMN)){return hold;}elseF diff --git a/parse/parse_statement.h b/parse/parse_statement.h --- a/parse/parse_statement.h +++ b/parse/parse_statement.h#ifndef PARSE_GCC_STATEMENT_H#define PARSE_GCC_STATEMENT_H PARSE_GCC_STATEMENT_H- #include <all.h>+ #include <scope.h>+ #include <ast.h>+ #include <queue.h>+ #include <program.h>- struct Queue;- struct Scope;- enum AST_Type;- struct AST* parse_finish_compound_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_op_e_cl_st(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_if_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_switch_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_do_while_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_while_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_for_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_goto_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_continue_statement(struct Queue* tokens);- struct AST* parse_finish_break_statement(struct Queue* tokens);- struct AST* parse_finish_return_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_expression_statement(struct Queue* tokens,struct Scope *scope);- struct AST* parse_finish_labeled_statement(struct Queue* tokens,struct Scope *scope,enum AST_Type type);- struct AST* parse_finish_default_statement(struct Queue* tokens,struct Scope *scope);+ struct AST* parse_finish_compound_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_op_e_cl_st(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_if_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_switch_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_do_while_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_while_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_for_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_goto_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_continue_statement(struct Translation_Data* translation_data);+ struct AST* parse_finish_break_statement(struct Translation_Data* translation_data);+ struct AST* parse_finish_return_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_expression_statement(struct Translation_Data* translation_data,struct Scope *scope);+ struct AST* parse_finish_labeled_statement(struct Translation_Data* translation_data,struct Scope *scope,enum AST_Type type);+ struct AST* parse_finish_default_statement(struct Translation_Data* translation_data,struct Scope *scope);F diff --git a/parse/parse_translation_unit.c b/parse/parse_translation_unit.c --- a/parse/parse_translation_unit.c +++ b/parse/parse_translation_unit.c#ifndef GCC_PARSE_TRANSLATION_C#define GCC_PARSE_TRANSLATION_C GCC_PARSE_TRANSLATION_C- #include "parse_declaration.h"- #include "parse_statement.h"+ #include <parse_translation_unit.h>+ #include <gcc_error.h>/*translation-unit:declaration [ translation-unit ]function-definition [ translation-unit ]*/- struct AST* parse_translation_unit(struct Queue *tokens,struct Scope *scope)+ struct AST* parse_translation_unit(struct Translation_Data *translation_data,struct Scope *externs){struct AST_Translation_Unit *hold;- hold=get_translation_unit_tree(scope);- while(tokens->size>0)+ hold=get_translation_unit_tree(externs);+ while(translation_data->tokens->size>0){- parse_declaration(tokens,hold->scope,&hold->components,1);+ if(translation_data->errors->size!=0)+ {+ while(translation_data->tokens->size>0)+ free(Queue_Pop(translation_data->tokens));+ break;+ }+ parse_declaration(translation_data,hold->scope,&hold->components,1);}return (struct AST*)hold;F diff --git a/parse/parse_translation_unit.h b/parse/parse_translation_unit.h --- a/parse/parse_translation_unit.h +++ b/parse/parse_translation_unit.h#ifndef GCC_PARSE_TRANSLATION_H#define GCC_PARSE_TRANSLATION_H GCC_PARSE_TRANSLATION_H+ #include <parse_declaration.h>+ #include <parse_statement.h>+ #include <error.h>- struct AST* parse_translation_unit(struct Queue *tokens,struct Scope *scope);+ struct AST* parse_translation_unit(struct Translation_Data *translation_data,struct Scope *externs);#endifF diff --git a/semantics/ast.c b/semantics/ast.c --- a/semantics/ast.c +++ b/semantics/ast.cret=malloc(sizeof(struct AST_Translation_Unit));ret->type=TRANSLATION_UNIT;Queue_Init(&ret->components);- /*TODO*/- //ret->scope=get_scope(parent_scope);- ret->scope=parent_scope;+ ret->scope=get_scope(parent_scope);return ret;}F diff --git a/semantics/gcc_error.c b/semantics/gcc_error.c new file mode 100644 --- /dev/null +++ b/semantics/gcc_error.c+ #ifndef GCC_ERROR_C+ #define GCC_ERROR_C 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)+ {+ struct Translation_Error *ret;+ ret=malloc(sizeof(struct Translation_Error));+ ret->error_message=error_message;+ ret->column=column;+ ret->line=line;+ ret->filename=filename;+ }++ struct Translation_Error* get_translation_error_by_token(const char *error_message,struct token *error_token)+ {+ if(error_token==NULL)+ {+ return get_translation_error(error_message,0,0,"");+ }else+ {+ return get_translation_error(error_message,error_token->column+1,error_token->line+1,error_token->filename);+ }+ }++ void push_translation_error(const char *error_message,struct Translation_Data *translation_data)+ {+ Queue_Push(translation_data->errors,get_translation_error_by_token(error_message,(struct token*)translation_data->tokens->first->data));+ }++ void push_lexing_error(const char *error_message,struct Source_File *src,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));+ }+ void print_translation_error(FILE *out,struct Translation_Error *error)+ {+ 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);+ }+++ #endifF diff --git a/semantics/gcc_error.h b/semantics/gcc_error.h new file mode 100644 --- /dev/null +++ b/semantics/gcc_error.h+ #ifndef GCC_ERROR_H+ #define GCC_ERROR_H GCC_ERROR_H+ #include <gcc_error.hh>+ #include <lexer.h>+ #include <stdio.h>++++ struct Translation_Error+ {+ const char *error_message;+ size_t line,column;+ const char *filename;++ };++++ 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);+ #endifF diff --git a/semantics/gcc_error.hh b/semantics/gcc_error.hh new file mode 100644 --- /dev/null +++ b/semantics/gcc_error.hh+ #ifndef GCC_ERROR_H+ #define GCC_ERROR_H GCC_ERROR_H+++ struct Translation_Error;+++ #endifF diff --git a/semantics/program.c b/semantics/program.c --- a/semantics/program.c +++ b/semantics/program.c#ifndef GCC_PROGRAM_C#define GCC_PROGRAM_C GCC_PROGRAM_C- #/*Don't mind me*/include/*When I grow up I want to be a new line*/"program.h"- #include"parse_translation_unit.h"+ #/*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));- Queue_Init(&ret->translation_units_tokens);- Queue_Init(&ret->source_files);- Map_Init(&ret->defines);- ret->global_scope=get_scope(NULL);+ ret->translation_units=malloc(sizeof(struct Queue));+ ret->source_files=malloc(sizeof(struct Queue));+ ret->errors=malloc(sizeof(struct Queue));- ret->number_of_translation_units=0;- ret->translation_units=NULL;+ Queue_Init(ret->translation_units);+ Queue_Init(ret->source_files);+ Queue_Init(ret->errors);+ ret->externs=get_scope(NULL);return ret;}- struct Source_File* get_source_file(char *name_of_file)+ struct Source_File* extract_source_file(FILE *in,struct Source_Name *name){- FILE *in;size_t file_size;struct Source_File *src;- in=fopen(name_of_file,"r");- if(in==NULL)- {- /*error*/- return NULL;- }fseek(in,0,SEEK_END);file_size=ftell(in);rewind(in);src=malloc(sizeof(struct Source_File));- src->src_name=name_of_file;++ src->src_name=name;+src->src=malloc(file_size+1);src->src_size=file_size;src->where_in_src=0;fclose(in);return src;}- struct Queue* lex_source_file(char *name_of_file,struct Program* program)+ struct Translation_Data* get_translation_data(){- struct Source_File *src;- src=get_source_file(name_of_file);+ 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);- Queue_Push(&program->translation_units_tokens,lex(src,program));- Queue_Push(&program->source_files,src);+ return ret;}- void lex_program(char *name_of_file,struct Program *program)+ struct Source_Name* get_source_name(char *filename,char *base){- lex_source_file(name_of_file,program);+ 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;+ struct Source_Name *name;+ assert(where_to_search!=NULL);+ assert(*where_to_search!=NULL);+ do+ {+ temp_name=gstr_append(*where_to_search,filename);+ in=fopen(temp_name,"r+");+ if(in!=NULL)+ {+ free(temp_name);+ name=get_source_name(filename,*where_to_search);+ return extract_source_file(in,name);+ }+ free(temp_name);+ }while(*(++where_to_search));+ return NULL;}- void parse_program(struct Program *program)+ /*this might cause compatability issues TODO*/+ void normalise_source_name(struct Source_Name *name){+ size_t offset;size_t i;- program->translation_units=malloc(sizeof(struct AST*) * program->translation_units_tokens.size);- program->number_of_translation_units=program->translation_units_tokens.size;- for(i=0;i<program->number_of_translation_units;++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);+ 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};++ assert(base_source_names!=NULL);++ if(*base_source_names==NULL){- program->translation_units[i]=parse_translation_unit(- Queue_Pop(&program->translation_units_tokens),- program->global_scope- );+ return NULL;}++ program=get_program();+ hold_translation_data=get_translation_data();+ do+ {+ base_file=get_source_file(*base_source_names,this_directory);+ if(base_file==NULL)+ {+ /*TODO error*/+ continue;+ }else+ {+ Queue_Push(hold_translation_data->source_files,base_file);+ lex(base_file,hold_translation_data);+ Queue_Push(program->translation_units,parse_translation_unit(hold_translation_data,program->externs));++ while(hold_translation_data->tokens->size!=0)+ {+ free(Queue_Pop(hold_translation_data->tokens));+ }++ Queue_Append(program->errors,hold_translation_data->errors);+ Queue_Init(hold_translation_data->errors);+ }+ }while(*(++base_source_names));++ Queue_Append(program->source_files,hold_translation_data->source_files);++ free(hold_translation_data->errors);+ free(hold_translation_data->tokens);+ free(hold_translation_data->source_files);+ free(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);}#endifF diff --git a/semantics/program.h b/semantics/program.h --- a/semantics/program.h +++ b/semantics/program.h#ifndef GCC_PROGRAM_H#define GCC_PROGRAM_H GCC_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>- struct Source_File- {- char *src;- char *src_name;- size_t src_size;- size_t where_in_src;- size_t which_column;- size_t which_row;+ struct Program+ {+ struct Queue *translation_units;+ struct Queue *source_files;+ struct Queue *errors;+ struct Scope *externs;+ };+ struct Translation_Data+ {+ struct Queue *tokens;+ struct Queue *errors;+ struct Queue *source_files;};+ struct Program* get_program();+ struct Source_Name* get_source_name(char *filename,char *base);- struct Program- {+ 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 Queue translation_units_tokens;- struct Queue source_files;- struct Map defines;+ struct Translation_Data* get_translation_data();- size_t number_of_translation_units;- struct AST **translation_units;- struct Scope *global_scope;- };+ struct Program* parse_program(char **base_source_names);+ void lex_program(struct Translation_Data *hold,struct Source_File *file);- struct Program* get_program();- struct Source_File* get_source_file(char *name_of_file);- struct Queue* lex_source_file(char *name_of_file,struct Program *program);- void lex_program(char *name_of_file,struct Program *program);- void parse_program(struct Program *program);#endifF diff --git a/semantics/program.hh b/semantics/program.hh --- a/semantics/program.hh +++ b/semantics/program.hh#ifndef GCC_PROGRAM_HH#define GCC_PROGRAM_HH GCC_PROGRAM_HH- struct Source_File;struct Program;+ struct Translation_Data;#endifF diff --git a/semantics/type.c b/semantics/type.c --- a/semantics/type.c +++ b/semantics/type.creturn (struct Type*)ret;}- char is_type(struct Queue *tokens,struct Scope *scope)+ char is_type(struct Translation_Data *translation_data,struct Scope *scope){struct token *hold;struct Denoted *thing;- hold=tokens->first->data;+ hold=translation_data->tokens->first->data;switch(hold->type){F diff --git a/semantics/type.h b/semantics/type.h --- a/semantics/type.h +++ b/semantics/type.h#include <denoted.h>#include <scope.h>#include <limits.h>+ #include <program.h>#define PTR_SIZE 4struct Type* get_enum_type(struct Denotation_Prototype *prototype);struct Type* get_type_bitfield(struct Type* base,struct AST* number_of_bits);struct Type* get_function_type(struct Type* return_type,struct Queue *parameters,struct Scope* function_prototype_scope);- char is_type(struct Queue *tokens,struct Scope *scope);+ char is_type(struct Translation_Data *translation_data,struct Scope *scope);size_t get_type_size(struct Type *type);F diff --git a/tests/test.c b/tests/test.c --- a/tests/test.c +++ b/tests/test.c- #include "test2.c"+ /**/ #include"test2.c"List ints;int main(){long int c;int a,b;+ struct ke d;c=a+b;return 0;F diff --git a/tests/test2.c b/tests/test2.c --- a/tests/test2.c +++ b/tests/test2.cint s;};typedef int List;++ struct ke asdf;F diff --git a/tests/test3.c b/tests/test3.c new file mode 100644 --- /dev/null +++ b/tests/test3.c+ int main()+ {+ struct A+ {+ int a;+ }as;+ }+ void asd()+ {+++++ struct const; A b;+ long long long short int a;+ }