F diff --git a/lex/preprocessing.c b/lex/preprocessing.c
--- a/lex/preprocessing.c
+++ b/lex/preprocessing.c
free(hold);
parse_define_line(src,translation_data);
return;
+ case PKW_IF:
+ free(hold);
+ //parse_preproc_if_line(src,translation_data);
+ return;
default:
return;
/*TODO error*/
if(hold_file==NULL)
{
/*TODO error*/
- push_translation_error("include error",translation_data);
+ push_lexing_error("file in include directive not found",src,translation_data);
return;
}
}
if(hold_file==NULL)
{
/*TODO error*/
- push_translation_error("include error",translation_data);
+ push_lexing_error("file in include directive not found",src,translation_data);
return;
}
}else
{
/*TODO error*/
- push_translation_error("include error",translation_data);
+ push_lexing_error("include error",src,translation_data);
return;
}
}
hold_index=malloc(sizeof(int));
*hold_index=number_of_arguments;
+ ++number_of_arguments;
Map_Push(new_macro->arguments,hold_token->data,hold_token->data_size,hold_index);
free(hold_token);
hold_token=get_next_token(src,&chonky[0],0);
}
}
free(hold_token);
- ++number_of_arguments;
}
hold_token=get_next_token(src,&chonky[0],0);
- make_define_argument_list(new_macro,number_of_arguments+1);
}else if(hold_token->type==KW_NOTYPE)
{
hold_tokens=translation_data->tokens;
translation_data->tokens=new_macro->macro_tokens;
+
+ new_macro->number_of_arguments=number_of_arguments;
/*there is something in hold_token*/
do{
expand_macro(hold_token,src,translation_data);
Map_Init(ret->arguments);
ret->number_of_arguments=0;
- ret->argument_list=NULL;
return ret;
}
- void make_define_argument_list(struct define_directive* directive,size_t number_of_arguments)
+ /*returns an array of queues*/
+ struct Queue* make_define_argument_list(size_t number_of_arguments)
{
size_t i;
- assert(directive->number_of_arguments==0 && directive->argument_list==NULL);
+ struct Queue *ret;
+
+ if(number_of_arguments==0)
+ return NULL;
- directive->number_of_arguments=number_of_arguments;
- directive->argument_list=malloc(sizeof(struct Queue)*number_of_arguments);
+ ret=malloc(sizeof(struct Queue)*number_of_arguments);
for(i=0;i<number_of_arguments;++i)
{
- Queue_Init(directive->argument_list+i);
+ Queue_Init(ret+i);
}
+ return ret;
+ }
+ void delete_define_argument_list(size_t number_of_arguments,struct Queue *args)
+ {
+ if(number_of_arguments==0)
+ {
+ assert(args==NULL);
+ return;
+ }
+ flush_macro_arguments(number_of_arguments,args);
+ free(args);
}
- void expand_macro_argument(struct Queue *replacement_tokens,struct Translation_Data *translation_data)
+ void expand_macro_argument(struct Queue *replacement_tokens,struct Source_File *src,struct Translation_Data *translation_data)
{
struct Queue_Node *it;
+ struct token *hold_token;
for(it=replacement_tokens->first;it!=NULL;it=it->prev)
{
- Queue_Push(translation_data->tokens,copy_token((struct token*)it->data));
+ hold_token=copy_token((struct token*)it->data);
+ hold_token->line=src->which_row;
+ hold_token->column=src->which_column;
+ Queue_Push(translation_data->tokens,hold_token);
+ //Queue_Push(translation_data->tokens,copy_token((struct token*)it->data));
}
}
- void load_macro_arguments(struct define_directive *macro,struct Source_File *src,struct Translation_Data *translation_data)
+ void load_macro_arguments(struct Queue *args,size_t number_of_arguments,struct Source_File *src,struct Translation_Data *translation_data)
{
struct token *hold;
struct Queue *hack;
size_t i;
+ size_t j;
- if(macro->number_of_arguments==0)
+ if(number_of_arguments==0)
return;
hold=get_next_token(src,&chonky[0],1);
free(hold);
hack=translation_data->tokens;
- for(i=0;i<macro->number_of_arguments-1;++i)
+ for(i=0;i<number_of_arguments-1;++i)
{
- translation_data->tokens=macro->argument_list+i;
+ translation_data->tokens=args+i;
for(
- hold=get_next_token(src,&chonky[0],1);
+ hold=get_next_token(src,&chonky[0],1),j=0;
hold->type!=KW_COMMA && hold->type!=KW_NOTYPE;
- hold=get_next_token(src,&chonky[0],1)
+ hold=get_next_token(src,&chonky[0],1),++j
)
{
expand_macro(hold,src,translation_data);
free(hold);
goto cleanup;
}
+ if(j==0)
+ {
+ push_lexing_error("expected argument in macro argument list",src,translation_data);
+ free(hold);
+ goto cleanup;
+ }
}
- translation_data->tokens=macro->argument_list+i;
+ translation_data->tokens=args+i;
for(
- hold=get_next_token(src,&chonky[0],1);
+ hold=get_next_token(src,&chonky[0],1),j=0;
hold->type!=KW_CLOSE_NORMAL;
- hold=get_next_token(src,&chonky[0],1)
+ hold=get_next_token(src,&chonky[0],1),++j
)
{
if(hold->type==KW_NOTYPE)
}
expand_macro(hold,src,translation_data);
}
+ if(j==0)
+ {
+ push_lexing_error("expected argument in macro argument list",src,translation_data);
+ free(hold);
+ }
cleanup:
translation_data->tokens=hack;
}
- void flush_macro_arguments(struct define_directive *macro)
+ void flush_macro_arguments(size_t number_of_arguments,struct Queue *args)
{
size_t i;
- for(i=0;i<macro->number_of_arguments;++i)
+ for(i=0;i<number_of_arguments;++i)
{
- while(macro->argument_list[i].size>0)
- free(Queue_Pop(macro->argument_list+i));
+ while(args[i].size>0)
+ free(Queue_Pop(args+i));
}
}
/*macro name token is freed on expansion , if it is not a macro name it is pushed into token queue*/
struct token *hold_token;
int *index;
struct Queue_Node *it;
+ struct Queue *argument_list;
if(macro_name->type==KW_ID)
hold=Map_Check(translation_data->macros,macro_name->data,macro_name->data_size);
if(hold!=NULL)
{
free(macro_name);
- load_macro_arguments(hold,src,translation_data);
+ argument_list=make_define_argument_list(hold->number_of_arguments);
+ load_macro_arguments(argument_list,hold->number_of_arguments,src,translation_data);
if(translation_data->errors->size>0)
+ {
+ delete_define_argument_list(hold->number_of_arguments,argument_list);
return;
+ }
for(it=hold->macro_tokens->first;it!=NULL;it=it->prev)
index=Map_Check(hold->arguments,hold_token->data,hold_token->data_size);
if(index!=NULL)
{
- expand_macro_argument(hold->argument_list+*index,translation_data);
+ expand_macro_argument(argument_list+*index,src,translation_data);
}else
{
- Queue_Push(translation_data->tokens,copy_token(hold_token));
+ hold_token=copy_token(hold_token);
+
+ hold_token->line=src->which_row;
+ hold_token->column=src->which_column;
+
+ Queue_Push(translation_data->tokens,hold_token);
}
}
- flush_macro_arguments(hold);
+ delete_define_argument_list(hold->number_of_arguments,argument_list);
}else
{
/*this isn't a macro, so we just push it to the token queue*/
F diff --git a/lex/preprocessing.h b/lex/preprocessing.h
--- a/lex/preprocessing.h
+++ b/lex/preprocessing.h
/*put arguments here*/
/*an array of token queues*/
size_t number_of_arguments;
- struct Queue *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);
+ void parse_preproc_if_line(struct Source_File *src,struct Translation_Data *translation_data);
+
+
+
+ /*preproc if stuff*/
+ /*
+ TODO
+ TODO
+ TODO
+ TODO
+ char proproc_is_if(struct Source_File *src,struct Translation_Data *translation_data);
+ char proproc_is_else(struct Source_File *src,struct Translation_Data *translation_data);
+ void preproc_find_matching_else(struct Source_File *src,struct Translation_Data *translation_data);
+ void preproc_find_endif(struct Source_File *src,struct Translation_Data *translation_data);
+ TODO
+ TODO
+ TODO
+ TODO
+ */
+
+ /*define stuff*/
+ void expand_macro(struct token* macro_name,struct Source_File *src,struct Translation_Data *translation_data);
- /*define stuff*/
struct define_directive* get_define_directive(struct token* macro_name);
- void make_define_argument_list(struct define_directive* directive,size_t number_of_arguments);
+ struct Queue* make_define_argument_list(size_t number_of_arguments);
- void expand_macro_argument(struct Queue *replacement_tokens,struct Translation_Data *translation_data);
- void load_macro_arguments(struct define_directive *macro,struct Source_File *src,struct Translation_Data *translation_data);
- void flush_macro_arguments(struct define_directive *macro);
- void expand_macro(struct token* macro_name,struct Source_File *src,struct Translation_Data *translation_data);
+ void expand_macro_argument(struct Queue *replacement_tokens,struct Source_File *src,struct Translation_Data *translation_data);
+ void load_macro_arguments(struct Queue *args,size_t number_of_arguments,struct Source_File *src,struct Translation_Data *translation_data);
+ void flush_macro_arguments(size_t number_of_arguments,struct Queue *args);
void parse_define_line(struct Source_File *src,struct Translation_Data *translation_data);
+ void delete_define_argument_list(size_t number_of_arguments,struct Queue *args);
#endif
F diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
}else
{
program=parse_program(command_arguments->source_names);
+ if(program==NULL)
+ return 0;
if(program->errors->size>0)
{
if(!command_arguments->is_quiet)
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
free(Queue_Pop(translation_data->tokens));
break;
}
- parse_declaration(translation_data,hold->scope,&hold->components,1);
+ if(is_type(translation_data,hold->scope) || kw_get(translation_data)==KW_ID)
+ {
+ parse_declaration(translation_data,hold->scope,&hold->components,1);
+ }else
+ {
+ push_translation_error("declaration expected",translation_data);
+ }
}
return (struct AST*)hold;
F diff --git a/semantics/gcc_error.c b/semantics/gcc_error.c
--- a/semantics/gcc_error.c
+++ b/semantics/gcc_error.c
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);
+ return get_translation_error(error_message,error_token->line+1,error_token->column+1,error_token->filename);
}
}
F diff --git a/tests/test3.c b/tests/test3.c
--- a/tests/test3.c
+++ b/tests/test3.c
+ #include "../tests/test.c"
#define max(a,b) (a>b?a:b)
+ #define version 1
+ #define current_version 3
+
+
+
+
int main()
{
- return max(1,3);
+ max(1,1);
+ return version;
}